機械学習の技術的負債について学んでみた【機械学習 論文100本ノック(2/100)】

こんにちは。機械学習論文100本ノック2本目です。

早速まいります。

論文100本ノックの目的と進め方

目的

  • この分野の研究の関心の動向を掴みたい。
  • 普段使っている技術の登場背景や詳細の理解を深めたい。

進め方

  • 最低限AbstractとIntroduction、Conclusionは読む。
  • 本編は興味に応じて。

今回読んだ論文

Hidden Technical Debt in Machine Learning Systems(2015)/Google

https://proceedings.neurips.cc/paper/2015/file/86df7dcfd896fcaf2674f757a2463eba-Paper.pdf

この論文を選んだ理由

最近この論文中に登場する図をよく目にしたから。(雑)

論文本文より

内容と学んだこと(箇条書き)

結局半分以上読んでしまった・・・

Abstract & Introduction

  • 機械学習モデルの開発とデプロイは比較的早く安価にできるが、長期間にわたってそれを維持することは困難であり、高価である。
  • この二律背反は1992年にWard Cunningham提唱されたソフトウェアエンジニアリングフレームワークである”技術的負債”の側面から理解することができる。
  • 技術的負債を負うことには戦略的な理由がある。すべての負債が悪いわけではないが、すべての負債には返済が必要。
  • 返済の目的は、機能を追加することでは、将来の改良を行いやすくする(保守性を向上させる)こと。
  • 返済には、コードのリファクタリング、単体テストの改善、デッドコードの削除、APIの強化、ドキュメンテーションの改善といった方法がありえる。
  • 返済を先延ばしすると、コストは複雑になっていく。(借金が金利の複利で膨れ上がっていくのと同じ)
  • 機械学習システムにも技術的負債を抱える可能性がある。
  • 上記従来のソフトウェアエンジニアリングで考えられてきた負債に加えて、機械学習固有の負債も発生しえる。
  • ただし、この固有の負債はコードレベルではなくシステムレベルで現れるため検出が難しい。
  • この論文では、こうした機械学習システムにおいて長期に考慮しなければならないトレードオフについてコミュニティの認識を高めることを目指す。

Complex Models Erode Boundarie

  • 従来のソフトウェアエンジニアリングではカプセル化や強力な抽象化境界が保守性の高い(変更・改良が容易な)コードに役立っていた。
  • 厳密な抽象化境界によって、あるコンポーネントから入出力される情報の不変性と論理的整合性が実現されてきた
  • 機械学習システムにおいては、厳密な抽象化境界の設定が困難
  • それは従来のソフトウェアエンジニアリングのようにコードで特定の意図された動作を規定することが困難だから。というかそれができるのであればそもそも機械学習システムの必要性はないはず。(現実世界は整然としたカプセル化はなじまない。)
  • この境界の浸食によって機械学習システムの技術的負債が著しく増加する可能性がある。
  • Entanglement(絡み合い)
    • 機械学習モデルでは、入力の特徴量X1の値や分布が変化したり、新しい特徴量を追加したりすると他の特徴量の重要度や重み、使用方法が変化する。どの入力も完全に互いに独立しているわけではない。(CACE原理)
    • 対策の方向性としては、モデルを分離してアンサンブル学習を取り入れるか、特徴量の分布の変化を素早く検出できるようにすることが有効。
  • Correction Cascade(補正のカスケード)
    • 問題Aに対処するモデルMAは存在するが、問題Aと少し異なる問題A’に対処できるモデルが必要となる場合がしばしばある。
    • このとき、モデルMAを入力として問題A’に対処するための補正を適用したモデルM’Aを開発することは魅力的なオプションとなる。
    • しかし、このモデルM’AはモデルMAへのシステム依存を生み、将来モデル改良を行う際の影響範囲の特定が複雑になっていく。(補正のカスケード)
    • こうした問題を防ぐためには、MAに依存したM’Aを開発するのではなく、MA自体を強化して問題A’にも対処できるようにするか、追加の開発コストを支払ってでもMAに依存しない別のモデルをつくることが有効。
  • Undeclared Consumers(無申告の消費者)
    • 機械学習システムによる予測結果は、ファイルやログに書き込まれることで広くアクセス可能になるので、他のシステム(あるいは業務)で使われることで、暗黙の依存性を生む可能性があり危険。
    • ソフトウェアエンジニアリングでは、こうした問題を可視性負債(Visibility Debt)と呼ぶ。
    • こうした負債は、それを防ぐよう意図的に考慮されていない限り検出が難しい。
    • 厳密なアクセス制限などが有効。

Data Dependencies Cost More than Code Dependencies

  • ソフトウェアエンジニアリングでは、依存性負債が技術的負債の主要因として挙げているが、機械学習システムでも前章であげたデータの依存性によって同様のことがいえ、かつさらに検出が困難。
  • コードの依存性はコンパイラなどの機能である程度検出できることもあるが、データの依存性に対しては同様のツールがない。
  • こうしたツールがないと、不適切なほど簡単に大規模なデータ依存の連鎖を構築してしまい解決するこ都が難しくなってしまう。
  • Unstable Data Dependencies(不安定なデータ依存性)
    • ことを早く進めるために他のシステムの出力を入力に用いることはよくある。
    • しかしこうした入力の中には不安定(=時間の経過とともに定性的・定量的な挙動が変わる)なものもある。
    • 機械学習システムは、他の後続システムにとってまさにこうした不安定な入力になりうる。
    • こうした場合、機械学習システム単体の改善は、後続システムにとって悪影響を及ぼす可能性がある。
    • こうした不安定なデータ依存性を緩和するための一つの方法は、入力となる機械学習システムのバージョン管理を行うこと。
    • バージョン管理によって、例えばシステムの改善が後続システムに即座に悪影響を与える子を防ぐことができる。
    • ただし、バージョン管理はそれなりにコストが高い。
  • Underutilized Data Dependencies(使用されていないデータ依存性)
    • コードにおける”使用されていない依存性”とは、”使用されていないパッケージ”といえる。
    • 使用されていないデータ依存性とは、後続のシステムにとって利点をほとんど提供しない入力を指し、こうした場合機械学習システムは不要なものとみなされてしまう。
    • こうした依存関係は削除しても支障がないにもかかわらず機械学習システムの変更に対してシステム全体を不必要に脆弱にしてしまう可能性があり、時には壊滅的なダメージを与える。
    • こうした使用されていないデータ依存性は、以下の要因で混入される可能性がある。
      • レガシーな機能
      • バンドルされた機能
      • (機械学習モデルの入力における)重要でない特徴量
      • (機械学習モデルの入力における)互いに強く相関する特徴量
    • こうした状況は定期的に検証して不要な依存性は排除してく必要がある。
    • Static Analysis of Data Dependencies(静的なデータ依存性)
      • コードにおいてはコンパイラやビルドシステムが依存性の静的な解析を行ってくれるがデータの依存性に対してはこうしたツールが圧倒的に少ない。(非常に重要にもかかわらず)
      • が、そうしたツールの一つに、自動化された特徴管理システムがある。
      • このシステムを使うと、データソースや特徴に注釈を与えることが可能になる。
      • 自動チェックにより、すべての依存性に適切な注釈が存在していること、依存性関係のツリーがすべて解決できることが保証される。

Feedback Loops(省略)

ML System Anti-Patterns

  • 機械学習システムのコードのうち、予測や学習に関わる部分はごく一部にすぎない。
  • 大半の部分は、”plumbing”(配管)と表現できる。
  • 機械学習を取り入れたシステムは、高負荷なシステムに行きつくことがよくあるため、この章ではそうしたアンチパターンを検証する。
  • Glue Code
    • ML研究者は自己完結型の汎用的なパッケージを作る傾向にある。
    • こうした汎用パッケージを多く使うと、パッケージにデータを出し入れするために大量のサポートコード(Glue Code)を記述する必要があり、またパッケージの特性によってシステムが固定化するため長期的にはコストがかかる。
    • このため、汎用的なパッケージを再利用するよりもクリーンなネイティブソリューションを作成する方が低コストになることが多い。
    • Glue Codeへの対処としては、ブラックボックスパッケージを共通のAPIに包含すること。これによって再利用性が高まり、パッケージの変更コストがさがる。
  • Pipeline Jungle:
    • Glue Codeの特殊な例。データ加工のプロセスが複雑化(スクレイプ、ジョイン、中間ファイル生成など)してしまう状態。
    • このようなパイプラインはエラーの検出・復旧などが難しかったり、テストのために高価なEnd to Endの統合テストツールを導入する必要があったりして、技術的負債が大きい。
    • こうした問題は、データ収集と特徴抽出のプロセスを総合的に考えなおすことによってのみ解消できる。
    • プロセスを一から設計しなおすことは大きなエンジニアリングの投資だが、継続的なコストを軽減させ、イノベーションを加速することができる。
    • Glue CodeやPipeline Jungleは統合の問題の兆候であり、根本的には研究とエンジニアリングの過剰なロールの分離にありそうなので、お互いに協力しあうハイブリッドな研究アプローチによって軽減できるかもしれない。
  • Dead Experimental Code Path:
    • テストコードは定期的に精査して、不要なものを残さない(たいていは一度つかっただけのブランチが多く残っていたりする)
  • Abstraction Debt:
    • 上記のような問題は、機械学習システムをサポートする強力な抽象化機能が明らかに不足していることを浮き彫りにしている。
    • Zhengの論文でも、機械学習の分野では、リレーショナルデータベースの成功に迫る強力な抽象化機能の登場はまだないと言及されている。
    • データ、モデルの学習、予測の流れを記述するのに適した良い抽象化がないことで、コンポーネント間の境界があいまいになりやすい。
  • Common Smells:
    • Plain-Odd-Data Type Smell:データは整数な少数など平凡なデータ型で表現されることが多いが、それが対数オッズなのかなどちゃんと意味を理解していないと危ない
    • Multiple Language Smell:一部のコードを他のプログラミング言語で書くと保守性が低下するから危ない
    • Prototype Smell:プロトタイプ環境をそのまま本番環境にしたり、依存しすぎていると危ない

(ちょっと疲れてきたので残りの章はスキップ、いったん結論に・・)

Conclusions

  • 技術的負債は、有用なメタファーだがそれ自体が具体的な指標を与えるものではない。
  • また、技術的負債は時間とともに表面化してくる問題なので、現在チームが機動的に動けていることは、技術的負債が少ないことの証明にはならない。
  • なので、次のような質問が有効。
    • 全く新しいアルゴリズムでのアプローチをフルスケールでテストすることは容易か?
    • すべてのデータ依存関係の推移閉包は何か?
    • システムに対する変更の影響はどの程度正確に測定できるか?
    • あるモデルや出力を変更すると他のモデルや入力がどれだけ劣化しうるか?
    • 新メンバーをいかに早く戦力化できるか?
  • この論文がより良い抽象化・テスト方法論・デザインパターンを含む保守可能な機械学習システムを目指してさらなる開発が促進されることを期待している
  • わずかな精度を向上させるために、システムの複雑性を大幅に増加させることは賢明な方法といえない。
  • 機械学習システムの技術的負債の返済には、一定のコミットメントが必要であり、それはしばしばチーム文化の転換によってのみ達成できる。
  • この努力を認識し、優先順位をつけ、報いることは機械学習システムに関わるチームの成功のために重要。

以上、今日は機械学習システムの技術的負債について学んでみました。

ブログに残しているのは日本語訳の箇条書きではありますが、少しでも同じことを勉強されている方の助けになりましたら幸いです。

おしまい

この記事を気に入っていただけたらシェアをお願いします!

コメントを残す

メールアドレスが公開されることはありません。 が付いている欄は必須項目です

ABOUT US
Yuu113
初めまして。ゆうたろうと申します。 兵庫県出身、東京でシステムエンジニアをしております。現在は主にデータ分析、機械学習を活用してビジネスモデリングに取り組んでいます。 日々学んだことや経験したことを整理していきたいと思い、ブログを始めました。旅行、カメラ、IT技術、江戸文化が大好きですので、これらについても記事にしていきたいと思っています。