Python(基本的なこと012: Tensorflow1.15_勾配降下法_簡単な方程式02_パラメータ変更)

■学習に関するパラメータをいじってみる
前回、下の方程式から作成したデータを使ってTensorflow勾配降下法のサンプルコードを動かしてみた。

データやコード内の式などは下のような感じ。コード自体は前回と同じ。
データ:x=1~100, y=1~100の値を上の方程式に入れzの値を求めた後、その10000のセット(x, y, z)よりランダムで1000選んだもの。
推定式:output = w1 * x + w2 * y + b (上の3x+y+7という式が分からないものとして、データからoutputを推定する)
損失関数:実際の数値zから推定で得られる数値outputの差を2乗し、batch 1つ分の和を損失関数とする。実際と値と推定値が近いほど0に近づく。


学習ロジック:勾配降下法(GradientDescentOptimizer(learning_rate))
learning_rate:学習率?
training_epochs:データの学習回数
batch_size:データの小グループ(batch)のサイズ。例えば、これが5なら、200のバッチができる(1000/5 = 200)。

前回、learning_rate = 0.00001、training_epochs = 100、batch_size = 10で、ぱっとみいい感じの推定が得られた。
今回は、これらのパラメータを変えて推定値を見てみる。
まず、learning_rateを変えて損失関数の結果を見てみた。

learning_rate training_epochs batch_size 損失関数の結果
0.000110010無限(inf) (epochs 2回目以降)
0.00001100 10 0.506 (epochs 12回目)
0.000001100 10 1.378 (epochs 100回目)
0.0000001100 10 4395.278 (epochs 100回目)

損失関数の値が小さいほどいい推定と考えるなら、上の表では0.00001の時が最もいい。learning_rate自体は、websiteのドキュメントを見ても「A Tensor or a floating point value. The learning rate to use.」との説明があるだけで実際何をやっているか分からないけど、この値に応じて何かを動かすのだろう。移動の値が大きすぎれば、いくら学習してもどこかへ落ち着くといったことはなく、発散してしまい、小さすぎれば結果が最も良くなるまで学習の回数が無駄に多くなる。

次にtraining_epochsを変えてみる。
下の図は、y=0の時(z=3x+7)のx, zの結果と、tensorflowで得られるx, zの結果のグラフ(赤が方程式、オレンジがtensorflow)。
learning_rate=0.00001, batch_size=10で、上から学習回数(training_epochs)を3、12、10000としたもの。

epochs: 3, 損失関数: 2668.511
epochs: 12, 損失関数: 0.506
epochs: 10000, 損失関数: 0.602

epochsが3の時は、損失関数も2668ほどあり、グラフを見ても実際の値とかけ離れていることが分かる。一方、12と10000の時は、実際の値と似たグラフとなっている。ただ、12と10000のtensorflowの結果のグラフはそれほど変わらない。回数が12のときに得られた以上のものは、学習回数を増やしても無理そう。これはデータを変えれば違ってくるのかな?

最後に、batch_sizeを見てみる。batch_sizeは、データの小グループのサイズで、この1グループの合計を損失関数としている。そのため、数を大きくするほど、損失関数の値も大きくなると思う。

learning_rate training_epochs batch_size 損失関数の結果
0.0000110011061.323 (epochs 100回目)
0.00001100 50.521 (epochs 6回目)
0.00001100 100.506 (epochs 12回目)
0.00001100 100 無限(inf) (epochs 15回目以降)
0.000011000010.070 (epochs 10000回目)

結果は思っていたものと少し違った。TensorflowのGradientDescentOptimizerメソッドの内部で何してるんだろう?
これまで見てきて、learning_rate=0.00001, training_epochs=10000, batch_size=1の0.070が最もいい値となった。グラフを見ると実際の値と見事に重なっている。