TensorFlowによる精度計算の流れを追う

accuracy = tf.reduce_mean(tf.cast(tf.equal(tf.argmax(Y, 1), tf.argmax(Y_, 1)), tf.float32))

Yをニューラルネットワークの出力層、Y_をその正解ラベルとした場合、学習モデルの精度を計算するとき、 TensorFlowでは上記ようにAPIを組合せて書くことがある。 式が長いので、各APIの処理の流れを、1つずつ出力しながら追ってみる。 分かれば非常にシンプルな処理の流れである。

計算の流れ

NumpyとTensorFlowをimportしておく。

>>> import tensorflow as tf
>>> import numpy as np

YとY_に[3, 4]のサンプルデータをセットする。 1行目を不正解としている。

>>> Y = np.array([
...                 [0.1, 0.2, 0.3, 0.4],
...                 [0.0, 0.8, 0.2, 0.0],
...                 [0.0, 0.4, 0.5, 0.1]
...             ])
>>> print Y
[[ 0.1  0.2  0.3  0.4]
 [ 0.   0.8  0.2  0. ]
 [ 0.   0.4  0.5  0.1]]

>>> Y_ = np.array([
...                 [0.0, 0.0, 1.0, 0.0],
...                 [0.0, 1.0, 0.0, 0.0],
...                 [0.0, 0.0, 1.0, 0.0]
...             ])
>>> print Y_
[[ 0.  0.  1.  0.]
 [ 0.  1.  0.  0.]
 [ 0.  0.  1.  0.]]

TensorFlowのSessionを開始。 Sessionと言えば、昨日、映画のSessionを見ましたが非常に良い映画でした。

>>> sess = tf.Session()

ここから精度計算におけるTensorFlowのAPIの説明。 まずはtf.argmax()から。 第2パラメーターに1をセットすると、行ごとに最大となる列を返す。 Yの場合、1行目が4列目の0.4、2行目が2列目の0.8、3行目が3列目の0.5が最大となる。 1行目は0からカウントされるので、以下のようになる。 Y_についても同様。 ちなみに、第2パラメーターに0をセットすると、列ごとに最大となる行を返す。

>>> print sess.run(tf.argmax(Y, 1))
[3 1 2]
>>> print sess.run(tf.argmax(Y_, 1))
[2 1 2]

続いてtf.equal()。 渡された2つのベクトルが一致しているか否かを見る。 今回は[3 1 2]と[2 1 2]を比較しているので次のようになる。

>>> eq = tf.equal(tf.argmax(Y, 1), tf.argmax(Y_, 1))
>>> print sess.run(eq)
[False  True  True]

tf.cast()では第1パラメーターを第2パラメーターのデータ・タイプに変換する。 [False True True]もfloat32に変換すると次の通り。

>>> print sess.run(tf.cast(eq, tf.float32))
[ 0.  1.  1.]

最後はtf.reduce_mean()。 np.mean()と同じで平均を計算する。 [ 0. 1. 1.]の平均なので2/3となる。

>>> print sess.run(tf.reduce_mean(tf.cast(eq, tf.float32)))
0.666667

最後に全部繋げれば、一気に計算できる。

>>> accuracy = tf.reduce_mean(tf.cast(tf.equal(tf.argmax(Y, 1), tf.argmax(Y_, 1)), tf.float32))
>>> print sess.run(accuracy)
0.666667