Help us understand the problem. What is going on with this article?

Tensorflow MNIST For ML Beginners

More than 3 years have passed since last update.

はじめに

メモ用、各関数がなにしてるか分かる範囲で記してます。
詳しい人は間違ってるとこを指摘してもらえると助かります。

参考サイト:
MNIST For ML Beginners
Variables: Creation, Initialization, Saving, and Loading

TensorFlow

Googleが作った機械学習ライブラリです。
https://www.tensorflow.org/

インストール

とりあえず、pyenvで環境構築します。
環境:MacOSX, Python3.5.0

pyenv.
pyenv install 3.5.0
pyenv virtualenv 3.5.0 tf35
pip install --upgrade https://storage.googleapis.com/tensorflow/mac/tensorflow-0.7.1-cp35-none-any.whl

MNIST For ML Beginners

MNISTは画像のデータセット(手書きの数字画像がたくさんあるやつ)です。
各画像に各数字のラベルが振られてます。

タスクとしては、手書き画像が0~9どの数字なのかあてることです(10クラス分類)。
ここでは簡単な、ソフトマックス回帰で分類します。

The MNIST Data

read_data.py
from tensorflow.examples.tutorials.mnist import input_data
mnist = input_data.read_data_sets("MNIST_data/", one_hot=True)

input_data.read_data_sets
第一引数にMNISTデータの保存先("MNIST_data/")を設定。ココは任意なので好きな名前で良い。
キーワード引数のone_hotは、Falseにするとラベルが実数(0~9)に、Trueにするとone_hot(今回の場合、10クラス分類なので要素数10のベクトル,ex: 4 = [0,0,0,0,1,0,0,0,0,0])になる。

ココで、獲得できるのは、 trainデータ55k, testデータ10k。
一枚の画像は要素数784のベクトル(実際は28*28の画像)で各要素[0, 1]の範囲(色の濃さ)で表されている、各画像にone_hotでラベル(0~9)がついている。

Softmax Regressions

ソフトマックス回帰は、シグモイド関数を多変量にしたもの

コード

準備

from tensorflow.examples.tutorials.mnist import input_data
import tensorflow as tf

mnist = input_data.read_data_sets("MNIST_data/", one_hot=True)
x = tf.placeholder(tf.float32, [None, 784])
W = tf.Variable(tf.zeros([784, 10]))
b = tf.Variable(tf.zeros([10]))

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

placeholderは型(float32)と大きさ(784)を定義して、計算する際にココに入れる形になります。

Variableにはzerosで0のベクトルが作られています。
文字通りvariableなので、中身は更新する事に変わっていきます。
10個のクラスに対してのバイアス(b)、重み(W)になります。

softmaxは、ソフトマックス関数を行ってくれる関数です。
matmulはおそらく、matrix multipleなので行列の掛け算してます。

training

y_ = tf.placeholder(tf.float32, [None, 10])
cross_entropy = -tf.reduce_sum(y_*tf.log(y))
train_step = tf.train.GradientDescentOptimizer(0.01).minimize(cross_entropy) 

init = tf.initialize_all_variables()
sess = tf.Session()
sess.run(init)

for i in range(1000):
    batch_xs, batch_ys = mnist.train.next_batch(100)
    sess.run(train_step, feed_dict = {x: batch_xs, y_: ys})

最初の行では、placeholderでラベルを入れる場所を作ります。
ココに入るのは正解データです。
cross_entropyは学習時に最小化したい関数になります。
GradientDescentOptimizer(最急降下法)は与えられた関数の最小値を探索するアルゴリズムです。引数の0.01は更新するときの重みみたいなものです。

ここまでで、変数の宣言や式の組み立てができました。
次に、学習をしていきます。

initialize_all_variablesで今まで宣言した変数等をどっかのクラスかなにかにのせていくのかな。
次に、Sessionでクラス定義、でsess.run(init)でさっきのinitをこん中に入れて、準備完了。

あとはfor文で学習させていくだけ。
ここでは、100個のデータをランダムに毎回渡しています。
こういうのをstochastic gradient descent(確率的勾配降下法)というそうです。
メモリ効率が良さそうな感じしますね。

モデルの保存

いちいち学習し直すのもめんどくさいのでとりあえず、モデル保存したいと思います。

init = ~~~~
saver = tf.train.Saver()

sess = ~~~~~
for i in range ~~~~~~:
    ~~~~~~~
    ~~~~~~~
saver.save(sess, "tmp/model.ckpt")

とりあえず、これで任意のファイルに保存できます

モデル評価

correct_prediction = tf.equal(tf.argmax(y, 1), tf.argmax(y_, 1))
accuracy = tf.reduce_mean(tf.cast(correct_prediction, "float")
print(sess.run(accuracy, feed_dict = {x: mnist.test.images, y_: mnist.test.labels}))

correct_predictionは評価する関数の定義です。
argmax(y, 1)とargmax(y_, 1)つまり、予測と正解が一緒であればTrue, 間違ってればFalseを出力する関数です。

accuracyでは、correct_predictionの出力のベクトル(True or False)をcastfloatに直してから、meanで平均をとる関数の宣言をしています

最後に、sess.runでテストデータ全体で走らせています。

出力

0.9082

とりあえず、サイトに載ってる数値通りの値がでました。

まとめ

今回はtensorflowを使って、softmax回帰で10クラスの分類を行った。

簡単な流れとしては、
variable, placeholderの宣言。
softmax等の学習の際に用いる関数の定義
最適化関数の定義(Gradient Descent Optimizer)
stochastic trainingをする(少しずつランダムサンプリングして学習していく)
最後に予測して答え合わせ

Kodaira_
python / rails ruby / 自然言語処理(NLP)をやっています
http://cl.sd.tmu.ac.jp/~kodaira/
Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away