More Related Content
Similar to Chainerチュートリアル -v1.5向け- ViEW2015 (20)
Chainerチュートリアル -v1.5向け- ViEW2015
- 6. 一般のニューラルネットは DAG = 計算グラフ
一般にはグラフが分岐したり合流したりする
分岐:同じ変数を複数の場所でつかう
合流:二つ以上の変数を受け取る関数を適用する
7
- 7. 計算グラフの例
z = x ** 2 + 2 * x * y + y
8
x
y
_ ** 2
2 * _ _ * _ _ + _ z
_ + _
z x x y y
- 17. Chainer はニューラルネットのフレームワーク
機能
ニューラルネットを順伝播を記述する
ニューラルネットの順伝播・逆伝播を実行する
勾配法を実行してパラメータを最適化する
Chainer の特徴
順伝播は単純に Python のスクリプトとして書ける
そのスクリプトで実行した計算手順を記録されて、
逆伝播を内部で自動生成する
18
- 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. 順伝播
今まで「変数」と呼んでいたものは、Chainer で
は Variable オブジェクト
Variable を Function に入れると、順伝播後の
Variable が返ってくる
Variable が計算グラフを保持している
Function は、四則演算以外に
chainer.functions に用意されている
21
- 22. Variable オブジェクト
計算グラフの(データ)ノード
NumPy または CuPy(後述)の配列を保持する
初期化時に配列を渡す
data 属性に保存される
多くの Function は配列の最初の軸をミニバッチとして使
うので注意
下の x は、20 次元ベクトルが 10 個入ったミニバッチとみなす
現状、Chainer は多くの場所で float32 配列を要求するの
で注意
23
x = Variable(np.zeros((10, 20),
dtype=np.float32))
x.data
- 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. 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~
- 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
- 29. Chainer を使う場合の全体の流れ
1. Linkを使ってChainを定義する
2. Optimizer に、Chain を設定する
3. forward 関数を定義する
4. データセットを読み込み、訓練用と評価用にわける
5. 訓練ループを回す
a. 勾配をゼロ初期化
b. 順伝播して、得られたロス値の backward メソッドを呼ぶ
c. Optimizerを、update
6. 適当な頻度で評価ループを回す
a. テストデータで順伝播関数を呼んで結果を記録
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. 新しい Function を自分で定義する
Function は Python で新しく作ることができる
forward(_cpu/_gpu) と backward(_cpu/_gpu) を実装する必
要がある
配列のタプルを受け取って、配列のタプルを返す
Linkは内部でFunctionを呼んで作る
32
- 33. 新しい Function を自分で定義する
Function を書いたらテストしましょう
とくに勾配チェック (gradient check) は必須
有限差分法で forward のみから計算した勾配が、backward で計
算した勾配と一致するかを確かめる
chainer.gradient_check.numerical_grad を使うと簡単
に書ける
公式リポジトリの
tests/chainer_tests/function_tests にたくさん例
が書いてあります
34
- 34. CUDA サポート
CuPy: 新しい CUDA 配列実装
NumPy と同じようなインターフェイスで使える
関数・メソッドのサブセットを実装
配列のスライス、転置、reshape 等も自由にできます
カスタムカーネルも記述できる(elementwise, reduction)
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. cuDNNの使い方
cuDNN
NNの計算を省メモリで高速におこなってくれるライブラリ
特にConvolutionに効果がある
cuDNNは画像系では超重要(メモリ使用量が数分の1に減る場合も)
NVIDIAのページでユーザー登録してダウンロード
ダウンロードできるようになるまで数日かかります
インストーラーはありません
展開して手動でCUDAのフォルダにコピー(おすすめ)
lib64とinclude に対応するファイルを放り込む
もしくはパスを通す
CPATH、 LIBRARY_PATH、LD_LIBRARY_PATHの設定が必要
CuDNNを導入したらChainerを再インストール
import cupy.cudnn で動作を確認
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. 公式の 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. Chainer を使う利点
Pythonで書ける
NumPyが書ければCuPyを使ってGPU化できる
自作のレイヤーも前処理もPythonで書ける
CuPyを使うことでPythonのまま簡単にGPU化
ループや複雑な分岐があるNNも直感的に書ける
Pythonの制御構文でNNのforward処理が書ける
Define by Run
デバッグが楽
Pythonのスタックトレースを活用してのデバッグが可能
ファンクションの中身もほとんどPythonコード
NNのバグの原因がどの行で起きているかが分かる
40
- 40. Chainer 1.5が正しくインストールできないときは?
v1.5 からHDF5とCythonに依存
周辺パッケージとの兼ね合いでインストールにちょっとしたテ
クニックが必要
ログを活用する
pip install chainer –vvvv
何が問題かが分かります
Cythonをあらかじめインストール
pip install -U cython
メモリを食いつぶすエラーを防げます
sudo に注意する
環境変数が引き継がれません
「Chainer 1.5 インストール」で検索
対処法が出てきます 41