TensorFlowと機械学習の勉強会 #2

## はじめに

※このスライドは、「ML初心者が、初心者におくる勉強会」のために用意しております。

[勉強会#1](http://qiita.com/mochizukikotaro/items/5258b4857fa6a78f9ed5) では、TensorFlowにおける、`Variable` や　`constant` についてご紹介しました。

今回は、MNISTの概要と、`placeholder` をご紹介したいと思います。


----
## MNIST


![mnist1.png](https://qiita-image-store.s3.amazonaws.com/0/45822/ef08964c-5d6d-183d-2bd8-ede424fba611.png)


----

## 数理的に書くと

784要素のベクトルから、10要素のベクトルへ変換。

```math
\begin{bmatrix}
0 \\
1 \\
\vdots \\
1 \\
0 \\
0
\end{bmatrix}
\xrightarrow{ここの変換を考える}
\begin{bmatrix}
0 \\
\vdots \\
1 \\
0
\end{bmatrix}
```

----

## 行列の計算です

```math
\left(	
\begin{array}{cc}
0 \\
\vdots \\
1 \\
0
\end{array}
\right)
\cdot
\left(
\begin{array}{c}
w_1 & \ldots & w_{1,m} \\
\vdots \\
w_{n} & \ldots & w_{n,m}
\end{array}
\right)
+
\left(
\begin{array}{c}
b_1 \\
\vdots \\
b_{n}
\end{array}
\right)
=
\left(
\begin{array}{l}
0 \\
\vdots \\
1 \\
0
\end{array}
\right)
```

ちょっと適当ですが、上の $W$ と $b$ を求めるイメージです。

----
## ここで注意 :skull: 

:skull: これまでは、記載しやすさのため縦ベクトルを使っていましたが、実際の計算では横ベクトルの扱いになります。

ですので、今後、入力ベクトルや出力ベクトルは、（可能な限り）横ベクトルでの記載をします。

----

## 簡単な問題

以下のように、4つのトレーニングデータがあります。変換器となる $W$ を考えてください。

```rb
(1,0,1,0) => (1,0)
(1,1,0,0) => (1,0)
(0,0,1,1) => (0,1)
(0,1,0,1) => (0,1)
```

----

## 解法のイメージ

```math
\begin{bmatrix}
1&0&1&0\\
1&1&0&0\\
0&0&1&1\\
0&1&0&1\\
\end{bmatrix}
\cdot
\begin{bmatrix}
w_{1,1}&w_{1,2}\\
w_{2,1}&w_{2,2}\\
w_{3,1}&w_{3,2}\\
w_{4,1}&w_{4,2}\\
\end{bmatrix}
+
\begin{bmatrix}
b_{1}&b_{2}
\end{bmatrix}
=
\begin{bmatrix}
1&0\\
1&0\\
0&1\\
0&1
\end{bmatrix}
```

----
## :earth_africa: 

----
## トレーニングデータ

```py:
train_x = np.array([
    [1, 0, 1, 0],
    [1, 1, 0, 0],
    [0, 0, 1, 1],
    [0, 1, 0, 1],
    ])

train_y = np.array([
    [1,0],
    [1,0],
    [0,1],
    [0,1],
    ])
```

----
## Variableを用意

```py
W = tf.Variable(tf.zeros([4, 2]))
b = tf.Variable(tf.zeros([2]))
```

初期値として、要素が全て0となるような行列を用意してみます。

```py:初期値の中身
>>> sess.run(W)
array([[ 0.,  0.],
       [ 0.,  0.],
       [ 0.,  0.],
       [ 0.,  0.]], dtype=float32)
>>> sess.run(b)
array([ 0.,  0.], dtype=float32)
```

----
## placeholderを用意

```py
x = tf.placeholder("float", [None, 4])
y_ = tf.placeholder("float", [None, 2])
```

ここには、後々、トレーニングデータを入れることになります。

----
## モデルをつくる

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

ひとまず $softmax$ は無視しましょうか :man: 

----
## コードの全貌

```py:mnist_sample.py
# coding:utf-8
import tensorflow as tf
import numpy as np
from IPython import embed

train_x = np.array([
    [1, 0, 1, 0],
    [1, 1, 0, 0],
    [0, 0, 1, 1],
    [0, 1, 0, 1],
    ])

train_y = np.array([
    [1,0],
    [1,0],
    [0,1],
    [0,1],
    ])

x = tf.placeholder("float", [None, 4])
y_ = tf.placeholder("float", [None, 2])
W = tf.Variable(tf.zeros([4, 2]))
b = tf.Variable(tf.zeros([2]))

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

# 誤差関数
loss = tf.reduce_sum(tf.square(y_ - y))

# トレーニング方法は、勾配降下法を選択
train_step = tf.train.GradientDescentOptimizer(0.01).minimize(loss)

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

with tf.Session() as sess:
    sess.run(init)

    for step in range(1000):
        sess.run(train_step, feed_dict={x: train_x, y_: train_y})
        if step % 200 == 0:
            print 'Step: %s' % step
            print '  誤差: %s \n' % str(sess.run(loss, feed_dict={x: train_x, y_: train_y}))

    # 作られたWとbによる、最終的な計算結果
    print sess.run(y, feed_dict={x: train_x, y_: train_y})
    # embed()
```

gist:
https://gist.github.com/mochizukikotaro/33eb56cc678a8e4df8b009a28eda8c41

----
## placeholderへの代入方法

```py
sess.run(train_step, feed_dict={x: train_x, y_: train_y})
```

このように `feed_dict={}` を使って、複数のplaceholderに対して代入できます。

----
## 動かしてみる

```py
% python mnist_beginner_sample.py                                                                                                        (git)-[test]
Step: 0
  誤差: 1.9602

Step: 200
  誤差: 0.201254

Step: 400
  誤差: 0.0903492

Step: 600
  誤差: 0.0566829

Step: 800
  誤差: 0.0408867

[[ 0.93689609  0.06310388]
 [ 0.93689609  0.06310388]
 [ 0.06310388  0.93689609]
 [ 0.06310388  0.93689609]]
```

----
## Homework

- Write your code. :information_desk_person: 
- Change learning rate. :information_desk_person: 


#### Advance

- Use TensorBoard. :princess: 
- Talk about ML or TensorFlow or AmazonML. :japanese_ogre: