Upload
taiga-nomi
View
6.387
Download
0
Embed Size (px)
Citation preview
Deep Learningの概要とドメインモデルの変遷
Taiga Nomi
2017/1/21 マルチパラダイムデザイン読書会 番外編
Embedded Computer Vision Software Engineer / The Author of tiny-dnn
Intro
● Deep Learningの概要
○ 最近の成果(主に画像関連)と学習の仕組み、脳との関連
● Deep Learningフレームワークのドメインモデルの変遷
について紹介します
Deep Learningの最近の成果 2012-2016
2012: Deep Learningブームの幕開け
● 物体画像認識のコンペで、Deep Learningを用いたチームが圧勝
○ エラー率を一気に10%近く改善(25.8->16.4%)○ 画像認識コミュニティに衝撃走る
“ImageNet Classification with Deep Convolutional Neural Networks ”, A. Krizhevsky, et. al.
2012: Deep Learningブームの幕開け
● 化合物の活性予測コンペでDeep Learningベースの手法が勝利
○ ドメイン知識を使わず、活性予測の素人が優勝
● Youtubeの動画を元に、”猫に反応するニューロン”を獲得
○ 画像からの特徴抽出の自動化…従来は人間のドメイン知識に基づいて設計
○ 2000台のマシンで1週間かけて10億パラメータを学習
○ 猫、人といった概念を教えずに(!)それらの概念を獲得
人の顔 (左)、猫の顔(右)によく反応するニューロンの可視化
Merck Competition Challenge http://blog.kaggle.com/2012/10/31/merck-competition-results-deep-nn-and-gpus-come-out-to-play/“Building High-level Features Using Large Scale Unsupervised Learning ”, Q. V. Le, et. al.
2013 - 2016
● ルールを教えずにAtari 2600をプレイ(2013)○ コンピュータが自分で試行錯誤しながら、様々なゲームのプレイ方法を学習
○ ブロック崩しなどの単純なゲームでは人間以上のスコア
“Playing Atari with Deep Reinforcement Learning”, V. Mnih, et. al.
2013 - 2016
● 物体画像認識タスクで人間のエラー率を超える(2015)○ Human:5.1% Deep Learning: 4.94% (by Microsoft Research)○ さらに2016/8には3.08%まで改善 (by Google)
● 画像拡大(超解像)で従来を大幅に超える精度を達成(2015)○ パッチ型超解像と呼ばれていた技術を応用、汎用的なDeep Learningで実現
“Delving Deep into Rectifiers: Surpassing Human-Level Performance on ImageNet Classification”, K. He, et. al.“Inception-v4, Inception-ResNet and the Impact of Residual Connections on Learning”, C. Szegedy, et. al.“Learning a Deep Convolutional Network for Image Super-Resolution”, C. Dong, et. al.
2013 - 2016
● 画風の変換(2015)○ 画像から”画風”の特徴だけを抽出して別の画像に適用
○ のちに動画にも適用: https://www.youtube.com/watch?v=Uxax5EKg0zA
“A Neural Algorithm of Artistic Style”, L. A. Gatys He, et. al.“Artistic style transfer for videos”, M. Ruder, et. al.
2013 - 2016
● 会話レベルの音声認識で人間と同レベルの精度を達成(2016)● 囲碁でトップ棋士に勝利(2016)
○ 2016/12には、オンライン囲碁で世界1位を含むトップ棋士相手に60勝0敗● 線画の自動着色(2016)
“Achieving Human Parity in Conversational Speech Recognition”, W. Xiong, et. al.“Mastering the game of Go with deep neural networks and tree search”, D. Silver, et. al. Qiita: 初心者がchainerで線画着色してみた。わりとできた。 http://qiita.com/taizan/items/cf77fd37ec3a0bef5d9d
2013 - 2016
● 多言語間の翻訳を単一のニューラルネットで実現(2016)○ 日⇔英、韓⇔英を学習させると、日⇔韓の翻訳もできる(Zero-Shot Translation)
■ 内部で言語に非依存な中間表現を獲得していると思われる
“Google’s Multilingual Neural Machine Translation System: Enabling Zero-Shot Translation”, M. Johnson, et. al.
a, b: 3言語で74の文章を入力した際の内部表現
の可視化(文章ごとに色分け)。
c: 3言語で同じ意味の文章は、近い内部表現
に対応している
2013 - 2016
● 文章から高精度な画像を生成(2016)○ 学習した画像の継ぎ接ぎではなく、ゼロから描画している(下段)
“StackGAN: Text to Photo-realistic Image Synthesis with Stacked Generative Adversarial Networks”, H. ZHang, et. al.
demo
● 落書き認識
○ https://quickdraw.withgoogle.com/● 画像キャプション生成
○ https://www.captionbot.ai/● アニメ顔生成
○ http://mattya.github.io/chainer-DCGAN/
Deep Learningの概要 歴史、機構、脳との関連
AI/機械学習/ニューラルネット/Deep Learning
● AI: 機械による知性
● 機械学習:人間のような学習機能を、データから自動的に習得する技術
○ ニューラルネットワーク、Deep Learningはその1カテゴリ
AI機械学習
ニューラルネットワーク
Deep Learning
ニューラルネットワーク
● 脳神経系における情報伝達を模した数学モデル
○ 多数のニューロンが互いに接続
○ ニューロン間の結合強度はそれぞれ異なる
○ この結合強度を調整(学習)することで問題解決能力を得る
第1世代:単純パーセプトロン (1958~60s)
● 入力値の重み付き和を取る、最も単純なニューラルネットワーク
○ ある閾値を超えると出力が発火するようなニューロンモデル
○ 出力の発火によって、入力を2つに分類する
犬
猫
単純パーセプトロンの学習
● サンプルを1つずつ試行し、正しく分類されるよう少しずつ重みを修正
出力yと期待結果tの差を縮めるように重みを更新
単純パーセプトロンの限界
● パーセプトロン:入力を平面で2つに分割していることに相当(線形分離)○ 平面で分割できないようなデータは、パーセプトロンで学習できない
?
第2世代:多層パーセプトロン (1980~90s)
● 単純パーセプトロンを複数重ねた構造
入力 出力 隠れ層
第2世代:多層パーセプトロン (1980~90s)
● 単純パーセプトロンを複数重ねた構造
入力データ 出力データ 隠れ層
(活性化関数:閾値処理の一般化)
第2世代:多層パーセプトロン (1980~90s)
● 単純パーセプトロンを複数重ねた構造
入力データ 出力データ 隠れ層
第2世代:多層パーセプトロン (1980~90s)
● 単純パーセプトロンを複数重ねた構造
入力データ 出力データ 隠れ層
多層パーセプトロンの特徴
● 非線形な問題を解くことができる
● 適切に学習すれば、有限個のニューロンで任意の連続関数を近似できる
(universal approximation)
Input OutputTrainable Building Blocks
- text
- audio
- image
- video
- ...
- text
- audio
- image
- video
- ...
多層パーセプトロンの学習
● どうすれば目的の機能を果たす重みが得られるか?
○ 単純パーセプトロンのように、少しずつ解に近づけていきたい■ ただし単純パーセプトロンと違い、隠れ層の重みは最終結果に間接的にしか寄与しない
○ 目標の出力と、実際の出力の誤差をなるべく小さくしたい
● 重みを変えたときの誤差の変化(勾配)が分かれば、進む方向が分かりそう
誤差J
重み
勾配の算出
● 微分の定義から算出
○ 適当に小さなhを置いて以下を計算すれば良い
○ 重み1個に対して2回Jを計算する必要があり、現実的でない■ Jの計算がO(n)なので、n個の重みを1ステップ更新するのにO(n^2)の計算量
■ 冒頭の“猫ニューロン”…n~10^9
● 1980sに勾配を効率良く求める方法が提案(再発見)された : 誤差逆伝播法
誤差逆伝播法(1/5)
● すべての重みを適当な値(乱数など)で初期化
● 学習用データをネットワークに与えて、まず答えを出させる
○ 最初はでたらめな値を出力する
Dogs or Cats?
Dog : 0.32
Cat : 0.34
resultinput
誤差逆伝播法(2/5)
● 期待結果と出力から誤差を計算
Dogs or Cats?
Dog : 0.32
Cat : 0.34
result desired
Dog : 0.0
Cat : 1.0(+0.66)
(-0.32)
input
誤差逆伝播法(3/5)
● 出力層の誤差を、入力層に遡って伝播させていく
○ 偏微分のChain Ruleを使うことで、効率的に誤差を計算できる
○ 下流のニューロンの誤差×そのニューロンとの結合度に比例し、上流も修正される
Dogs or Cats?
Dog : 0.32
Cat : 0.34
result desired
Dog : 0.0
Cat : 1.0(+0.66)
(-0.32)
input
誤差逆伝播法(3/5)
● 出力層の誤差を、入力層に遡って伝播させていく
○ 偏微分のChain Ruleを使うことで、効率的に誤差を計算できる
○ 下流のニューロンの誤差×そのニューロンとの結合度に比例し、上流も修正される
○ 組織のメタファ:部下のミスの大きさと、その部下への関与の大きさに応じて上司も怒
られていくDogs or Cats?
Dog : 0.32
Cat : 0.34
result desired
Dog : 0.0
Cat : 1.0(+0.66)
(-0.32)
input
誤差逆伝播法(4/5)
● 計算された誤差に応じて、重みを少しだけ修正
● これを学習データ集合に対して繰り返し行う
Dogs or Cats?
ニューラルネット冬の時代
● 問題点:層を積み重ねても学習が上手くいかない
○ 誤差を伝播するにつれて、上流側で誤差が消失してしまう
○ 結果、上流はほとんど学習されず、下流だけが過学習する状態になる■ 組織のメタファ:現場での局所最適化ばかりが進んでしまう
● 他の手法の流行もあり、ニューラルネットは下火に
○ ”ニューラルネットを論文タイトルに入れると採択確率が下がる”と言われる始末
第3世代:Deep Learning (2006~)
● さらに多層(7層~)から構成されるニューラルネットワーク
● 基本的な構成要素は第2世代と同じ
○ 学習が上手く行きやすくなるテクニックの蓄積
○ GPGPUを使った計算の効率化
○ ビッグデータの活用
● 研究での最初のブレークスルーは2006頃
Why Deep ?
● 直観的な理解:対象の階層的な構造をうまく取り込めるから
○ 画像認識…単純な特徴(エッジetc)と、それを組み合わせた複雑な特徴が使われる■ 従来は、ドメイン知識に基づいて人が特徴抽出部を設計していた
■ Deep Learningによって、End-to-Endで学習ができるように
○ 特徴の自動抽出=表現学習(representation learning)を行っていると考えられる
Input OutputDeep Learning
Input OutputFeature Extraction
Perceptronetc.
Why Deep ?
● 理論的な研究…未解決の問題が多い
○ 1) 世の中の様々な問題がXというクラスに分類できるか
○ 2) XというクラスをDeep Learningが学習できるか■ 2-1) Deepかつ現実的な規模のモデルが、対象を十分表現する能力を持つか
■ 2-2) Deepなモデルの学習が (局所最適に陥りそうだという直観に反して)なぜ上手くいくのか
Why Deep ?
● Linの仮説:世の中に以下の特徴がある
○ 低次性:多くの物理現象で相互作用の次数は2~4○ 局所性: 現象の影響範囲が局所的
○ 対称性: 回転や移動に対する対称性が広くみられる
○ マルコフ性: 生成過程が直前の状態にのみ依存
● これらを満たす場合、Deep Learningは現実的な
パラメータ数で問題を解ける
“Why does deep and cheap learning work so well?”, H. W. Lin and M. Tegmark
畳み込みニューラルネット(CNN)
● 対称性、局所性を構造に取り込んだニューラルネットの亜種
● 畳み込みとプーリングの組み合わせで特徴抽出したのち、多層パーセプトロン
で分類
“Gradient-Based Learning Applied to Document Recognition”, Y. LeCun, et. al.
畳み込みニューラルネット(CNN)
● 畳み込み=フィルタ処理
○ 結合を近傍ニューロンに限定することで局所性を得る
○ 重みをニューロン間で共有することで対称性を得る
○ 画像処理でのフィルタ処理と等価
https://github.com/vdumoulin/conv_arithmetichttps://en.wikipedia.org/wiki/Kernel_(image_processing)
畳み込みニューラルネット(CNN)
● プーリング=縮小処理
○ 縮小の過程で並行移動、回転に対する一定の対称性を得る
https://en.wikipedia.org/wiki/Convolutional_neural_network
CNNによって学習された特徴
“Convolutional Deep Belief Networks for Scalable Unsupervised Learning of Hierarchical Representations”, H. Lee, et. al.
…
● 1回目の畳み込み…単純なエッジ検出(Gaborフィルタによく似た形)● 2回目/3回目の畳み込み…特定のパーツ、顔全体etc
CNNと脳(大脳皮質の視覚野)との類似点
● 脳も階層構造を持ち、下位は単純な特徴、上位は複雑な特徴を獲得
○ V1野: 単純なエッジに反応するフィルタ(Gabor Filterで近似できる)が後天的に獲得
○ IT野: 自動車に反応するニューロン、オペラハウスに反応するニューロン(!)etc
http://kazoo04.hatenablog.com/entry/agi-ac-7 https://bsd.neuroinf.jp/wiki/受容野
Deep Learningは人間を超えるか?
● 汎用的な意味では(現状)No○ 画像、音声、ビデオといった知覚的な入力(perceptual input)をターゲットにした、特定
のタスク群で非常にうまく機能している点が従来との差分
○ ある種の表現学習が出来ていそうだという点も興味深い
○ ただし、特定のタスクで人間を上回る=汎用的な”知的思考”が出来る訳ではない■ 電卓だって人間より高性能
● 汎用AIの実現に向けた小さな前進ではあるかも
Deep Learningのドメインモデル フレームワークの進化とドメインモデルの深化
Deep Learningフレームワーク
● 研究だけでなく、フレームワークによる実装も大きく変化
○ 研究と実装、お互いが影響を与えながら進化している
○ どっちがソリューションドメイン? →視点に依存
● OSS上でニューラルネットモデルがどのような変遷を辿っているのかを紹介
第1世代: 人工ニューロンモデル
● FANN(2003-)など : 人工ニューロンモデルの素直な実装
○ ニューロン:活性化関数の種類と結合先、現在の値を保持する構造体
○ レイヤ: ニューロンのリストで表現
○ “積和演算とニューロンによる活性化からなるレイヤの連鎖”○ 層の数、各層のニューロン数と活性化の種類が設計パラメータ
Layer Network
NeuronNeuron
Weight
Activation
※世代は本スライドで便宜的に付けたもの
Example / FANN
const unsigned int num_input = 2;const unsigned int num_output = 1;const unsigned int num_layers = 3;const unsigned int num_neurons_hidden = 3;const float desired_error = (const float) 0.001;const unsigned int max_epochs = 500000;const unsigned int epochs_between_reports = 1000;
struct fann *ann = fann_create_standard(num_layers, num_input, num_neurons_hidden, num_output);
fann_train_on_file(ann, "xor.data", max_epochs, epochs_between_reports, desired_error);
第2世代: レイヤによる抽象化
● pybrain(2008-)など
○ ニューロンを明示的にモデル化せず、レイヤをブラックボックス化
○ レイヤ:”値を伝播し(forward/backward), 活性化する(activation)”モジュール
○ ”活性化を持つ、誤差伝播可能なレイヤの連鎖”○ 畳み込みやプーリングなどが実現できるようになった
Layer Network
conv
pool
conv
Activation
第2.5世代: 活性化関数の分離
● Torch5(2006-)など
○ 活性化関数をひとつのレイヤとして扱うことで、レイヤをより汎用化
○ レイヤ:”N次元ベクトル(テンソル)を入出力とする、微分可能な関数”○ “微分可能なレイヤの連鎖”○ 活性化にこだわらず、あらゆる計算を含められるようになった
Layer Network
conv
pool
conv
sigmoid
sigmoid
第3世代: リストから有向グラフへ
● Torch7(2010-), tiny-dnn(2012-), Caffe(2013-), Keras(2015-)など
○ 偏微分のチェインルールは1対1接続でなくても成立
○ “微分可能なレイヤの有向グラフ”○ 多入力・多出力を含む、より柔軟な設計ができるようになった
■ 2017年現在では、分岐構造を持たないモデルの方が珍しい
※考え方自体は1990sから存在
“Gradient-Based Learning Applied to Document Recognition”, Y. LeCun, et. al.
Example / Caffe
DSLでモデル(グラフ)を定義layer { name : “conv1” type : “Convolution” convolution_param { num_output: 20 kernel_size: 5 } bottom: “data” top: “conv1”}layer { name : “pool1” type : “pooling”...
入出力に接続するエッジ
ノードの種別と詳細パラメータ
第4世代: レイヤから演算子へ
● Theano(2011-), TensorFlow(2015-), Chainer(2015-), pytorch(2017-)など
○ グラフのノードの粒度を、レイヤではなく演算子(operator)の粒度に下げる■ さらに柔軟な構造が定義できるように
○ “微分可能なオペレータの有向グラフ”
mul
plus
sqr
plus
op
○ もはや、単なるニューラルネットワークの実装では無くなっている
“TensorFlow™ is an open source software library for numerical computation using data flow graphs.”https://www.tensorflow.org/
Example / TensorFlow
x_data = np.random.rand(100).astype(np.float32)
y_data = x_data * 0.1 + 0.3
W = tf.Variable(tf.random_uniform([1], -1.0, 1.0))
b = tf.Variable(tf.zeros([1]))
y = W * x_data + b
# Minimize the mean squared errors.
loss = tf.reduce_mean(tf.square(y - y_data))
optimizer = tf.train.GradientDescentOptimizer(0.5)
train = optimizer.minimize(loss)
命令型(imperative) vs 記号型(symbolic)
● 記号型:計算を即時に行わず、式自体を保持するモデル
○ TheanoやTensorFlowで採用
○ 学習の実行時にモデルをフレームワーク側で”コンパイル”し、グラフ構造を解析する
○ “コンパイラ”での最適化が(頑張れば)できるため、高速・高効率■ 一時メモリの再利用、分散学習の効率化など
A = Variable('A')
B = Variable('B')
C = B * A
D = C + Constant(1)
# compiles the function
f = compile(D)
d = f(A=np.ones(10), B=np.ones(10)*2)
http://mxnet.io/architecture/program_model.html#symbolic-vs-imperative-programs
ここで初めてグラフが実行される
ここで計算対象のグラフが確定
命令型(imperative) vs 記号型(symbolic)
● 命令型:呼び出した時点で計算が実行されるモデル
○ Chainerやpytorchで採用■ 実行時に演算グラフをバックエンドで記録しておき、後から自動微分で逆伝播する
○ 言語側の組み込み関数とMixしやすく、デバッグが容易
A = Variable(rand())
B = Variable(rand())
C = B * A
D = C + Constant(1)
D.backward() 裏で生成しておいたグラフから自動微分
この時点でCは計算されている
ドメインモデルの深化
● 人工ニューロンモデルから、データフロー計算をサポートするDSLへ進化
LayerNeuron Op
Neuron
Weight
Activation
Tensor
ドメインモデルの深化
● 研究側でも、より多彩な構造をもったNetworkが次々に提案されている
○ 層を飛び越えた接続、非決定的な動作、再帰、外部記憶の導入...
“Deep Networks with Stochastic Depth”, H. Lee, et. al.“Densely Connected Convolutional Networks”, G. Huang, et. al.“Quasi-recurrent Neural Networks”, J. Brudbury, et. al.“DeepBach: a Steerable Model for Bach chorales generation”, G. Hadjeres and F. Pachet
ユビキタス言語
● TensorFlowが普及することで柔軟なモデルが定義できるようになった一方、
APIが低レイヤすぎると感じることも…○ TensorFlow上のAPIは、Deep Learningでのユビキタス言語と抽象度が異なる
Words in Deep Learning World APIs in TensorFlow
neuron -
layer op
network session
forward-propagation compute
train minimize
Wrapper Framework
● Theano/TensorFlow上に、Deep Learning用の使いやすいAPIを構築する高レ
ベルフレームワークが多数出てきている
○ Keras(2015):Theano/TensorFlowをバックエンドにしたレイヤ粒度のAPI○ tf-slim(2016): TensorFlow公式のWrapper
● かつては単一ライブラリで賄っていたものが、2つのドメインに分割
○ 高度な最適化を伴う、数値計算グラフのドメイン
○ Deep Learningモデルのドメイン
まとめ
● Deep Learningは知覚系のタスクを中心に大きな成功を収めている
○ 理論的背景はまだ未知の部分が多い
● Deep Learningのドメインモデルも旧来から大きく変化
○ 人工ニューロンから計算グラフへ
○ フレームワーク実装の深化、ドメイン分割
おまけ: tiny-dnn
tiny-dnn(2012-)
● C++での高レベルAPIを持ったdeep learningフレームワーク
● Header-only、かつ外部依存無しで手軽に使えることが最大の売り
○ 組み込み系含む、アプリケーションへの統合がやりやすい
○ 別フレームワーク(Caffe)で学習した結果をインポートできる
● Google Summer of Code 2016にOpenCVを経由して参加し、開発が活性化
○ 2016/1-2017-1の間で、Github starが150 -> 2400まで伸びた
○ 個人レポジトリからOrganizationに移行。現在Core member4名+Reviewer2名● ドメインモデルは第3世代相当
○ 実装をシンプルに留めるための意図的なデザイン
API比較
network<sequential> net;net << conv<>(28, 28, 5, 1, 32) << max_pool<relu>(24, 24, 2) << conv<>(12, 12, 5, 32, 64) << max_pool<relu>(8, 8, 64, 2) << fc<relu>(4*4*64, 1024) << dropout(1024, 0.5f) << fc<>(1024, 10);
x = tf.Variable(tf.random_normal([-1, 28, 28, 1]))wc1 = tf.Variable(tf.random_normal([5, 5, 1, 32]))wc2 = tf.Variable(tf.random_normal([5, 5, 32, 64]))wd1 = tf.Variable(tf.random_normal([7*7*64, 1024]))wout = tf.Variable(tf.random_normal([1024, n_classes]))bc1 = tf.Variable(tf.random_normal([32]))bc2 = tf.Variable(tf.random_normal([64]))bd1 = tf.Variable(tf.random_normal([1024]))bout = tf.Variable(tf.random_normal([n_classes]))
conv1 = conv2d(x, wc1, bc1)conv1 = maxpool2d(conv1, k=2)conv1 = tf.nn.relu(conv1)conv2 = conv2d(conv1, wc2, bc2)conv2 = maxpool2d(conv2, k=2)conv2 = tf.nn.relu(conv2)fc1 = tf.reshape(conv2, [-1, wd1.get_shape().as_list()[0]])fc1 = tf.add(tf.matmul(fc1, wd1), bd1)fc1 = tf.nn.relu(fc1)fc1 = tf.nn.dropout(fc1, dropout)out = tf.add(tf.matmul(fc1, wout), bout)
tiny-dnn (C++)
TensorFlow (Python)