Back to Top

プログラムの覚書

Category: Chainer

chainer Variableの使い方

Variableオブジェクトの使い方について記載します。

使用する場合、Variableをインポートします。from chainer import Variable

Variableオブジェクト作成

from chainer import Variable
from chainer import cuda
import numpy as np

# numpyのデータを作成
x_data = np.array([10], dtype=np.float32)
または
#cudaのデータを作成
x_data = cuda.cupy.array([10], dtype=np.float32)

# Variableオブジェクトの作成
x = Variable(x_data)

Variableは、numpyまたは、cudaのデータをパラメータで引き渡して作成します。

Variableでの計算

x = Variable(np.array([10], dtype=np.float32))

y = x**2 - 2*x + 1                              ①

x = Variable(np.array([10], dtype=np.float32))

# 計算結果
print (y.data)
# 逆伝播表示
print (y.grad)

# 誤差逆伝播法(バックプロパゲーション) 
y.backward()

# 逆伝播表示
print (y.grad, x.grad)

①のように通常の変数のように計算することができます。(ここでは逆伝番は計算されません)

結果は、 .data に格納されます。

.backward() により逆伝播を処理します。

結果は、 .grad に格納されます。

上記の結果

[81.]
None
[1.] [18.]

 

逆伝番での注意

a1 = Variable(np.array(10.0))
a2 = Variable(np.array(11.0))

b1 = a1 + a2
b2 = Variable(np.array(12.0))

c1 = b1 * b2

print ('a1={0} a2={1} b1={2} b2={3} c1={4}'.format(a1.data ,a2.data, b1.data, b2.data, c1.data))
print ('a1={0} a2={1} b1={2} b2={3} c1={4}'.format(a1.grad, a2.grad, b1.grad, b2.grad, c1.grad))

c1.backward()

print ('a1={0} a2={1} b1={2} b2={3} c1={4}'.format(a1.data ,a2.data, b1.data, b2.data, c1.data))
print ('a1={0} a2={1} b1={2} b2={3} c1={4}'.format(a1.grad, a2.grad, b1.grad, b2.grad, c1.grad))

b1とc1の値は、Variableになります。

c1で backward() を行うと以下の結果になります。

a1=10.0 a2=11.0 b1=21.0 b2=12.0 c1=252.0
a1=None a2=None b1=None b2=None c1=None
a1=10.0 a2=11.0 b1=21.0 b2=12.0 c1=252.0
a1=12.0 a2=12.0 b1=None b2=21.0 c1=1.0

b1は計算の対象外になります。
 

Posted in Chainer | Leave a reply

Chainer 基本1

説明は、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に近づいていきます。

学習前の重み、バイアスと学習後の重み、バイアスが変化しているのがわかります。

※重み、バイアスを調整して答えを引き出すので、答えの出る重み、バイアスがわかるなら学習させる必要はありません。

 

Posted in Chainer | Leave a reply