ゼロから始めるTensorFlow　1.何も知らない初心者が機械学習を始める

機械学習を勉強しているhibinoだよ

TensorFlowをしばらく触ってみたので、学んだことを記事にしてみようと思いました。
記事を書いている中の人はTensorFlow以外でpythonを使ったことがなく、まだ勉強開始から半年くらいなので甘いところも多々あると思いますが、よろしくお願いします。

本記事は、まどろっこしいことはなしにして、とにかく機械学習をやってみたい！という方向けです。
対象は、現在流行のまっただ中のDeepLearning、そのうちのCNNというものです。
最終的に読者の方が.jpgや.pngなどの画像データを読み込ませて、自由に好きな識別を行わせるところまで辿り着ければいいなと思います。
(つまり、何か適当な画像をプログラムにかけて、ディープラーニングくんが「この画像は○○だね！」と返してくれるところまで解説します)

ディープラーニングには種類が色々あり、TensorFlowでは他にもリカレントニューラルネットワーク(RNN)や、オートエンコーダなども使うことができますが、私は深層畳み込みニューラルネットワーク(CNN)を勉強しているので、本記事でもCNNを対象にして書いていきます。

まずここではTensorFlowの導入、サンプルの実行、任意画像の2種類識別ができるようになるところまで解説します。


#1.導入

導入方法は色々な方が書かれているので、自身の環境にあったものをqiita上の記事や、その他のサイトを参考にして導入してください。
一応私の行った方法も書いておきます。といっても公式に書いてあるコマンドをそのまま打つだけですが…

Ubuntu16.04ダウンロード
https://www.ubuntu.com/download/desktop


Ubuntuを導入した後に、Python上にTensorFlowをインストール。



TensorFlowインストールで参考にしたページ(TensorFlow公式)
https://www.tensorflow.org/versions/r0.12/get_started/os_setup.html#virtualenv-installation



ここで一つ、導入中に気づいたことを書いておきます。
python2系でなく、python3系にインストールした場合ですが、夏頃に試した時にはTensorFlowの機能の一つである学習過程を可視化してくれるツールTensorBoardが使えませんでした。
今も同じバグがあるかどうか分かりませんが、TensorBoardを使いたい方は、python2系を使うことをお勧めします。
pythonのバージョンは以下のコマンドで確認できます。

```
$ python -V
```

次にpipとdev,virtualenvをインストール
私は後でGPUモードとCPUモードを使い分けてTensorFlowを動かしたいなーと思って導入しただけなので、特別な理由がなければvirtualenvは必要ないです。

```
$ sudo apt-get install python-pip python-dev python-virtualenv
```

次にTensorFlowをインストールします。
virtualenvを使わない方は、1つ目、2つ目のコマンドは必要ありません。

```
$ virtualenv --system-site-packages ~/tensorflow_cpu
$ source ~/tensorflow_cpu/bin/activate
$ export TF_BINARY_URL=https://storage.googleapis.com/tensorflow/linux/cpu/tensorflow-0.12.0rc0-cp27-none-linux_x86_64.whl
$ sudo pip install --upgrade $TF_BINARY_URL
```


今後virtualenvを使う人は、TensorFlowを使う前に以下のコマンドを打ってください。

```
$ source ~/tensorflow_cpu/bin/activate
```


やめるときはこれ。

```
$ deactivate
```


これでTensorFlowがインストールできました。
確認は以下のコマンドで、インポートできれば成功です。


```
＄python
>> import tensorflow as tf
```




#2.mnistを学習させてみる

tensorflowをインポートできることを確認したら、まずは本当に学習ができるかどうか確かめたほうがよいでしょう。
TensorFlowの公式が、GitHubでプログラムを公開しているのでまずはそれを動かしてみることにしました。以下のコマンドでチュートリアルのプログラムを導入できます。
```
$ git clone https //github.com/tensorflow/tensorflow
```

以下のディレクトリに移動してください。
```
$ cd ./tensorflow/tensorflow/g3doc/tutorials/mnist
```

この中に、fully_connected_feed.pyというプログラムがあると思います。
これを試しに実行してみてください。

```
$ python fully_connected_feed.py 
Extracting data/train-images-idx3-ubyte.gz
Extracting data/train-labels-idx1-ubyte.gz
Extracting data/t10k-images-idx3-ubyte.gz
Extracting data/t10k-labels-idx1-ubyte.gz
Step 0: loss = 2.30 (0.048 sec)
Step 100: loss = 2.06 (0.005 sec)
Step 200: loss = 1.73 (0.006 sec)
Step 300: loss = 1.47 (0.007 sec)
…
```
このような出力が出てくれば成功です。

このプログラムはmnistという、28*28ピクセルの手書き文字を学習させるプログラムです。0~9までの数字の画像を入力して、最終的にこの画像はその数字ですか？という質問に答えさせるようなCNNを構築します。

何はともあれ、ここまで成功すればTensorFlowでオリジナルのプログラムを動かすことはできると思いますので、最後にTensorBoardを使えるかどうか確認しましょう。
このプログラムを実行したあと、同ディレクトリに./logdataというフォルダができていると思います。この中に以下のようなファイルがあると思います。

./logdata/events.out.tfevents.~~~

これがTensorBoardで表示するための情報が詰まっているファイルになります。
まずは、このテストプログラムの出力結果を表示してみましょう。以下のコマンドで実行できます。
```
$ tensorboard --logdir=./logdata/
```
すると、実行されるメッセージの中に以下のような出力があると思います。

```
Starting TensorBoard  on port 6006
(You can navigate to http://0.0.0.0:6006)
```

言われた通りに、このURLにアクセスするとTensorBoardが見えると思います。
指定ディレクトリに複数ログがある場合は最新のものを表示するようです。任意のものを表示したいときは、./logdataディレクトリに対象のデータを1つだけ置いておけばよいと思います。

![スクリーンショット 2016-12-14 17.25.03.png](https://qiita-image-store.s3.amazonaws.com/0/122929/fd8f8a33-3b90-8211-eeea-4a6fe5ed9d70.png)

TensorBoardは4つの項目に別れています。
EVENTSとHISTOGRAMSは、学習においてネットワークがどのように収束するかを、グラフで示してくれます。
GRAPHはネットワークの構造を視覚的に示してくれます。
IMAGESは、入力やプログラム内で指定したテンソルを画像化して表示してくれます。
fully_connected_feed.pyではEVENTSとGRAPHに出力があります。

余談ですが、TensorBoardで何かを表示させるためには、プログラム内で表示させたい場所(正解率や収束するまでの全結合層の状態など)を指定しなければなりませんが、この表示機能がけっこう便利です。
特にやっていて感心したのが、仮想環境で有効ということ。
最近のチュートリアル本をいくつか見ていたのですが、どれもpyplotを使って可視化していました。私の今の環境ではそれで問題ないのですが、たとえばDockerの仮想環境などではディスプレイ表示ができない都合でpyplotが使えません。
Mac環境でDockerを使っていたとき、ChromeなどでこのURLにアクセスして可視化結果を見ることができました。(もちろん、プログラム上でTensorBoardで結果表示するようにプログラムを書いておく必要はありますが)
便利。

需要があれば、Docker環境でTensorBoardを使う方法も書くかもしれないです(｀・ω・ ´)
設定したのが昔なので、方法思い出せなかったらごめんなさい…… (´・ω・｀)






#3.オリジナルの学習を行わせてみる

じゃあ、tensorflowでプログラムを書いてみよう！
…どうやって？
サンプルプログラムを読もう！fully_connected_feed.pyを一行づつ読めば……
なんだこのソースコード(真顔)


と、当時はこんな状態でした。
サンプルを一行づつ読んでいけばいけると思って死亡。そもそもTensorFlowもPythonもほとんど知らなかった私はわけも分からず断念。そもそも画像データを.gzというファイルからとってきているみたいでしたが、そこが何をしているのか今でも理解してないです...

このプログラムを動かせばmnistは学習できる。
でもこっちで.jpgや.pngなどの画像を用意して、あるいはグラフなんかのデータを読み込ませ、それを学習させたい。
というわけで、右も左も分からない自分は日本語でコメントの書かれたサンプルを探しました。
そして探し当てたのがこちら。



ディープラーニングで顔写真から巨乳かどうかを判別してみる (うまくいったか微妙)
http://qiita.com/summer4an/items/db0124eee8103c1d3b85


さらに、この方が元にしたプログラムがこちら。

kivantium活動日記 -TensorFlowでアニメゆるゆりの制作会社を識別する
http://kivantium.hateblo.jp/entry/2015/11/18/233834



というわけで、ありがたくソースコードを参考にさせて頂きました。
kivantiumさん、 summer4anさん、ありがとうございます。

まずは実行といきたいところですが、学習させるためのデータセットがない。だからひとまず集めようと思いましたが…あまり複雑なデータだと、学習できるかどうかなど、色々心配に。
なので、まずは.gzという訳の分からなかったファイルではなく、画像化されたmnistを学習させてみることにしました。
どこかに落ちてないかなーと探してみたところ、画像をGitHubで公開してくれている方が！

https://github.com/gskielian/JPG-PNG-to-MNIST-NN-Format

ありがたくgit cloneさせて頂いて、画像データを取得。
上記のGitでダウンロードしたtest-imagesとtraining-imagesというフォルダを、ゆるゆりプログラムと同じディレクトリにmnistというフォルダを作って入れておいてください。

それから画像のあるディレクトリとタグの一覧が記述された.txtファイルを作成するようなpythonプログラムを書きました。

```
./mnist/test-images/0/im6917.png 0
./mnist/test-images/0/im6935.png 0
./mnist/test-images/0/im6973.png 0
…
```
こんな感じで.txtファイルに画像ディレクトリとタグの一覧ができました。

ゆるゆり学習プログラムではtrain.txtに学習させたい画像データ、test.txtにテストに使いたい画像データ・タグの一覧を記述します。
つまりこのプログラムのCNNは、train.txtに書いてある画像とタグを見て、この画像は[0]なんだな、こっちは[1]か、次も[1]だな…といった風に、学習を行っていきます。
そして学習が終わった後に、test.txtに書いてある画像を見て「この画像は[0]だな！」という風に一つ一つに予想を行います。その結果と、正解のタグを比較して、どれだけ正解しているかの割合を最後に出力してくれます。

上記のプログラムなら、ゆるゆりというアニメの制作会社を識別するような2種類のタグ付けを行っておいて、この画像は[動画工房]だ、こっちは[TYOアニメーションズ]だなと見分けるわけです。


さて学習を行っていきましょう。
pythonでプログラムを実行すると、step0からstep99まで学習が行われて、どこかで

```
step x, training accuracy 1
```
と、表示されると思います。
0か1かを見分けるだけの簡単な学習なのですぐに収束すると思います。正解率が0.9以上にならない場合は、何度かやり直してみてください。
そして最後に未知の画像に対する正解率が表示されますが、こちらも、0.99程度の値になっていると思います。
念のため書いておくと、正解率1なら全部正解、正解率0.15なら15％正解という感じですね。


ちなみにこちらもtensorboardで実行結果を確認できます。

```
$ tensorboard --logdir=./logdata
```


##最後に


さてひとまず、ここまでで今回の記事は終わります。

さて、ここまででオリジナルの学習を行わせる用意は整いました。
現段階では、2種類のオリジナルな判別を行うネットワークができました。しかし、現実には3種類以上の判別を行わせるといったことも必要になってくると思います。
また、このプログラムはいったいどういうものなのか。どういう処理をしているのか。そもそもCNNとは何なのか。そういったことも簡単にでいいので知っておく必要があります。

というわけで、次回は3種類以上の識別と、学習を収束させるための方法。
いつ書いていくかは未定。書くかも未定。需要があれば、適当に書いていければなと思います。(書くとは言ってない)

以上、機械学習を勉強するhibinoでした