TensorFlowでdeep learningをやってみるその２

http://qiita.com/northriver/items/17e936343110d392cce8
上記で初心者向けチュートリアルをやってみたので、Deep MNIST for Expertsへ

https://www.tensorflow.org/versions/master/tutorials/mnist/pros/index.html

まずは、初心者向けと同じように、一回学習させる

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

import tensorflow as tf
sess = tf.InteractiveSession()

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]))

#初期化は少し短縮しているみたい
sess.run(tf.initialize_all_variables())

y = tf.nn.softmax(tf.matmul(x,W) + b)
cross_entropy = tf.reduce_mean(-tf.reduce_sum(y_ * tf.log(y), reduction_indices=[1]))
train_step = tf.train.GradientDescentOptimizer(0.5).minimize(cross_entropy)

for i in range(1000):
  batch = mnist.train.next_batch(50)
  train_step.run(feed_dict={x: batch[0], y_: batch[1]})

correct_prediction = tf.equal(tf.argmax(y,1), tf.argmax(y_,1))
accuracy = tf.reduce_mean(tf.cast(correct_prediction, tf.float32))
print(accuracy.eval(feed_dict={x: mnist.test.images, y_: mnist.test.labels}))
```
>0.9085
ここまでは、初回の復習

#ここからは多層畳み込みネットワークへ
MNISTの学習で、91％の精度は呆れるほど低いそうです。多層畳み込みネットワークを使って、99%まで精度を上げます


初心者なので、自作の関数とかあると、理解できなくなるので、まずは、それは全部元に戻します。
まず、グラフのノード作りその１

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

import tensorflow as tf
sess = tf.InteractiveSession()

x = tf.placeholder(tf.float32, shape=[None, 784])
y_ = tf.placeholder(tf.float32, shape=[None, 10])

w1=tf.Variable(tf.truncated_normal([5,5,1,32],stddev=0.1))
b1=tf.Variable(0.1,[32])
x_image = tf.reshape(x,[-1,28,28,1])
#畳み込み層、プーリング層その１
h_conv1=tf.nn.relu(tf.nn.conv2d(x_image, w1, strides=[1, 1, 1, 1], padding='SAME')+b1)
h_pool1 = tf.nn.max_pool(h_conv1, ksize=[1, 2, 2, 1],strides=[1, 2, 2, 1], padding='SAME')

```

畳み込み層とプーリング層とは？
ニューラルネットワークとディープラーニングの違い出しているのがこれら層です。

畳み込み層は「入力画像に対してフィルタをかけ特徴抽出を行っているところ」。プーリング層は「微小変位に対する頑健性の向上を行っているところ」、、、ん？頑健性の向上？

これは、例えば、数字の「7」が画像の真ん中に書かれていても少し左や右にずれていても同じように「7」と判定できるように、ストライクゾーンを広げているところと考えれば良いという感じです

ちなみに、[5, 5, 1, 32]の意味は[width, height, input, filters]で、各画像に対して5x5のサイズのフィルターを適用しているみたいです。x_image = tf.reshape(x, [-1,28,28,1])は
28x28のマトリックスで処理していたものを元のベクトルの形に戻しているそうです

第2層を作る

```
w2=tf.Variable(tf.truncated_normal([5,5,32,64],stddev=0.1))
b2=tf.Variable(0.1,[64])

h_conv2 =tf.nn.relu(tf.nn.conv2d(h_pool1, w2, strides=[1, 1, 1, 1], padding='SAME')+b2)
h_pool2 = tf.nn.max_pool(h_conv2, ksize=[1, 2, 2, 1],strides=[1, 2, 2, 1], padding='SAME')
```

全結合層を作ります
ここまでくると、画像サイズは7x7まで落ちています。これに、1024のニューロン素子を持った全結合層を加える
※7x7x64=3136はTensorのsize, 1024は適当。 業界的に大抵は1024もしくは1024*nの倍数らしい。 

```
W_fc1=tf.Variable(tf.truncated_normal([7 * 7 * 64, 1024],stddev=0.1))
b_fc1=tf.Variable(0.1,[1024])

h_pool2_flat = tf.reshape(h_pool2, [-1, 7*7*64])
h_fc1 = tf.nn.relu(tf.matmul(h_pool2_flat, W_fc1) + b_fc1)
```
できるだけ特徴を残しながら答え合わせに近づきたいというのと、学習データだけに適応してしまう過学習を回避するため、一旦この隠れ層を作るそうです、、、、よくわからん


ドロップアウトの設定、、、こちらもよくわからないですが、必要みたいです

```
keep_prob = tf.placeholder(tf.float32)
h_fc1_drop = tf.nn.dropout(h_fc1, keep_prob)
```

読み出し層
ここはビギナー向けと同じ

```
W_fc2=tf.Variable(tf.truncated_normal([1024, 10],stddev=0.1))
b_fc2=tf.Variable(0.1,[10])

y_conv=tf.nn.softmax(tf.matmul(h_fc1_drop, W_fc2) + b_fc2)
```

モデルを学習し、評価する

```
cross_entropy = tf.reduce_mean(-tf.reduce_sum(y_ * tf.log(y_conv), reduction_indices=[1]))
train_step = tf.train.AdamOptimizer(1e-4).minimize(cross_entropy)
correct_prediction = tf.equal(tf.argmax(y_conv,1), tf.argmax(y_,1))
accuracy = tf.reduce_mean(tf.cast(correct_prediction, tf.float32))
sess.run(tf.initialize_all_variables())
```
実行

実行
```
for i in range(20000):
  batch = mnist.train.next_batch(50)
  if i%100 == 0:
    train_accuracy = accuracy.eval(feed_dict={x:batch[0], y_: batch[1], keep_prob: 1.0})
    print("step %d, training accuracy %g"%(i, train_accuracy))
  train_step.run(feed_dict={x: batch[0], y_: batch[1], keep_prob: 0.5})

print("test accuracy %g"%accuracy.eval(feed_dict={
    x: mnist.test.images, y_: mnist.test.labels, keep_prob: 1.0}))
```
>step 0, training accuracy 0.12
step 100, training accuracy 0.8
step 200, training accuracy 0.88
step 300, training accuracy 0.84
step 400, training accuracy 0.96
・・・
step 19900, training accuracy 1
test accuracy 0.9914

２万回やるので、結構時間がかかります。数時間はかかるみたいです
精度99%

```統合ver.py

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


import tensorflow as tf
sess = tf.InteractiveSession()

x = tf.placeholder(tf.float32, shape=[None, 784])
y_ = tf.placeholder(tf.float32, shape=[None, 10])

w1=tf.Variable(tf.truncated_normal([5,5,1,32],stddev=0.1))
b1=tf.Variable(0.1,[32])
x_image = tf.reshape(x,[-1,28,28,1])

h_conv1=tf.nn.relu(tf.nn.conv2d(x_image, w1, strides=[1, 1, 1, 1], padding='SAME')+b1)
h_pool1 = tf.nn.max_pool(h_conv1, ksize=[1, 2, 2, 1],strides=[1, 2, 2, 1], padding='SAME')

w2=tf.Variable(tf.truncated_normal([5,5,32,64],stddev=0.1))
b2=tf.Variable(0.1,[64])

h_conv2 =tf.nn.relu(tf.nn.conv2d(h_pool1, w2, strides=[1, 1, 1, 1], padding='SAME')+b2)
h_pool2 = tf.nn.max_pool(h_conv2, ksize=[1, 2, 2, 1],strides=[1, 2, 2, 1], padding='SAME')

W_fc1=tf.Variable(tf.truncated_normal([7 * 7 * 64, 1024],stddev=0.1))
b_fc1=tf.Variable(0.1,[1024])

h_pool2_flat = tf.reshape(h_pool2, [-1, 7*7*64])
h_fc1 = tf.nn.relu(tf.matmul(h_pool2_flat, W_fc1) + b_fc1)

keep_prob = tf.placeholder(tf.float32)
h_fc1_drop = tf.nn.dropout(h_fc1, keep_prob)

W_fc2=tf.Variable(tf.truncated_normal([1024, 10],stddev=0.1))
b_fc2=tf.Variable(0.1,[10])

y_conv=tf.nn.softmax(tf.matmul(h_fc1_drop, W_fc2) + b_fc2)

cross_entropy = tf.reduce_mean(-tf.reduce_sum(y_ * tf.log(y_conv), reduction_indices=[1]))
train_step = tf.train.AdamOptimizer(1e-4).minimize(cross_entropy)
correct_prediction = tf.equal(tf.argmax(y_conv,1), tf.argmax(y_,1))
accuracy = tf.reduce_mean(tf.cast(correct_prediction, tf.float32))
sess.run(tf.initialize_all_variables())

for i in range(10000):
  batch = mnist.train.next_batch(50)
  if i%100 == 0:
    train_accuracy = accuracy.eval(feed_dict={x:batch[0], y_: batch[1], keep_prob: 1.0})
    print("step %d, training accuracy %g"%(i, train_accuracy))
  train_step.run(feed_dict={x: batch[0], y_: batch[1], keep_prob: 0.5})

print("test accuracy %g"%accuracy.eval(feed_dict={
    x: mnist.test.images, y_: mnist.test.labels, keep_prob: 1.0}))
```