説明は、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に近づいていきます。
学習前の重み、バイアスと学習後の重み、バイアスが変化しているのがわかります。
※重み、バイアスを調整して答えを引き出すので、答えの出る重み、バイアスがわかるなら学習させる必要はありません。