素人がAI部門に配属されてやること1ヶ月目(keras、cnn、mnist)

#はじめに、対象など
筆者は製造業の開発部門です。そしてAIでの画像検査を去年からやり始めました。
　それまでは全くプログラミングとかはしてなかったのですが、会社が「やっぱ時代はAIだよね」となり画像検査を始める際に、色々あってやることになりました。
　そんな「AIに詳しい人がいない」「自分もAIについて全然知らない」「でもやる気はあるし成果は出したい」って人がいたら参考になるかなと、AIでの画像検査部門に配属されてそこそこの成果出すまでの技術的な流れを説明します。nヶ月めにはこれを抑えておきたいよねって技術を6ヶ月目くらいまで書いていけたらなと思ってます。
　「IT系の会社じゃないからAI（プログラムも）詳しい人いない」、「なんか動かすための道筋が欲しい」って人が対象です。

#1ヶ月目の目標はどのあたりまで？
これはズバリ、成果として**「mnist(エムニスト)をCNNで判別するプログラムを書く」**を目標とします。
　プログラム以外の理解としての目標は、「機械学習とは？」「deep learningは他の機械学習と何が違うの？」「層を重ねるとは？」「CNNってなに？」あたりを説明できるようになる。くらいでしょうか。
　普段よく触っている人からすると、こんなの1日仕事だろ、レベル低すぎでは？と思われるかもしれませんが、きっとこれくらいで十分だと思います。「AIとは何か？」を説明する資料作りとかに時間を取られてると思うのでちょっとの成果さえあれば1ヶ月目は乗り切れます。

#1ヶ月目でやること
- python（Anaconda）のインストール
- （GPUマシンの場合）
- pythonにある程度慣れる
- モジュールをインストールする
- CNNでmnistを分類する
- 結果を出力する

の流れで解説していきます。メインの解説はQiitaの他の記事の紹介で済ませています。そちらの方が説明上手いので。[ここ](https://github.com/chun1182/start_ai_project)にプログラム全文が載せています。

#python(Anaconda)のインストール
　まずはこれからです。pythonのインストールから。pythonについてはあまり詳しくありませんが、非常に書きやすい言語です。自分は大学のときにc言語とpythonしか知らないのであまり比較はできませんが、少なくともc言語より何倍も書きやすいです。**大学の授業もpythonでやって欲しかった。**あの授業で「自分はプログラミングは無理だ・・・」と思った記憶があります。
　なぜpythonかというとAIを動かすためのモジュール（プログラム）がpythonで開発されているからです。すごい頭のいい人たちが作ったプログラムを使わせてもらうことで、簡単に、短いプログラムでAIを動かすことができます。
　そしてインストールするのはpythonではなく**Anaconda**です。Anacondaは「python+色々な便利ツール、モジュール」をひとまとめで入れてくれるもので、色んなサイトや教科書でAnacondaでのインストールが推奨されています。
Anacondaのインストールのやり方はこちらから。python3をインストールしましょう。2のメリットはないです。

[Python3.6環境構築(Win環境Anaconda利用)](https://qiita.com/kiyoneet/items/f440ac890e1a7a5931e8)
これに従って入れましょう。重要なのはpathを通すところでしょうか。
あと仮想環境はしばらく作らなくていいと思います。自分が作ってないから理解してないだけですが。

#（GPUマシンの場合）
GPUマシンのセットアップの場合は、追加でcudaとcudnnをインストールする必要があります。このときの注意としては、**最新バージョンをインストールしないこと。**があります。サイトのトップからではなくて少し探って必ず**少し古いのをインストールしましょう。**最新バージョンは何かと互換性とかで動かない場合が多いのでリスキーです。かと言って古すぎる組み合わせもgithubのプログラムを落として動かそうとしたときに動かない場合が多くなるので、ここ1年位の記事を参考にして入れるバージョンを決めると良いです。
ちなみに私はcuda:7.0、cudnn:9.0です。

#pythonにある程度慣れる
　インストールお疲れ様です。ここまで来るだけでもすごいです。けっこう大変だった人は多いと思います。自分はインストールしようとしたら会社のセキュリティの関係で色々と大変でした。こういう会社は意外とあると思います。
　さて、見事Anacondaをインストールできたらスタートメニュー/anaconda3からJupyter Notebookを開きます。以後簡単なプログラムはこれで書くのが良いです。ちょっと書いてすぐ動かすなら最適です。今月やるまでならこれだけで大丈夫です。
[Python環境の準備](https://qiita.com/Laundly_KUW/items/9122c933b3fede7e5366)
[python で非常に使用頻度が高い tip 9選](https://www.ganbaruyo.net/details/python-10-useful-tips/)
とかが参考になるでしょうか。

len、enumerateなどの基本的な関数、関数の作り方、numpy、内包表記、for、あたりは1ヶ月目から2ヶ月目で覚えておきたいです。マスターとなると程遠いですが。
if __name__ == '__main__'の意味、クラス、変数名、PEP8あたりはおいおいでいいです。
半年くらいまでは、動けば良いんですよ！

#モジュールをインストールする
Pythonではいろんな便利なライブラリが公開されています。機械学習は1からコードを書いていたらとんでもなく大変なので、ちょっと書いただけで層を増やして学習のための準備もしてくれるモジュールも公開されています。これらがあるからこそ、pythonが人気とも言えます。
モジュールのインストールはpipでもできますが、Anacondaを使っている場合はできるだけ

```python
conda install インストールするもの
```
でやることをおすすめします。理由はpipとcondaで保存の仕方が違うからです。環境がおかしくなるのを防ぐためにもできるだけcondaで入れた方が良いです。できるだけと言うのは上手く入らなかった時に延々と悩むくらいならpipで入れてもいいです。問題が起きるのは後なので、詳しくなってから直せばよいのです。初心者だもの。


#CNNを動かすmnistを分類する
さて本題に入って行きます。
全結合(nn)だけの分類についてはこの記事がまとまっていて解説もあって良いと思います。
[kerasのmnistのサンプルを読んでみる](https://qiita.com/ash8h/items/29e24fc617b832fba136)
この記事をjupyterに貼り付けていけば結果を得られるところまで進めると思います。

それではcnnに入っていきます。cnnのcは畳み込みのことですが、畳み込みが何かってのはこの記事が良いです。そしてこのHPはいい記事が多いので時間のあるときに見ていったら色々捗ります。
[定番のConvolutional Neural Networkをゼロから理解する](https://deepage.net/deep_learning/2016/11/07/convolutional_neural_network.html)

cnnで変えるところは入力を(28,28,1)にすることと、モデルにConv2D層を入れることです。
具体的には、まずデータのロード下記のようにします。elseの方で動いています。
気になったところはprint(x_train.shape)としておけば次元が確認できます。よくやります。
上の記事から修正するところだけ書きます。

```python
from keras import backend as K
(x_train, y_train), (x_test, y_test) = mnist.load_data()
# 場合分け
if K.image_data_format() == 'channels_first':
    x_train = x_train.reshape(x_train.shape[0], 1, 28, 28)
    x_test = x_test.reshape(x_test.shape[0], 1, 28, 28)
    input_shape = (1, 28, 28)
else:
    x_train = x_train.reshape(x_train.shape[0], 28, 28, 1)
    x_test = x_test.reshape(x_test.shape[0], 28, 28, 1)
    input_shape = (28, 28, 1)
x_train = x_train.astype('float32')
x_test = x_test.astype('float32')
x_train /= 255
x_test /= 255
y_train = keras.utils.to_categorical(y_train, num_classes)
y_test = keras.utils.to_categorical(y_test, num_classes)
```
次にモデルにConv2D層が入ります。入力は(28,28,1)が入ってます。

```python
from keras.models import Sequential
from keras.layers import Dense, Dropout, Flatten
from keras.layers import Conv2D, MaxPooling2D

model = Sequential()
model.add(Conv2D(32, kernel_size=(3, 3), activation='relu', input_shape=input_shape))
model.add(MaxPooling2D(pool_size=(2, 2)))
model.add(Dropout(0.25))
model.add(Flatten())
model.add(Dense(128, activation='relu'))
model.add(Dropout(0.5))
model.add(Dense(num_classes, activation='softmax'))
```
これで動かすとこんな感じの出力が得られます。
![month1_1.JPG](https://qiita-image-store.s3.amazonaws.com/0/189568/44d7ccc4-e1ac-535e-a8ac-da73a95174a6.jpeg)

cnnが入ると一気に計算時間伸びるのでここらへんからGPU欲しくなりますね。
持ってない人のために無料で使えるGPUがあります。
[Google Colaboratory事始め](https://qiita.com/kouki_outstand/items/cd24dccbaa92274be39e)

#matplotlibでのグラフの作り方
計算したら出力、グラフ化もしないと発表できないので出力をグラフとして得る方法も書いておきます
matplotlibはこれが参考になります。
[matplotlib入門](https://qiita.com/yohm/items/1daa5aabbdb1e8edbf26)
先程までのプログラムに以下のコードを最後にかけば学習の様子を可視化でき、グラフがpngで保存されます。
jupyterでmatplotlibを使う際には%matplotlib inlineを忘れずに。

```python
import matplotlib.pyplot as plt
%matplotlib inline

#Accuracy
plt.plot(history.history['acc'])
plt.plot(history.history['val_acc'])
plt.title('model accuracy')
plt.ylabel('accuracy')
plt.xlabel('epoch')
plt.legend(['train', 'test'], loc='upper left')
plt.ylim([0.8,1.0])
plt.savefig('accuracy.png')
plt.show()

#loss
plt.plot(history.history['loss'])
plt.plot(history.history['val_loss'])
plt.title('model loss')
plt.ylabel('loss')
plt.xlabel('epoch')
plt.legend(['train', 'test'], loc='lower left')
plt.ylim([0.0,0.35])
plt.savefig('loss.png')
plt.show()
```
グラフはこのようになります。
![train.png](https://qiita-image-store.s3.amazonaws.com/0/189568/dc2a1018-32f1-3e6b-fd3e-ea7f1515ef8a.png)
![test.png](https://qiita-image-store.s3.amazonaws.com/0/189568/7c681deb-3173-3538-229c-86b1f6412bee.png)


#さいごに
取り敢えずここまでできれば1ヶ月目としては十分だと思います。十分じゃなかったらそれは私のいる会社よりもレベル高い会社ということです。悔しいですがどんどん先に進んで行きましょう。
2ヶ月目はcv2,shuttle,glob,osを使います。自分の用意したデータセットで分類できないと意味ないですからね。
あとはcallbackを解説したいと思います。最後の重みではなく一番いい重みを使ったり、学習収束したら打ち切ったりしたいですよね。
[素人がAI部門に配属されてやること２ヶ月目(自作データセット、opencv、callback)](https://qiita.com/chun1182/items/cbfc1cdd1422cb7218ea)