ソフトウェアの品質を学びまくる

ソフトウェアの品質、ソフトウェアテストなどについて学んだことを記録するブログです。

「ソフトウェアエンジニアリング技術ワークショップ2017 ~人工知能ブームの中でのソフトウェアエンジニアリング~」に参加

 2017年12月15日(金)に、JEITA(一般社団法人 電子情報技術産業協会)の「ソフトウェアエンジニアリング技術ワークショップ2017」に参加してきました。プログラムなどはこちらをご覧ください。
 テーマは「人工知能ブームの中でのソフトウェアエンジニアリング」。とても勉強になった催しでしたので、許される(であろう)範囲でシェアしたいと思います。

 なお、わたしはディープラーニング初学レベル以下です(堂々)。講演者の方のご発言の趣旨を正しく理解できず、間違った要約をしてしまっているかもしれません。申し訳ありませんが、その際はご指摘いただければ修正・削除いたします。

基調講演: 機械学習工学に向けて

 株式会社Preferred Networksの丸山宏さんの基調講演では、機械学習の概要や潮流について、幅広くお話しいただきました。どちらかといえば、機械学習のすばらしさよりも、限界や注意点に重点を置かれているように感じました。

ディープラーニングが合うもの合わないもの

 演繹的な「モデルベース開発」と、帰納的な「モデルフリー開発」、という言葉がありました。
 銀行のトランザクションにように、人間が定義したルールに従って動くシステムは前者。複雑すぎてルールが書き下せないようなものに後者を適用とするというお話です。 後者の開発においては、十分な精度が出るかはやってみないとわからないため、Expectation Controlと、アジャイル的なアプローチ・PoCが必須との注意点もありました。

 品質の判断として、これまでは「レビュー工数」のようなプロセス指標で測定していたところを、ディープラーニングのシステムにおいてはプロダクト自体の性能(判定精度)で示せるのが大きな違い、とのお話がありました。ただ個人的には、「正確に判定できる」というのは品質特性の1つでしかないので、それだけとって「品質を定量的に示せる」とするのは物足りないと感じます。

機械学習に基づくソフトウェアの難しさ

 技術的な難しさとして、要求定義と品質保証について言及がありました。
 要求定義の難しさは、いわゆる「フレーム問題」と呼ばれるもので、ハイコンテキスト前提の人間の指示を、ソフトウェアがパーフェクトに忖度することはできないという点です。
 品質保証の難しさは、ディープラーニングにおける「何かを変えるとすべてが変わってしまう」(Changing Anything Changes Everything)性質に由来するものです。この性質のもとでは、ユニットテストを定義することさえ困難であるということです。また、adversarial exampleのような新しいタイプの脆弱性が生まれていることも、保証の難しさにつながります。

 またビジネス面の難しさとして、「100%のものはできない」ということに対する社会的な受容が必要ということです。同様の話は、SQiP2016における、デンソーの早川浩史氏のご講演「つながるクルマのセーフティ&セキュリティ」でもあったと記憶しています。そもそも現在のソフトウェアだって完璧なものではないことは明らかなのですが、「ディープラーニング/自動運転車は判定を間違うこともある」ことを社会が受け入れ(あるいは麻痺し)なくてはなりません。

統計を勉強しよう

 ソフトウェアエンジニアに必要な知識として統計、特に事前確率などベイズ統計の基本的な知識を挙げていました。
 質疑応答では、ソフト屋は統計を知らないといった論調があったように思いますが、割とみなさん統計好きですよね? 僕はそうでもありませんが・・・特に自由d・・・うっ頭が・・・。

所感

 機械学習のニュースやトレンドをきちんと追っている人には当たり前のお話だったのかもしれませんが、特徴や注意点などの概要をお聞きすることができて有益でした。また、今後テストがますます難しくなっていくことがよくわかりました。
 こんな話もありましたね・・・これも、Changing Anything Changes Everythingの一種だと思います。

itpro.nikkeibp.co.jp

AIによるソースコードレビューの変革

 富士通アプリケーションズ株式会社の森崎雅稔さんによる、「AIでソースコードの良しあしを判定する」お話です。Twitterでも話題になりましたね。ニュース記事はコチラ。

itpro.nikkeibp.co.jp

何をやっているのか

 記事を読んだだけでは、従来のソースコード解析との違いがよくわからなかったのですが、かなり別ものでした。この技術ではコードの文法や意味を理解させるのではなく、コードを画像のパターンとして認識させて、良い/悪いの判定を行っているのだそうです。
 ここでの判定は「バグの有無」ではなく、保守性や可読性といった内部品質の良しあしです。ただ経験則的に、内部品質が悪いコードを書く人は、バグを作り込むことも多いという相関があり、悪い判定はそうズレないとのことでした。

 なお、単純に画像化するだけでなく、レビューエキスパートの観点が反映される工夫をしています。
 たとえば、いわゆる「複雑度」といえばネストの深さなどで計算されますが、そういう制御構造以外にもレビュアが「複雑でレビューしづらい」と感じるコードの特徴があるので、そういう特徴がうまく画像パターンに現れるようにしているということです。
 ディープラーニングといえば、学習用の加工だけして後は機械に学習させるというイメージを持っていたので、これは意外でした。

運用面での工夫・苦労

 今回紹介された技術は、少なくとも現時点では既存のコード解析ツールを代替するものではなく、互いに補完するものとしています。既存のツールに加え、今回のツールをSEの日常に自然に組み込んでいくことが大事だとのお話がありました。また、既存のツールのように「ダメな点をひたすら指摘する」のではなく、良い部分は良いと見える化することが、ユーザのモチベーションにもつながると。

 その他、「いいコード」「悪いコード」の収集と、それらのスコアリング(もちろんレビュアによる手動!)に苦労されたとのこと。これは想像に難くないですね・・・。

所感

 どんどん大量のデータが集まってくるセンサーデータと違って、人間の手による成果物をディープラーニングの入力にするのは厳しそうだと思います。特に教師あり。こんな話もありました・・・。

itpro.nikkeibp.co.jp

ソフトウェアの不具合検知・修正への機械学習の応用について

 産業技術総合研究所の森彰さんのお話です。
 「AIによるソースコードレビューの変革」とこちらが、「AI for SE」のカテゴリです。

AIで何ができるのか

 Fault Detection、Fault Localization、Fault Repairの、3つの分野での応用を紹介されています。検知、同定、修復、ですね。
 重点が置かれていたのは、修復です。
 方法の1つとしては、バグを含んだソースコードの一部を変換し、そのコードでテストを実行するというもの。テストをパスすればスコアが得られるゲームとして、変換を繰り返し行っていくうちに、ものによっては修復ができてしまうそうです。この場合の「修復」は、「既存のテストをすべてパスする」という意味でしかなく、単にテストが弱かったということもあるのですが、それを踏まえても3~4%は「本当に」直るとのこと。

 これも十分、力業という印象を受けたのですが、さらに力づく感があるのが、Vertical Code Transplantingという技術。ある特定の機能を実現するためのコードは、似たものがきっと世界中のどこかのリポジトリにあるだろうということで、それを探してもってきて、それを自分のコードに反映してしまうのだそうです。この「似たもの」というのは、文法構造の類似ではなく、やろうとしていることが似ていなければならないのですが、この「意味的コードクローン」の判定がそれなりにできてしまうので、荒唐無稽な話でもないようなのです。
 自動的にコードが修復されていく世界が未来過ぎたのですが、「GenProg」で検索すると関連資料がたくさんあり、驚きました。

質問したこと

 今回のお話で気になったのは、ユニットテストが完備されていて、かつ短時間で完了できるということが前提になっている点です。
 たとえばIoTの世界だと、多数の機器が接続された、バリエーション多彩な環境で動作して初めて発現するバグがより深刻だと考えられます。そのようなバグを見つけるにはシステムテストレベルのテストが必要で、その実行はおそらくユニットテストのような時間オーダーでは終わらないのでは・・・という点が疑問で、質問させていただきました。

 そのようなケースは、修復よりまず検知と同定が課題であり、AIによるログのパターン解析が使えるだろうとのご回答をいただきました。
 また上述のような背景から、今後はプロダクトコードよりもテストコードを正確に書くことが重要になってくるとのご意見もいただきました。

所感

 このような話を弊社の大先輩エンジニアとしたところ、「テストコードを完璧に書くというアプローチと、要件を形式的に書くというアプローチの本質的な違いは何なのか、意見を聞きたい」と言われました。

 テストコードをプロダクトコードに対する要件と捉えると、本質的な違いはないようも思います。
 少し考えて、「前者のアプローチは、適切なテストコードが追加されるごとに、自動的に品質が良くなる(蓋然性が高い)点が違うのでは」といった趣旨の回答をしましたが、それは後者でも変わらないですね。つまり、不足していた仕様を追加すれば、そこから導出されるソフトウェアの品質は上がっているはずなので。

 もう1点、形式的に記述された仕様から導出するプログラムが仕様を完全に満たすのに対して、テストコードから修復されるプログラムはあくまで「いろんな可能性の中で一番よくテストコードをパスしそうなもの」であるにすぎず、すべてのテストコードをパスすることを保証しない(もっとも多くパスすることも保証しない)という点が違うのかなーと思いました。
 みなさんはどう思われますか?(全然所感じゃない)

Neural Network ConsoleによるDeep Learning研究開発の効率化

 ソニーの小林由幸さんによる、ソニー謹製のディープラーニング研究開発ツールのお話で、ここから2つが「SE for AI」のカテゴリー。  プログラマ向けの関数プログラムである「ライブラリ」と、商用開発に対応したツールである「コンソール」があり、セッションは主に後者のデモでした。
 自社ツールの紹介ではありますが、お金のにおいを感じさせない、開発者の情熱に溢れたプレゼンテーションでした。

 製品紹介は、YouTube上でも見ることができます。
 こちらもディープラーニング学習者ならとっくに知っているものなのでしょうが、わたしは初見でして。
 GUI上で各種レイヤをグリグリ並べて、整形済みデータを流し込むと、すぐに学習が始まって精度も測定される。一番よい精度を出せそうなネットワーク構成の探索も自動でやってくれる。コストに効いてくる計算量もわかる。そしてそのGUIも、SONYらしく美しい。


Neural Network Console:ツールで体験する、新しいディープラーニング

所感

 AffineやCNNなどは、プログラミングにおけるif文と同じで、一度理解すればそれで済む。理解したら、コンソールのようなツールでいろいろ試してほしい。というお話がありました。
 わたしは『ゼロから作るDeep Learning』でゼロから学びきれず落伍しましたが、再度立ち上がって一通り基礎を習得し、そのあと堂々とこの手のツールを使えるようになりたいです。

ゼロから作るDeep Learning ―Pythonで学ぶディープラーニングの理論と実装

ゼロから作るDeep Learning ―Pythonで学ぶディープラーニングの理論と実装

機械学習における品質保証のチャレンジ

 国立情報学研究所の石川冬樹さんによるセッションです。
 機械学習に基づくソフトウェアにおける困難と、その打開策についてお話いただきました。

何が難しいのか

 欠陥に気づくことができるのか、直せるのか。何をもって完成とし、どのようにユーザに説明するのか。
 テスト工程以降のあらゆる工程に困難さが発生することになります。それを解決する方法として、いくつかの手段を紹介いただきました。

  • Metamorphic Testing: 入力をこう変えると出力はこう変わるはず、という関係を活用して多数のテストケースを生成する。たとえばアイテムのランキングの機能があったとして、アイテム群から1つのアイテムを抜いても、残ったアイテムのランキングの上下関係は変わらないはず、という関係を確認するためのテストは、たくさん考えることができる。
  • Search-based Testing: メタヒューリスティックを用いて、スコアを最大にするようにテストスイートやテストケースを生成し、カバレッジを高く、テストケース数を少なくする技法です。
    ・・・これではまったくわかりませんが、辰巳敬三さんによる記事がこちら(pdf)にあります。

 またホワイトボックステストにおいて、コードをカバーするだけではダメで、ニューロンのカバレッジを上げる必要があるとのお話がありました。とはいえこれは人手でできるものではないので、やはり機械による大量入力を回すしかない。また、GAN(Generative Adversarial Network)による意地悪なデータでソフトを試すというアプローチも実用になりそうとのことでした。

blogs.nvidia.co.jp

所感

 テスト技法といえば、「無限ともいえるテスト空間をいかに効率よく、合理的に狭めるか」、ざっくりいうと「テストケースをどう減らすか」に焦点を当てたものを捉えていました。
 が、「テストケースをどう増やすか」という真逆の目的をもった技法があることを学びました。短時間で完了するテストケースと期待値をできるだけ多く、自動的に生成し、それを全部流してプロダクトの妥当性を検証するというアプローチなんですね。
 誰かMetamorphic Testingの勉強会やりませんか? 理解できる自信はないのですが。

総合討論

 5人の講演者の方と会場からの質問による、パネルディスカッションです。
 いろいろなトピックがあったのですが、特に印象に残ったのは「ディープラーニングに基づくソフトウェアが出した答えをどう説明するか」についてでした。単に「学習の結果、こうなりました」では、答えを言われた方は納得できないでしょう。

 富士通の森崎さんは、たとえば「コードが良くない」と判定された理由をできるだけ伝えるようにしているとの答えでした。やはり判定を誤ることもあるので、既存のメトリクスも使って総合的に判断しているとのこと。

 一方、ソニーの小林さんのご意見は逆で、「理解してもらう必要はない」とのこと。なぜなら、人が理由を知りたがるのは、その理由に基づいて人が対処しなくてはならないから。将来的にはその対処を機械が行うようになるので、人の介入は不要、説明も不要になるという見解です。
 森さんのお話にあった欠陥修正にしても、自動で修復されていくのであれば「コードのどこの部分が悪かったのか」を人が知る必要はなくなるのかもしれません。
 ただそうはいってもその見解に誰もが納得するわけではないので、人の意識を変革していく必要があり、それは我々の仕事だ、というご意見でした。

 石川さんのご意見は、「説明できない、ルール化できないからこそディープラーニングを使っているのだから、説明を必須とすると普及しない」というものでした。ただし、社会学的・心理学的に「説明」が必要なのであれば、ディープラーニングでそれっぽい説明を自動生成すればいい、との極論(?)も出ました。

おわりに

 パネル含め、すべてのセッションが有意義で面白く、ディスカッションも活発で、参加できたのは本当にラッキーでした。
 JEITAさんのイベントは初めてだったのですが、今後もウォッチしていきたいと思います。ありがとうございました!