LoginSignup
6
10

More than 5 years have passed since last update.

私的TensorFlow入門

Last updated at Posted at 2017-01-04

私的Chainer入門してみたイキオイで、続きをやってみることにする。
とはいえ、chainerを極める方向に行くよりも、いろいろと食い散らかしておきたい。
まあ、そんなワケで、TensorFlowである。

MNIST For ML Beginnersを参照しつつすすめる。

私的Chainer入門PythonでKNNを使った手書き文字認識でもMNISTを扱ったワケだけれど、こいつをつかって「数字判別機を作る」というのは、機械学習のチュートリアルの基礎中の基礎だ。言うなれば、Oracleデータベースを初めて触る人がscott/tigerのempデータベースをselectするSQL文から入るようなもんだ。

TensorFlowの準備から

PythonからTensorFlowを使う。AnacondaでPython環境を作っているので、ドキュメントに従い、以下のようにインストールする。

% conda install -c conda-forge tensorflow

以上でインストール完了である。

MNIST For ML Beginnersに戻る

ワケの分からないまま、以下のコードを実行する。

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

とりあえず、ipythonで実行したところ、以下のようになった。

In [1]: from tensorflow.examples.tutorials.mnist import input_data

In [2]: mnist = input_data.read_data_sets("MNIST_data/", one_hot=True)
Successfully downloaded train-images-idx3-ubyte.gz 9912422 bytes.
Extracting MNIST_data/train-images-idx3-ubyte.gz
Successfully downloaded train-labels-idx1-ubyte.gz 28881 bytes.
Extracting MNIST_data/train-labels-idx1-ubyte.gz
Successfully downloaded t10k-images-idx3-ubyte.gz 1648877 bytes.
Extracting MNIST_data/t10k-images-idx3-ubyte.gz
Successfully downloaded t10k-labels-idx1-ubyte.gz 4542 bytes.
Extracting MNIST_data/t10k-labels-idx1-ubyte.gz

どうやら、データがダウンロードされたようだ。

% % ls -s1 MNIST_data/
total 22672
 3224 t10k-images-idx3-ubyte.gz
   16 t10k-labels-idx1-ubyte.gz
19368 train-images-idx3-ubyte.gz
   64 train-labels-idx1-ubyte.gz

TensorFlowでのMNIST実装

MNIST For ML Beginnersによると、chainerのチュートリアルであったように、28x28ピクセルの手書き数字の画像が0〜9のいずれであるのか?をy = Wx + bの線形の式で評価する。
違いは、chainerのチュートリアルでは、chainer.links.Linear()していたところを、Softmax Regressionを使って評価せよという点か。
このあたりの違いについては、勉強不足過ぎて分からない。

チュートリアルによると、数字1個あたり28x28ピクセルの画像データになっているが、これを1次元の28x28=784の配列データであるとみなして、それが55000個あるという前提で考えるようだ。すなわち全データが784行×55000列の行列であるとみなして、これをmnist.train.xsとしている。それぞれの列のラベル(すなわち、各列が0〜9のいずれであるか?を示す)を10行×55000列の行列として保持していて、ソレをmnist.train.ysとしている。なんで、10行か?というと、0を[1,0,0,0,0,0,0,0,0,0]、3を[0,0,0,1,0,0,0,0,0,0]のように表現しているから、だそうだ。

データの読み込みと式の定義

import tensorflow as tf
x = tf.placeholder(tf.float32, [None, 784])

784列のデータをplaceholderとして、まずは定義する。

W = tf.Variable(tf.zeros([784, 10]))
b = tf.Variable(tf.zeros([10]))

Variableとして学習の対象となるパラメーターを定義する。

そして、モデルを定義する。

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

matmul()というのは、行列の掛け算。ここで、softmax regressionによってyを得ることができる。なおyは以下のように示される10行の行列である。

<tf.Tensor 'Softmax_1:0' shape=(?, 10) dtype=float32>

最適化の準備

y_ = tf.placeholder(tf.float32, [None, 10])
cross_entropy = tf.reduce_mean(-tf.reduce_sum(y_ * tf.log(y), reduction_indices=[1]))

さて、最適化というと最小二乗化法かなと思うところなんだけれど、どうやらそうではなく−Σy'log(y)というcross_entropy functionというのを用いるらしい。
ということで、このcross_entropyを最小化させるべく、gradient descent algorithmを使う、と。これは、chainerのチュートリアルで呼んでいたSGDとはよく似ているけれど、違う手法だ。

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

では、変数を初期化し、実行の準備をする。
変数初期化の定義であるが、チュートリアルによると、
init = tf.global_variables_initializer()
と書くべきらしいのだが、実際にはこれはエラーになる。

Traceback (most recent call last):
  File "./mnist_train_tf.py", line 14, in <module>
    init = tf.global_variables_initializer()
AttributeError: module 'tensorflow' has no attribute 'global_variables_initializer'

どうやら、https://github.com/tensorflow/tensorflow/issues/5514#issuecomment-260840208 によると、tensorflowのr0.12からglobal_variables_initializer() が定義されたようで、r0.11以前はinitialize_all_variables()を使っていたようだ。チュートリアルはr0.12準拠だけれど、anaconda環境でinstallしたtensorflowはr0.11なので、エラーになっていたらしい。

最適化のための試行

tensorflowでSessionを定義して、そのsessionの中で、テストデータから100個ずつ選択して学習する。
というのを、1000回繰り返す。

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_: batch_ys})

先に定義したtrain_stepはcross_entropyを最小化するためのものであり、そこにmnistから取得したデータbatch_xsとラベルbatch_ysをfeed_dictという引数を介して入力する。

実行結果

20170104_004.png

0.9184ということで、数値としては予想外に低いかなと思う。

チュートリアルにも、こんなふうに書いてある。

This should be about 92%.

Is that good? Well, not really. In fact, it's pretty bad. This is because we're using a very simple model. With some small changes, we can get to 97%. The best models can get to over 99.7% accuracy!

まあ、チュートリアル用に簡単なモデルを使ったからだよってことらしい。

本日のまとめ

  • TensorFlowを使ってみた
    • chainerとはまた違ってた
    • release 0.12と0.11で違う名前になっているmethodがあった

ニューラルネットによるアプローチといっても、ツールごとにまったく実装方法が有るということが分かった。
そして、このコードをきちんと理解できるだけのニューラルネット・人工知能周辺の知識が全く足りてないことも分かった。

本日のコード


2017/02/22 の追記

TensorFlow の1.0が出て、インストール方法が変わった。手元のWindows機で試してみる。

Windowsへのインストール

condaではなく、pipでインストールしろと、https://www.tensorflow.org/install/install_windows に書いてある。

あれ?

とりあえず、installできたかどうかの確認のために、サンプルコードを実行してみると、動くんだけど、たくさんのwarningが出る。

>>> import tensorflow as tf
>>> hello = tf.constant('Hello, Tensorflow!')
>>> sess = tf.Session()
>>> print(sess.run(hello))
E c:\tf_jenkins\home\workspace\release-win\device\cpu\os\windows\tensorflow\core\framework\op_ke
rnel.cc:943] OpKernel ('op: "BestSplits" device_type: "CPU"') for unknown op: BestSplits
E c:\tf_jenkins\home\workspace\release-win\device\cpu\os\windows\tensorflow\core\framework\op_ke
rnel.cc:943] OpKernel ('op: "CountExtremelyRandomStats" device_type: "CPU"') for unknown op: Cou
ntExtremelyRandomStats
E c:\tf_jenkins\home\workspace\release-win\device\cpu\os\windows\tensorflow\core\framework\op_ke
rnel.cc:943] OpKernel ('op: "FinishedNodes" device_type: "CPU"') for unknown op: FinishedNodes
E c:\tf_jenkins\home\workspace\release-win\device\cpu\os\windows\tensorflow\core\framework\op_ke
rnel.cc:943] OpKernel ('op: "GrowTree" device_type: "CPU"') for unknown op: GrowTree
E c:\tf_jenkins\home\workspace\release-win\device\cpu\os\windows\tensorflow\core\framework\op_ke
rnel.cc:943] OpKernel ('op: "ReinterpretStringToFloat" device_type: "CPU"') for unknown op: Rein
terpretStringToFloat
E c:\tf_jenkins\home\workspace\release-win\device\cpu\os\windows\tensorflow\core\framework\op_ke
rnel.cc:943] OpKernel ('op: "SampleInputs" device_type: "CPU"') for unknown op: SampleInputs
E c:\tf_jenkins\home\workspace\release-win\device\cpu\os\windows\tensorflow\core\framework\op_ke
rnel.cc:943] OpKernel ('op: "ScatterAddNdim" device_type: "CPU"') for unknown op: ScatterAddNdim

E c:\tf_jenkins\home\workspace\release-win\device\cpu\os\windows\tensorflow\core\framework\op_ke
rnel.cc:943] OpKernel ('op: "TopNInsert" device_type: "CPU"') for unknown op: TopNInsert
E c:\tf_jenkins\home\workspace\release-win\device\cpu\os\windows\tensorflow\core\framework\op_ke
rnel.cc:943] OpKernel ('op: "TopNRemove" device_type: "CPU"') for unknown op: TopNRemove
E c:\tf_jenkins\home\workspace\release-win\device\cpu\os\windows\tensorflow\core\framework\op_ke
rnel.cc:943] OpKernel ('op: "TreePredictions" device_type: "CPU"') for unknown op: TreePredictio
ns
E c:\tf_jenkins\home\workspace\release-win\device\cpu\os\windows\tensorflow\core\framework\op_ke
rnel.cc:943] OpKernel ('op: "UpdateFertileSlots" device_type: "CPU"') for unknown op: UpdateFert
ileSlots
b'Hello, Tensorflow!'

Hello Tensorflow!は最後に表示されてるけれど、途中のこれはなんなんでしょうね。

6
10
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
6
10