FPGA開発日記

カテゴリ別記事インデックス https://msyksphinz.github.io/github_pages , English Version https://fpgadevdiary.hatenadiary.com/

機械学習初心者がTensorFlowのチュートリアルを勉強して分かったことをまとめる(2)

当方は機械学習の全くの初心者なので、間違ったことを書いている可能性があります。内容についての保証は致しません。 ↑むしろ、間違った理解をしてるようならば、教えて頂ければとても感謝します。

結局TensorFlowのプログラムを追い掛けならがら、ググりながら本を読みながら進んでいくことになるのだが、理解が浅いというか、何となく理解した気になっても、自分では全く書けないことが多い。くそう。

結局、プログラムのフローはどうなってるの?ということで、チュートリアルの中ではバラバラになっているプログラムを一つにまとめてみようよ。

import tensorflow as tf
sess = tf.InteractiveSession()
x = tf.placeholder("float", shape=[None, 784])
y_ = tf.placeholder("float", shape=[None, 10])

W = tf.Variable(tf.zeros([784,10]))
b = tf.Variable(tf.zeros([10]))

sess.run(tf.initialize_all_variables())

y = tf.nn.softmax(tf.matmul(x,W)+b)
cross_entropy = -tf.reduce_sum(y_*tf.log(y))
train_step = tf.train.GradientDescentOptimizer(0.01).minimize(cross_entropy)

for i in range(1000):
  batch = mnist.train.next_batch(50)
  train_step.run(feed_dict={x: batch[0], y_: batch[1]})

correct_prediction = tf.equal(tf.argmax(y,1), tf.argmax(y_, 1))
accuracy = tf.reduce_mean(tf.cast(correct_prediction, "float"))
print accuracy.eval(feed_dict={x: mnist.test.images, y_: mnist.test.labels})

ソフトマックス関数は、結局何を計算しているの?

もう一度関数をじーっと眺めてみる。

y = tf.nn.softmax(tf.matmul(x,W)+b)

ここでは単層のニューラルネットワークなので、入力を計算してそのまま出力なっているが、{W}{b}って、最初は0で初期化していたんだよなー。 でも、最終的にこれらを使って入力を分類するということは、この{W}{b}に適切な値を設定してやる必要がある、ということになる。 この部分を、うまく学習させてやれば良いのかな。

次にcross_entropyという名前で、良く分からない式が定義されている。

cross_entropy = -tf.reduce_sum(y_*tf.log(y))

深層学習の本によれば、交差エントロピーとして定義されるらしく、つまりこれは誤差関数のことらしい。

深層学習 (機械学習プロフェッショナルシリーズ)

深層学習 (機械学習プロフェッショナルシリーズ)

[tex:{ E(\textgt{w}) = -\sum{n=1}^N\sum{k=1}^K d_{nk}\log y_k(\textgt{x_n;w}) }]

結局上記のPythonの式はどういう意味なんだろう? チュートリアルを読み直してみる。

First, tf.log computes the logarithm of each element of y. Next, we multiply each element of y_ with the corresponding element of tf.log(y_). Finally, tf.reduce_sum adds all the elements of the tensor.

分かるわ!(笑)

モデルのトレーニング

以下直訳。

ここまでで、モデルとトレーニング関数の定義は完了した。このコスト関数はTensorFlowを使ってトレーニングをするのには単純なものである。
何故ならば、TensoFlowは計算グラフ全体を知っているため、Tensorflowは自動的にdifferentiationを利用して
各Varibleのコスト勾配を探すことができるからである。
TensorFlowは多くの最適化アルゴリズムを組み込んである。

train_step = tf.train.GradientDescentOptimizer(0.01).minimize(cross_entropy)

ここでは、最急降下法(?)を使って交差エントロピーを最小化している。

上記の1行で、何をやっているかと言うと計算グラフに新しい処理を追加している。
これらの操作には、勾配を計算する処理、パラメータを更新するステップ、パラメータにアップデートを適用するステップが含まれている。

トレーニング

上記のtrain_stepを何度も繰替えすことで、 最急降下法を何度も繰り返し実行しているものと思われる。トレーニングデータを実行して、学習させているという訳か。

ここらへん以降は直訳。

for i in range(1000):
  batch = mnist.train.next_batch(50)
  train_step.run(feed_dict={x: batch[0], y_: batch[1]})

各トレーニングでは、50個のトレーニングの例をロードしている。train_step処理を読み出し、feed_dictによってplaceholderのテンソルxとy_をトレーニング用の例と置き換えている。 feed_dictを使えば、計算グラフ中のどのようなテンソルでも置き換えることができる。

モデルの評価

最後の結果あつめだ。このモデルは、どの程度うまく動作しただろうか?

correct_prediction = tf.equal(tf.argmax(y,1), tf.argmax(y_, 1))

これにより、正解、不正解のリストが作られる。 これにより、正解、不正解の数を浮動小数点に変換し、平均を取る。例えば、[True, False, True, True]だと[1,0,1,1]になり、正解率は0.75になる。

accuracy = tf.reduce_mean(tf.cast(correct_prediction, "float"))

最後に、テストデータの正解率を評価する。この例では、91%が正解になるはずだ。

print accuracy.eval(feed_dict={x: mnist.test.images, y_: mnist.test.labels})
0.9092