機械学習のお勉強(chainerの概要)
- chainerの特徴
- 計算グラフ
- Config オブジェクト
- Variableクラス
- Functionクラス
- Linkクラス
- Chainクラス
- Optimizerクラス
- Trainerクラス
- Updateクラス
chainerの特徴
ネットワーク構築と学習を同時に行う「Define-by-Run」方式。イメージはインタプリタ。デバッグしやすい。
tensorflowは「Define-and-Run」方式。イメージはコンパイラ。
計算グラフ
class MulAdd(Function): def forward_cpu(self, inputs): x, y, z = inputs w = x * y + z return w, def backward_cpu(self, inputs, grad_outputs): x, y, z = inputs gw, = grad_outputs gx = y * gw gy = x * gw gz = gw return gx, gy, gz
Define your own function — Chainer 3.0.0rc1 documentation
全結合層におけるバックワード計算
class LinearFunction(Function): def forward(self, inputs): x, W, b = inputs return x.dot(W.T) + b, def backward(self, inputs, grad_outputs): x, W, b = inputs gy, = grad_outputs gx = gy.dot(W) gW = gy.T.dot(x) gb = gy.sum(axis=0) return gx, gW, gb def linear(x, W, b): return LinearFunction()(x, W, b)
Config オブジェクト
train/test flagを立てれたり、debug modeの指定などができる
Configuring Chainer — Chainer 3.0.0rc1 documentation
Variableクラス
最高にわかりやすい 👉 Chainerのソースを解析。順伝播と逆伝播の仕組み | コード7区
参考:
chainer-cifar10/Cifar10.py at master · mitmul/chainer-cifar10 · GitHub
ノート/Chainerでネットを可視化する(備忘) 2017-04-27 - 東邦大学理学部情報科学科 山内のサイト
Functionクラス
最高にわかりやすい 👉 Chainerのソースを解析。順伝播と逆伝播の仕組み | コード7区
Standard Function implementations — Chainer 3.0.0rc1 documentation
Linkクラス
イメージ: Function Class + Parameter Class
import chainer import chainer.functions as F from chainer import initializers import numpy as np class LinearLayer(chainer.Link): def __init__(self, n_in, n_out): super(LinearLayer, self).__init__() with self.init_scope(): self.W = chainer.Parameter( initializers.Normal(), (n_out, n_in)) self.b = chainer.Parameter( initializers.Zero(), (n_out,)) def __call__(self, x): return F.linear(x, self.W, self.b)
chainer.Link — Chainer 3.0.0rc1 documentation
Chainクラス
上記のクラスを統合、管理するクラス
これを継承して作成したネットワーク構造のインスタンスをモデルオブジェクトとして使用する
Link機能のように機能させることも可能(ChainクラスはLinkクラスの子クラス)
以下の例ではchainクラスを通常のLinkと同様に用いている
import chainer import chainer.functions as F import chainer.links as L class Fire(chainer.Chain): def __init__(self, in_size, s1, e1, e3): super(Fire, self).__init__( conv1=L.Convolution2D(in_size, s1, 1), conv2=L.Convolution2D(s1, e1, 1), conv3=L.Convolution2D(s1, e3, 3, pad=1), bn4=L.BatchNormalization(e1 + e3) ) def __call__(self, x): h = F.relu(self.conv1(x)) h_1 = self.conv2(h) h_3 = self.conv3(h) h_out = F.concat([h_1, h_3], axis=1) return F.relu(self.bn4(h_out)) class SqueezeNet(chainer.Chain): def __init__(self, ): super(SqueezeNet, self).__init__( conv1=L.Convolution2D(3, 96, 7, stride=2), fire2=Fire(96, 16, 64, 64), fire3=Fire(128, 16, 64, 64), fire4=Fire(128, 16, 128, 128), fire5=Fire(256, 32, 128, 128), fire6=Fire(256, 48, 192, 192), fire7=Fire(384, 48, 192, 192), fire8=Fire(384, 64, 256, 256), fire9=Fire(512, 64, 256, 256), conv10=L.Convolution2D(512, 1000, 1, pad=1, initialW=normal(0, 0.01 (1000, 512, 1, 1))) ) def __call__(self, x, train=False): h = F.relu(self.conv1(x)) h = F.max_pooling_2d(h, 3, stride=2) h = self.fire2(h) h = self.fire3(h) h = self.fire4(h) h = F.max_pooling_2d(h, 3, stride=2) h = self.fire5(h) h = self.fire6(h) h = self.fire7(h) h = self.fire8(h) h = F.max_pooling_2d(h, 3, stride=2) h = self.fire9(h) h = F.dropout(h, ratio=0.5, train=train) h = F.relu(self.conv10(h)) h = F.average_pooling_2d(h, 13) return F.reshape(h, (-1, 1000))
squeezenet-chainer/model.py at master · ejlb/squeezenet-chainer · GitHub
Optimizerクラス
登録
optimizer = optimizers.SGD(lr=0.01)
optimizer.setup(model)
更新
loss = model(x,t) loss.backward() optimizer.update()
正規化するメソッドもある
optimizer.add_hook(chainer.optimizer.WeightDecay())
optimizerオブジェクトを作成したあとにadd_hookメソッドを用いて、最適化計算に追加する
Optimizers — Chainer 3.0.0rc1 documentation
Optimizer — Chainer 3.0.0rc1 documentation
Trainerクラス
これを用いることで途中経過や学習経過の監視が一行でかける
ChainerのTrainerを使ってみた - のんびりしているエンジニアの日記
Chainer の Trainer 解説と NStepLSTM について
Trainer使用しない: chainer/train_cifar_custom_loop.py at master · chainer/chainer · GitHub
Trainer使用する: chainer/train_cifar.py at master · chainer/chainer · GitHub
Reporterによる監視対象のフック
self.loss = F.softmax_cross_entropy(y, t) self.accuracy = F.accuracy(y, t) chainer.report({'loss': self.loss, 'accuracy':self.accuracy},self)
Updateクラス
chainer 1.11.0のMNISTサンプルを例にtrainerを読み解く - Monthly Hacker's Blog