たにしきんぐダム

プログラミングやったりゲームしてます

Coursera / Structuring Machine Learning Projects 受講メモ

Deep Learning Specialization 3つ目のコース

www.coursera.org

この講座では機械学習プロジェクトの進め方(メトリクスを取りましょう、bias/variance/human-level performanceがどういう状態のときはどう対処しましょうみたいなこと)を学んでいく。Deep Learning Specialization のコースの1部であるが、Deep Learning じゃなくとも適用できそう。

ただ結構抽象的な内容なので実務で機械学習プロジェクト(学習モデル構築じゃなくても良いので)に携わったことがあったり、研究で機械学習プロジェクトを長期間回したりしてないといまいち実感がわかないかもしれない。


Setting up your goal

できるだけ単一の評価指標を定めて複数のモデルを一元的に比較できるようにできると意思決定がしやすいよという話。

  • precision と recall を使うのではなくて F-1 major を使おうみたいなやつ。(モデル作成だけで見るとそうかもしれないけど実際の機械学習プロジェクトでモデルの評価をするときに1つだけ見ればだいたい分かるみたいなことにはならないと思うけど...)
  • 評価指標も解決したい課題にいろいろあるので適切なものを選ぼうね。
  • プロジェクトを進行しているうちに評価指標をを変えたくなったときは柔軟に変えてまた学習プロセスを回しましょう

data.gunosy.io

satisficing metric と optimizing metric

  • precision や recall のような良ければ良いほど嬉しくてoptimizeしたい指標と
  • 推論にかかる実行時間やメモリ使用量のような最低限の基準を満たしてほしいsatisficing metric
  • は分けて考えましょうねという話
    • もちろん何が satificing metric で何が optimizing metric かは問題によって変わってくる。

train / dev / test set

  • train set と dev set
    • cross validation やりつつハイパラを決めるために利用する
  • test set
    • 最終的にできたモデルからどの程度のパフォーマンスが得られるかを計算するために利用するデータセット
    • train/dev set で学習した後、test set を利用してモデルをチューニングしない。

(少なくとも僕の知っている限りでは)学習データは train set と dev set に 7:3 とかで分割し、それぞれを利用して cross validation を走らせつつ最適なハイパラを決めるのが普通だと思ってた。

dev set と test set を分ける理由は、dev set は学習に利用されているデータなので、これを利用してパフォーマンスを測ってしまうとバイアスのかかった評価になってしまうから。

stats.stackexchange.com

  • dev / test set はそれぞれ同一の分布からサンプリングすること
    • training set は同一分布からサンプリングを必ずしもする必要はない(まじ?)(data mismatch の項で詳しく学ぶ)
  • かつては 7:3 とか 8:2 で(train と dev を)分割していたが、ビッグデータの時代では dev set / train set に十分な(どれくらいが十分なのかは...)データが用意できるなら 9.5:0.25:0.25 などのように多くのデータをtraining setにまわしても良い。

human-level performance

概要

medium.com

  • Bayes optimal error (best possible error)
    • どんなに頑張っても理論的にこの指標より良い精度は出せないというライン
    • これがどの程度の値かを知るすべはない
  • human-level performance
    • 人間がその機械学習タスクを手づからやったときに出る精度
    • human-level performance は bayes optimal error を推測するための手がかりとして利用すると良い
      • 例えば癌画像の識別モデルを作る時、普通の単独の医者による精度(ぼちぼちの精度)と、複数人数の経験豊富な医者(高精度)とでは精度が違ってくる。
      • このhuman-level performanceとして設定するべきは後者(より bayes optimal error により近いはずなので)
      • もちろん解決すべき課題に酔っては単独の医者による精度を、最低限の精度として利用するのも良い
  • 機械学習モデルがhuman-level performanceより弱いときはどうするか(教師あり学習)
    • より多くのラベルデータを人間から取得する
    • 後述するmanual error analysisで精度が低くなっている要因を検証し、何故人間ができてモデルがうまくタスクをこなせなかったのかを調べる。

human-level performance とモデル精度を比較して bias を減らすか variance を減らすか作戦を決める

  • human-level の精度と training set における精度の差は avoidable bias
    • 以下のようなことをすることで、avoidable bias を小さくする余地がある
    • training による精度が human-level を超えてきた場合は、最早そこに bias を小さくできる余地があるかはわからない
  • training と dev(test) での精度の差は variance
    • ここが大きい場合は以下のような対応をすることで variance を抑えられる
      • データを増やす
      • regularization
      • NNアーキテクチャ変更の検討、ハイパラの探索を頑張る

Error Analysis

概要

towardsdatascience.com

  • 学習モデルがhuman-performanceまで達成していない場合にどうするか
    • misclassified data をランダムに100とか500件程度集めてきて、目視でデータを確認して、誤って分類されたのはどういうデータなのかや備考を書き込んでいく
      • 集計プラットフォームは別になんでも良いのだが、こういうとき spreadsheet は便利だよね(画像ならIMAGE関数とか使って表示すると捗る)
      • (基本的にはランダムに集めれば良いが、例えばユーザーからアクセス頻度の高いmisclassified dataを優先して眺めたり、確信度が低くmisclassifyされたデータを優先して眺めるなどのやりようは色々あると思う)。
    • エラーのうち何が原因でmisclassifiedされているのかを集計する。

例えば猫画像判別機のうち、誤って判別された画像をランダムに集めて以下のように、何故誤って判別されたのかなどをチェックをつけていく。

画像 猫に似てる犬 ライオン 画質悪い猫 画面が暗い 備考
IMAGE("https://...") x ほとんど目しか判別できない
IMAGE("https://...") x 体の模様が猫っぽい
IMAGE("https://...") x 猫っぽい体勢のライオン

チェックを付け終わったら、抽出した誤判定のうちどれくらいのデータが何故誤判定しているのかわかる。例えば抽出したデータのうち50%が画面が暗いことが原因でご判定されているなら、そういうデータを正しく判別できるようモデルを修正(データを足したり)するとhuman-performanceに近づくことができる。

エラーの原因を正すためのデータを集めるのが難しい場合は?

ただし、例えば画質の暗所にいる猫の画像データを集めるのが難しいかもしれない。そういうときは

  • 本当にそういうデータを作るのが難しい場合は、多少エラーへの寄与が少なくともデータを集めやすく楽にモデルを改善できそうな問題からとりかかるのも有り
  • 人工的にデータを作る(この場合は画像の明度を下げるとか?)
    • 人間の目で見てそれっぽければ良いが、人口データの出来が微妙な場合はそれらの人口データにoverfitしてしまうリスクもあるので注意

プロトタイプはシュッと作ろう

新しく機械学習プロジェクトを始めたときはまずプロトタイプを早めに作ってしまう。これにより

  • その機械学習プロジェクトが役に立つ/立たないことを証明できるかもしれない
  • ひとまずの学習モデルを構築することで、次に何を改善するべきかがはっきりする
    • データを工夫するべきか
    • human-performance と比較して、bias / variance どちらを減らしていく余地があるのか~

Mismatched training and dev / test set

training set と dev / test set の分布が違う場合

  • ここまではtraining / dev / test set は同一の分布からサンプルすることを前提としていた
  • deep learning era では大量のトレーニングセットが必要
  • リアルなデータを十分大量に取得できるならそれを traning / dev / test set に分類すれば良いが、そうでない場合は traning set 水増しのために元のデータとは異なる分布からサンプルしたデータをtraning setに含めることもある
    • 例えば自動運転車のための信号機の画像認識タスクを考える
    • できれば車付属のカメラから取得した信号機の画像を大量に集められるのがベストだが、traning set 水増しのためにインターネットからクローリングした信号機の画像(必ずしも車のカメラから撮ったわけではない)をtraning setに追加することもある。(車付属のカメラからの画像は少量、クロールした画像は大量にあると仮定しよう)
      • もしクロールした画像と車付属のカメラからの画像をすべて混ぜて traning / dev / test set に分類すると、それぞれ同一分布からサンプルできるという利点はあるものの、dev / test set のデータはほとんどクロールした画像になる。
      • その結果、モデルはクロールした画像をよく分類できるように学習してしまい、本来学習したいタスク(車載カメラからの信号機の画像認識)がうまくできなくなってしまう可能性がある
    • dev / test set は車載カメラからの画像からのデータを使い、traning set には 車載カメラからの画像 + クローリングデータを使うと良いだろう

そのような場合の bias / variance の計算

  • training / dev / test set がすべて同一分布からサンプルされている場合は以下のように bias variance が計算できた
    • training error と dev / test error の差は variance
    • dev / test error と human performance の差は avoidable bias
  • しかし、training set と dev / test set の分布が違う場合は一概にはそう言えなくなってくる
    • varianceをどう測るか
      • training-dev set という training set と 同一 distribution (ただし training set には含まれない)を作る。training set と training-dev set での差が大きい場合は variance が大きいということになる。
    • avoidable bias
      • 普通に training set と human-level での performance の差
    • data-mismatch problem
      • training error と training-dev error の差
    • degree of overfitting (to dev set)
      • dev set と test set での差

data-mismatch をどう解決するか

  • Manual Error Analysis を行い、training set と dev/test set でのデータの差がなんなのかを調べる、どういうデータがdev/test setで誤判定されているのかの分析
  • training set のデータを dev/test set に近いものにする。もしくは dev/test set で利用するようなデータをもっと集める
    • 難しかったら自分でデータを作ったり...

transfer learning

概要

machinelearningmastery.com

www.tensorflow.org

transfer learning (転移学習)は、ある学習済モデルを、他の関連するタスクのための学習モデルのtrainingの下地として利用する手法。

例えば猫画像識別モデルを作りたいが、猫画像を多く集められない場合(そんなことないと思うが)、ネット上に公開されていたりする学習済みの汎用画像識別モデルを学習の下地に利用することで、十分なサンプルが得られない場合でもよく学習された猫画像識別モデルを作ることができるようになる。

transfer learning がうまくいく直感

  • deep learning では、浅い(inputに近い)レイヤーでデータの細かい特徴を捉え(例えば画像ならエッジの認識など)、層を重ねるごとに特徴を組み合わせて行き、深い(outputに近い)レイヤで具体的な物体を識別する。
  • 汎用的な画像識別モデルでも浅いレイヤでは画像のエッジ認識など、他の物体識別でも利用できそうな特徴が学習できていると考えられる。
  • なので、関連する学習済みモデルのうちoutputに近いレイヤだけを捨て、他のレイヤを再利用しつつ猫画像識別機を学習すれば、基本的な画像認識のための要素はpre-trained modelから転用しつつ猫画像をうまく識別できるモデルが作れる。

自分で作った関連する学習済みモデル(例えば猫画像識別機を作るのに、以前作った犬画像識別モデルを下地に使うなど)を使ってもよいが、インターネットに公開されている学習済みモデルを使ってもOK


multi-task learning

概要

例えば、猫画像を識別するモデル、猫の血統を識別するモデル、犬を識別するモデルなど複数のタスクを実現しようと思ったら、タスクの数だけモデルを作らないといけなかった。

  • マルチタスク学習では、そのような複数の(関連する(この場合すべて画像識別))学習モデルを、ひとつの学習モデルで全部やってしまうという手法。
    • ひとつのネットワークで画像識別しつつ、semantic segmentation しつつ ...
    • ひとつのネットワークで犬/猫/蛇/ライオン/虎/パンダなどいろんな動物を識別する
  • イデアは転移学習と似ていて、inputに近い層のレイヤは共通で利用し、outputレイヤをタスクの数だけ分岐させる
    • そのため、統合するタスク同士に共通点が多い場合にマルチタスク学習は効果を強く発揮する
  • 各outputレイヤでのloss関数を重み付きで足し合わせたものをコスト関数として利用する
    • 必ずしもすべてのデータにすべてのタスク向けのラベルがついているとは限らないので、あるタスクのためのラベルが付いていない場合はそのタスクに関するlossは0に固定して他のタスクloss関数の微分だけを使って重みを更新したりすることになる。

youtu.be

pros / cons

  • pros
    • 複数のタスクを単一のモデルで扱うのでモデルがコンパクトになる
    • 転移学習と同様に、基本的な識別部分を複数のタスク間で共有できるので、より多くのデータを使ってモデルを学習させることができる
  • cons
    • 複数のタスクを同時に解くことになるので、どうしてもモデルの複雑度が大きくなる
      • そのため、単一タスクだけで見るとモデルのサイズは大きくなってしまう
    • あるタスクにそぐわないデータを利用して浅い層の重みを更新することもあるので、シングルタスク学習をするよりも個々のタスクの精度が下がる場合もある
      • ネットワークの複雑度を上げる、learning_rate などのハイパラをマルチタスク用に最適化し直す必要がある
      • タスク間のloss関数のスケールが異なる場合もあるので、重みを調整する
      • データセットの数に差がある
        • データセット数が小さいタスクについては割と早い段階で精度が落ち着いているが、他のデータ数が多いタスクのデータを使って学習を進めていくうちに、データ数の少ないタスクのモデルがoverfittingし始めてしまうなどある
        • 対策
          • 重みの調整
          • データaugumentationやオーバーサンプリング/アンダーサンプリングで調整
          • データ数の少ないタスクについては、学習の後の方で学習する

End-to-end deep learning

towardsdatascience.com

従来機械学習システムでは、あるunstructured dataに対するタスクを構築する場合、複数のモデルをパイプラインのように組み合わせてシステムを構築してきた。

例えば以下の動画で紹介されている、デリーのair quolaityを写真から識別するモデルの場合

  • まず写真から空の画像を切り出して
  • 天候などの推論
  • 画像と天候からからair qualityを推論

というパイプラインにより画像からair qualityを推測するモデルを構築している。

youtu.be

End to end learning はこのようなパイプラインをすっ飛ばして データ → (NN) → 結果 を出してしまうというもの

ニューラルネットワークは層を重ねていくことで、パイプラインがなしていたような中間表現の学習ができてしまうという主張。

じゃあ全部ディープで ポンできるかというとそんなことは無く、うまくいくためにはいくつか条件や課題がある。

  • input output のデータが大量に必要
    • そのため入出力対応データが多く手に入らないならいくつかパイプラインを挟むのが懸命
  • システムが変更しにくくなる
    • パイプラインだと一部のデータの傾向や仕様が変わったらそのパイプラインだけ学習し直せばよかったがE2Eだと全部学習し直しになる
    • 大量のデータを学習するのはもちろん時間がかなりかかる
  • パイプラインモデルなら一部のモデルに学習済みの便利モジュールを利用することができたかもしれないが、E2Eだと無理
  • まとめて学習するので何が問題で学習がうまくいってないのかわかりにくい

次はCNNの予定だが、RNNとかのが興味あるのでそっちからやる