はじめに
サンプルをなぞりながら、Tensorflowを利用してニューラルネットワークを一通り動かしてみる。
参考: 新村 拓也. TensorFlowではじめるDeepLearning実装入門 impress top gearシリーズ . Kindle 版
やること
手書きの0~9の数字を渡して(入力データ)、それぞれどの数字なのかを判別していく(出力データ)。
画像のデータは1枚あたり、28px*28pxの画像を1列の行列に直し、784個の画素値の並びを利用する。
入力データ: 画素数(784) * 画像の枚数(n)
出力データ: 0~9のどの文字であるかの確率(10) * 画像の枚数(n)
実行
データの取得
from tensorflow.examples.tutorials.mnist import input_data
import tensorflow as tf
### MNISTデータを格納したオブジェクトを呼び出す
mnist = input_data.read_data_sets("MNIST_data/", one_hot=True)
## 全訓練データの取得
# 訓練用の入力データ、正解データをミニバッチを指定して取得
train_images, train_labels = mnist.train.next_batch(50)
# テスト用の全画像データを取得
test_images = mnist.test.images
# テスト用の全正解データを取得
test_labels = mnist.test.labels
順伝播
# 入力データを定義
# [ミニバッチサイズ(まだわからないのでNone), 1枚の画像の画素数(画素数)]の行列
x = tf.placeholder(tf.float32, [None,784])
### 入力層から中間層
# 正規分布からランダムに取り出したテンソルを生成
# 入力層のユニット数:784, 中間層のユニット数:64
w_1 = tf.Variable(tf.truncated_normal([784,64],stddev=0.1),name="weight1")
# [1, 64]のテンソルにしておけば、tensorflowがいい感じに計算してくれる
b_1 = tf.Variable(tf.zeros([64]),name="bias1")
# 入力[バッチサイズ, 784] * 重み[784, 64] + バイアス= [バッチサイズ, 64]
# relu関数: 0以下→0, 0以上→そのまま出力
h_1 = tf.nn.relu(tf.matmul(x,w_1) + b_1)
### 中間層から出力層
# 出力層のユニット数:10
w_2 = tf.Variable(tf.truncated_normal([64, 10], stddev=0.1), name="w2")
b_2 = tf.Variable(tf.zeros([10]), name = "b2")
# softmax関数:出力される各成分を0~1、すべての成分の和を1にしてくれる確率を表現する関数
out = tf.nn.softmax(tf.matmul(h_1, w_2) + b_2)
誤差関数
# 正解データ[None(ミニバッチサイズ), 出力層のユニット数]
y = tf.placeholder(tf.float32, [None, 10])
# 出力結果との差を求める → それを2乗して二乗誤差を求める → 全二乗誤差を平均
loss = tf.reduce_mean(tf.square(y - out))
訓練
# 確率的勾配降下法(学習率:0.5)
train_step = tf.train.GradientDescentOptimizer(0.5).minimize(loss)
評価
# 正解データ、出力データから最大値は何番目かを取得(一番確率の列(0~9)を求める)
# [バッチサイズ, 1]の行列を作成 → 出力データが正解かどうか判定 → 正解率を求める
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)
# テスト用データをロード
test_images = mnist.test.images
test_labels = mnist.test.labels
for i in range(1000):
step = i + 1
train_images, train_labels = mnist.train.next_batch(50) #ミニバッチサイズ50
# ミニバッチ取得 → placeholderへ渡す → train_step実行
sess.run(train_step, feed_dict={x:train_images, y:train_labels})
# 10stepごとに精度を確認
if step % 10 == 0:
acc_val = sess.run(accuracy, feed_dict = {x:test_images, y:test_labels})
print('Step %d: accuracy = %.2f' % (step, acc_val))
出力結果
Extracting MNIST_data/train-images-idx3-ubyte.gz
Extracting MNIST_data/train-labels-idx1-ubyte.gz
Extracting MNIST_data/t10k-images-idx3-ubyte.gz
Extracting MNIST_data/t10k-labels-idx1-ubyte.gz
Step 10: accuracy = 0.16
Step 20: accuracy = 0.18
Step 30: accuracy = 0.21
...
Step 990: accuracy = 0.89
Step 1000: accuracy = 0.90