FPGA開発日記

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

TensorFlowによる基本的な演算についての勉強

TensorFlowについて読み進めていくと、機械学習の理論的なところが全く理解できていないことに絶望するとともに、インタフェースであるPythonについても理解が全く足りていないことが分かる。 はっきり言って、Pythonはこれまでインタプリタの肩代りとして使ったことはあるけど、Pythonそのものについては殆ど無知なんだよな。。。 そこらへんを少しずつ埋めていくと、TensorFlowで何をやっているのかが分かってくる。

特にTensorFlowのインタフェースの基礎については、下記のQittaが非常に分かりやすかった。

qiita.com

つまり、TensorFlowでは式、というか関数を定義していき、それをApplyしていくことにより計算を進めていく。 関数を定義するような形で「式」を定義していき、その式の引数を与える形で計算をするという訳だ。

まずはプレースホルダを作成する。これはfloat型の2x2の行列を作成している。

import tensorflow as tf
mat_x = tf.placeholder("float", shape=(2, 2))
mat_y = tf.placeholder("float", shape=(2, 2))

次に、「式」を定義する。例えば、行列の加算、乗算、要素の乗算、逆行列の計算を定義するには以下のようになる。

op_add = mat_x+mat_y
op_matmul = tf.matmul(mat_x, mat_y)
op_mul = tf.mul(mat_x,mat_y)
op_inverse = tf.matrix_inverse(mat_x)

これに具体的な数値をはめて計算させるためには以下のようになる。これには、一度セッションを作成する必要がある。

with tf.Session() as sess:
  x_1 = [[1, 2], [3, 4]]
  y_1 = [[5, 6], [7, 8]]
  print sess.run (op_add, feed_dict={mat_x: x_1, mat_y: y_1})
  print sess.run (op_matmul, feed_dict={mat_x: x_1, mat_y: y_1})
  print sess.run (op_mul, feed_dict={mat_x: x_1, mat_y: y_1})
  print sess.run (op_inverse, feed_dict={mat_x: x_1})
  print sess.run (op_inverse, feed_dict={mat_x: y_1})

それぞれ、計算結果が出力される。

[[  6.   8.]
 [ 10.  12.]]
[[ 19.  22.]
 [ 43.  50.]]
[[  5.  12.]
 [ 21.  32.]]
[[-2.   1. ]
 [ 1.5 -0.5]]
[[-4.   3. ]
 [ 3.5 -2.5]]

このように、式を構成していき、何度もトレーニングデータを適用することで学習していく、と考えれば、TensorFlowの意味が何となく分かってくる。

MNISTの学習のソースコードをもう一度見直すと、

# Create the model
x = tf.placeholder("float", [None, 784])
W = tf.Variable(tf.zeros([784,10]))
b = tf.Variable(tf.zeros([10]))
y = tf.nn.softmax(tf.matmul(x,W) + b)

上記までで、ソフトマックス関数を定義した訳だ。ソフトマックス関数は、 {
u_k^{(L)}=(W^{(L)}z^{(L-1)}+b^{^{(L)}})
} を定義したときに(これは、上記のtf.matmul(x,W)+bに相当する)、

{
y_k=z_k^{(L)}=\dfrac{\exp{(u_k^{(L)})}}{\sum_{j=1}^K\exp{(u_j^{(L)})}}
} と定義でき、これをtf.nn.softmax()を使って定義しているに過ぎない。

次に学習フェーズだが、交差エントロピーを、

[tex:{ E(w)=-\sum{n=1}^N\sum{k=1}^Kd_{nk}\log y_k(x_n; w) }] と定義し、これを最小化することから、下記のコードとなる。

# Define loss and optimizer
y_ = tf.placeholder("float", [None,10])
cross_entropy = -tf.reduce_sum(y_*tf.log(y))
train_step = tf.train.GradientDescentOptimizer(0.01).minimize(cross_entropy)

cross_entropyを定義し、これをtf.train.GraidentDescenOptimizerを使って最小化する訳だ。これをトレーニングデータを使って何度も行い、最小の交差エントロピーを求めていくことなる。