Chainerチュートリアル -v1.5向け- ViEW2015

47,971 views

Published on

Deep Learning の簡単な説明から実装、そしてChainer の使い方を紹介します。CUDA サポートについても簡単に解説します。
最新のインストール方法も含んでいます。

Published in: Software
0 Comments
63 Likes
Statistics
Notes
  • Be the first to comment

No Downloads
Views
Total views
47,971
On SlideShare
0
From Embeds
0
Number of Embeds
29,622
Actions
Shares
0
Downloads
281
Comments
0
Likes
63
Embeds 0
No embeds

No notes for slide

Chainerチュートリアル -v1.5向け- ViEW2015

  1. 1. Chainerチュートリアル - v1.5向け - 2015/12/04 ViEW 2015@パシフィコ横浜 (株)Preferred Networks 奥田 遼介
  2. 2. Chainer(http://chainer.org/) 3  Chainer の使い方を紹介します  Deep Learning の簡単な説明から実装へ  CUDA サポートについても簡単に解説します  学術的な詳細は既存の文献を参考にしてください  CUDA の詳細は NVIDIA のドキュメントを参照してください
  3. 3. ニューラルネットの基礎と実装準備
  4. 4. ニューラルネット  値が伝播していく有向グラフ  エッジで重みをかけて、ノードに入るところで足し 込み、ノードの中で非線形変換する  全体としては巨大で複雑な関数を表す 5
  5. 5. ニューラルネット=合成関数  ベクトルに対して線形・非線形な関数をたくさん適 用する合成関数と捉えるとよい  各ノードはベクトルを保持する変数 6
  6. 6. 一般のニューラルネットは DAG = 計算グラフ 一般にはグラフが分岐したり合流したりする  分岐:同じ変数を複数の場所でつかう  合流:二つ以上の変数を受け取る関数を適用する 7
  7. 7. 計算グラフの例 z = x ** 2 + 2 * x * y + y 8 x y _ ** 2 2 * _ _ * _ _ + _ z _ + _ z x x y y
  8. 8. 機械学習のおさらい 多くの機械学習手法は、 1. 目的関数の設計 2. 勾配の計算 3. 最小化のための反復計算 からなる 9 先ほどの計算は ここに使う
  9. 9. 機械学習の例:分類学習の目的関数 10 argminw ∑(x, y) l(x, y; w)  xは入力ベクトル、yは予測ラベル  l(x, y)は予測が正しければ小さく、間違えれば大 きくなる値(損失関数)  上記関数を最小化するパラメータwを求めたい
  10. 10. 機械学習の例:分類学習のアルゴリズム  目的関数をパラメータwで微分した値(勾配)を 計算する方法を用意する  wを勾配の方向に少しだけ動かす、を繰り返す  実際は更新方向の取り方に工夫が他数ある 11 initialize w until converge: w := w - η d/dw L(x, y; w) 最急降下法
  11. 11. 誤差逆伝播(後退型自動微分) 合成関数の微分を計算するには連鎖律 (chain rule) をつかう 12 各関数の微分がわかれば機械的に計算できる
  12. 12. 誤差逆伝播は、計算グラフを逆向きにたどる 計算グラフと順伝播時の各変数の値があれば計算可能 13
  13. 13. ニューラルネットの学習方法 1. 目的関数の設計  計算グラフを自分で設計する 2. 勾配の計算  誤差逆伝播で機械的に計算できる 3. 最小化のための反復計算  勾配を使って反復更新する 14 1は設計が必要 2、3は自動化されている
  14. 14. Recurrent Net  ループがあるニューラルネット  時刻の概念があり、t=T の状態は t=T-1 の状態と t=T の入力 を使って求める 15 T T-1 T
  15. 15. Recurrent Net は時間展開して考える  時間展開すれば、DAG の計算グラフになる  DAG の計算グラフは誤差逆伝播できる(Backprop Through Time) 16 t=1 t=2 t=3 t=4
  16. 16. Chainer の使い方
  17. 17. Chainer はニューラルネットのフレームワーク  機能  ニューラルネットを順伝播を記述する  ニューラルネットの順伝播・逆伝播を実行する  勾配法を実行してパラメータを最適化する  Chainer の特徴  順伝播は単純に Python のスクリプトとして書ける  そのスクリプトで実行した計算手順を記録されて、 逆伝播を内部で自動生成する 18
  18. 18. ニューラルネットワークフレームワークの構成要素 構成要素 Chainerの場合 変数 chainer.Variable 関数 (損失関数/活性化関数) chainer.Functionを継承 パラメーター付き関数 chainer.Linkを継承 パラメーター付き関数集合 chainer.Chainを継承 最適化 chainer.Optimizer 19  大きく分けて三要素  変数・関数・最適化
  19. 19. Chainer のインストール  環境は Linux(特に Ubuntu)がおすすめ  インストール方法  新しめの Python 環境を用意(CPython 2.7+, 3.4+, 3.5+)  pip も用意  コマンドを実行  pip install -U cython  pip install chainer  chainer パッケージが import できれば完了です  Python 環境は、Anaconda がおすすめ  Python のバージョン管理は pyenv がおすすめ  pyenv からコマンド一つで Anaconda もインストールできます 20
  20. 20. 順伝播  今まで「変数」と呼んでいたものは、Chainer で は Variable オブジェクト  Variable を Function に入れると、順伝播後の Variable が返ってくる  Variable が計算グラフを保持している  Function は、四則演算以外に chainer.functions に用意されている 21
  21. 21. 順伝播とコード例 22 x = Varaible(...) y = Variable(...) z = x ** 2 + 2 * x * y + y x y _ ** 2 2 * _ _ * _ _ + _ z _ + _
  22. 22. Variable オブジェクト  計算グラフの(データ)ノード  NumPy または CuPy(後述)の配列を保持する  初期化時に配列を渡す  data 属性に保存される  多くの Function は配列の最初の軸をミニバッチとして使 うので注意  下の x は、20 次元ベクトルが 10 個入ったミニバッチとみなす  現状、Chainer は多くの場所で float32 配列を要求するの で注意 23 x = Variable(np.zeros((10, 20), dtype=np.float32)) x.data
  23. 23. Function オブジェクト  計算グラフの「演算」ノード  chainer.functions (以降 F) にいろいろ定義され ている  F.relu, F.max_pooling_2d, F.lstm, ...  Functionの呼び出し結果が、再びVariableになる  v1.5からパラメータはLinkとして分離された(後述) 24 x = Variable(...) y = F.relu(x) # yもVariable
  24. 24. Link オブジェクト  パラメータ付きの関数  最適化の対象となる  save/loadができる(v1.5からsave/loadをサポート)  chainer.links(以降L)に色々用意されている  L.Linear, L.Convolution2D, L.EmbedID, ...  Linkの呼び出し結果が、再びVariableになる  v1.5からFunctionとパラメータは分離され、パラメータ 付きの関数はLinkオブジェクトになった 25 v1.5~
  25. 25. ChainでLinkをまとめる  一般的にパラメータ付きの関数(Link)は複数あるので、 Chainでまとめて管理できる  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) 26 v1.5~
  26. 26. ロス関数、勾配計算  ロス関数もFunctionの一種  ロス関数の出力に、Variable.backward() を呼ぶと 勾配が計算できる loss = F.softmax_cross_entropy(y, t) loss.backward() 27
  27. 27. Optimizer の設定  勾配が計算できたら、あとは勾配法をまわす  勾配法のアルゴリズムは Optimizer クラスの子クラス  chainer.optimizers に定義されている  実装されている最適化手法:SGD, MomentumSGD, AdaGrad, RMSprop, RMSpropGraves, AdaDelta, Adam  最適化対象をsetup メソッドに渡す  正則化はhook関数として登録する optimizer = optimizers.SGD() optimizer.setup(model) optimizer.add_hook(optimizer.WeightDecay()) 28
  28. 28. Optimizer による最適化  まず勾配をゼロ初期化:zerograds()  順伝播・逆伝播を実行  最適化ルーチンを実行:update()  以上を何回も繰り返す model.zerograds() loss = ... loss.backward() optimizer.update() 29
  29. 29. Chainer を使う場合の全体の流れ 1. Linkを使ってChainを定義する 2. Optimizer に、Chain を設定する 3. forward 関数を定義する 4. データセットを読み込み、訓練用と評価用にわける 5. 訓練ループを回す a. 勾配をゼロ初期化 b. 順伝播して、得られたロス値の backward メソッドを呼ぶ c. Optimizerを、update 6. 適当な頻度で評価ループを回す a. テストデータで順伝播関数を呼んで結果を記録 30
  30. 30. 例:MNIST # Model definition class MnistMLP(chainer.Chain): def __init__(self, n_in, n_units, n_out): super(MnistMLP, self).__init__( l1=L.Linear(n_in, n_units), l2=L.Linear(n_units, n_units), l3=L.Linear(n_units, n_out)) # Forward computation def __call__(self, x): h1 = F.relu(self.l1(x)) h2 = F.relu(self.l2(h1)) return self.l3(h2) # Setup model = L.Classifier(net.MnistMLP( 784, n_units, 10)) opt = optimizers.SGD() opt.setup(model) # Training loop for epoch in xrange(n_epoch): for i in xrange(0, N, batchsize): x = Variable(...) t = Variable(...) opt.update(model, x, t)
  31. 31. 新しい Function を自分で定義する  Function は Python で新しく作ることができる  forward(_cpu/_gpu) と backward(_cpu/_gpu) を実装する必 要がある  配列のタプルを受け取って、配列のタプルを返す  Linkは内部でFunctionを呼んで作る 32
  32. 32. 自作Functionの例 class SquaredDiff(Function): def forward_cpu(self, inputs): x, y = inputs z = x – y return z * z, def backward_cpu(self, inputs, grad_outputs): x, y = inputs gz = grad_outputs gx = 2 * (x – y) * gz return gx, -gx 33 tupleを返す 勾配をtupleで返す
  33. 33. 新しい Function を自分で定義する  Function を書いたらテストしましょう  とくに勾配チェック (gradient check) は必須  有限差分法で forward のみから計算した勾配が、backward で計 算した勾配と一致するかを確かめる  chainer.gradient_check.numerical_grad を使うと簡単 に書ける  公式リポジトリの tests/chainer_tests/function_tests にたくさん例 が書いてあります 34
  34. 34. CUDA サポート  CuPy: 新しい CUDA 配列実装  NumPy と同じようなインターフェイスで使える  関数・メソッドのサブセットを実装  配列のスライス、転置、reshape 等も自由にできます  カスタムカーネルも記述できる(elementwise, reduction) 35
  35. 35. CuPy を使う準備  まず CUDA が使える GPU を用意する  CUDA 6.5 以上をインストール  Ubuntu なら公式に deb パッケージがお薦め(aptがdriverも管理してくれる)  パスを通す  PATH を通すことが必要  CuPyはnvccのパスからライブラリの場所を見つけます  デフォルトでは /usr/local/cuda にインストールされます  PATH=/usr/local/cuda/bin:$PATH  Chainer をインストールしたらimport cupyで動作を確認 36
  36. 36. cuDNNの使い方  cuDNN  NNの計算を省メモリで高速におこなってくれるライブラリ  特にConvolutionに効果がある  cuDNNは画像系では超重要(メモリ使用量が数分の1に減る場合も)  NVIDIAのページでユーザー登録してダウンロード  ダウンロードできるようになるまで数日かかります  インストーラーはありません  展開して手動でCUDAのフォルダにコピー(おすすめ)  lib64とinclude に対応するファイルを放り込む  もしくはパスを通す  CPATH、 LIBRARY_PATH、LD_LIBRARY_PATHの設定が必要  CuDNNを導入したらChainerを再インストール  import cupy.cudnn で動作を確認 37
  37. 37. CuPy の使い方  numpy の代わりに cupy を使う(だいたい動く)  CPU/GPU の両方で動く関数の書き方  chainer.cuda.get_array_module() を使うと、引数に cupy.ndarray があるかないかで numpy / cupy のどちらかを返してくれ ます  例えば下は NumPy と CuPy の両方で動く logsumexp の実装例(より省 メモリな実装を考えてみてください) 38 def logsumexp(x, axis=None): xp = cuda.get_array_module(x) x_max = x.max(axis=axis) return x_max + xp.log( xp.exp(x – x_max).sum(axis=axis))
  38. 38. 公式の Examples 公式リポジトリの examples にいくつか例があります  画像系  mnist: MNIST を多層パーセプトロンで学習。NN界のHello World  imagenet: ImageNet からの大規模ConvNet学習  modelzoo: Caffe 公式モデルを読み込んで使うサンプル  言語系  ptb: Penn-Tree Bank から LSTM 言語モデルを学習する  無限長の入力に対する Truncated BPTT の例にもなっています  word2vec: word2vec の実装と PTB からの学習  sentiment: Recursive Net を使った極性判定 39
  39. 39. Chainer を使う利点  Pythonで書ける  NumPyが書ければCuPyを使ってGPU化できる  自作のレイヤーも前処理もPythonで書ける  CuPyを使うことでPythonのまま簡単にGPU化  ループや複雑な分岐があるNNも直感的に書ける  Pythonの制御構文でNNのforward処理が書ける  Define by Run  デバッグが楽  Pythonのスタックトレースを活用してのデバッグが可能  ファンクションの中身もほとんどPythonコード  NNのバグの原因がどの行で起きているかが分かる 40
  40. 40. Chainer 1.5が正しくインストールできないときは?  v1.5 からHDF5とCythonに依存  周辺パッケージとの兼ね合いでインストールにちょっとしたテ クニックが必要  ログを活用する  pip install chainer –vvvv  何が問題かが分かります  Cythonをあらかじめインストール  pip install -U cython  メモリを食いつぶすエラーを防げます  sudo に注意する  環境変数が引き継がれません  「Chainer 1.5 インストール」で検索  対処法が出てきます 41
  41. 41. まとめ  ニューラルネットを実装面から簡単におさらいしました  Chainer の構成と使い方をざっくりお伝えしました  本チュートリアルを参考にChainer を使っていただけれ ば幸いです  Chainer 自体へのフィードバックもお待ちしております 42
  42. 42.  ご清聴ありがとうございました 43 We are Hiring! https://www.preferred-networks.jp/job_ja

×