狠狠撸

狠狠撸Share a Scribd company logo
Chainerチュートリアル
- v1.5向け -
2015/12/04 ViEW 2015@パシフィコ横浜
(株)Preferred Networks
奥田 遼介
Chainer(http://chainer.org/)
3
? Chainer の使い方を紹介します
? Deep Learning の簡単な説明から実装へ
? CUDA サポートについても簡単に解説します
? 学術的な詳細は既存の文献を参考にしてください
? CUDA の詳細は NVIDIA のドキュメントを参照してください
ニューラルネットの基础と実装準备
ニューラルネット
? 値が伝播していく有向グラフ
? エッジで重みをかけて、ノードに入るところで足し
込み、ノードの中で非線形変換する
? 全体としては巨大で複雑な関数を表す
5
ニューラルネット=合成関数
? ベクトルに対して線形?非線形な関数をたくさん適
用する合成関数と捉えるとよい
? 各ノードはベクトルを保持する変数
6
一般のニューラルネットは DAG = 計算グラフ
一般にはグラフが分岐したり合流したりする
? 分岐:同じ変数を複数の場所でつかう
? 合流:二つ以上の変数を受け取る関数を適用する
7
計算グラフの例
z = x ** 2 + 2 * x * y + y
8
x
y
_ ** 2
2 * _ _ * _ _ + _ z
_ + _
z x x y y
機械学習のおさらい
多くの機械学習手法は、
1. 目的関数の設計
2. 勾配の計算
3. 最小化のための反復計算
からなる
9
先ほどの計算は
ここに使う
機械学習の例:分類学習の目的関数
10
argminw ∑(x, y) l(x, y; w)
? xは入力ベクトル、yは予測ラベル
? l(x, y)は予測が正しければ小さく、間違えれば大
きくなる値(損失関数)
? 上記関数を最小化するパラメータwを求めたい
機械学習の例:分類学習のアルゴリズム
? 目的関数をパラメータwで微分した値(勾配)を
計算する方法を用意する
? wを勾配の方向に少しだけ動かす、を繰り返す
? 実際は更新方向の取り方に工夫が他数ある
11
initialize w
until converge:
w := w - η d/dw L(x, y; w)
最急降下法
誤差逆伝播(後退型自動微分)
合成関数の微分を計算するには連鎖律 (chain rule)
をつかう
12
各関数の微分がわかれば機械的に計算できる
誤差逆伝播は、計算グラフを逆向きにたどる
計算グラフと順伝播時の各変数の値があれば計算可能
13
ニューラルネットの学習方法
1. 目的関数の設計
? 計算グラフを自分で設計する
2. 勾配の計算
? 誤差逆伝播で機械的に計算できる
3. 最小化のための反復計算
? 勾配を使って反復更新する
14
1は設計が必要
2、3は自動化されている
Recurrent Net
? ループがあるニューラルネット
? 時刻の概念があり、t=T の状態は t=T-1 の状態と t=T の入力
を使って求める
15
T
T-1
T
Recurrent Net は時間展開して考える
? 時間展開すれば、DAG の計算グラフになる
? DAG の計算グラフは誤差逆伝播できる(Backprop Through
Time) 16
t=1
t=2
t=3
t=4
Chainer の使い方
Chainer はニューラルネットのフレームワーク
? 機能
? ニューラルネットを順伝播を記述する
? ニューラルネットの順伝播?逆伝播を実行する
? 勾配法を実行してパラメータを最適化する
? Chainer の特徴
? 順伝播は単純に Python のスクリプトとして書ける
? そのスクリプトで実行した計算手順を記録されて、
逆伝播を内部で自動生成する
18
ニューラルネットワークフレームワークの構成要素
構成要素 Chainerの場合
変数 chainer.Variable
関数
(損失関数/活性化関数)
chainer.Functionを継承
パラメーター付き関数 chainer.Linkを継承
パラメーター付き関数集合 chainer.Chainを継承
最適化 chainer.Optimizer
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
順伝播
? 今まで「変数」と呼んでいたものは、Chainer で
は Variable オブジェクト
? Variable を Function に入れると、順伝播後の
Variable が返ってくる
? Variable が計算グラフを保持している
? Function は、四則演算以外に
chainer.functions に用意されている
21
順伝播とコード例
22
x = Varaible(...)
y = Variable(...)
z = x ** 2 + 2 * x * y + y
x
y
_ ** 2
2 * _ _ * _ _ + _ z
_ + _
Variable オブジェクト
? 計算グラフの(データ)ノード
? NumPy または CuPy(後述)の配列を保持する
? 初期化時に配列を渡す
? data 属性に保存される
? 多くの Function は配列の最初の軸をミニバッチとして使
うので注意
? 下の x は、20 次元ベクトルが 10 個入ったミニバッチとみなす
? 現状、Chainer は多くの場所で float32 配列を要求するの
で注意
23
x = Variable(np.zeros((10, 20),
dtype=np.float32))
x.data
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
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~
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~
ロス関数、勾配計算
? ロス関数もFunctionの一種
? ロス関数の出力に、Variable.backward() を呼ぶと
勾配が計算できる
loss = F.softmax_cross_entropy(y, t)
loss.backward()
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
Optimizer による最適化
? まず勾配をゼロ初期化:zerograds()
? 順伝播?逆伝播を実行
? 最適化ルーチンを実行:update()
? 以上を何回も繰り返す
model.zerograds()
loss = ...
loss.backward()
optimizer.update()
29
Chainer を使う場合の全体の流れ
1. Linkを使ってChainを定義する
2. Optimizer に、Chain を設定する
3. forward 関数を定義する
4. データセットを読み込み、訓練用と評価用にわける
5. 訓練ループを回す
a. 勾配をゼロ初期化
b. 順伝播して、得られたロス値の backward メソッドを呼ぶ
c. Optimizerを、update
6. 適当な頻度で評価ループを回す
a. テストデータで順伝播関数を呼んで結果を記録
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)
新しい Function を自分で定義する
? Function は Python で新しく作ることができる
? forward(_cpu/_gpu) と backward(_cpu/_gpu) を実装する必
要がある
? 配列のタプルを受け取って、配列のタプルを返す
? Linkは内部でFunctionを呼んで作る
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で返す
新しい Function を自分で定義する
? Function を書いたらテストしましょう
? とくに勾配チェック (gradient check) は必須
? 有限差分法で forward のみから計算した勾配が、backward で計
算した勾配と一致するかを確かめる
? chainer.gradient_check.numerical_grad を使うと簡単
に書ける
? 公式リポジトリの
tests/chainer_tests/function_tests にたくさん例
が書いてあります
34
CUDA サポート
? CuPy: 新しい CUDA 配列実装
? NumPy と同じようなインターフェイスで使える
? 関数?メソッドのサブセットを実装
? 配列のスライス、転置、reshape 等も自由にできます
? カスタムカーネルも記述できる(elementwise, reduction)
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
cuDNNの使い方
? cuDNN
? NNの計算を省メモリで高速におこなってくれるライブラリ
? 特にConvolutionに効果がある
? cuDNNは画像系では超重要(メモリ使用量が数分の1に減る場合も)
? NVIDIAのページでユーザー登録してダウンロード
? ダウンロードできるようになるまで数日かかります
? インストーラーはありません
? 展開して手動でCUDAのフォルダにコピー(おすすめ)
? lib64とinclude に対応するファイルを放り込む
? もしくはパスを通す
? CPATH、 LIBRARY_PATH、LD_LIBRARY_PATHの設定が必要
? CuDNNを導入したらChainerを再インストール
? import cupy.cudnn で動作を確認
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))
公式の 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
Chainer を使う利点
? Pythonで書ける
? NumPyが書ければCuPyを使ってGPU化できる
? 自作のレイヤーも前処理もPythonで書ける
? CuPyを使うことでPythonのまま簡単にGPU化
? ループや複雑な分岐があるNNも直感的に書ける
? Pythonの制御構文でNNのforward処理が書ける
? Define by Run
? デバッグが楽
? Pythonのスタックトレースを活用してのデバッグが可能
? ファンクションの中身もほとんどPythonコード
? NNのバグの原因がどの行で起きているかが分かる
40
Chainer 1.5が正しくインストールできないときは?
? v1.5 からHDF5とCythonに依存
? 周辺パッケージとの兼ね合いでインストールにちょっとしたテ
クニックが必要
? ログを活用する
? pip install chainer –vvvv
? 何が問題かが分かります
? Cythonをあらかじめインストール
? pip install -U cython
? メモリを食いつぶすエラーを防げます
? sudo に注意する
? 環境変数が引き継がれません
? 「Chainer 1.5 インストール」で検索
? 対処法が出てきます 41
まとめ
? ニューラルネットを実装面から簡単におさらいしました
? Chainer の構成と使い方をざっくりお伝えしました
? 本チュートリアルを参考にChainer を使っていただけれ
ば幸いです
? Chainer 自体へのフィードバックもお待ちしております
42
? ご清聴ありがとうございました
43
We are Hiring!
https://www.preferred-networks.jp/job_ja

More Related Content

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