シリコンバレーのエンジニアが一年ほどをDLを追いかけてみて思ったこと、感じたこと、伝えたいことをまとめてみました。とにかく伝えたいことは、DLはもはやその一言では片付けられないほどに構造やアプローチが多様化しているということ。そしてその進化スピードがえげつないほど速いということです。
将来のプログラミングや問題解決の仕方を変え、人を取り巻く環境を変えていくかもしれないというじりじりとした圧迫感。これを少しでも伝えられればと思っています。
このポストの方針
技術部分の説明は初心者向け。今からDLをキャッチアップしていく人のために各構成要素など基礎から解説します。
最初と最後だけ読むのも良いですが、各部の技術的な部分や難しさはできるだけ短く分かりやすく書くつもりですしここが一番大事なところです。できれば時間のあるときにじっくり読んでもらえればと思います。
内容
DLは何を変えたか:あるいはDLとは何か?
基本要素:DLを構成する要素とその仕組み。
DLのデメリット:DLシステムを構築するのがいかに難しいか。
各種改善手法・最新事例:各種のモデルや手法の紹介。ここがメインです。
DLは何を変えるのか?:エンジニアを取り巻く環境はどう変わるか?
DLは何を変えたか
DLは各分野で飛躍的な性能を発揮していますが、何故そのようなジャンプが可能になったのでしょうか。ここでは僕の感じるポイントをまとめてみます。
1. ビッグデータ対応
既存の一般的な機械学習のモデルに対して飛躍的に大きなデータを入力として扱えるようになりました。
例えば碁のAIであるAlphaGoでは従来とは比べものにならない量の対戦データを初期フェーズで学習しています。今までの手法ではメモリやコンピューティングパワーの限界にあったデータしか扱えませんでした。
DLは超大量のデータでも学習できる工夫があります。さらに、データの量が多ければ多いほど性能を上げることができるという特徴があります。
2. 複雑/多層モデルの実現
今までの機械学習アルゴリズムでは例えば人間がパラメータをチューニングしていたとします。これに対して破壊的に複雑なモデルが可能になりました。具体的なモデルは後で説明しますが、システム全体で数千万以上のパラメータや10以上のレイヤーを持っていても学習できるようになりました。
例えば初期の物体認識ネットであるAlexNet ではパラメータが約 6000 万個もあります。表現力の高い複雑なモデルでも学習してしまうことができるのです。
3. 汎化性能(非線形システムへの信頼性)の向上
DLは非線形システムです。これは従来扱いが難しいものでした。さらに過学習という問題があって、例えば学習時に使ったのとは違うシチュエーションの入力データが入った時にとんでもない答えを出す可能性が出てしまうのです。これだと実用のシステムとしては信頼しにくいのです。
DLでは非線形なシステムでも過学習を抑え信頼性を上げることができました。汎化性能は大きく向上しています。
4. 時系列データ
音声や文章、人の行動など、世の中のデータは時系列、可変長、多次元の複雑なデータです。DLではRNNやLSTMなどの構造を持つことで音声認識や自然言語処理などで精度の良い学習を可能にしました。これは従来プログラミング技術的にもいろいろと難しい分野でした。
DLとは何か?何を変えたか?
大枠的には上記で説明したように「非線形で、複雑なモデルあるいは大量のパラメータを持ち、大規模なデータや時系列のデータなどにも対応できるなどの工夫を備えたニューラルネットベースの機械学習システム」という認識で問題ないでしょう。
ただ、当初使われていたDLという言葉が指すモデルとは大きく離れたモデルがどんどん提案されてきています。とにかくここがエキサイティングなところで、後にじっくりと見ていきたいと思います。
- 何を変えたか?
上記の特徴により画像処理や音声認識、自然言語処理の分野で大きな性能の飛躍を可能にしました。これはいくつかの分野で単に性能を押し上げたということだけでは留まらなかったのです。
上記分野は写真や音声、文章とどれも人間が外界とのインタフェースとして使っているものです。つまりは人間と直接交わる部分であって、人間の生活に関わるものをAIで豊かにしていく可能性が開いたわけです。
そしてこのロマンと可能性が世界中の優秀な科学者・技術者を大量にDLの道に引き込む導線になりました。この変化がある意味一番大きな変化のようにも思えます。シリコンバレーではほぼ毎日のようにどこかでDLや機械学習のミートアップが開催されてます。まだまだ一過性のブームでは終わらない、エンジニアを惹きつけるものがあるのだと感じます。
基本要素
全体が長くなってしまったのでこのパートは分割してもう一つのポストにしました。DLはブラックボックスで性能改善が難しいと良く言われていますが、いろいろな方法論が提唱されています。各要素の持つ特徴や役割を理解しておけばDLモデルの改善はそれほど難解なものではありません。
Inside of Deep Learning (基本要素)
DLのデメリット
過学習しやすい
機械学習システムの本質的な問題は
誤:「学習データに対してシステムを最適化する」ことではなく
正:「学習データに含まれない未知の入力データに対してシステムを最適化する」ことです。
過学習と言ってトレーニング用のデータに対して解答を最適化しすぎると逆に実際の性能が落ちてしまうという問題があります。下の図は購入するときの家の大きさと価格のサンプルです。y = ax2 + bx + c の2次式(中央)で推定すれば全体的にフィットしますが、より表現力の高い6次式(右)で推定しようとすると実際とは大きく離れた推定モデルになってしまいます。
from scikit-learn:Machine Learning 101
特に非線形システムは線形システムに比べて過学習しやすく、予測範囲外の出力が出る可能性が高くなります。例えば下の図で、線形のシステム(左)ではp1とp2の間の入力に対する出力値はp1とp2の間になりますが、非線形のシステム(右)では予期しない値が出ることがあります。これは自動運転など安全が優先されるシステムでは特に大きな問題となります。
大量の学習用データが必要
教師なし学習や強化学習などもありますが、やはり教師データを与えるシステムが多いです。特にディープラーニングでは汎化性能をあげるためにも従来に比べてかなり多くのデータが必要になります。規模や対象にもよりますが例えば画像認識では最低でも数万件以上の学習データが必要と言われています。
また、例えば年齢や職業などから既婚状態、車の所持、年収(5段階)を予測する場合、出力クラスの全ての組み合わせである2x2x5=20のそれぞれの場合で十分な質と数のデータが必要になります。
正解データの作成に人手が必要な場合などでは非常にコストがかかってしまいます。このためにニューラルネットベースのシステムに移行できないという話は非常によく聞きます。またDLのブームの火付け役ともなった物体認識のタスクですが、これは当時に非常に大規模で質の良いデータセットが提供されていたこともあってDLと相性が良かったのでした。
膨大なコンピューティングリソースが必要
さらにDLではモデルがディープで複雑なものになることが多く、学習用データが多いことも相まって計算に非常に時間がかかります。GPUも必須になりますし、クラウドを使って気軽に分散化できるものではありません。
特に学習フェーズでは実験に数日から一週間ほどかかるような論文も少なくないです。この場合はモデルの改善に何度も試行錯誤しながら試すのが難しくなります。例えば本番環境でソフトを走らせるまでには通常何回テストランを走らせるでしょうか。一回の実行に一日かかると考えればその難しさが伝わるかと思います。
パラメータの収束が難しい
多数のレイヤーを持つ場合など、もともと数百万以上ある多数のパラメータをそれぞれ最適値へ収束させていくのは非常に難しくなります。バックプロパゲーションをかけて出力に近い層から学習させていった場合、正解との誤差がどんどん分散してしまって学習できなくなってしまうからです。またモデルが複雑になるほど鞍点と呼ばれる数次元で損失が極値になる点へ陥り、学習が進みにくくなるポイントも増えるからです。
上はInception-Net v1(GoogLeNet)のモデル図でレイヤーは合計で22層、計算要素は100程度あります。下のResNet-152は極端な例ではありますがレイヤー数が152層にもなります。Inception-Netの2年前に物体認識でDLが注目されるきっかけを作ったAlexNetは8層構造でした。まさに"The Deeper, the Better"と言われる所以です。
性能改善が難しい
DLのモデルはブラックボックスであるなどと良く表現されます。例えば下図の物体認識の場合、既存手法では特徴抽出や学習判別機などそれぞれの機能で問題があった場合はそれを検出して各ステップごとに改善を試みることができます。
ところがDLの場合はこれらの処理を全部まとめて学習してしまいます。問題があった場合にどのステップの能力が低いのか判断しにくく、また改善するための方法も多岐に渡るためどれを選択して良いのか分かりません。また問題を把握するために数学的な技術が必要になることも多いです。
同様に既存手法の場合は人間が持っている知識を組み込むことができますがDLでは非常に難しくなることが多くなってしまいます。総じて言えばとにかくコストが高いということです。高い技術レベルのエンジニア、学習データ、コンピュータリソース、時間、ほぼ全ての領域において既存技術の数倍〜数十倍のコストがかかり、ハイリスク/ハイリターンのシステムという感覚がぴったりです。
またこれは日本人にしか当てはまらないことですが、最新論文が全て英語であり特にアメリカ、あるいは欧米諸国や中国でしか最新事例が生まれていないこともあると思います。とにかくDLシーンの進化のスピードが早いので、言葉と文化の壁や産業構造の違いが悪い方向へ出てしまっているように感じます。皆でDLやろう!
各種改善手法・最新事例
いろいろなモデルや改善手法をみて見ましょう。ここからがやっと本ポストで書きたかった部分です。改善手法として大まかに4つの項目に分けてみました。
↑ Best
* より表現力があり発散しにくいモデルを考案する
* より多くのデータあるいはより精度の良いデータを使う
* パラメータを収束させるための工夫
* 汎化性能をあげるための工夫
↓ Better
モデルの進化
- Inception Net (GoogLeNet)
Googleが開発し大規模画像認識のコンテストILSVRC 2014で優勝した物体認識のためのモデルです。22層のレイヤーを持ち複数のCNNを並列に並べているのが特徴で、CNNのサイズやパラメータ数を抑える代わりに非常にディープにした構造です。3つの判定結果を使って総合的に判断し非常に高い性能を持っています。
現在では順調に進化を繰り返し、Inception-Net v4やInception-ResNet v2が公開されています。Inception-Net v3はgithub上でソースコードが公開され、AndroidやiPhone上でビルドして世界最高峰の物体認識機能を利用することも可能です。
- ResNet
ResNetはDeep Residual Learningという論文でMicrosoft Research Asiaにより発表されたもので、Residual(残差あるいは差分)をだけを学習するようにして非常に深いモデルでも効率良く学習できるようにしたモデルです。
2014年のILSVRCではGoogleがInception Netで飛躍的な成果を出して優勝したところをその翌年にはMicrosoftがさらに飛躍的な成果を出してひっくり返すと言う動きの速さがDLシーンの見どころです。
上図 左の画像がその一部を図にしたもので、上図 中央がそれを簡略化したものです。入力データを保持しておいてCNNの結果に加えることで各学習器は入力データとの変化分のみを学習すればよくなります。また上図 右の画像は比較のためのモジュールです。3x3x64のCNNフィルタを2枚重ねるよりも、1x1x64, 3x3x64, 1x1x256の3枚のフィルタを使うことで同等の表現力をもちながらもパラメータの数を抑えています。
直感的な説明にすると次に見るRNNとLSTMの関係に似ています。例えば今までのモデルでは入力されたデータを後ろのレイヤーに伝えるためのウェイトも特徴抽出の為のウェイトと同時に学習せねばなりませんでした。そうするともともとのウェイトが高くなり層が深くなると発散しやすくなってしまうということのようです。
Residual Netも他で応用されています。例えば下のリンクにある単眼超解像という画像の解像度を上げる論文では、これを利用することで飛躍的に深く、かつ学習率を従来の1万倍にして短時間でも学習できてしまうというモデルが提案されています。
- RNN
RNN (Recurrent Neural Network)は前回の出力データ(の一つ前の中間層出力)を保持しておき、次の入力データと共に別の入力値として利用する構造です。
文章や音声のような時系列のデータを処理できます。例えば "a" という単語が入ってきた場合にその直前に "I" と "have" が来ていたら "pen" を返す様にネットワークをトレーニングできます。状態メモリーを持つことに近く、DLのテキストや音声理解への道を開きました。
またRNNは必ずしもテキストや音声のような時系列のものが対象ではありません。例えば下の左の画像はDeepMindにより発表されたもので、住所の地番の画像を見せると注目するべき点の流れをRNNで生成します。人間の目のように左から右下へ順に番号を読んでいくように学習しました。右の画像ではRNNを使って数字の画像を生成するよう学習されたものです。
- LSTM
例えばRNNで文章を処理する場合、ずっと前の段落で言及された内容を整理して覚えておくことは不可能でした。LSTM(Long Short Term Memory) では一度保持した内容をずっと覚えておいて毎回の処理時に入力として与えることができます。さらに忘却ゲートという機構を備え、これを使うことで一度覚えた情報を消去することが可能になります。
上図は下記のリンクから引用した初代LSTMの図に幾つか説明を加えたものです。input gateでは今回得られた情報から現在の保持情報をどのように変更するかを決定します。forget gateでは現在の保持情報からどの情報を消すかを選択し、output gateでは今回の入力と現在の保持情報からどのような出力を行うかを選択する役割を持っています。
LSTMもいろいろな改良型が考案されており音声認識や機械翻訳で大きな成果を上げています。構造的にも引き続き大きな発展・変化をしています。例えば2015年にはLSTMを使ってIT製品のヘルプデスクの応答を自動で作成するチャットボットが発表され話題となりました。
- DQN
AlphaGoやDeep Dreamを開発したDeepMindの構築したdeep Q-network あるいは Deep Reinforcement Learningと呼ばれるモデルです。
ある状態でエージェントがとれる行動が有限の種類だけあったとします。その場合にどの行動を取れば将来的に最大の報酬が得られるかを経験的に学習していくものです。
Q Learningと呼ばれる古典的な強化学習の手法に対して、CNNを用いた画像認識や、後に説明するようなミニバッチや最新のオプティマイザなどのDL技術を組み合わせたモデルです。ロボットの制御やボードゲームのAIなどに利用できます。
最近ではさらにLSTMの手法を追加して自分が過去にとった行動を考慮するDeep Recurrent Q-Learningなども提案されています。DQNの強化版は特にGoogle DeepMindが力を入れている分野のようにみえます。
Human-level control through deep reinforcement learning
Deep Recurrent Q-Learning for Partially Observable MDPs
- DCGAN
DCGAN = deep convolutional generative adversarial networks です。二つの目的が正反対のモデルを交互に学習させながらお互いを鍛えていき、画像生成で革命的な成果を出したモデルです。IndicoというマシンラーニングのAPIを提供しているスタートアップとfacebookの研究所が出したものです。
Generatorこと"G" (僕の中では"爺さん")と、Discriminatorこと"D" (僕の中では"ディスラー") の2つのモデルを使って画像生成をするGANという技術にDLのCNN技術を応用したものです。ここでは3種類の学習を行います。
ディスラー(上図 下) は学習データとして与えられた顔画像を見て正解と答えるように学習します。構造的にはCNNを用いた画像分類器と似ています。
爺さん(上図 上) は与えられたランダムなパラメータから画像を生成します。この画像をディスラーに見せたときにディスラーが正解と答えるように学習します。
ディスラーは爺さんの作った画像を見たときは正解とせずに正しくディスるように学習します。
上記を繰り返していくことで学習していきます。また、ただCNNを使うというだけでなくてバッチの正規化や伝達関数に工夫などをして精度を高めているようでした。
ここでさらに興味深いのはこの爺さんが獲得した生成機では各パラメータがword2vecのような顔の特徴を掴んだものになることです。学習後にパラメータをランダムではなく手動で変更することで色々な特徴の顔をミックスして自由に画像を生成することができます。
顔以外にも風景などに適用でき、また近年では複数のGeneratorとDiscriminatorを使った複雑なStacked GANなども提案されています。
- SyntaxNet
SyntaxNetはGoogleの開発した自然言語用の構文解析器です。残念ながら僕はNLPについては全然分からないのでSyntaxNetの仕組みは説明できません。
ただ簡単に説明を読む限りではRNNのように順に単語を入れていくのではなく、ある程度まとめてタグをつけた上でネットワークに入力するようです。それをどうやって学習させているのかは分かりませんが、従来の構文解析器に比べて非常に高い精度を持ち、さらにどんな言語にでも学習可能というなかなか凄いふれ込みです。実際に最近になってgoogle翻訳の精度が大きく向上したと話題になっていましたが、ここら辺の技術が応用されている可能性も高そうです。
- アンサンブル学習
二つのネットワークを用いて画像生成を行うDCGANもその一種として良いと思います。近年とみに有効な手段として用いられているのがアンサンブル学習です。これは複数のネットワークを作ってそれぞれで個別にトレーニングを行い実行時にはそれらの多数決や協調により判断を行う仕組みです。
例えばAlphaGoでは初手の探索にはディープなネットワークを用いて高精度な予想を行い、手を読むときには返答の速い浅いネットワークを協調させて大きな性能を達成しています。また物体認識のための初期のInception netでは3つの出力を使って多数決で決めていました。一つのモデルを巨大にすると細部までの学習ができなくなるため、別々のケースを各モデルに個別に学習させるアンサンブル学習は分かりやすいです。
個人的にですが、異なる目的のネットワークが協調動作する様はまさに生命と言って良い面白さがあります。
- Differentiable Neural Computer
Differentiable Neural Computer もDeepMindから発表されたものです。従来のDLの枠組みにはまらない新しいもので、イメージとしてはチューリングマシンに非常に近いです。大きな特徴として自由なメモリ領域を持ちます。
DNCはデータが入力されるとそれに合わせてヘッドを動かしてメモリからデータを読み込みます。さらにリンク情報に従って順次別のメモリも読んで行きます。読み込みが終わったら出力を出すと同時に空いているメモリを探してそこに情報を書き込んだりメモリの消去を行います。メモリから出力された情報は次に来た入力データと合わせてRNNのように処理されます。
論文ではパズルを解いたり地下鉄の路線図や家系図を解析するなどいろいろなタスクが可能になったとされており今後の大きな可能性を感じます。
Differentiable Neural Computer
The Deeper, The Better
ここまで見てきたモデルはどれも話題になった有名なものですが、これ以外にも非常に沢山のモデルが考案されています。現在のトレンドとしては2つあり、パラメータを少なくして学習しやすくなる代わりに層を深くしていく方向と、複数のモデルを使っていく方向です。例えば下記の図は各年のILSVRCの優勝モデルの深さの変化です。但しどちらかというと単体のモデル自体は複雑にするのではなくシンプルにしつつ深くしていって、アンサンブルで組み合わせるというのが多いように思います。
次からはDLの性能を改善していくポイントを駆け足で見て行きましょう。
学習データの追加、改善
DLシステムの性能を上げるためにはためにはより沢山の学習データが必要と言われています。例えば下記の図は、顔のパーツやバスの認識について学習データを増やすほど性能が上がるとした論文のものです。
画像であれば左右反転させた画像を2枚使ってどちらを向いていても正しく特徴を取れるようにしたり、少し拡大したりノイズを混ぜるなどしてデータを水増しする手法がよく使われます。ユニークなのは例えばCGを用いて画像を作成し学習データして利用する方法などでしょうか。
またプレディクションなどに用いる場合は学習用データの分布が実データの分布と合っていることなども大事です。過学習を抑えるためにもデータの数は重要で、データ数がある数を超えた瞬間に急に性能が上がったというケースも沢山報告されています。
パラメータを収束させる
レイヤーの多いモデルを使うと表現力が上がる代わりにパラメータの収束(学習)が難しくなります。前に説明したResNetはそのために残差項を学習させるようにした例ですが、ここれはもう少し一般的な手法を紹介して行きます。
初期値の調整 (Xavierの初期化, Heの初期化)
フォワードプロパゲーション及びバックプロパゲーション中に信号や逆伝搬誤差の大きさ(分散)がどのように変わるかを計算し、各層でそれらの分散が一様になるように各レイヤーのランダムな初期値の分散を決める手法です。利用する伝達関数によって最適な値が決まります。
何故これが重要かというと、例えばウェイトが大きすぎた場合は信号が層を経るごとにどんどん大きくなり発散する可能性が増えてしまうためで、逆に小さすぎた場合は信号が減衰し最終レイヤーに到達する前に消失してしまう可能性があるからです。また初期値を設定するという意味では転移学習も重要な技術です。これは後に解説します。
Understanding the difficulty of training deep feedforward neural networks
Delving Deep into Rectifiers:
Surpassing Human-Level Performance on ImageNet Classification
モデル規模の適正化(あるいはモデル圧縮)
今までに見て来た通り、モデルを複雑にしてノード(特徴量)やレイヤーを増やすと性能を上げられる代わりに汎化性能や学習能力が下がり、結果的にモデルの規模を大きくすると性能が下がってしまいます。"次元の呪い"などとも言われていますが適切なサイズのノード数が必要と言われています。
またモデルが複雑になるにつれパラメータ数や計算時間が増えてしまい、モバイル端末上などで実行するには難しくなってしまっていました。学習後にネットワークを圧縮することで同等の性能を持ちながらも計算やモデルを簡略化できる手法が提案されています。
ミニバッチ、(+確率的勾配降下法)
ほとんどの大規模なDLのシステムではミニバッチを使用します。これは学習データの中からn個のサンプルごとに分けて(ミニバッチ)各集合に対して全ての勾配を計算し平均して利用する方法です。その勾配によりウェイトを更新したら次のミニバッチを利用し、全てのミニバッチを利用し終わったら学習用データを順番をランダムに入れ替えまた最初のミニバッチから処理を行います。(学習データを全て学習するたびにエポックという単位を1増やし、この値を用いて学習係数を減衰させたりします)
この方法を用いると下図のように損失の変化がギザギザして不安定に見えますが、これを行うことにより巨大なデータでも少しづつ学習を行うことができ、また局所解に落ちにくくなるというメリットもあります。
各種オプティマイザ (AdamとEve)
オプティマイザについてもいろいろな手法が考案されて来ました。オプティマイザのアルゴリズムによっては次に探索するべきパラメータをうまく求められず学習が進まなくなってしまうからです。
特にパラメータの数(次元)が増えると、局所解となるポイントが減り局所最適解に落ちる可能性は大幅に減りますが、代わりに損失値の勾配上で鞍点と呼ばれるポイントが増えます。これはある軸では局所的に損失が最小になり、ある軸では最大になるような点です。この点では勾配がすべての方向で0になるためどの方向にパラメータを持っていけば良いか分からず、ここから脱出するのが難しくなってしまいます。
Momentumという方法があります。これはその文字どおり、パラメータを探索してきた方向に慣性をつけて同じ方向へ移動し始めた場合に加速させてやる方法です。これにより鞍点からより早く脱出することができます。
Adagrad や Adadelta RMSprop などではさらに学習係数を自動で調節します。今まで何度も試してきたようなパラメータについては学習係数を小さくして探索幅を狭くし、逆にあまり試したことのない未知の領域にきた場合は学習係数を大きくして探索幅を広げていく方法です。
近年では Adam(Adaptive Moment Estimation)という上記のAdagradやRMSpropとMomentumのいいとこ取りをしたようなアルゴリズムで、今までの勾配の一次モーメント(指数移動平均)と2次モーメント(2乗値の移動指数平均)を考慮して更新値を決めます。
それぞれにモーメントの強さや初期値などの幾つかのパラメータがありこれらを適切に設定する必要があります。近年ではAdamオプティマイザが良く使われていますが、いつでもこれが良いというわけではなく損失空間の特徴によって適するアルゴリズムが異なります。下図はある損失空間上での各オプティマイザの動きです。
また、最近Eveという名前の新しいオプティマイザが考案されました。これはAdamの強化版で、論文を読んだ限りでは損失値の変化を見てやり変化が大きい場合はより大きな学習係数を設定し、変化が小さくなったらより小さな学習係数を設定する機能を追加したもののようです。これによりさらに性能があったとしています。イブというと僕は風邪薬を想起してしまいなかなか良く効きそうですが、Adamの上位版がEveというのはなかなか面白い名前だと思います。
入力データの正規化 (Data Normalization)
入力データに対して前処理を行い、各入力データの平均を0、分散を1となるようにするに調整します。データごとに平均値や大きが違う場合、各層のウェイトやバイアスはそれに適合するための学習を行わなければなりません。正規化によりこの手間を省き、各ウェイトと信号の大きさ(分散)を適切に保つ効果があります。
これを行うことで学習係数を大きくすることができたり多層でも収束するようにできる重要な要素です。入力データ全体の分散を揃え平均を1にする以外にも、データの最大値と最小値を揃える方法や、入力バッチごとに揃える(Batch Normalization)方法などがあります。
転移学習、ファインチューニング
転移学習(Transfer learning)は、例えば事前に学習済みの他のモデルから初期値を得て自分のモデルに転移(コピー)して初期値とする方法です。現状の物体認識やその他の画像処理タスクではCNN層は特徴抽出器として利用されていますが、最新のモデルではこの学習に1週間や2週間かかることも珍しくありません。既に公開されている学習済みのウェイトを使って初期化し汎用性の高い特徴抽出機として利用できます。その後に例えばある特別な花の判定に利用するためにその花のデータセットで追加で学習を行わせることで、データセットが少ない場合でも高い性能を出したり学習時間を大幅に節約することができます。
ファインチューニングも考え方は似ています。これは例えばディープなネットワークがあった場合に最初は少ない数のレイヤーで構築して学習させ、そのあとにレイヤーの数を増やして追加で学習を行わせたり、一部のネットワークの更新を止めてある部分のネットワークだけに学習を行わせる手法です。
パラメータを共有する
パラメータについては、値が小さくなるようにすると多層でも発散しにくい等のノウハウも幾つかありますが、同じパラメータを他のレイヤーで共有して繰り返し使うとことで正則化の効果を強くしよりディープにしても学習できるようになるというテクニックもあります。
例えば下記のDRCNは超解像という画像の解像度を上げるためのモデルですが、全く同じCNNを16回もかけてそれぞれの結果を合成することによりstate of the artの補完性能を獲得しています。( 実は僕の方で実装したサンプルもgithubにおいてます )
汎化性能を上げる
過学習状態をいかに避けるかというトピックは今までも繰り返し出てきました。モデルが過学習しているかを判定するのは実はそれほど難しくなく、学習時の損失と実データのテスト時の損失を比べてみて学習時の損失がテスト時よりもずっと小さくなってしまっていれば過学習状態にあると見て取れます。
(例えば学習が進み過学習状態になってしまうとテストセットでの損失が小さくならずに逆に大きくなってしまうことがあります。その場合は過学習が進む前に学習を中断させるアーリーストッピングというテクニックもあります。ただしあまり本質的な対処ではないので他の手法を使う方がお勧めです。)
ウェイトディケイ (正則化)
ウェイトディケイ、重み減衰、あるいは正則化などと呼ばれるテクニックは非常に広く使われています。損失関数に全ての重みの絶対値の総和=L1 Weight Decay(L1正則化)あるいは全ての重みの二乗値の総和=L2 Weight Decay(L2正則化)を係数をかけてたしてやるだけです。(バイアスは含まず、基本的にはL2が使われます)
これだけのものですが、パラメータの発散を防いで過学習状態を防ぐ強い効果があります。
ドロップアウト
ドロップアウトも有名です。これは学習時にランダムにノードのうち幾つかを全く使わずに出力とバックプロパゲーションを行うものです。これによりノード間の依存関係を減らしモデルが過学習してしまうことを防ぎます。ただし通常よりも学習が遅くなってしまうという欠点もあります。
例えば擬人化して考えます。あるノードの前にはA,B,Cの3つのノードがありました。Aさんが非常に優秀なので、このノードは常にAさんの出した答えを後ろに渡すことしか考えていませんでした。ところがドロップアウトにより突然Aさんが失踪したので仕方なくBさんとCさんの答えも考慮して判断するようになりました。というイメージです。また本質的にはアンサンブル学習と近い意味があるようです。
【Deep Learning】過学習とDropoutについて from sonickun.log
ハイパーパラメータの学習、自動調整
学習率の大きさやCNNあるいはノード(特徴量)のサイズ、隠れ層の数は重要ですが、それ以外にも上で説明したようにドロップアウトやウェイトディケイの係数、バッチの大きさや利用するオプティマイザの種類・モーメントの強さなど沢山のハイパーパラメータがあります。
モデルについては、例えば精度が出なくなったら広くして過学習しはじめたら狭くしながら深くしたりを試すなど、それぞれのパラメータを調節するためのガイドのような指針はあります。しかし実際に調節して試していくには大きな時間がかかります。2週間以上かけたというケースも珍しくないほど、ここの調整が一番時間のかかるところかもしれません。
これらの各ハイパーパラメータを自動で調整する機構をつけるケースも増えて来ました。トレーニングデータや実際の評価用(テスト)データに対してバリデーションデータとして別のデータセットを追加し、この損失勾配からハイパーパラメータを自動調整する手法です。
DLは何を変えるのか?
DLの進化は非常に早く、今回紹介したモデルや手法はほとんどが既に過去のものです。それぞれ多くの派生モデルが提案されています。
下記のページがよくまとまっていますが、2016年も恐ろしい数の論文が提出されその話題の幅も非常に幅広いものでした。是非ちらっとでも確認されてみると良いと思います。
DLは本当に"賢い"のか? 弱点は?
大手メディアの記事を読んでいると非常に賢いと思えてしまうDLを利用したAIですが、実際はちょっとイメージが違うと思います。
例えばDQNを用いてブロック崩しを解くAIが発表された時、幾つかのメディアは”ルールを勝手に推測して”プレイすると記事にしていました。ですが実際はルールなどは理解せずにただその状況ではどの行動をとれば良かったかを経験から学習して選んでいるだけです。(もちろんCNNを用いてゲーム中の画像から現在の状態把握ができるようになったという点は大きな進歩ではありますが)
あるいはAlphaGoの時も"棋士が次に打つ手を57%の精度で予測"などと書かれていました。この表現だとまるで相手の打つ手を高確率で予測できるように聞こえますが、実際はそうではありません。次にコンピュータが選んだ手が、過去のプロの対戦の中で使われたようなまともな手である確率が57%です。43%の確率で変な手を選んでしまうのです。
とにかく言いたかったことは、メディアの記事は鵜呑みにせず興味がある場合はできるだけ引用元を読みましょうということと、今のAIはあくまで限定的な状況での最適化がメイントピックであるということです。
そして弱点というとまず思い浮かぶのは、どうしても学習用データが必要になることです。教師データが作れない分野はまだまだ多く、また教師なし学習でできることは非常に限られているように思えます。
医療革命、生産革命、エネルギー問題、そして...?
知能の実現はまだ難しそうですが、逆に言えば非常に単純なタスクか、あるいはスペシャリストが対応するような限定された問題の両極端なところから実用化が始まっていきそうです。
現在でも既に各種の画像処理、翻訳や文章解析、音声認識などで一気に技術シーンを塗り替えていますが、これからは各種医療技術に応用されガンの予測や遺伝子解析、病気の診断などが一気に進んで行くでしょう。
PFNやnVidiaさんが勧めているIoT機器の知能化も非常に面白いです。モバイルやIoT機器にDL処理用のチップを使って知能化し、ネットに繋がなくても手元で高度なAIが動いたり、あるいはデバイスが得たデータをクラウドに送ってさらなる学習を中央で行いデバイスにアップデートして行くことが可能になります。工場や各種の生産技術はさらなる知能化や無人化が進み生産能力が大きく上がるのは間違いなさそうです。
DLは計算量も多く、大量に電気を消費します。最後に残された問題はエネルギー問題でしょうか。ただしそれもAIがエネルギー消費の効率化を進めています。おそらく電力が足りなくなるのは過渡期だけで、最終的には全てが効率化されエネルギーがむしろ余りそうな気もします。需要予測や最適化はAIの得意分野ですし、余ったエネルギーは無駄なく効率よくAIが使ってくれることでしょう。
ソフトエンジニアの在り方は変わるか?
「深層学習は何を変えるのか」なんていう立派なお題をつけてしまったわりには、実を言うと世の中がどう変わっていくかについてはそんなに良く分かりません。実はエンジニアの身の回りの変化についての考察がメインでした。
一番気になるのは、「自分の子どもたちにエンジニアになることを勧めるべきか否か」です。
ぱっと見ではAIを作る側にいるエンジニアは安泰なようにも思えますが...
これは究極的に言えば、"AIを作るAI"を作ることは現実的なのかという問題に近いと思います。
例えば現時点で既にLSTMでプログラムコードを読むという論文があります。あるいは「オプティマイザのオプティマイザ」とも言うべきもので、やはりLSTMを用いてオプティマイザ自体を学習してしまう論文も発表されています。つまりは既にその兆候が現れています。
さらに、この記事を書いているまさに丁度のタイミングで、AIを最適化するAIの記事が出てきました。
今まで見てきた進化の速度から考えるに、恐らく子供達が今の僕の年になる30年後には、今のようなソフトウェア職への需要は大きく下がっているのではと感じています。ベイエリアで年収2000万円もらってひーはーやってるエンジニアの職は多分なくなりません。問題なのはIT土方なんて言われるような大部分の中産階級のエンジニアです。
少なくともソースコードを書く部分はかなりの部分をAIが担当すると思います。人間や社会のことを理解し、ソフトの仕様を定義する"人間"は一定数必要になると思いますが、仕様を箇条書きで書くだけなので難しい要素は全くありません。仕様を書いたら後はAIがコードを生成しもし矛盾があれば自動で直してくれるか、優先順位やさらなる仕様を要求するだけでしょう。もちろんAIはこちらの性格を把握済みですから、こちらが気を悪くせずに仕事ができるよう最大限の配慮をしてくれます。もしかしたら今の上司や同僚よりも気持ちよく仕事ができちゃったりするかもしれません。
AIのチューニングはほとんどAIがやります。人間も一部手伝うとは思いますが、今のようなプログラムコードを書くやりかたではなく、何かビジュアルなツールを用いてモデルの構造をや組み合わせを変えたりするような感じになるのではと思いました。
結論としては、子供にプログラミングを教えるのはちょっと躊躇っています。
僕自身は高校時代からプログラミングを始めて凄いハマったのでちょっと寂しい気はします。もちろん論理的思考やクリエイティビティを刺激するようなものは積極的に与えたいです。かつての僕がしたように、CPUの動作やアドレスバスの動作を理解させてコンピュータの動作原理を教えるのも良いと思います。
ただしプログラミング自体の形は大きく変わり、開発に必要な人の人数も大きく減るだろうなとは感じています。そこはやはり30年後の子供達にとってはリスクになるのではないでしょうか。
最後に
この道を行けば、どうなるものか。
危ぶむなかれ。危ぶめば道はなし。
迷わず行けよ、行けばわかるさ。
みんなでやろう、DL!