Successfully reported this slideshow.
We use your LinkedIn profile and activity data to personalize ads and to show you more relevant ads. You can change your ad preferences anytime.

Chainer, Cupy入門

63,833 views

Published on

Chainer meetup #3ではなした、ChainerとCuPyの入門資料です

Published in: Technology
  • Be the first to comment

Chainer, Cupy入門

  1. 1. Chainer, Cupy⼊⾨ 2016/07/02 Chainer Meetup #03 (株)Preferred Networks 海野 裕也 v1.10向け
  2. 2. 今⽇のおはなし l  Deep Learningのおさらい l  Chainer の使い⽅の紹介 l  CuPyの使い⽅の紹介 2
  3. 3. ニューラルネットの基礎
  4. 4. ニューラルネット l  値が伝播していく有向グラフ l  エッジで重みをかけて、ノードに⼊るところで⾜し 込み、ノードの中で⾮線形変換する l  全体としては巨⼤で複雑な関数を表す 4
  5. 5. ニューラルネット=合成関数 l  ベクトルに対して線形・⾮線形な関数をたくさん適 ⽤する合成関数と捉えるとよい l  各ノードはベクトルを保持する変数 5
  6. 6. ⼀般のニューラルネットは DAG = 計算グラフ ⼀般にはグラフが分岐したり合流したりする l  分岐:同じ変数を複数の場所でつかう l  合流:⼆つ以上の変数を受け取る関数を適⽤する 6
  7. 7. 計算グラフの例 z = x ** 2 + 2 * x * y + y 7 x y _ ** 2 2 * _ _ * _ _ + _ z _ + _
  8. 8. 誤差逆伝播は、計算グラフを逆向きにたどる 計算グラフと順伝播時の各変数の値があれば計算可能 8
  9. 9. 機械学習(教師あり学習)のおさらい ⽬的 l  ⼊⼒Xに対して出⼒Yを予測する関数fを求めたい l  例:Xがメール、Yはスパムか否か ⽅法 l  正解のわかっているデータx1, y1 … xn, ynに対し て、f(xi)とyiがなるべく⼀致するfを求める l  |f(x1) – y1| + … + |f(xn) – yn| を最⼩にしたい 9 ⽬的関数
  10. 10. 機械学習のおさらい 多くの機械学習⼿法は、 1.  ⽬的関数の設計 2.  勾配の計算 3.  最⼩化のための反復計算 からなる 10 先ほどの計算は ここに使う
  11. 11. ニューラルネットの学習⽅法 1.  ⽬的関数の設計 l  計算グラフを⾃分で設計する 2.  勾配の計算 l  誤差逆伝播で機械的に計算できる 3.  最⼩化のための反復計算 l  勾配を使って反復更新する 11 1さえ設計すれば残りは ほぼ⾃動化されている
  12. 12. Chainer の使い⽅
  13. 13. Chainer はニューラルネットのフレームワーク l  機能 l  ニューラルネットを記述する l  ニューラルネットの順伝播・逆伝播を実⾏する l  勾配法を実⾏してパラメータを最適化する l  Chainer の特徴 l  順伝播は単純に Python のスクリプトとして書ける l  そのスクリプトの実⾏結果は計算⼿順を記憶してい て、逆伝播を⼿で書く必要はない 13
  14. 14. Chainer のインストール l  環境は Linux(特に Ubuntu)がおすすめ l  インストール⽅法 l  新しめの Python 環境を⽤意(CPython 2.7+, 3.4+, 3.5+) l  pip も⽤意 l  コマンドを実⾏: pip install chainer l  chainer パッケージが import できれば完了です l  Python スタックの環境構築は、Anaconda がお すすめ l  Python のバージョン管理は pyenv がおすすめ l  pyenv からコマンド⼀つで Anaconda もインストールできます 14
  15. 15. 順伝播 l  今まで「変数」と呼んでいたものは、Chainer では Variable オブジェクト l  Variable を Function に⼊れると、順伝搬後の Variable が返ってくる l  Variable が計算グラフを保持している l  Function は、四則演算以外に chainer.functions に⽤意されている 15
  16. 16. 順伝搬とコード例 16 x y _**2 2*_ _*_ _+_ z _+_ x = Varaible(...) y = Variable(...) z = x ** 2 + 2 * x * y + y
  17. 17. Variable オブジェクト l  計算グラフの(データ)ノード l  NumPy または CuPy(後述)の配列を保持する l  初期化時に配列を渡す l  data 属性に保存される l  多くの Function は配列の最初の軸をミニバッチとして 使うので注意 l  下の x は、20 次元ベクトルが 10 個⼊ったミニバッチとみなす l  現状、Chainer は多くの場所で float32 配列を要求する ので注意 17 x = Variable(np.zeros((10, 20), dtype=np.float32)) x.data
  18. 18. Function オブジェクト l  計算グラフの「演算」ノード l  chainer.functions (以降 F) にいろいろ定義され ている l  F.relu, F.max_pooling_2d, F.lstm, ... l  Functionの呼び出し結果が、再びVariableになる l  v1.5からパラメータはLinkとして分離された 18 x = Variable(...) y = F.relu(x) # yもVariable
  19. 19. Link オブジェクト l  パラメータ付きの関数 l  最適化の対象となる l  save/loadができる(v1.5からsave/loadをサポート) l  chainer.links(以降L)に⾊々⽤意されている l  L.Linear, L.Convolution2D, L.EmbedID, ... l  Linkの呼び出し結果が、再びVariableになる l  v1.5からFunctionとパラメータは分離され、パラメータ 付きの関数はLinkオブジェクトになった 19 v1.5~
  20. 20. ChainでLinkをまとめる l  ⼀般的にパラメータ付きの関数(Link)は複数あるので、 Chainでまとめて管理できる l  Chainを継承すると再利⽤しやすくなる model = Chain(embed=L.EmbedID(10000, 100), layer1=L.Linear(100, 100), layer2=L.Linear(100, 10000)) x = Variable(...) h = F.relu(model.layer1(model.embed(x))) y = model.layer2(h) 20 v1.5~
  21. 21. ロス関数、勾配計算 l  ロス関数もFunctionの⼀種 l  ロス関数の出⼒に、Variable.backward() を呼ぶと 勾配が計算できる loss = F.softmax_cross_entropy(y, t) loss.backward() 21
  22. 22. Optimizer の設定 l  勾配が計算できたら、あとは勾配法をまわす l  勾配法のアルゴリズムは Optimizer クラスの⼦クラス l  chainer.optimizers に定義されている l  実装されている最適化⼿法:SGD, MomentumSGD, AdaGrad, RMSprop, RMSpropGraves, AdaDelta, Adam l  最適化対象をsetup メソッドに渡す l  正則化はhook関数として登録する optimizer = optimizers.SGD() optimizer.setup(model) optimizer.add_hook(optimizer.WeightDecay()) 22
  23. 23. Optimizer による最適化 l  まず勾配をゼロ初期化:zerograds() l  順伝播・逆伝播を実⾏ l  最適化ルーチンを実⾏:update() l  以上を何回も繰り返す model.zerograds() loss = ... loss.backward() optimizer.update() 23
  24. 24. Chainer を使う場合の全体の流れ 1.  Linkを使ってChainを定義する 2.  Optimizer に、Chain を設定する 3.  forward 関数を定義する 4.  データセットを読み込み、訓練⽤と評価⽤にわける 5.  訓練ループを回す a.  勾配をゼロ初期化 b.  順伝搬して、得られたロス値の backward メソッドを呼ぶ c.  Optimizerを、update 6.  適当な頻度で評価ループを回す a.  テストデータで順伝搬関数を呼んで結果を記録 24 次のバージョンで訓練ループは抽象化されます
  25. 25. CUDAによる⾏列ライブラリCuPy 25
  26. 26. CuPyとは何か? NumPy互換インターフェースの CUDA実装の⾏列ライブラリ 26 Pythonの⾏列ライブラリ NVIDIA GPUの開発環境とライブラリ
  27. 27. 既存のライブラリと 同じインターフェースで GPUの⾼速性を⼿に⼊れられる 27
  28. 28. CuPyとNumPyの⽐較 import numpy x = numpy.array([1,2,3], numpy.float32) y = x * x s = numpy.sum(y) print(s) import cupy x = cupy.array([1,2,3], cupy.float32) y = x * x s = cupy.sum(y) print(s) 28
  29. 29. CuPyはどのくらい早いの? l  状況しだいですが、最⼤数⼗倍程度速くなります def test(xp): a = xp.arange(1000000).reshape(1000, -1) return a.T * 2 test(numpy) t1 = datetime.datetime.now() for i in range(1000): test(numpy) t2 = datetime.datetime.now() print(t2 -t1) test(cupy) t1 = datetime.datetime.now() for i in range(1000): test(cupy) t2 = datetime.datetime.now() print(t2 -t1) 29 時間 [ms] 倍率 NumPy 2929 1.0 CuPy 585 5.0 CuPy + Memory Pool 123 23.8 Intel Core i7-4790 @3.60GHz, 32GB, GeForce GTX 970
  30. 30. なぜCuPyが求められるのか? l  GPUを使った応⽤研究では、必 要な知識が以前より増えた l  GPU⾃体が複雑 l  GPUを効率的に扱うアルゴリズム も複雑 l  使わないと効率で勝てない l  GPUを効率的に⼿軽に使える仕 組みが必要になっている 30 GPU CUDA ⾏列ライブラリ 深層学習エンジン 応⽤研究
  31. 31. 裏の仕組み l  CUDA⽤ソースを⾃動⽣成してコンパイラが⾛る l  ⽣成されたバイナリをGPUに⾃動的に転送・実⾏する l  ビルド結果はキャッシュされるので2回⽬移⾏⾼速 31 スタブ スタブ 実処理 nvcc コンパイラ .cubin GPU 実行 キャッシュ する
  32. 32. ⾃分でコードを書きたい時 例:z[i] = x[i] + 2 * y[i] を書きたい 32 引数の型: “float32 x, float32 y” 戻り値の型: “float32 z” 処理: “z = x + 2 * y;” ループやインデックスの処理は ⾃動で埋めてくれる これだけ書け ば良い
  33. 33. チューニングの⽅法 l  CUDAのツールがそのまま使える l  NVIDIA Visual Profiler (nvvp)やnvprofコマンド l  CPU⽤のプロファイラではGPUのボトルネックがわ からないので注意 l  詳細はCUDAのサイトへ 33
  34. 34. 深層学習以外にも利⽤できる l  既存のNumPyコードがほぼそのまま動く l  既存の解析⼿法がそのままCUDA上で動く l  NumPyのベクトルデータとの変換は1⾏ 34
  35. 35. まとめ l  ニューラルネットを(おもに実装⾯から)簡単におさら いしました l  Chainerは直感的なインターフェスで深層学習できるラ イブラリ l  CuPyはNumPyインターフェースでCUDAを使えるライ ブラリ 35

×