何も買わずに試すディープラーニング

# はじめに
　相変わらずAIが流行ってますね。その実態は機械学習、特にディープラーニングによるパターン認識やその逆変換による生成ですが、膨大な数の神経細胞を模しているニューラルネットワークであるため、かなりのコンピューティングパワーが必要です。
　僕も今頃になって試してみようと思うのですが、運悪く自宅の自作PC(古ぼけたSandy Bridge)は故障して電源が入らなくなってしまい、使えるのはモバイルなSurface GoとMacBookのみです。最新GPUも欲しいですが、お金と時間と作業場所(部屋片付けないと…)が必要です。
 というわけで、いまどきならモノを買わなくても、クラウド上でお安くお手軽に試せるはずだと調べてみると、[Google Cloud Platform](https://console.cloud.google.com/)や[Google Colaboratory](https://colab.research.google.com/) が見つかりました。 
メジャーなTensorFlowを開発しているGoogleのクラウドですから、相性も良いのではないでしょうか。
<img src="https://qiita-image-store.s3.amazonaws.com/0/185735/9ec79263-9101-b56a-c740-dd572e0d456a.jpeg" width="50%" />
レッツ、喫茶店でディープラーニング！

## Google Cloud Platform (Cloud Shell) と Google Colaboratory
Googleのクラウドで手軽に試す環境としては、Google Cloud Platformの他にGoogle Colaboratory というものがあるようです。

### [「Google Cloud Platform」](https://console.cloud.google.com/) [Cloud Shell](https://cloud.google.com/shell/)
  * Dockerコンテナが自動的に起動し、そこにWebブラウザ(Chrome)上からターミナル接続をしてくれるお手軽環境。
  * デフォルトではDebian GNU/Linux。
  * Java, Go, Python, Node.js, PHP, Ruby(Railsも) Google Cloud SDK 等がプリインストールされている。
  * ログインしているGoogleアカウントに紐付いたアカウントで自動ログインされる。
  * ログアウトしてもストレージの内容は残り続ける。(5GBの永続ディスクストレージ付き)
  * 無料!!
  * その他詳細: https://cloud.google.com/shell/docs/features?hl=ja

### [「Google Colaboratory」](https://colab.research.google.com/)
  * 説明文の合間にその場で実行可能なコードが織り交ぜられるブログみたいなものが作れる環境で、教育・研修にぴったりです。
  * 参考: [【スマホOK/実行しながら学ぶ】東大松尾研のデータサイエンティスト育成/ Deep Learning基礎講座を自習する](https://qiita.com/tomo_makes/items/5d6f5860bb793e3b354a) 
に従って演習のノートを開いてみると、その素晴らしさが分かるかと思います。Pythonの基礎から実際に実行しながら勉強が進められます。
  * なお僕の環境では最初「The user has exceeded their Drive storage quota」エラーで動かなかったのですが、Google Driveの容量不足が原因でした。しかたないので、100GBを年額2500円で契約したところ動作しました。

### どっちがいいの?
入門者としては後者の松尾研テキストを読みインラインのコード実行しつつ勉強し、前者の環境で本気の応用に向けて検証していきたいと思います。

ということで、以下はGoogle Cloud Platform上でKeras/TensorFlowを試してみたメモです。

----
## MNISTの手書き数字認識をkeras/TensorFlowで実行してみる
### TensorFlowとKerasって? MNISTって?
* [TensorFlow](https://www.tensorflow.org/?hl=ja) 
  * 機械学習で最大シェアを持つGoogle製のオープンソース ソフトウェア ライブラリです。
* [Keras](https://keras.io/ja/)
  * Pythonで書かれた，TensorFlowなどの上で実行可能な高水準のニューラルネットワークライブラリです。TensorFlowのラッパーのようなもので、TensorFlowだけだと記述が大変なコードを比較的シンプルに記述できます。
* MNIST(Mixed National Institute of Standards and Technology database)
  * 手書き数字画像60,000枚と、テスト画像10,000枚を集めた、画像データセットです。機械学習の画像認識の学習において、初心者でも使いやすく、サンプルデータとしてもよく利用されているそうです。([機械学習で便利な画像データセット「MNIST」を丁寧に解説！](https://udemy.benesse.co.jp/ai/mnist.html)より)

### Google Cloud Shellの画面を開く
* [Cloud Shell](https://cloud.google.com/shell/) をGoogle Chromeで開き、「Cloud Shellを起動する」ボタンを押す。(Googleアカウントでログインする必要があります)
* 画面下に黒い背景のターミナル(TeraTerm的な…)がひらいて、プロンプトが表示され!たらOK。なお右端から2番目のアイコン「新しいウィンドウで開く」を押すと大きく画面を使えます。

<img src="https://qiita-image-store.s3.amazonaws.com/0/185735/99e2f5d3-bf1b-0dc8-d4a8-e66a66cd92f0.png" width="50%"/>

* 【小言】
  * ブラウザのショートカットにとられてしまうせいで、WindowsだとCtrl-NやCtrl-Tなどがシェルに入力できず、emacs使うときなどけっこうストレス溜まりますが、調べた範囲ではChromeのショートカットキーは変更出来ないようです… <br/>→ いちおう左端のアイコン「キーの組合せを送信」でCtrl-N等を送信できます。また同じメニューから「Chromeの拡張機能をインストール」を選ぶとSSH for Google Cloud Platformという拡張機能がインストールでき、これを使うと好きなキーが入力できるようです。

### Kerasをインストール
* Cloud ShellのデフォルトイメージにはTensorFlowはプリインストールされていますが、kerasは入っていないのでインストール。(pipではなくpip3であることを注意!)

```sh
$ pip3 install keras
```

### MNISTの数字を認識するPythonサンプルソースをダウンロード
* サンプルをダウンロード(GitHubからKerasソースまるごとクローン!)

```sh
$ git clone https://github.com/keras-team/keras.git
```
* この[Kerasソースの「examples」フォルダ](https://github.com/keras-team/keras/tree/master/examples)には、今回試すMNISTの数字を認識する「mnist_なんとか.py」というサンプルコードがいくつも入っていて、これを読むだけで勉強になります。

### ダウンロードしたサンプルをいきなり実行
* ダウンロードしたソースに含まれるサンプルのうち[「mnist_mlp.py」](https://github.com/keras-team/keras/blob/master/examples/mnist_mlp.py)を実行してみます。
* pythonではなくpython3で実行しないとエラーになるので注意!

```sh
$ cd keras/examples
$ python3 mnist_mlp.py
```

* 成功すれば以下のような出力がされます。

```
Using TensorFlow backend.
60000 train samples
10000 test samples
_________________________________________________________________
Layer (type)                 Output Shape              Param #
=================================================================
dense_1 (Dense)              (None, 512)               401920
_________________________________________________________________
dropout_1 (Dropout)          (None, 512)               0
_________________________________________________________________
dense_2 (Dense)              (None, 512)               262656
_________________________________________________________________
dropout_2 (Dropout)          (None, 512)               0
_________________________________________________________________
dense_3 (Dense)              (None, 10)                5130
=================================================================
Total params: 669,706
Trainable params: 669,706
Non-trainable params: 0
_________________________________________________________________
Train on 60000 samples, validate on 10000 samples
Epoch 1/20
60000/60000 [==============================] - 13s 214us/step - loss: 0.2422 - acc: 0.9248 - val_loss: 0.1048 - val_acc: 0.9655
〜中略〜
Epoch 20/20
60000/60000 [==============================] - 25s 420us/step - loss: 0.0188 - acc: 0.9954 - val_loss: 0.1118 - val_acc: 0.9831
Test loss: 0.11178437210872762
Test accuracy: 0.9831
```
* 何のことかさっぱり分からないので、[kerasのmnistのサンプルを読んでみる](https://qiita.com/ash8h/items/29e24fc617b832fba136) を読んでみましょう。
* このサンプルコードの中では、MNISTの手書き数字サンプルを教師データと共に読み込んで繰り返し学習し、その結果のニューロンの結びつきを使って手書き数字サンプルを認識させているようです。
* 最後の「Test accuracy: 0.9831」が認識精度。つまり学習結果を使って書き数字を認識した結果、98.31%の確率で正解したということでしょう。
* また、20回学習する行の最後に毎回ついてる「val_acc: 0.9831」というのがその回数での精度で、1回目では0.9655だったのが、20回目には0.9831と精度が向上していますね。

### ディープラーニングじゃない!?
* 先ほど実行したサンプル(mnist_mlp.py)はMLP(多層パーセプトロン。バックプロパゲーション利用)というモデルを使っていて、1980年代の第二次AIブーム時に人気があった手法です。
* では第三次AIブーム(2000年代)から流行っている「ディープラーニング」を試すには? 同じexampleフォルダ内の[「mnist_cnn.py」](https://github.com/keras-team/keras/blob/master/examples/mnist_cnn.py)を実行すればいいんじゃないでしょうか。
* サンプルのファイル名にある「CNN」はConvolutional Neural Networkの略で日本語だと「畳み込みニューラルネットワーク」といいます。MLPより遙かに多数(深い=ディープ)のニューラルネットワーク中間層を持てることで、学習(ラーニング)が高性能になったものですね。(ざっくり)

```sh
$ cd keras/examples
$ python3 mnist_cnn.py
```

実際試してみると、1回の学習に時間がかかりますが、少ない回数ではMLPより高い認識率となっているのが分かります。

# おわりに
今回はKerasのサンプルを実行するだけでしたが、Cloud Shell上でかなり手軽に試せることは分かりました。ただ、これはDockrコンテナ上で普通のCPUを使って処理しているだけなので、とても遅いです。
次は大量のGPUを擁する[CLOUD MACHINE LEARNING ENGINE](https://cloud.google.com/ml-engine/?hl=ja)を使ってみたいですね。