DeepLearningを勉強するために、VirtualBox上のUbuntuで、日本発(Chainer)とGoogle発(TensorFlow)のフレームワークを動かすまで

#はじめに
DeepLearningの書籍をいろいろと読んではみたものの、理論がだいぶ難しい...
とりあえず動かしてみようと思い、手元で環境を整えてみることにしました。

##やりたいこと
文章の分類、画像の分類など、ざっくりと機械学習を体験したい。

##Python
日頃はPerlやPHPなどを扱うことが多いのですが、調べてみると機械学習関連は圧倒的にPythonのドキュメントが多く、理由は、統計や機械学習などに関するライブラリが充実しているとのこと。(数値計算->NumPy、SciPy / データフレーム->pandas / 可視化->matplotlib)
統計用の言語としてRが選択肢として挙げられることもあったり、他の言語で実装もできそうでしたが、とりあえず一番ドキュメントが需実していそうなPythonを選択しました。

##2系or３系
Pythonは2系と3系が存在していて、既存のライブラリは豊富なのは2系のようでしたが、サポートが2020年までとのことで、今回は3系で実施しました。
（MeCabとPython3を組みあわせると、MecabのparseToNodeの動作に難があったり、いくつか注意しなければならないこともあります。
https://shogo82148.github.io/blog/2015/12/20/mecab-in-python3-final/
)

##Ubuntu
使用するフレームワークによっては、環境によって、エラーが頻発するなど報告があり、あまり環境を用意するのに時間をかけたくなかったので、
今回はMacのVirtualBox上にUbuntuをインストールし、まっさらな状態でPythonを動かすところから準備してみました。

##ChainerとTensorFlow

| 名称 | 言語 | 開発 |
|:-----------|------------:|:------------:|
| Theano | Python | モントリオール大学 |
| Pylearn2 | Python | モントリオール大学 |
| Caffe | C++,Python | カリフォルニア大学バークレー校 |
| Chainer | Python | PFN |
| TensorFlow | C++,Python | Google |

使用するフレームワークは、選択肢がありすぎて迷いましたが、
「chainerとtensorflow、結局どっちがいいんだろう。（軽い書評も含む）」
http://saleslog.hatenadiary.jp/entry/2016/10/01/200000
などを参考に、ドキュメントの豊富さや、インストールのしやすさから
日本発->Chainerと、Google発->TensorFlow の２つのフレームワークを試してみることにしました。


##動作環境
>Mac OS X El Capitan
>VirtualBox  5.0.30
>Vagrant 1.8.1
>Python 3.5.2 :: Anaconda 4.2.0 (64-bit)

#A.インストール方法(ローカル環境の構築)
##1. VirtualBoxのインストール
https://www.virtualbox.org/wiki/Downloads 

##2. Vagrantのインストール
https://www.vagrantup.com/downloads.html 

##3.使用するboxの確認
http://www.vagrantbox.es/
ここではversionを確認するだけ。4の手順で追加するboxをここで確認する。

>今回は現時点でのUbuntuの最新を使用
>Ubuntu 15.04 (based on amd64 server iso file) [source]	VirtualBox	Copy https://github.com/kraksoft/vagrant-box-ubuntu/releases/download/15.04/ubuntu-15.04-amd64.box


##4.box追加
```
$ vagrant box add ubuntu-15.04 https://github.com/kraksoft/vagrant-box-ubuntu/releases/download/15.04/ubuntu-15.04-amd64.box
```

##5.インスタンス作成
```bash
#vagrant initすればその場所がcurrentになるので、ディレクトリはどこでも良い。
$ mkdir ~/Vagrant_Test/ubuntu-15.04
$ cd ~/Vagrant_Test/ubuntu-15.04
$ vagrant init ubuntu-15.04
$ vim Vagrantfile でコメントアウト (ssh-client使いたい人だけ)
 -#config.vm.network "private_network", ip: "192.168.33.10"
 +config.vm.network "private_network", ip: "192.168.33.10" 
$ vagrant up
```

##6.インスタンスへ接続
```bash
$ vagrant ssh
Welcome to Ubuntu 15.04
(/home/vagrant# cat /etc/issue
Ubuntu 15.04 \n \l)
```

##7.Git他必要なものをインストール
```bash
$ sudo apt-get update
$ sudo apt-get install git
$ sudo apt-get install vim
$ sudo apt-get install openssh-server
```

##9.bashに登録
```
export LANG=ja_JP.UTF-8
env |grep LANG
LANG=ja_JP.UTF-8
```

#B.インストール方法(Pythonのインストール + mecab)
##1.pyenvをインストール
```bash
  $ git clone https://github.com/yyuu/pyenv.git ~/.pyenv
  $ echo 'export PYENV_ROOT="$HOME/.pyenv"' >> ~/.bashrc
  $ echo 'export PATH="$PYENV_ROOT/bin:$PATH"' >> ~/.bashrc
  $ echo 'eval "$(pyenv init -)"' >> ~/.bashrc
  $ source ~/.bashrc
```

##2.anacondaをインストール.
Anacondaはデータサイエンスに特化したプラットフォームのような位置づけで、
Python含めた主要ライブラリをオールインワンでインストールできます。
>ANACONDA PACKAGE LIST
>https://docs.continuum.io/anaconda/pkg-docs
>(必要なものがインストールされるので、自身で行うインストール作業が最低限で済む）

```bash
$ pyenv install -l | grep ana
# 最新版を確認。anaconda3-4.2.0(3系を選ぶ)
$ pyenv install anaconda3-4.2.0
$ pyenv rehash
$ pyenv global anaconda3-4.2.0
# anacondaをpathに通す
$ echo 'export PATH="$PYENV_ROOT/versions/anaconda3-4.2.0/bin/:$PATH"' >> ~/.bashrc
$ source ~/.bashrc
$ conda update conda
```

##3.mecabのインストール
mecabは作るものによっては、必須ではないが、日本語の文章を扱う場合に必要になるのでここで入れておく。
```bash
$ apt-get install libmecab-dev
$ apt-get install mecab mecab-ipadic-utf8
```

```bash
(mecab試す)
#確認
$ mecab --version
$ mecab
すもももももももものうち

すもも	名詞,一般,*,*,*,*,すもも,スモモ,スモモ
も	助詞,係助詞,*,*,*,*,も,モ,モ
もも	名詞,一般,*,*,*,*,もも,モモ,モモ
も	助詞,係助詞,*,*,*,*,も,モ,モ
もも	名詞,一般,*,*,*,*,もも,モモ,モモ
の	助詞,連体化,*,*,*,*,の,ノ,ノ
うち	名詞,非自立,副詞可能,*,*,*,うち,ウチ,ウチ
EOS
```

##4.mecab-pythonをinstall
```bash
#pipをupgradeしておく
$ pip install --upgrade pip
$ pip install mecab-python3
```

#B.インストール方法(chainerとgensim)
chainerはディープラーニングで使用するフレームワーク。
gensimとは、トピックモデルを扱うことのできるライブラリで、文章を扱う場合に、使うことがあるので、一緒に入れておく。
>(トピックモデルとは）文書で用いられる単語には、それぞれの相関関係があり、それらを統計的に導き、話題を発見する手法のこと。LDAなどが有名。

##1.chainerとgensimのインストール
```bash
$ pip install chainer --no-cache
$ pip install gensim --no-cache
```

#coffee break
ここまでで、chainerはインストールできたので、chainerのサンプルコードを試してみます。
chainerの本家にMNISTデータセットを使ったサンプルコードがあるのでこれを使います。
(MNISTデータとは、0-9までの手書きの数字70000点を入れたデータのこと)
![mnist](http://vision.is.tohoku.ac.jp/~kyamagu/en/teaching/undergrad-seminar-2015/mnist.png "mnist")

```
$ git clone https://github.com/pfnet/chainer.git
$ cd /chainer/examples/mnist

#実行(デフォルトのepochは20だが時間がかかるので、5に減らす)
$ python train_mnist.py --epoch 5
```

```
epoch       main/loss   validation/main/loss  main/accuracy  validation/main/accuracy  elapsed_time
1           0.190057    0.103864              0.94315        0.968                     36.7214
2           0.0739945   0.0819866             0.976417       0.9735                    76.7412
3           0.047808    0.0752293             0.984983       0.9787                    114.994
4           0.0361402   0.0776405             0.987867       0.9787                    156.867
5           0.0269419   0.0959652             0.990933       0.9751                    204.872
```

```
main/loss -> 答えとの差の大きさ
mian/accuracy -> 正解率
正解率は90%を超えている
```


#C.インストール方法(TensorFlow)

##1.「tensorflow」環境の作成
```
$ conda create -n tensorflow python=3.5
```

##2.環境をアクティベート
```
$ source activate tensorflow
```

##3.TensorFlowのCPUバージョンをインストール
```
$ export TF_BINARY_URL=https://storage.googleapis.com/tensorflow/linux/cpu/tensorflow-0.9.0-cp35-cp35m-linux_x86_64.whl
$ pip install --ignore-installed --upgrade $TF_BINARY_URL
```

##4.動作確認

```python:test2.py
import tensorflow as tf
hello = tf.constant('Hello, TensorFlow!')
sess = tf.Session()
print(sess.run(hello))
 
a = tf.constant(10)
b = tf.constant(32)
print(sess.run(a + b))
```

```
(tensorflow) python test2.py
>>Hello, TensorFlow!
>>42
```

##4.1TFLearn他必要なライブラリも入れておく
TFLearnはTensorFlow1をScikit-learnのように使えるライブラリ。文章を扱う場合、便利なので入れておく。

```
(tensorflow) pip install tflearn
(tensorflow) pip install scikit-learn
(tensorflow) pip install scipy
(tensorflow) pip install pandas
```

##5.使い終わったら、ディアクティベート
```
(tensorflow) source deactivate
```
##6.再度アクティベート
```
$ source activate tensorflow
```
#coffee break2
ここまでで、TensorFlowの動作環境が準備できたので、
TensorFlow自体に含まれるチュートリアルを実行したいと思います。

##チュートリアルのために、cloneしてくる
```
git clone -b r0.11 https://github.com/tensorflow/tensorflow.git
```

##MNISTの学習を試す
```
cd tensorflow/tensorflow/examples/tutorials/mnist
```
##一部修正
```
-from tensorflow.g3doc.tutorials.mnist import input_data
-from tensorflow.g3doc.tutorials.mnist import mnist
+import input_data
+import mnist
```
##実行
```
python fully_connected_feed.py
```

```
Successfully downloaded train-images-idx3-ubyte.gz 9912422 bytes.
Extracting data/train-images-idx3-ubyte.gz
Successfully downloaded train-labels-idx1-ubyte.gz 28881 bytes.
Extracting data/train-labels-idx1-ubyte.gz
Successfully downloaded t10k-images-idx3-ubyte.gz 1648877 bytes.
Extracting data/t10k-images-idx3-ubyte.gz
Successfully downloaded t10k-labels-idx1-ubyte.gz 4542 bytes.
Extracting data/t10k-labels-idx1-ubyte.gz
Step 0: loss = 2.31 (0.038 sec)
Step 100: loss = 2.14 (0.006 sec)
Step 200: loss = 1.83 (0.005 sec)
Step 300: loss = 1.52 (0.006 sec)
Step 400: loss = 1.27 (0.006 sec)
Step 500: loss = 0.89 (0.006 sec)
Step 600: loss = 1.03 (0.006 sec)
Step 700: loss = 0.73 (0.006 sec)
Step 800: loss = 0.44 (0.005 sec)
Step 900: loss = 0.61 (0.006 sec)
Training Data Eval:
  Num examples: 55000  Num correct: 47202  Precision @ 1: 0.8582
Validation Data Eval:
  Num examples: 5000  Num correct: 4348  Precision @ 1: 0.8696
Test Data Eval:
  Num examples: 10000  Num correct: 8639  Precision @ 1: 0.8639
Step 1000: loss = 0.43 (0.012 sec)
Step 1100: loss = 0.52 (0.101 sec)
Step 1200: loss = 0.45 (0.005 sec)
Step 1300: loss = 0.34 (0.005 sec)
Step 1400: loss = 0.37 (0.005 sec)
Step 1500: loss = 0.41 (0.005 sec)
Step 1600: loss = 0.43 (0.005 sec)
Step 1700: loss = 0.37 (0.007 sec)
Step 1800: loss = 0.24 (0.006 sec)
Step 1900: loss = 0.30 (0.006 sec)
```

##次に、画像の分類のサンプルも試してみる
本来は自分で画像認識用のデータをかき集め、分類をしなければならないのですが、
事前学習済のデータが公開しているので、そのデータを使います。
(classify_image.pyが最初に実行された時、 tensorflow.org から訓練済モデルをダウンロードしてくる)

```bash
$ cd tensorflow/models/image/imagenet
```

##パンダの画像の分類結果
引数なしで実行すると、パンダの画像を照らし合わせた結果を返します。
![panda](https://www.tensorflow.org/versions/master/images/cropped_panda.jpg "panda")

```bash
$ python classify_image.py
```
##結果
パンダの確率が89%で、インドリ?である確率が0.00%ということで、ほぼパンダという結果が返ってきます。

```
giant panda, panda, panda bear, coon bear, Ailuropoda melanoleuca (score = 0.89233)
indri, indris, Indri indri, Indri brevicaudatus (score = 0.00859)
lesser panda, red panda, panda, bear cat, cat bear, Ailurus fulgens (score = 0.00264)
custard apple (score = 0.00141)
earthstar (score = 0.00107)
```

##パンダ以外も..
自分で用意した画像も引数で渡すことができるので、いろいろ遊べそう。
下記は自分が富士のルマン6hで撮影した写真ですが、ちゃんとracing carが69%として認識されてます。このle mansの車のフォルムが、sports carよりもgo-kartの方に近いと認識されているのが個人的に胸熱でした^^。

![car.JPG](https://qiita-image-store.s3.amazonaws.com/0/43766/2fb997ed-c72b-9b6d-4b6b-2b9eeac0b603.jpeg)


```
python classify_image.py --image test.jpg
W tensorflow/core/framework/op_def_util.cc:332] Op BatchNormWithGlobalNormalization is deprecated. It will cease to work in GraphDef version 9. Use tf.nn.batch_normalization().
racer, race car, racing car (score = 0.69429)
bobsled, bobsleigh, bob (score = 0.07586)
go-kart (score = 0.05916)
sports car, sport car (score = 0.02232)
bannister, banister, balustrade, balusters, handrail (score = 0.00569)
```



#おしまい

理論からやっていると、結構詰まりそうなDeepLearningですが、
こういう面白い記事を参考にすると、モチベーションがぐっと上がりそうな予感でした^^


>TensorFlowによるももクロメンバー顔認識（前編）
http://qiita.com/kenmaz/items/4b60ea00b159b3e00100

>自然言語処理の最新手法"word2vec"で艦これ加賀さんから乳を引いてみる
http://antibayesian.hateblo.jp/entry/2014/03/10/001532

>ディープラーニングでおそ松さんの六つ子は見分けられるのか 〜実施編〜
http://bohemia.hatenablog.com/entry/2015/11/22/174603

>【Python】自然言語処理でラーメン屋を分類してみる
http://qiita.com/n_uchida/items/87d717961bd0c34e7a64

>TensorFlowで食神の定食画像を分類する実験
http://daiiz.hatenablog.com/entry/2016/02/18/130436

>Chainerを使ってウォーリーを探せをしようと思ったけど、結果全然至らずな話
http://qiita.com/shunter1112/items/8d0b1ec0a85a32655b6d

>【エヴァンゲリオン】アスカっぽいセリフをDeepLearningで自動生成してみる
http://qiita.com/S346/items/24e875e3c5ac58f55810

>Chainer で競馬予想をしてみる
http://qiita.com/takecian/items/5f2334bea701a70cc06a

>単純なRNNを使ってズンドコキヨシを学習する
http://qiita.com/knok/items/3077230a9dc6b7979173

>LSTMを使ってズンドコキヨシを学習する
http://qiita.com/dsanno/items/3b8e75c91cee799877a4

>ChainerでオセロのAIをつくってみる　～前編～
http://qiita.com/kanlkan/items/6bff417519ed7d5ce4da

>「とぼけないでください」「ん！！ です です です！」第二回Google TensorFlow 勉強会が面白過ぎた」
http://robotstart.info/2016/02/23/report-tensorflow2.html