lispmeetup #39 mglの紹介: common lispによるディープラーニング

29
MGLの紹介 Satoshi Imai / 今井 悟士 Twitter: @masatoi 0 Github: masatoi Common Lispによるディープラーニング

Upload: satoshi-imai

Post on 26-Jan-2017

5.381 views

Category:

Engineering


0 download

TRANSCRIPT

Page 1: Lispmeetup #39 MGLの紹介: Common Lispによるディープラーニング

MGLの紹介

Satoshi Imai / 今井 悟士

Twitter: @masatoi0 Github: masatoi

Common Lispによるディープラーニング

Page 2: Lispmeetup #39 MGLの紹介: Common Lispによるディープラーニング

MGLとは

● Common Lisp用の機械学習ライブラリ

● ディープラーニングの割と最近の手法までカバー

● MGL-MATという行列演算ライブラリを使う

– cl-cuda、LLA(Lisp Linear Algebra)によって高速化

● cl-cuda非対応の旧版はQuicklispにある(最新版はGithubから)

● サンプルが長かったので整理した

– https://github.com/masatoi/mgl-user

Page 3: Lispmeetup #39 MGLの紹介: Common Lispによるディープラーニング

MGLに実装されているモデル

● 教師あり学習

– FFNN (Feed Forward Neural Networks)

● 教師なし事前学習

– DBN (Deep Brief Networks)

– DBM (Deep Boltzmann Machine)

● 時系列向けモデル

– RNN (Reccurent Neural Networks)

– LSTM (Long Short Term Memory)

Page 4: Lispmeetup #39 MGLの紹介: Common Lispによるディープラーニング

ニューラルネットワーク

入力層 隠れ層 出力層

● フィードフォワードニューラルネットワーク(FFNN)

Page 5: Lispmeetup #39 MGLの紹介: Common Lispによるディープラーニング

ニューラルネットワークによる予測

入力層 隠れ層 出力層

入力

重み

Page 6: Lispmeetup #39 MGLの紹介: Common Lispによるディープラーニング

活性化関数

入力層 隠れ層 出力層

入力

重み

活性化関数

Page 7: Lispmeetup #39 MGLの紹介: Common Lispによるディープラーニング

出力層の活性化関数は問題に応じて変える

入力層 隠れ層 出力層

● 回帰問題なら恒等写像● 分類問題ならソフトマックス関数

0.2

0.5

0.3

例えば3クラス分類問題なら...

Page 8: Lispmeetup #39 MGLの紹介: Common Lispによるディープラーニング

ニューラルネットワークの学習

● 予測値と実測値の違いを表す損失関数を最小化する → 勾配法

● 勾配は出力層から入力層に向かって伝搬するように計算(逆伝搬)

● 勾配法の色々なバリエーション

– 確率的勾配降下法(SGD)

– Momentum SGD

– ADAM

● 詳細は本を読もう!

Page 9: Lispmeetup #39 MGLの紹介: Common Lispによるディープラーニング

ディープラーニング

● 隠れ層を多層にしたニューラルネットワーク

– 勾配消失問題:多層にすると逆伝搬のときに勾配が消失/発散する

● → オートエンコーダ/RBMによる教師なし事前学習 (後述)

● → 活性化関数にReLUやMaxoutを使う (後述)

● 特徴量を作りこまなくても生のデータを与えればいい。手軽。性能良し

● 一方で計算時間はかかる

– → データを小分けしてまとめて並列に処理する → ミニバッチ

● ネットワークを複雑にすると過学習する

– → Dropout (後述)を使って汎化性能を上げられる

Page 10: Lispmeetup #39 MGLの紹介: Common Lispによるディープラーニング

ディープラーニングで使われる活性化関数: ReLU、Maxout

● 正規化線形関数(Rectified Linear Unit; ReLU)

– 勾配が消失しにくい

– 計算が単純で速い

– 多分一番メジャー

● Maxout

– 複数の線形ユニットから成る

– 活性化関数自体が学習

– ReLUよりも良い場合も多い

– 計算時間は増える

Page 11: Lispmeetup #39 MGLの紹介: Common Lispによるディープラーニング

例題:MNIST

● 手書き数字認識のデータセット。よく例題に使われる

● 28×28ピクセルの画像(784次元)に正解ラベルがついている

● 訓練データ60000個、テストデータ10000個

● http://yann.lecun.com/exdb/mnist

Page 12: Lispmeetup #39 MGLの紹介: Common Lispによるディープラーニング

データセットの読み込み

● MNISTのデータを読み込む関数training-data、test-data

● データセットはデータ点の構造体の配列

● データ点の中身

MGL­USER> (aref *training­data* 0)#S(DATUM   :ID 1   :LABEL 5   :ARRAY #<MAT            784 AB #(0.0d0 0.0d0 0.0d0 0.0d0 0.0d0 0.0d0 0.0d0 0.0d0 0.0d0                     0.011764705882352941d0 0.07058823529411765d0...                     0.0d0 0.0d0 0.0d0 0.0d0 0.0d0 0.0d0 0.0d0 0.0d0 0.0d0                     0.0d0 0.0d0 0.0d0 0.0d0)>)

MGL-MATの構造体

Page 13: Lispmeetup #39 MGLの紹介: Common Lispによるディープラーニング

ネットワークの構造を定義する

● build-fnnマクロでネットワークの構造を指定してmake-instanceする

– 入力層784次元、1200次元の隠れ層が3層、出力層10次元

– 隠れ層の活性化関数はReLU、出力層の活性化関数はソフトマックス関数

– バッチサイズ100

(defparameter my­fnn  (build­fnn (:class 'fnn :max­n­stripes 100)    ;; Input Layer 784 dim    (inputs (­>input :size 784))    ;; Hidden Layer 1 1200 units, ReLU    (f1­activations (­>activation inputs :name 'f1 :size 1200))    (f1 (­>relu f1­activations))    ;; Hidden Layer 2 1200 units, ReLU    (f2­activations (­>activation f1 :name 'f2 :size 1200))    (f2 (­>relu f2­activations))    ;; Hidden Layer 3 1200 units, ReLU    (f3­activations (­>activation f2 :name 'f3 :size 1200))    (f3 (­>relu f3­activations))    ;; Output Layer: Softmax layer 10 dim    (prediction (­>softmax­xe­loss (­>activation f3 :name 'prediction :size 10)                                   :name 'prediction))))

Page 14: Lispmeetup #39 MGLの紹介: Common Lispによるディープラーニング

ネットワークの内容

● ネットワークはlumpというオブジェクトの集合から構成されている

– ->input、 ->relu、 ->softmax-xe-lossなど

– ->activationは層間の重みを持っている

MGL­USER> (describe my­fnn)#<FNN {10205FDD53}>BPN description:  CLUMPS = #(#<­>INPUT INPUTS :SIZE 784 1/100 :NORM 0.00000>             #<­>ACTIVATION (F1 :ACTIVATION) :STRIPES 1/100 :CLUMPS 4>             #<­>RELU F1 :SIZE 1200 1/100 :NORM 0.00000>             #<­>ACTIVATION (F2 :ACTIVATION) :STRIPES 1/100 :CLUMPS 4>             #<­>RELU F2 :SIZE 1200 1/100 :NORM 0.00000>             #<­>ACTIVATION (F3 :ACTIVATION) :STRIPES 1/100 :CLUMPS 4>             #<­>RELU F3 :SIZE 1200 1/100 :NORM 0.00000>             #<­>ACTIVATION (PREDICTION :ACTIVATION) :STRIPES 1/100               :CLUMPS 4>             #<­>SOFTMAX­XE­LOSS PREDICTION :SIZE               10 1/100 :NORM 0.00000>)  N­STRIPES = 1  MAX­N­STRIPES = 100

Page 15: Lispmeetup #39 MGLの紹介: Common Lispによるディープラーニング

ネットワークの内容

● 各層のオブジェクトはnodesとderivativesというスロットを持っていて、それ

ぞれ順伝搬、逆伝搬の値が入る

MGL­USER> (describe (aref (clumps my­fnn) 0))#<­>INPUT INPUTS :SIZE 784 100/100 :NORM 94.94252>  [standard­object]

Slots with :INSTANCE allocation:  NAME               = INPUTS  SIZE               = 784  NODES              = #<MAT 100x784 AF #2A((0.0d0 0.0d0 0.0d0 0.0d0 0.0d0..  DERIVATIVES        = #<MAT 100x784 A #2A((­3.2746879326098654d­13 ­2.3442..  DEFAULT­VALUE      = 0  SHARED­WITH­CLUMP  = NIL  X                  = #<­>INPUT INPUTS :SIZE 784 100/100 :NORM 94.94252>  DROPOUT            = NIL  MASK               = NIL

Page 16: Lispmeetup #39 MGLの紹介: Common Lispによるディープラーニング

ネットワークの内容

● 出力層は教師信号を表すtargetスロットを持っている

MGL­USER> (describe (aref (clumps my­fnn) 8))#<­>SOFTMAX­XE­LOSS PREDICTION :SIZE 10 100/100 :NORM 9.98895>  [standard­object]

Slots with :INSTANCE allocation:  NAME               = PREDICTION  SIZE               = 10  NODES              = #<MAT 100x10 ABF #2A((2.017507522628972d­9..  DERIVATIVES        = NIL  DEFAULT­VALUE      = 0  SHARED­WITH­CLUMP  = NIL  X                  = #<­>ACTIVATION (PREDICTION :ACTIVATION) :STRIPES 100/10  TARGET             = (3 8 6 1 0 0 9 4 8 7 0 4 2 5 6 0 6 3 9 3 2 0 9 3 1 ..

Page 17: Lispmeetup #39 MGLの紹介: Common Lispによるディープラーニング

ネットワークに入出力を設定

● 入力層のnodesと出力層のtargetにデータセットの値を設定する

(defmethod set­input (samples (bpn fnn))  (let* ((inputs (or (find­clump (chunk­lump­name 'inputs nil) bpn :errorp nil)                     (find­clump 'inputs bpn)))         (prediction (find­clump 'prediction bpn)))    (clamp­data samples (nodes inputs))    (setf (target prediction) (label­target­list samples))))

Page 18: Lispmeetup #39 MGLの紹介: Common Lispによるディープラーニング

学習部分

● 最適化の本体はminimize

● 最適化アルゴリズムを表すoptimizerと学習対象を表すlearnerを渡

(defun train­fnn (fnn training &key                                 (n­epochs 3000)                                 (learning­rate 0.1) (momentum 0.9))  (let ((optimizer (make­instance 'segmented­gd­optimizer                      :segmenter                      (constantly                       (make­instance 'sgd­optimizer                          :learning­rate learning­rate                          :momentum momentum                          :batch­size (max­n­stripes fnn)))))        (learner (make­instance 'bp­learner :bpn fnn))        (dateset (make­sampler training :n­epochs n­epochs)))    (minimize optimizer learner :dataset dateset)    fnn))

Page 19: Lispmeetup #39 MGLの紹介: Common Lispによるディープラーニング

モニタリング関数

● optimizerに学習の途中経過を表示するモニタリング関数を付ける

(defun train­fnn­with­monitor (fnn training test                               &key (n­epochs 3000)                                    (learning­rate 0.1) (momentum 0.9))  (let ((optimizer (monitor­optimization­periodically                    (make­instance 'segmented­gd­optimizer­with­data                       :training training                       :test test                       :segmenter (constantly                                   (make­instance 'sgd­optimizer                                      :learning­rate learning­rate                                      :momentum momentum                                      :batch­size (max­n­stripes fnn))))                    '((:fn log­bpn­test­error :period log­test­period)                      (:fn reset­optimization­monitors                       :period log­training­period                       :last­eval 0))))        (learner (make­instance 'bp­learner :bpn fnn))        (dateset (make­sampler training :n­epochs n­epochs)))    (minimize optimizer learner :dataset dateset)    fnn))

Page 20: Lispmeetup #39 MGLの紹介: Common Lispによるディープラーニング

学習の進行部分

● fnnの重みをランダムに初期化して訓練を実行

● with-cuda*マクロを被せることでGPUを使った計算ができる

– CPUを使う場合は変数 *cuda-enable* を nil に設定する

(defun train­fnn­process­with­monitor (fnn training test                      &key (n­epochs 30) (learning­rate 0.1) (momentum 0.9))  (with­cuda* ()    (repeatably ()      (init­bpn­weights fnn :stddev 0.01)      (train­fnn­with­monitor fnn training test                              :n­epochs n­epochs                              :learning­rate learning­rate                              :momentum momentum)))  fnn)

Page 21: Lispmeetup #39 MGLの紹介: Common Lispによるディープラーニング

実験

● 784-1200-1200-1200-10のネットワーク

● 隠れ層の活性化関数はReLU

(time (train­fnn­process­with­monitor       my­fnn       *training­data*       *test­data*       :n­epochs 30))

Evaluation took:  1638.934 seconds of real time  1638.103618 seconds of total run time (1364.208722 user, 273.894896 system)  [ Run times consist of 0.873 seconds GC time, and 1637.231 seconds non­GC time. ]  99.95% CPU  5,559,500,797,670 processor cycles  1 page fault  6,657,802,576 bytes consed

Page 22: Lispmeetup #39 MGLの紹介: Common Lispによるディープラーニング

Dropout

● 一定確率でユニットを無効化して学習する

– 小さなネットワークの集団学習と見なせる → 汎化性能が向上

● 一方で収束は遅くなる

入力層 隠れ層 出力層

Page 23: Lispmeetup #39 MGLの紹介: Common Lispによるディープラーニング

Dropoutを入れたネットワークの定義

● Dropoutのためのlumpが増えている

● 入力層の20%、隠れ層の50%を無効化する

(defparameter fnn­relu­dropout  (build­fnn (:class 'fnn :max­n­stripes 100)    (inputs (­>input :size 784 :dropout 0.2))    (f1­activations (­>activation inputs :name 'f1 :size 1200))    (f1* (­>relu f1­activations))    (f1 (­>dropout f1* :dropout 0.5))    (f2­activations (­>activation f1 :name 'f2 :size 1200))    (f2* (­>relu f2­activations))    (f2 (­>dropout f2* :dropout 0.5))    (f3­activations (­>activation f2 :name 'f3 :size 1200))    (f3* (­>relu f3­activations))    (f3 (­>dropout f3* :dropout 0.5))    (prediction (­>softmax­xe­loss (­>activation f3 :name 'prediction :size 10)                                   :name 'prediction))))

Page 24: Lispmeetup #39 MGLの紹介: Common Lispによるディープラーニング

Dropout+Maxout

● 隠れ層の活性化関数をReLUからMaxoutに

● Maxoutのユニット数(group-size)を指定する

(defparameter fnn­maxout­dropout  (let ((group­size 5))    (build­fnn (:class 'fnn :max­n­stripes 100)      (inputs (­>input :size 784 :dropout 0.2))      (f1­activations (­>activation inputs :name 'f1 :size 1200))      (f1* (­>max f1­activations :group­size group­size))      (f1 (­>dropout f1*))      (f2­activations (­>activation f1 :name 'f2 :size 1200))      (f2* (­>max f2­activations :group­size group­size))      (f2 (­>dropout f2*))      (f3­activations (­>activation f2 :name 'f3 :size 1200))      (f3* (­>max f3­activations :group­size group­size))      (f3 (­>dropout f3*))      (prediction (­>softmax­xe­loss (­>activation f3 :name 'prediction :size 10)                                     :name 'prediction)))))

Page 25: Lispmeetup #39 MGLの紹介: Common Lispによるディープラーニング

テストデータに対する予測性能

● 大差ない (ReLU: 98.51%、 ReLU+Dropout: 98.65%、Maxout+Dropout:98.51%)

Page 26: Lispmeetup #39 MGLの紹介: Common Lispによるディープラーニング

計算時間

● 同じ784-1200-1200-1200-10のネットワーク

● CPUとGPUでReLU、ReLU+Dropout、Maxout+Dropoutを比較

● CPU: Core i5 4670 (4コア)、GPU: GeForce GTX750Ti (640 CUDAコア)

● MGL-MATのデータ型がdouble-floatになっていると遅い

– → MGL-MAT:*default-mat-ctype* を :float に設定

ReLU ReLU+Dropout Maxout+Dropout

CPU 884s 1030s NIL

GPU 243s 248s 130s

Page 27: Lispmeetup #39 MGLの紹介: Common Lispによるディープラーニング

Tensorflowとの比較

● Tensorflow: Googleが出しているフレームワーク (C++/Python)

– Tensorflow 0.8.0

● MNIST、隠れ層2層(256ユニット)、ReLU、Momentum SGD

● CPU(Core i5 4670)による実行時間の比較

– TensorflowはCPU使用率が低く、220%くらいしか出ていない

– MGLのCPU使用率はほぼ400% (4コアCPU)

real total

MGL 36.6s 146.04s

Tensorflow 95.52s 175.55s

Page 28: Lispmeetup #39 MGLの紹介: Common Lispによるディープラーニング

Tensorflowとの比較

● MNIST、隠れ層2層(256ユニット)、ReLU、Momentum SGD

● GPU(GeForce GTX750Ti)による実行時間の比較

● MNIST、隠れ層2層(2560ユニット)、ReLU、Momentum SGD

– 隠れ層の次元を10倍にしてみる

real

MGL 22.609s

Tensorflow 28.209s

real

MGL 206.371s

Tensorflow 216.011s

Page 29: Lispmeetup #39 MGLの紹介: Common Lispによるディープラーニング

まとめ

● Lispで機械学習できない理由はない

– 同じ言語の中で高い記述力と計算速度のトレードオフを調節できる

– モデル記述はPython、学習アルゴリズムはC++で書くといった面倒がない

● ReLU、Maxout、Dropout、RNN、LSTMなど、最近よく使われる手法や

モデルが揃っている

– 畳み込みニューラルネットは実装されていない

● 計算速度も他のライブラリに比べて遜色ない。むしろ速い