[データ拡張 Data Augmentation]     画像分類で精度を上げる方法

#About
・データ拡張で更に精度UP
・最後にテストデータで性能チェック

＊下記の前記事の続きです（もちろんこの記事だけでも理解できるようになっています）
https://qiita.com/Phoeboooo/items/2c7457d1bfba514e2dc8


#データ拡張
・データ不足を解消する方法
・データの水増し
・既にダウンロードしてある画像にランダムな変換を与えて、データ数を増やすこと

```python

train_datagen = ImageDataGenerator(
    rescale=1./255,
    rotation_range=20,
    width_shift_range=0.1,
    height_shift_range=0.1,
    shear_range=0.1,
    zoom_range=0.1,
    horizontal_flip=True,)

# the validation data should NOT be augmented
test_datagen = ImageDataGenerator(rescale=1./255)

train_generator = train_datagen.flow_from_directory(
        train_dir,
        target_size=(150, 150),
        batch_size=80,
        class_mode='binary')

validation_generator = test_datagen.flow_from_directory(
        validation_dir,
        target_size=(150, 150),
        batch_size=80,
        class_mode='binary')
```
###データ拡張のオプション
>rotation_range=20,       　　画像を回転させる範囲(0~180)
width_shift_range=0.1,　　　　水平移動
height_shift_range=0.1,　　　　垂直移動
shear_range=0.1,　　　　　　　等積変形
zoom_range=0.1,　　　　　　　　ズーム
horizontal_flip=True　　　　　反転

数字（20,0.1)は個々で変えてみて適したものを探してみてください
他のオプションはkerasのドキュメントを参照


###検証データの扱い
・検証データはオリジナルの画像だけ
・水増しはしないように注意

#学習
```python

history = model.fit_generator(
      train_generator,
      steps_per_epoch=200,
      epochs=20,
      validation_data=validation_generator,
      validation_steps=40)
```
#学習結果
```python

Epoch 1/20
200/200 [==============================] - 1054s 6s/step - loss: 0.3346 - acc: 0.8549 - val_loss: 0.3665 - val_acc: 0.8278
Epoch 2/20
200/200 [==============================] - 1045s 6s/step - loss: 0.3323 - acc: 0.8518 - val_loss: 0.3066 - val_acc: 0.8631
Epoch 3/20
200/200 [==============================] - 1046s 6s/step - loss: 0.3312 - acc: 0.8547 - val_loss: 0.2861 - val_acc: 0.8778
Epoch 4/20
200/200 [==============================] - 1041s 6s/step - loss: 0.3314 - acc: 0.8553 - val_loss: 0.4071 - val_acc: 0.8100
Epoch 5/20
200/200 [==============================] - 1059s 6s/step - loss: 0.3310 - acc: 0.8565 - val_loss: 0.2879 - val_acc: 0.8775
.
.
.
Epoch 16/20
200/200 [==============================] - 1121s 6s/step - loss: 0.3179 - acc: 0.8570 - val_loss: 0.3144 - val_acc: 0.8600
Epoch 17/20
200/200 [==============================] - 1099s 6s/step - loss: 0.3140 - acc: 0.8591 - val_loss: 0.2878 - val_acc: 0.8766
Epoch 18/20
200/200 [==============================] - 1100s 6s/step - loss: 0.3186 - acc: 0.8587 - val_loss: 0.3033 - val_acc: 0.8622
Epoch 19/20
200/200 [==============================] - 1111s 6s/step - loss: 0.3186 - acc: 0.8591 - val_loss: 0.3234 - val_acc: 0.8550
Epoch 20/20
200/200 [==============================] - 1159s 6s/step - loss: 0.3105 - acc: 0.8629 - val_loss: 0.2748 - val_acc: 0.8769
```
<b>データ拡張をしたことで82.25%から87.69%に精度が上がった</b>

＊今回は記事の簡略化のために、エポック数等を変更しています
データ拡張のハイパーパラメーターやエポック数を探りながらやっていたために冗長となったものを短くしました



#テストデータで評価
```python

from keras.models import load_model
from keras.preprocessing.image import ImageDataGenerator
model = load_model('baby_550')     

test_dir = 'downloads/baby/test'
test_datagen = ImageDataGenerator(rescale=1./255)
test_generator = test_datagen.flow_from_directory(
    test_dir,
    target_size=(150,150),
    batch_size=50,
    class_mode='binary')

test_loss, test_acc = model.evaluate_generator(test_generator, steps=68)
print('test loss:', test_loss)
print('test acc:', test_acc)
```

テストデータで評価して汎用性をチェックしましょう
・保存しておいたモデルをロード
・テストデータはもちろんデータ拡張はしない
・今回の場合テストデータが3400枚だったので68ステップ(3400÷50=68)

#テスト結果
```python

Found 3400 images belonging to 2 classes.
test loss: 0.28147747696322556
test acc: 0.873529406154857
```
<b>精度は87.35%でした</b>