説明は、Chainer V4.2 を使用しています。
初歩的な使い方を説明しています。
chainerは、バージョンによってコーディングが、若干違いますので注意
深層学習は、入力層(Input)、隠れ層(Hidden)、出力層(Output)で構成されています。
層から層へ値を渡す処理の、重みとバイアスを調整して、結果を得ます。
とりあえずchainerのバージョン確認
import chainer def main(): print (chainer.__version__) if __name__ == '__main__': main()
モデルの作成と使い方
以下は、入力層、出力層で説明します。隠れ層はありません。
線形モデルを生成して、出力値を取得するだけのプログラムです。
import numpy as np import chainer import chainer.links as L import chainer.functions as F def main(): #モデルを作成 model = L.Linear(3,3) # 重みを表示 print ( model.W ) # バイアスを表示 print ( model.b ) #入力データを作成 入力データ実数(floatの32ビット)にて作成する x = np.array([[1,2,3]] , dtype=np.float32) #モデルにデータを入力して、加工データを取得する(順方向に計算して誤差を算出) y = model(x) #モデルの取得データを表示 print(y.data)
・モデルの生成は、リニア(線形)で、入力、出力ともに3層で作成
・重み、バイアスを表示していますが、モデル生成時に自動で生成されます。初期値を設定することもできます。
・入力値に、1、2、3を作成しています。入力値は、32ビットの実数で作成します。
また上記はNumPyの配列ですが、GPUを使う場合は、cuda配列、実際にchainerで使用される、Variableで渡すことができます。
・モデルの戻り値は、Variableなので、結果はy.dataになります。
今回結果は、以下が表示されました。(結果はW,bが自動設定なので異なります)
variable W([[-0.9276639 1.5477576 1.0143428 ] [-0.8048758 -0.75833696 -0.07835717] [-0.21749797 -0.07819887 0.08992271]]) variable b([0. 0. 0.]) [[ 5.21088 -2.556621 -0.10412759]]
上記のプログラムでは、何の役にも立ちませんので、以下学習させて、重み、バイアスを調整して結果が出せるようにします。
モデルの学習
以下は、入力に1,2,3を入れて、出力に2,3,4を出力するように学習します。
import numpy as np import chainer import chainer.links as L import chainer.functions as F from chainer import optimizers def main(): model = L.Linear(3,3) #最適化アルゴリズム(勾配法)の設定 optimizer = optimizers.SGD() #最適化(Optimization)にモデルを登録する optimizer.setup(model) print ( model.W ) print ( model.b ) #入力データを作成 x = np.array([[1,2,3]] , dtype=np.float32) #正解のデータを作成 (回帰で処理するので実数(floatの32ビット)にて作成) t = np.array([[2,3,4]] , dtype=np.float32) #100回学習させます for i in range(0,100): #勾配を初期化 optimizer.target.cleargrads() y = model(x) #モデルの取得データを表示 print(y.data) # 入力値と出力値がどれくらい違うか算出する loss = F.mean_squared_error(y, t) #違いの値を与えて学習させる(誤差関数から逆伝播) loss.backward() # 重み、バイアスを更新する optimizer.update() print ( model.W ) print ( model.b )
・ オプティマイザの、深層学習で用いられる勾配法は様々あり(SGD, Momentum SGD, AdaGrad, RMSprop, AdaDelta, Adam)などがあります。今回はSGDを使用しています。
・回帰処理(mean_squared_error)をしているので、教師データは32ビット実数にします。(分類処理の場合[softmax_cross_entropy]、intの整数になります)
実行結果
variable W([[ 0.5133376 -0.38993472 0.44601002] [ 0.84694535 -0.5978481 -0.01354601] [-1.0464118 0.9306227 -0.21142463]]) variable b([0. 0. 0.]) [[ 1.0714983 -0.38938892 0.18055975]] [[ 1.1643485 -0.05045006 0.5625038 ]] [[1.2479136 0.25459498 0.9062534 ]] [[1.3231223 0.52913547 1.215628 ]] [[1.3908099 0.7762219 1.4940654]] [[1.4517289 0.99859965 1.7446588 ]] [[1.506556 1.1987396 1.9701929]] [[1.5559002 1.3788657 2.1731737]] | [[1.9999624 2.9998631 3.9998453]] [[1.9999661 2.9998767 3.9998608]] [[1.9999696 2.9998891 3.9998748]] [[1.9999726 2.9998999 3.9998872]] variable W([[ 0.5752361 -0.2661377 0.63170534] [ 1.0728986 -0.14594167 0.66431385] [-0.79178905 1.439868 0.5524431 ]]) variable b([0.06189848 0.22595328 0.25462252])
学習されるにつれ、モデルの出力値が2,3,4に近づいていきます。
学習前の重み、バイアスと学習後の重み、バイアスが変化しているのがわかります。
※重み、バイアスを調整して答えを引き出すので、答えの出る重み、バイアスがわかるなら学習させる必要はありません。