初めに
TensorFlow再入門シリーズ第3回です。今回は世界で最も有名なデータセットであるMNISTを使い、単層パーセプトロンで画像認識を実行します。
TensorFlowで単層パーセプトロンをする際の要素
これまで利用した関数などを用いることでほぼ実装可能ですが、一部新しい関数も利用しています。
ミニバッチ学習
大規模なデータを扱って学習をする場合、訓練データからランダムにデータを取り出して計算し、その平均誤差を利用することで、効率的に学習を進めることができます。その際の取り出すデータサイズをミニバッチサイズと言います。
今回はtensorflow.examples.tutorials.mnist.input_data
に組み込まれたread_data_sets
関数を利用します。
read_data_sets(train_dir, fake_data=False, one_hot=False, dtype=dtypes.float32, reshape=True, validation_size=5000 )
評価関数
今回はMNISTのデータセットに含まれる0~9の10種類の数字から、同じ数字を推測できているかどうかで評価を行っています。
推測の出力結果は0~9のどの数字に近いかが確率として表示されています。
まずtf.argmax
を用いて、そのリストの中で最も大きな値となるラベル(=正解と予測されたラベル)を取り出し、実際のラベルと比較します。比較の際にはtf.equal
という関数を利用します。2つの引数を比べ、True/Falseのboolで返します。
次に返ってきたboolを数値に変換し、評価に利用します。
その際にtf.cast
という関数を利用します。これはデータの型(dtype)を別のものに変更する関数です。
# 使い方 tf.math.argmax( input, axis=None, name=None, dimension=None, output_type=tf.dtypes.int64 ) tf.math.equal( x, y, name=None ) tf.cast( x, dtype, name=None )
公式ページは以下になります。
実装
実際のコード
まずは実際のコードを載せます。
# ライブラリのインポート import tensorflow as tf from tensorflow.examples.tutorials.mnist import input_data # データセット mnist = input_data.read_data_sets("data", one_hot=True) train_x, train_y = mnist.train.next_batch(100) test_x = mnist.test.images test_y = mnist.test.labels # ハイパーパラメータ num_epochs = 10000 learning_rate = 0.01 # 計算グラフ X = tf.placeholder(tf.float32, [None, 784]) Y = tf.placeholder(tf.float32, [None, 10]) W = tf.Variable(tf.zeros([784, 10])) b = tf.Variable(tf.zeros([10])) out = tf.nn.softmax(tf.matmul(X, W) + b) ## 損失関数 loss = tf.losses.softmax_cross_entropy(Y, out) ## 最適化関数 optimizer = tf.train.GradientDescentOptimizer(learning_rate) train_step = optimizer.minimize(loss) ## 評価 correct = tf.equal(tf.argmax(out, 1), tf.argmax(Y, 1)) accuracy = tf.reduce_mean(tf.cast(correct, tf.float32)) # 変数の初期化 init = tf.global_variables_initializer() # 計算処理 with tf.Session() as sess: sess.run(init) for epoch in range(num_epochs): sess.run(train_step, feed_dict={X: train_x, Y: train_y}) if epoch != 0 and epoch % 1000 == 0: train_loss, accuracy_value = sess.run(loss, feed_dict={X: train_x, Y: train_y}), \ accuracy.eval(feed_dict={X: train_x, Y: train_y}) print("epoch: ", epoch, " train_loss: ", train_loss, " accuracy_value: ", accuracy_value) tf.reset_default_graph()
0. ライブラリのインポート
TensorFlowに組み込まれたMNISTデータセットを呼び出します。
# ライブラリのインポート import tensorflow as tf from tensorflow.examples.tutorials.mnist import input_data
1. データセットの読み込み
データセットをミニバッチ化し、訓練データとテストデータに分けますensorFlowの提供するMNISTデータセットでは、初めからtrain、testに分かれているので、それぞれ別の変数に入れます。
# データセット mnist = input_data.read_data_sets("data", one_hot=True) train_x, train_y = mnist.train.next_batch(100) test_x = mnist.test.images test_y = mnist.test.labels
2. データフローグラフの構築
データセットの入れ物となるX
Y
、変数となるW
b
、出力結果を格納するout
などを指定します。
また損失関数・最適化関数に加え、上述した評価関数も指定します。
# 計算グラフ X = tf.placeholder(tf.float32, [None, 784]) Y = tf.placeholder(tf.float32, [None, 10]) W = tf.Variable(tf.zeros([784, 10])) b = tf.Variable(tf.zeros([10])) out = tf.nn.softmax(tf.matmul(X, W) + b) ## 損失関数 loss = tf.losses.softmax_cross_entropy(Y, out) ## 最適化関数 optimizer = tf.train.GradientDescentOptimizer(learning_rate) train_step = optimizer.minimize(loss) ## 評価 correct = tf.equal(tf.argmax(out, 1), tf.argmax(Y, 1)) accuracy = tf.reduce_mean(tf.cast(correct, tf.float32))
3. 各変数の初期化
変数を含むので初期化をします。
# 変数の初期化 init = tf.global_variables_initializer()
4. 各関数の実行(実行フェーズ)
これまでと同様、セッションを開始してtf.Session.run
で計算を実行します。
# 計算処理 with tf.Session() as sess: sess.run(init) for epoch in range(num_epochs): sess.run(train_step, feed_dict={X: train_x, Y: train_y})
5. 計算結果の確認・評価
実行結果を確認します。ここでは損失関数の値と評価関数の値を見ています。
if epoch != 0 and epoch % 1000 == 0: train_loss, accuracy_value = sess.run(loss, feed_dict={X: train_x, Y: train_y}), \ accuracy.eval(feed_dict={X: train_x, Y: train_y}) print("epoch: ", epoch, " train_loss: ", train_loss, " accuracy_value: ", accuracy_value)
6. 計算グラフのリセット
最後に計算グラフのリセットを行います。
tf.reset_default_graph()
計算結果
実行結果を載せます。ハイパーパラメーターを変更すれば、より精度は向上します。
epoch: 1000 train_loss: 1.8928964 accuracy_value: 0.72 epoch: 2000 train_loss: 1.7550746 accuracy_value: 0.8 epoch: 3000 train_loss: 1.6716672 accuracy_value: 0.89 epoch: 4000 train_loss: 1.6261232 accuracy_value: 0.91 epoch: 5000 train_loss: 1.6011841 accuracy_value: 0.92 epoch: 6000 train_loss: 1.5857533 accuracy_value: 0.92 epoch: 7000 train_loss: 1.5758034 accuracy_value: 0.92 epoch: 8000 train_loss: 1.5691535 accuracy_value: 0.92 epoch: 9000 train_loss: 1.5644498 accuracy_value: 0.92
その他
ミニバッチを使わない場合
ミニバッチ化せずに実行した場合も載せます。実行時間はミニバッチと比べてかなりかかります(30~40分程度)。
# コード変更箇所 #train_x, train_y = mnist.train.next_batch(100) train_x = mnist.train.images train_y = mnist.train.labels test_x = mnist.test.images test_y = mnist.test.labels # 実行結果 epoch: 1000 train_loss: 2.03642 accuracy_value: 0.59145457 epoch: 2000 train_loss: 1.8735378 accuracy_value: 0.73687273 epoch: 3000 train_loss: 1.8022996 accuracy_value: 0.78023636 epoch: 4000 train_loss: 1.7664666 accuracy_value: 0.7906909 epoch: 5000 train_loss: 1.7446582 accuracy_value: 0.7978909 epoch: 6000 train_loss: 1.7297618 accuracy_value: 0.8022182 epoch: 7000 train_loss: 1.7188071 accuracy_value: 0.80572724 epoch: 8000 train_loss: 1.7103248 accuracy_value: 0.8087636 epoch: 9000 train_loss: 1.7034981 accuracy_value: 0.8113091
公式ページにあるチュートリアルコード
TensorFlowはバージョンが上がるにつれ、TensorFlow単体での利用からKerasの利用を推奨しているようです。チュートリアルの初めのページでは、kerasを用いてとてもコンパクトにMNISTの学習を実行しています。
# チュートリアルのコード import tensorflow as tf mnist = tf.keras.datasets.mnist (x_train, y_train),(x_test, y_test) = mnist.load_data() x_train, x_test = x_train / 255.0, x_test / 255.0 model = tf.keras.models.Sequential([ tf.keras.layers.Flatten(input_shape=(28, 28)), tf.keras.layers.Dense(512, activation=tf.nn.relu), tf.keras.layers.Dropout(0.2), tf.keras.layers.Dense(10, activation=tf.nn.softmax) ]) model.compile(optimizer='adam', loss='sparse_categorical_crossentropy', metrics=['accuracy']) model.fit(x_train, y_train, epochs=5) model.evaluate(x_test, y_test) # 結果 Epoch 1/5 60000/60000 [==============================] - 14s 234us/sample - loss: 0.2200 - acc: 0.9348 Epoch 2/5 60000/60000 [==============================] - 14s 230us/sample - loss: 0.0972 - acc: 0.9699 Epoch 3/5 60000/60000 [==============================] - 13s 224us/sample - loss: 0.0692 - acc: 0.9782 Epoch 4/5 60000/60000 [==============================] - 13s 220us/sample - loss: 0.0537 - acc: 0.9832 Epoch 5/5 60000/60000 [==============================] - 13s 224us/sample - loss: 0.0418 - acc: 0.9862 10000/10000 [==============================] - 1s 57us/sample - loss: 0.0634 - acc: 0.9818 [0.06343337026094087, 0.9818]
参考リンク
Tensorflow run() vs eval() と InteractiveSession() vs Session()