TensorFlow2.0系でCIFAR-10データを学習して予測するまで（２）

#概要（TL;DR）

tensorflow2系でCIFAR-10の分類テストをしてみた。（個人的な覚書程度）
[前回](https://qiita.com/takashi_42331/items/7f22f51d8d284b340d1a)に続いて、今回は簡単なネットワークで学習をさせてみる。

下記の作業はすべて、[Google Colab](https://colab.research.google.com/notebooks/intro.ipynb?hl=ja)で実施しています。★GPUも使ってます。（ランタイム-> ランタイムのタイプを変更 -> ハードウェアアクセラレータでGPUを選択）

#TensowFlowで学習

## CIFAR-10のデータを取得
学習データと評価データを取得する

```python
from tensorflow.python.keras.datasets import cifar10
(x_train,y_train),(x_test,y_test) = cifar10.load_data()
```

## 学習データの整形
入力データが、画像データなのでRGBの255,255,255で値が保存されているので、0から1の間の値に変更します。

```python
x_train,x_test = x_train/255.0,x_test/255.0
```

出力データ側は0から9の値になっているので、1-hotベクトル化する。

```python
from keras.utils import to_categorical
#第2引数の10は、今回のCIFAR10は10分類するため。
y_train,y_test = to_categorical(y_train,10),to_categorical(y_test,10)
```

1-Hotベクトル

| y_train|→| 0(airplane)| 1(automobile)| 2(bird)| 3(cat)| 4(deer)| 5(dog)| 6(frog)| 7(horse)| 8(ship)| 9(truck)|
|:--|:--|:--|:--|:--|:--|:--|:--|:--|:--|:--|:--|
| 3|→| 0| 0| 0| 1| 0| 0| 0| 0| 0| 0|
| 5|→| 0| 0| 0| 0| 0| 1| 0| 0| 0| 0|
| 0|→| 1| 0| 0| 0| 0| 1| 0| 0| 0| 0|


## CNN(Convolutional neural network)モデルを作成する

畳み込みニューラルネットワークを構築する。

```python
model = Sequential([
     Conv2D(filters=32,input_shape=(32,32,3),kernel_size=(3,3),strides=(1,1),padding='same',activation='relu'),
     Conv2D(filters=32,kernel_size=(3,3),strides=(1,1),padding='same',activation='relu'),
     MaxPool2D(pool_size=(2,2)),
     Dropout(0.25),
     Conv2D(filters=64,kernel_size=(3,3),strides=(1,1),padding='same',activation='relu'),
     Conv2D(filters=64,kernel_size=(3,3),strides=(1,1),padding='same',activation='relu'),
     MaxPool2D(pool_size=(2,2)),
     Dropout(0.25),
     # Dense層に渡すために、多次元配列を2次元配列に変換する
     Flatten(),

     # 全結合層を追加する
     Dense(512,activation='relu'),
     Dropout(0.5),
     # 出力層は10種類、softmax関数を設定することで、確率が最も高いもののみが発火するようにする
     Dense(units=10,activation='softmax')  
])
```

## モデルをコンパイルする

この辺は、まだ理解が浅いので、今後勉強が必要。
損失関数は「categorical_crossentropy」にしました。Nクラスに分類する場合は、categorical_crossentropyを使うのがベターとのことです。この関数を使う為に、出力データは1-Hotベクトル化する。

最適化関数は「adam」にしました。



```python
model.compile(optimizer='adam',
              loss='categorical_crossentropy',
              metrics=['accuracy'])

```

## 学習する

```python
history = model.fit(x_train, y_train, validation_split=0.25, epochs=10, batch_size=16, verbose=1)
```
model.fit()で学習、model.evaluate()で検証、model.predict()でテストデータ確認
学習回数はepochs

## 出力結果

ここが、自分のMacBook Airですると30分ぐらいかかる・・・・。でもGoogle Colab　+ GPUなら4分程度で終わります。

```
Epoch 1/10
2344/2344 [==============================] - 25s 11ms/step - loss: 1.6056 - accuracy: 0.4095 - val_loss: 1.2285 - val_accuracy: 0.5563
Epoch 2/10
2344/2344 [==============================] - 23s 10ms/step - loss: 1.1888 - accuracy: 0.5756 - val_loss: 0.9763 - val_accuracy: 0.6602
Epoch 3/10
2344/2344 [==============================] - 25s 11ms/step - loss: 1.0390 - accuracy: 0.6349 - val_loss: 0.9312 - val_accuracy: 0.6744
Epoch 4/10
2344/2344 [==============================] - 24s 10ms/step - loss: 0.9379 - accuracy: 0.6696 - val_loss: 0.8622 - val_accuracy: 0.6991
Epoch 5/10
2344/2344 [==============================] - 25s 11ms/step - loss: 0.8692 - accuracy: 0.6926 - val_loss: 0.7900 - val_accuracy: 0.7230
Epoch 6/10
2344/2344 [==============================] - 24s 10ms/step - loss: 0.8134 - accuracy: 0.7126 - val_loss: 0.7626 - val_accuracy: 0.7391
Epoch 7/10
2344/2344 [==============================] - 25s 11ms/step - loss: 0.7708 - accuracy: 0.7295 - val_loss: 0.7465 - val_accuracy: 0.7378
Epoch 8/10
2344/2344 [==============================] - 24s 10ms/step - loss: 0.7348 - accuracy: 0.7420 - val_loss: 0.8097 - val_accuracy: 0.7237
Epoch 9/10
2344/2344 [==============================] - 24s 10ms/step - loss: 0.7039 - accuracy: 0.7528 - val_loss: 0.7362 - val_accuracy: 0.7454
Epoch 10/10
2344/2344 [==============================] - 24s 10ms/step - loss: 0.6787 - accuracy: 0.7586 - val_loss: 0.7299 - val_accuracy: 0.7486
```
loss:損失（学習データ）
accuracy:精度（学習データ）
val_loss:損失（validation（評価）データを用いた場合の）
val_accuracy:精度（validation（評価）データを用いた場合の）


# 結果の確認

```python
import matplotlib.pyplot as plt
# Plot training & validation accuracy values
plt.plot(history.history['accuracy'])
plt.plot(history.history['val_accuracy'])
plt.title('Model accuracy')
plt.ylabel('Accuracy')
plt.xlabel('Epoch')
plt.legend(['Train', 'Test'], loc='upper left')
plt.show()

# Plot training & validation loss values
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='upper left')
plt.show()
```

<img width="409" alt="スクリーンショット 2020-04-28 23.40.24.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/44112/b7699830-a66d-087b-5d5a-a4f3bd1a6cea.png">

# 評価する

```python
model.evaluate(x_test,y_test)
```

```
313/313 [==============================] - 2s 6ms/step - loss: 0.7613 - accuracy: 0.7448
[0.7612716555595398, 0.7447999715805054]
```
74%ぐらいの精度がでているみたい。
次は、パラメータとかを調整して、この精度を上げてみようと思います。