【Chainer基礎1】Variableってなに?分かりやすく5分で解説

【Chainer基礎1】Variableってなに?分かりやすく5分で解説

最近、幼いころによく「バ~リア」という掛け声とともに腕をクロスすると、世の中に蔓延する全ての災厄から身を守ることが出来ていたことを思い出し、30歳を経て久々に「バ~リア」と叫んでみたものの、社会という苦難から一向に解放されないどころか、お隣さんからの壁ドンを頂戴したことから察するに、あのころ僕を守っていてくれたのは「バリア」ではなく父と母だったことを痛感しましたアイーンです。

 

バリアといえば、ChainerにもVariableという便利なオブジェクトが用意されています。

今回は、Chainerの基礎ということで、深層学習に超便利なVariableについて解説したいと思います。

 

Variableってなに?

VariableはChainerの構成要素であり、ディープラーニング内でいう各ノードを作成するためのオブジェクトです。

 

 

Variableオブジェクトは値の保持だけを行うものではありません。

実は、既に行った計算の履歴(どういった流れで計算されたのか)も持っています。

例えば、どの変数と変数をどんな演算したかという情報等です。

このような計算履歴を「計算グラフ」というそうです。

何がスゴいのかって?

それは後半でお伝えしますので、頭のすみっこに置いといてください。

 

それでは早速Variableオブジェクトを作ってみましょ~

 

Variableオブジェクトの作り方

まずは下準備

まずは、importを使ってnumpyとchainerを使えるようにしましょう。

加えて、chainerの要素Variableも呼び出しておきます。

import chainer

import numpy as np

from chainer import Variable

 

importが終わったら、numpyでリストを作ります。

a = np.array( [ [ 1 , 2 , 3 ] , [ 4 , 5 , 6 ] ] , dtype = np.float32)

 

これまでとの違いは、後ろのdtype = np.float32ですね。

実はchainerは、今のところ使用するデータ型をfloat32型で固定しないといけません。

float32型とは、32bitまでの少数を含む数(0.6532とか32.1156など)の事です。

float64型もあるけれど、使いません。

このコードで、float32型に固定してやります。

 

ちなみにimport chainerの行に出ている警告メッセージは、

 

issubdtypeの2番目の引数を `float`から` np.floating`に変換することは推奨されていません。
将来、 `np.float64 == np.dtype(float).type`として扱われます。

 

と、型に関する警告が出ていますが、あくまで将来的に変わるよ~と言ってるだけで

今は悪さしませんので、道端の石ころのごとく無視してやります。

 

さぁ、下準備が終わりました。

[1. 2. 3.]

[4. 5. 6.]

 

という小数点を含むnumpyリストinput_arrayが作成されました。

それでは、コイツをVariableオブジェクトに変換してやりましょう。

 

x = Variable(input_array)

これだけ。

3分クッキングより手早い。

 

Variableの内部データを確認するときは、変数の後に.dataを付けます。

x.dataを確認すると

[1. 2. 3.]

[4. 5. 6.]

・・・なんも変わってへんやん。

いえいえ、表示されてないだけで、このxには他のデータも入っています。

だから、参照するデータを.dataと指定する必要があるんですね。

 

ためしにxを使って計算してみます。

yという変数に x × 2 + 1 を入れてみると

[3.  5.  7.]

[9. 11. 13.]

とでました。

numpyと同様、xの各要素に計算が行われます。

 

また、Variableオブジェクトであるxを使った計算をすると、なんと

y自体もVariableオブジェクトになっています。便利。

 

それでは、xの中にある他のデータを見るため

こんな処理をしましょう。

y.grad = np.ones( ( 2 , 3 ) , dtype = np.float32)

これは初期設定です。

 

ここでは、yのxに対する変化量(xが増えた時、yがいくら増減したか等)つまり、微分値を見ます。

微分値は、グラフの一部に対する接線の傾きをいいます。

 

このグラフが

y  =  x × 2 + 1 の形です。

yが+1の場所から始まり

xが1増えるとyが2増えています。

つまり傾きは2です。

 

詳細は、別の機会に分かりやすく解説します。

いまは、「微分パねぇ」と覚えましょう。

 

 

あと、yのデータが複数個ある場合、y.gradに初期値が必要です。

今回は、y6個のデータがあるので初期値に1を入れときましょう。

y.grad

[1. 1. 1.]

[1. 1. 1.]

これで初期値を設定できました。

初期値は何でもいいです。

 

y.backward()

と入力すると、微分値が前のノードであるxに入力されます。

コレは、yからxへ「変化をさかのぼって」微分値をみるための処理です。

 

 

print( x.grad )を使って、xの持つ微分値を見てみると

[2. 2. 2.]

[2. 2. 2.]

と出ました。

傾きは2、正解です。

 

 

xに入ってるデータが複数個あって、個別に見ることが出来るのがお分かりいただけたでしょうか。

 

これで貴方の肩書は「バリアブラー」です。

小学生に、「バリアブラーの○○です」と名乗りましょう。

うんこを踏んだヤツから逃げられます。

 

この流れで、Chainer基礎編をやっていきたいと思います。

 

それでは。