chainerの使い方
DeepLearningフレームワークchainerのニューラルネットワークプログラムの書き方を解説します!
2016/10/27 更新 (chainer version 1.17.0)
基本ライブラリのインポート
import numpy as np import chainer import chainer.functions as F import chainer.links as L from chainer import training from chainer.training import extensions
【重要】データについて
配列は、numpyもしくはcupyの配列となっていること。
X(入力データ)のデータ型はfloat32にしておくこと。
分類の場合:y(正解・教師データ)のデータ型はint32。
回帰の場合:y(正解・教師データ)のデータ型はfloat32。
そしてこのような変数と呼ばれるような物を「Variableオブジェクト」と呼びます。
型の指定方法は2つあります。
x = Variable(np.array([配列], dtype=np.float32))
もしくは、型を変換するastypeを使用して以下のようにします。
x = Variable(np.array([配列]).astype(np.float32))
linksパッケージ
linksパッケージにある関数は、variableを変数として持ちます。
links内の関数には、パラメータがあります。
linksパッケージ内にある、Linearモデルは代表的な関数です。
pythonでは、このように書きます。
h = L.Linear(2,3)
パラメータは、W(初期値ランダム)とb(初期値0)です。
>>> h.W.data array([[-0.05319989, 0.57975596], [-0.98233205, -0.06193497], [-0.45000005, 0.76258951]], dtype=float32) >>> h.b.data array([ 0., 0., 0.], dtype=float32)
functionパッケージ
functionパッケージにある関数は、variableを変数として持ちます。
活性化関数や、損失関数など様々な関数が実装されています。
多層パーセプトロンモデル
Chainクラス
chainerは合成関数内に含まれるパラメータを学習します。
chainクラスはモデルである合成関数を定義するためのクラスです。
※参考URL : http://d.hatena.ne.jp/ura_ra/20111026/1319642014
このようなNNを組んでみます。
class Model(Chain): def __init__(self): super(Model, self).__init__( l1 = L.Linear(2, 3) l2 = L.Linear(3, 1) )
順伝播
__call__関数に、順伝播の計算を定義します。
class Model(Chain): def __init__(self): super(Model, self).__init__( l1 = L.Linear(2, 3) l2 = L.Linear(3, 1) ) def __call__(self, x, y): h1 = F.relu(self.l1(x)) return self.l2(h1)
F.relu()は正規化線形関数(Rectified Linear Unit function)といいます。
relu関数は単純なためsigmoid関数やtanh関数よりも計算が早いです。
[relu関数]
Optimizerの定義
Optimizerというのは、数値最適化アルゴリズムのこと。
パラメーターの勾配の配列をあらかじめsetupメソッドに渡しておく必要があります。
① モデルを生成
② 最適化アルゴリズムの選択
③ アルゴリズムにモデルをセット
model = L.Classifier(Model()) optimizer = chainer.optimizers.Adam() optimizer.setup(model)
chainer.optimizersについて
最適化アルゴリズムは以下のものが実装されている。
- SGD
- MomentumSGD
- AdaGrad
- RMSprop
- RMSpropGraves
- AdaDelta
- Adam
Adamという手法が最近ではよく使用される。
どうやら、計算スピードが早く、比較的良い精度になるらしい(アルゴリズムは理解してない...)
バージョン1.11.0からの新機能
「trainer」の登場で、コードがだいぶ抽象化され、書きやすくなりました!
train_iter = chainer.iterators.SerialIterator(train, 100) test_iter = chainer.iterators.SerialIterator(test, 100,repeat=False, shuffle=False) updater = training.StandardUpdater(train_iter, optimizer, device=-1) trainer = training.Trainer(updater, (100, 'epoch'), out="result")
chainer.iterators.SerialIteratorについて
chainer.iterators.SerialIterator(dataset, batch_size, repeat=True, shuffle=True)
パラメーター解説
- dataset
- イテレーションするデータセット
- batch_size [int]
- バッチサイズ
- repeat [boolean]
- 繰り返しなし(エポック数1、主にテスト用)か繰り返しあり(エポック数1以上、主に訓練用)か
- shuffle [boolean]
- データをシャッフルしない(主に時系列データ用)か、シャッフルするか
training.StandardUpdaterについて
chainer.training.StandardUpdater(iterator, optimizer, converter=<function concat_examples>, device=None, loss_func=None)
パラメーター解説
- iterator
- 学習対象のイテレーターです。複数のイテレーターを辞書型で指定することができます。
- optimizer
- 最適化手法。
- converter
- iteratorに辞書型で複数のイテレーターを入力したときに、結合に使う関数を指定します。
- device
- 0だったらGPU、-1だったらCPUを使用して計算します。
- loss_func
- 誤差関数。通常はoptimizerがセットアップしたリンクを指定するので、サンプルコードのように下準備を済ませておけばNoneで問題ないです。
chainer.training.Trainerについて
chainer.training.Trainer(updater, stop_trigger=None, out='result')
パラメーター解説
- updater
- 使用するupdaterを指定します。(updater)
- stop_trigger
- エポック数やイテレーション数などを(1000, 'iteration')や(1, 'epoch')のように指定します。(tuple)
- out
- 出力先を指定します。(str)
Extension機能
実行中に学習経過を見るための関数が用意されている。
trainer.extend(extensions.Evaluator(test_iter, model, device=-1)) trainer.extend(extensions.LogReport()) trainer.extend(extensions.PrintReport( ['epoch', 'main/loss', 'validation/main/loss', 'main/accuracy', 'validation/main/accuracy'])) trainer.extend(extensions.ProgressBar())
↓ こんな感じに、途中経過が見れる
epoch main/loss validation/main/loss main/accuracy validation/main/accuracy 1 0.333247 0.163566 0.90525 0.951 2 0.13979 0.120721 0.95835 0.9645 3 0.0972047 0.10129 0.970817 0.9682 4 0.0724406 0.0958347 0.9781 0.9712 5 0.05642 0.0935157 0.983267 0.9707 6 0.0443315 0.0999502 0.987183 0.9684 total [##############################....................] 60.00% this epoch [..................................................] 0.00% 3600 iter, 6 epoch / 10 epochs
詳しくは、このリンクに詳しく書いてある。
Trainer extensions — Chainer 1.21.0 documentation
あとで、記事にまとめる予定。
学習済みモデルの保存
学習をしていい結果が出たモデルは保存しておく。
modelを”my.model”という名前で保存する。
serializers.save_npz('my.model', model)
保存されたモデルは以下のように呼び出す。
serializers.load_npz('my.model', model)
Optimizerの状態も保存できる。
serializers.save_npz('my.state', optimizer) serializers.load_npz('my.state', optimizer)
もっと詳しく知りたい人は
この本がおすすめです
chainerを使用するためのチュートリアルとして最適!
本気でやってる人は、
最近出たDeep Learning本も買っておくことをおすすめする。
参考サイト
ttlg.hateblo.jp
qiita.com
qiita.com
www.monthly-hack.com