MaruLabo × JAWS-UG AI 資料 古川新

# この資料について

この記事は、2017/1/20に[MaruLaboとJAWS-UG AIの共催のイベント](https://jawsug-ai.connpass.com/event/46920/)の資料です。

私、古川新からは、MNISTの学習の可視化と実際にテストを行えるアプリのデモと、ソースコードの解説をさせていただきます。

この資料は[TensorFlow ハンズオン環境構築](http://qiita.com/pottava/items/2fb2572f7099d432ebd9)によるセットアップが終わっていることを想定しています。

## 自己紹介

古川新

- 東海大学 理学部1年
- MaruLabo管理者

# さて、本日はハンズオンですが、ソースコードは書かせません！

プログラムを書くのは簡単ですが、何が起きているのかを理解するのは難しいものがあります。

今日は「クラウドでのTensorFlowの動かし方」と「プログラムの雰囲気」を知る、そして「**実際に体験する**」ことを目的とします。
今日は、そのためのサンプルを用意しましたので、動かしてみましょう。

---

# サンプルアプリのインストール

```
# 依存パッケージ
# DeepLearning AMIの場合はすでにインストールされているのでインストール不要です
# scipy tornado futures Pillow

# ダウンロード
cd ~
wget https://github.com/ornew/mnist-visual/releases/download/v3.0.1/mnist-visualize-example_3.0.1.tar.gz

# 展開
tar zxvf mnist-visualize-example_3.0.1.tar.gz
cd ~/mnist-visualize-example_3.0.1/
```

---

## GPUインスタンスの場合

CPUインスタンスの場合はこのステップは不要です。

```
# GPU上での実行のためにCUDAをリンクします
sudo ldconfig /usr/local/cuda/lib64

# このアプリはTensorFlow v0.12用に作られていますが
# DeepLearning AMIにインストールされているのは
# v0.10なので、お手数ですが以下のパッチを当ててください
sed -i -e 's/summary\.scalar/scalar_summary/g' mnist/mnist.py
sed -i -e 's/summary\.merge_all/merge_all_summaries/g' train.py 
sed -i -e 's/summary\.FileWriter/train\.SummaryWriter/g' train.py
sed -i -e 's/global_variables_initializer/initialize_all_variables/g' train.py
sed -i -e 's/global_variables_initializer/initialize_all_variables/g' server.py
```

---

## CPUインスタンスの場合

TensorFlowをv0.12にアップデートします。

```
sudo su -
curl -kL https://bootstrap.pypa.io/get-pip.py | python
sudo pip install --upgrade tensorflow
exit
```

---

## サンプルサーバの起動

```
# 起動
sudo python server.py -p 80
```

---

# このアプリについて

このアプリは、TensorFlowチュートリアル「Deep MNIST for Experts」（[原文](https://www.tensorflow.org/versions/r0.11/tutorials/mnist/pros/)｜[翻訳](http://ornew.net/tensorflow-deep-mnist-for-experts)）のMNISTモデルの学習状況をブラウザで閲覧できるようにしたものです。

---

- サーバを起動したのち、インスタンスのIPアドレスにブラウザでアクセスしてください。
- Chrome,FireFoxで動作を確認しています。

ブラウザでアクセスしたら「訓練を開始する」というボタンを押してください。少し待っているとテスト結果が表示され始めます。

学習がどうやって進んでいくのかに注目して観察してみてください。

---

# テスト結果の見方

- 緑→テストで正解したもの
- 赤→テストで間違えたもの

![スクリーンショット 2017-01-16 13.59.17.2.png](https://qiita-image-store.s3.amazonaws.com/0/143108/cfab7938-0dcc-9395-119d-72aab9846faf.png)

- どの数字とどの数字を間違えやすいでしょうか。
- 間違いが正解に直ったり、逆に一度正解したものを間違えたり、なかなかうまくいかない文字が見えてくると思います。

--- 

## 参考：100ステップ目
![スクリーンショット 2017-01-16 13.59.17.png](https://qiita-image-store.s3.amazonaws.com/0/143108/70e2b2ac-2066-b514-3e23-6e543f1f6c66.png)

---

## 参考：1000ステップ目
![スクリーンショット 2017-01-16 13.59.27.png](https://qiita-image-store.s3.amazonaws.com/0/143108/6c41774e-bde1-3234-c3d1-4f6cc6f5abd9.png)

---

## 参考：20000ステップ目

![スクリーンショット 2017-01-16 15.34.28.png](https://qiita-image-store.s3.amazonaws.com/0/143108/4d0bef94-f465-5ba1-17a2-38b8dc76e1f0.png)

---

# 手書きテスト

実際に訓練で作ったモデルを試すことが出来ます。ステップを選択したら、枠線の中に数字を書いて評価してみてください。下部に結果と分布が表示されます[^1]

[^1]: この分布はソフトマックスで正規化して**いません**。これは、訓練によって中身がどう変わっているのかを直感的に確認することが、このサンプルの目的であるためです。意図的なものです。

![スクリーンショット 2017-01-18 23.11.38.png](https://qiita-image-store.s3.amazonaws.com/0/143108/ffebe823-0cd0-0ecd-cd90-9ea15481a37f.png)

同じ数字のまま、ステップだけを切り替えてみると、学習状況によって判定が変わっていくのが確認できます。

ちなみに、これが今日がハンズオンたる所以、ハンドライティングです（）

---

さて、「なんとなく精度が上がっている」のはわかったと思います。

もう少し数学的に、このことを確認してみましょう。

---

# TensorBoardの起動

```
tensorboard --logdir ~/mnist-visualize-example_3.0.1/var --noinspect &
```

インスタンスのIPアドレスの6006番ポートにアクセスするとTensorBoardにアクセスできるようになります。

---

# クロスエントロピーの推移

精度が上がっていることをきちんと数値で示すと以下のようなグラフになります。これは、クロスエントロピーの値を学習ステップごとにプロットしたものです。

<img width="1008" alt="スクリーンショット 2017-01-16 19.00.18.png" src="https://qiita-image-store.s3.amazonaws.com/0/143108/76c1c54b-e07b-479e-b0c1-16a56ac910fc.png">

最初の100ステップで大幅に下がったのち、徐々に0に収束していくのが確認できます。

---

# 誤差の評価

このモデルでは、算出した確率分布と本当の答えが「どのくらい間違ってるのか」（これは、見方を変えれば「どのくらい正しいのか」を示す値でもあります）をクロスエントロピーという手法で定式化して計算しています。

```python
cross_entropy = tf.reduce_mean(
  tf.nn.softmax_cross_entropy_with_logits(
    inference, # 予測された値
    label))    # 正解の値
```

この値は、両者の値の誤差を示すもので、両者の値が近づくほどに小さくなります。つまり、この値が０に収束するということは、正解の値に近づいている＝精度が上がっているということを示します。

---

# 誤差をどうやって小さくしている？

```
tf.train.AdamOptimizer(1e-4).minimize(cross_entropy)
```

このプログラムは、「cross_entropyを最小化するようにグラフをADAMオプティマイザで最適化する」という意味です。

ディープラーニングでは、この誤差が小さくなるように確率的勾配降下法などを利用してモデルを訓練をしていくのが一般的です。このサンプルではADAMオプティマイザを利用しています。

TensorFlowでは、この一行ですべてやってくれます。学習率を調整したければ`1e-4`を変更するだけです。ADAMオプティマイザ以外の最適化アルゴリズムも組み込みで用意されています。理論を知らなくても、TensorFlowに組み込みのオプティマイザを使うことができますし、独自のものを自分で定義する能力もTensorFlowには用意されています。

いずれにせよ、TensorFlowでモデルを訓練するのは簡単です。

---

なぜその数字を間違えるのでしょう？

数字でない文字を入力した場合はどうなるでしょう？

人間でも判断が難しい数字をどうやったら判断できるようになるでしょう？

TensorFlowを書くのは簡単です。そりゃあもう簡単です。問題は、「何を書くのか」であり、「あなたが手を動かすかどうか」です。そこからが本当のハンズオンです。

このサンプルアプリの下部に載せてある、チュートリアルのコードはものの数十行です。チュートリアル「Deep MNIST for Experts」（[原文](https://www.tensorflow.org/versions/r0.11/tutorials/mnist/pros/)｜[翻訳](http://ornew.net/tensorflow-deep-mnist-for-experts)）を読んでみてください。

---

手を動かせば、TensorFlowはなんでもできる不思議な魔法の杖ではなく、ただの鉛筆でしかないことに気づくと思います。

そして、TensorFlowが素晴らしく効率の良い鉛筆であることにもきっと気づくでしょう。

自分で手を動かしましょう。今回のイベントがそのきっかけになってくれればと思います。