LoginSignup
1
2

More than 3 years have passed since last update.

TensorFlow MNIST のコード解説【初心者向け】

Last updated at Posted at 2019-02-25

TensorFlow を使い始め、MNISTでどのようなものが使えるのか調べた結果をまとめていく。
初歩の初歩のものがほとんどであるが、MNISTのコード内のものが大半であるため、始めたばかりの自分のような者には有益なものとなると嬉しい。
なお、定数を、

image_size = 28*28     //画像サイズ
output_num = 10        //数字の数
learning_rate = 0.001  //学習率
loop_num = 30000       //ループ回数
batch_size = 100       //バッチサイズ

としている。表記の都合上y_と$y'$は同じものとした。
また、扱ったコードは文末にある。

mnist

mnist = input_data.read_data_sets("MNIST_data/", one_hot=True)

MNISTで用いるデータの読み込みである。
one_hot とはn種類のデータを表すのに、n次元ベクトルを用い、mを表すにはm番目のベクトルを1、他を0とすることを示しており、7は[ 0, 0, 0, 0, 0, 0, 0, 1, 0, 0]と表される。

tf.placeholder()

x = tf.placeholder("float", [None, image_size])

placeholderとは、値の入る場所の確保である。上の例では、float型のNone*image_sizeの配列(Noneは任意)を入れる場所を示している。

tf.Variable()

tf.Variable(tf.zeros([image_size, output_num]))

変数(Variable)をゼロ初期化している。上記のplaceholder同様この例もimagesize*output_numの配列変数を初期化している。

【+α】 tf.random_normal()

tf.random_normal([image_size, H], mean=0.0, stddev=0.05)

tf.zeros以外に、tf.random_normalを用いて初期化することもできる。これは、正規分布で乱数を発生させ、それを初期値とする。機械学習では、初期値が0でないほうが良いことがあり、こちらで初期化することが多い。meanは平均、stddevは標準偏差である。この例では0近傍の数字を発生させることができる。

tf.nn.softmax()

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

ソフトマックス関数によって回帰している。tf.matmulは行列積である。
ソフトマックス関数とは、
$$softmax(x_1,x_2,...,x_n) = y(y_1,y_2,...,y_n)$$
ただし、
$$y_i=\frac{e^{x_i}}{\sum_{k=0}^{n} e^k}$$
というものである。
この関数は、
$$0\leq y_i\leq1$$
$$\sum y_i=1$$という性質があるため、確率の出力に適している。

cross_entropy

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

クロスエントロピーを計算する。クロスエントロピーCとは、
$$C=-\sum (y')log(y)$$
である。ただし、$y'$は正解、$y$は予測値である。
--ここからは大雑把な説明--
情報でいう一般的なエントロピーは、
$$entropy=-\sum_{i} y_ilog(y_i)$$
で表され、確率$y$での情報量の最小値を表すのに使う。
$log(y_i)^{-1}$の部分は確率$y_i$で表される情報の最小の情報量を表すから、クロスエントロピーを最小にする$y$は$y'$に近いものとなるはずである。

train_step

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

GradientDescentOptimizerとは、勾配降下法によるオプティマイザーを実行するものである。
learning_rateで学習率を指定し、minimize()でcross_entropyを最小化するようにすることを示す。

init

init = tf.initialize_all_variables()

全変数を初期化する。

tf.Session()

sess = tf.Session()

Sessionをsessとして定義。

sess.run()

sess.run(init)

TensorFlowではSessionを実行することで実行される。ここではinitを実行する。

train.next_batch()

batch_xs, batch_ys = mnist.train.next_batch(batch_size)

batch_xs、batch_yを、mnistの中の(batch_size)個のデータを取り出す。

sess.run(train_step)

sess.run(train_step, feed_dict={x: batch_xs, y_: batch_ys})

先述のtrain_stepを実行する。feed_dictはtrain_stepの$x$、$y'$の値を指定している。

correct_prediction

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

予測値$y$と正解値$y'$が等しければbool値を返す。tf.argmaxは、予測値の最大値のインデックスを返す。

accuracy

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

bool値を0,1に変換して平均を取る。これは正解率となる。

print()

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

accuracyを実行して、結果を出力している。

今回扱ったコードの全容

以下のサイトを参考にした。
https://www.trifields.jp/try-tutorial-mnist-for-ml-beginners-of-tensorflow-1713

tutorial.py
import tensorflow as tf
import input_data

image_size = 28*28
output_num = 10
learning_rate = 0.001
loop_num = 30000
batch_size = 100
# MNISTデータを読み込み
mnist = input_data.read_data_sets("MNIST_data/", one_hot=True)

# 画像データ
x = tf.placeholder("float", [None, image_size])

# モデルの重み
W = tf.Variable(tf.zeros([image_size, output_num]))

# モデルのバイアス
b = tf.Variable(tf.zeros([10]))

# トレーニングデータxとモデルの重みWを乗算した後、モデルのバイアスbを足し、
# ソフトマックス回帰(ソフトマックス関数)を適用
y = tf.nn.softmax(tf.matmul(x, W) + b)

# 正解データ
y_ = tf.placeholder("float", [None, output_num])

# 損失関数をクロスエントロピーとする
cross_entropy = -tf.reduce_sum(y_ * tf.log(y))

# 学習係数を0.01として、勾配降下アルゴリズムを使用して、
# クロスエントロピーを最小化する
train_step = tf.train.GradientDescentOptimizer(learning_rate).minimize(cross_entropy)

# 変数の初期化
init = tf.initialize_all_variables()

# セッションの作成
sess = tf.Session()

# セッションの開始および初期化の実行
sess.run(init)

# トレーニングの開始
for i in range(loop_num):
    # トレーニングデータからランダムに100個抽出する
    batch_xs, batch_ys = mnist.train.next_batch(batch_size)

    # 確率的勾配降下によりクロスエントロピーを最小化するよう重みを更新
    sess.run(train_step, feed_dict={x: batch_xs, y_: batch_ys})

# 予測値と正解値を比較して、bool値(true or false)にする
# tf.argmax(y, 1)は、予測値の各行で、最大値となるインデックスを一つ返す
correct_prediction = tf.equal(tf.argmax(y, 1), tf.argmax(y_, 1))

# bool値を0 or 1に変換して平均値をとる -> 正解率
accuracy = tf.reduce_mean(tf.cast(correct_prediction, "float"))

# テストデータを与えて、テストデータの正解率の表示
print(sess.run(accuracy, feed_dict={x: mnist.test.images, y_: mnist.test.labels}))

次の記事

TensorFlow MNIST のコード解説【隠れ層のある場合】

1
2
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
2