どのようにサービスにディープラーニングを適用すればいいか、ベストプラクティスがまとまっていた論文があったので、訳してみました。
元論文
Best Practices for Applying Deep Learning to Novel Applications
Leslie N. Smith
https://arxiv.org/ftp/arxiv/papers/1704/1704.01568.pdf
アブスト
- このレポートは、特定のドメインのエキスパートだがディープラーニングに詳しくない人向け
- ディープラーニングを試してみたいと思っている初心者のための経験的なアドバイス
- フェイズを分割することで、マネージメントしやすくすることを薦めている
- 各フェイズごとに、新規学習者へのおススメと知見を含んでいる
イントロダクション
- ディープラーニングの研究してるから、ディープラーニングのアプリケーションを作りたいって人から、助けてくれって言われる。それがこのレポートを書いたモチベーション
- 既存のベストプラクティスもあるから読んで欲しい
- いくつかのフェーズに分割した。前のフェーズに一度戻ることも役にたつので、イテレーティブに戻ったりして、プロジェクトを改善させていくのが良い
フェイズ1 準備する
-
この記事は、あなたが作ろうとしているアプリのドメインのエキスパートであることを前提にしてる
-
あなたは、関連する問題を解決するために、文献や研究に親しむ必要があり、state-of-the-artの方法と性能を知る必要がある
-
まずはディープラーニング手法をやる価値があるか検討すべき
-
state-of-the-art手法の性能が高いか、継続的改善のリソースに時間と労力をかけるだけの値打ちのあるのか
-
ディープが最新で凄いという理由だけでいきなりディープラーニングに飛びつかないこと
-
学習に数日から数週間かかるので、計算リソースがあるかどうかも検討する
-
学習に大量のラベル付けされたデータが必要なことも忘れない
-
最初のステップは、成功がどのようなものか定量的に定義すること
- 人がやっても機械がやったとしても、どのようなものが成功したとするのか。
- 成功の定義は、評価指標の設定する際に役立つ
- どう行った指標が大事か、大事でないかを決める
- プロジェクトの成功を担う定量的な指標を確定、重みづけする
- 目標設定 人を超えるパフォーマンスが必要なのか
- 人がそのタスクをやった場合の性能を知ることが、目標設定において大事
- state-of-the-art手法と人との比較をどうやるかを定義する
- 実際に人が解いてみると、機械学習でどうやって解かせるのが良いのか、という知見が得られる
-
モデル設計におけるソフトマックスや損失関数だけを評価指標することに固執しない
- 一番初めには考慮すべき
- 評価指標があなたのアプリケーションで重要なものである
- 重みづけに従ってテストしよう
-
ディープラーニングにさせるジョブをいかに簡単にさせるかを考慮する
- ディープは強力だから試したくなる
- 反直感的だが、ジョブを簡単にすることで学習も簡単になり、よいパフォーマンスがでる
- 複雑な関係を学習させようとするときに、思い出そう
- 既存の業績の応用でてこを利かせられるかどうか、ネットワークに何が必要なのか考慮すべき
- 自分で学習させたほうが精度は良いが、手動での潜在的なヒューリスティックに頼ってはいけない
- 最も希少なリソースは人。固定された手動の前処理でなくネットワークに表現そのものを学習させよう
- state-of-the-art手法の想定や予想は、自分自身のためにはっきりさせるために書いてお苦と良い
フェイズ2 データの準備
- ディープはデータが大量に必要
- 学習データの数はネットワークのパラメータ数と相関がある
- 学習データ数によってモデル設計が制限される
- データがあればあるだけ精度が上がるので、データ数はphase1で決めた目標次第
- バリデーションデータ, テストデータも必要
- テストデータは学習データと似ているが、同じものではない
- テストデータは学習に使わないが、生成されたネットワークをテストするのに使う
- 学習データが限られるのなら、転移学習、ドメイン適用を検討すべき
- 元データに近いデータセットをダウンロードして、事前学習に使うのもあり
- サンプル数を増やし、多様にするため、合成データを作ることも検討する
- プロジェクトの目的で訓練データの選択が決まってくる
- その訓練データはタスクに直接関係してて、問題空間をカバーするほど多様か
- 良い例:犬と猫
- ダメな例:猫とその他の哺乳類
- 本質的にデータが不均等な問題の場合、深層学習のエキスパートに相談すべし
- 前処理
- 平均を0にする 正規化
- 平均を学ぶ仕事を取り除き、サンプルの類似性を高め、ネットワークの仕事を簡単にする
- 先験的な知見やヒューリスティックスで次元削減できないか
- 手動でヒューリスティックを決める作業はしない。これは時間を削減するため
- ネットワークに独自の表現を学習させること
- ネットワーク自身がふるいにかける必要がある関係のないデータが多いほど、学習データもより多く必要で時間もかかる
- 平均を0にする 正規化
フェイズ3 あなたのアプリともっと近いディープラーニングアプリの類似点を探す
- いきなりスクラッチで開発しない。再利用を考える
- 他の研究者の業績を使えないか検討する
- 誰もやったことがないタスクにおいても
- 様々な問題のDLの文献を読み、自分の解こうとしている問題と近いものを探す
- モデル構造の変更にかかわるので、問題の違いをメモしておく
- 近いアプリを見つけたら、コードをダウンロード
- 多くの研究者が、自分の研究を広く広めるためにコードを利用可能にしている
- まずは成果を再現することを目標に
- 次に、理解するステージとして、成果の効果を見るために様々な視点で修正してみる
- 幸運な場合、全てを再現できることも。
- ここでの比較は、phase4でベースラインを作るための十分な情報をもたらす
- いくつか古典的な、よく知られた深層学習の手法がある
- クラス分類・物体認識ならCNN,
- 時系列ならRNN, LSTM, GRU
- 複雑な意思決定なら深層強化学習
- そのほか、超解像度、類似マッチングなど
- 参考までに、下に様々なアプリケーションのリストをおく
フェイズ4 ベースラインモデルを作る
- いつも、シンプルに小さく、簡単に始める
- 必要だと感じたよりも小さい設計モデルを使う
- 一般的な目的関数から始める
- 一般的なハイパーパラメーターから始める
- 一部の学習データから始める
- アジャイル開発の経験を適用するのによい
- シンプルデザイン
- ユニットテスト
- 短いリリース
- 今は基本的な機能を得ることから始め、後ほどphase6で改善する
- これは継続的なアップデートとイテレーションのプランの小さなステップ
- Caffe, TensorFlow, MXNetなどの一般的なフレームワークから一つだけ選ぶ
- 複雑さを避けるため1つに絞る
- phase3で選んだアプリの再現実装で決まることが多い
- ネットワークが大きなフレームワークの一部のものなら、フレームワークのAPIがきちんと動作するか確認するとよい
フェイズ5 可視化ツールとデバッグツールを作る
-
あなたのモデルの中で何が起きているのか理解することが、プロジェクト成功のコツ
- 大工「2回計測して、1回で切れ!」
- 「1回コードを書いて、2回計測しろ」
- なぜこの結果が出たのかを理解するため、内部本体の可視化と計測をすべし
- 誤診がなければ、暗闇でも問題を解決しパフォーマンスを改善できる
-
高いバイアス、高いバリアンスに関連する問題に対する一般的な理解をすべし
- それぞれ解決方法が異なる
- 高いバイアス(間違った結果に収束)→ネットワークを大きくする
- 高いバリアンス(収束しない)→学習データを増やす
-
モデル設計が進化していく様がモニターできるようにできるだけ可視化する
- 全てのコード修正にたいしてユニットテストを実行する
- 学習データ、テストデータのエラー、人のパフォーマンスを比較する
- モデルが奇妙に振る舞っているように見えるかも。どうなっているのか、なぜそうなのかを知る方法が必要
- 最も悪い問題からデバッグを始める
- 問題が、訓練データ、設計の視点、損失関数のどこにあるのか
-
エラー解析は、完璧なモデルと現在のモデルの差を説明するもの
-
アブラティブ解析は、ベースライン手法と現在のモデルの性能の違いを説明するもの
-
TensorFLowを使う理由になるのは、TensorBoardという可視化ツール
- TensorFlowで必要なファイルをアウトプットすると、TensorBoardでモデルの可視化、重みと特徴マップのモニタリング、ネットワークが生成する埋め込みスペースの探検ができる
- TensorFlowだとこのツールが使える。他のフレームワークでは探すか、自分で作るしかない
フェイズ6 ファインチューニング
-
ここが一番時間がかかる.実験を広範囲に行う
-
あなたが「これだ!」と思うパラメータだけでなく、すべてのパラメータを変更して、何が変わるかを学ぶ
- ネットワーク設計、深さ、幅、パス、重み初期化、損失関数など
- それぞれのハイパーパラメータを変更し、増加・減少がどんな効果があるのか
-
学習率範囲テストがオススメ
- 広範囲の学習率の挙動を知る
-
同様に他のハイパーパラメータの効果を研究するプログラムを作る
-
データ拡張、ドロップアウト、重み減衰などの様々な正則化手法を試そう
-
汎化はディープラーニングの最も重要な利点の一つ
- あまり出てこないケースに対応する汎化性能を最大化するために、、正則化手法のテストをする
-
損失関数も同様に実験すべき
- ベースライン手法では、シンプルな損失関数を使っていた
- 他にもあなたが成功と定義した評価指数がいくつかある
- 評価指数と損失関数の違いは、テストデータに適用した数値なのか、ネットワークを学習させるための訓練データに適用した数値か
- より複雑な損失関数はより良い結果を生み出すか?
- それぞれの評価指数の重要性を反映させるため、損失関数に重みづけした数値を追加する
- 重要でない基準で損失関数を複雑にしないよう、非常に気をつける。モデルを壊す可能性
-
先に、あなたのアプリケーションと既存のディープラーニング手法の類似点を見つけ、もっとも近い手法をベースライン手法として選択したが、次に、2番目、3番目に近い手法を比較検討する
- 他の類似点を見て、そのネットワーク設計を使ったらどうなるか
- その2つの手法を組みわせてテストするとどうなるか
-
初めは、低く吊るされたフルーツを選べば成功するはずだったが、ここからの性能を向上させる道は、とても難しくなる
- フェイズ1で決めた目的で、どこまで性能を向上させるべきか決まる
- もしくは、先に決めた目的を再検討することも。
フェイズ7 エンドトゥエンド学習、アンサンブル、その他複雑性
-
予算と時間があれば、より複雑な手法に投資してみる
- 非常に多くのディープラーニング手法があり、日々論文が増え続けている
- ほとんどの論文がひとひねりした手法で新たなstate-of-the-artな結果を残している。
- それは性能向上につながるかもしれない
- このセクションだけで長いレポートがかける
- 非常に多くの、考慮すべき選択肢がある
- ディープラーニングのエキスパートと話すべき。
- ここまでくると、あなたのアプリケーション特有の助言になる
-
検討すべき一般的な手法が2つある エンドトゥエンド学習とアンサンブル
-
一般的に、結合されたシステムのエンドトゥエンド学習は、複数のパーツを持ったシステムより性能が良い。
- それぞれのパートがタスクに適応するため
- あなたのアプリケーションにとってふさわしいなら、パートを結合するのが役立つ
-
バッギング、ブースティング、スタッキングなどの、多様な学習器のアンサンブルは、単体のモデルよりも性能を向上させることができる
-
だがすべてのアンサンブルを構成するモデルの学習とメンテナンスが必要
-
高い性能が必要なら、アンサンブル手法を試す価値がある
まとめ
- このレポートは、今までディープラーニングが使われていないアプリケーション上でディープラーニングを実験する時に考慮すべき多くのファクターを並べている
- すべての要素が適切でないかもしれないが、あなたがプロジェクト中に考慮すべきほとんどの要素をカバーしていることを願う
- あなたの努力に幸運と成功を!
参考資料 様々なディープラーニングのアプリケーション
この表は、最近のディープラーニングのアプリケーションと、使われているネットワーク構造、アプリケーションについて詳しく書かれた文献をリスト化している。