pythonで果物分類をしてみた②モデル学習編


#4.モデルの学習


#ColaboratoryでのGoogle Driveへのマウント
```python:マウント
from google.colab import drive
drive.mount('/content/drive')
```


%cd (自分の今いるディレクトリを移動するときに使うコマンド)


```
%cd /content/drive/MyDrive/ColabNotebooks/
```

#5.モデルの構築と保存
1.まず画像を読み込みます。
画像を読みこむには「cv2.imread( )」を使用します。

2.import cv2　でOpenCVを使用します。

3.cv2.resizeで画像を指定のサイズにリサイズします。
画像のサイズ変更を行うには「cv2 . resize( )」を使用


###OpenCVとは？

・画像の読み込み・表示
・画像の作成・保存
・画像のトリミング・リサイズ・重ね合わせ
・画像の回転・上下反転・左右反転
・グレースケール変換・色チャンネル分析・減色処理
・モザイク処理・マスク処理・2枚の画像を合成
・図形の描画・文字の描画
・ノイズ除去・平滑化・ぼかしフィルタ・メディアンフィルタ・ガウシアンフィルタ
・物体検出
・テンプレートマッチング 

などがあります。


```python

import os
import cv2
from os import listdir

#path_apple = [filename for filename in listdir('./fruits-360/Training/all_apple/') if not filename.startswith('./')]　　

path = '/content/drive/MyDrive/fruits_360/Training/'
path = '/content/drive/MyDrive/scraping_data/'

path_apple = [filename for filename in listdir('/content/drive/MyDrive/fruits_360/Training/all_apple/') if not filename.startswith('./')]
path_banana = [filename for filename in listdir('/content/drive/MyDrive/fruits_360/Training/all_banana/') if not filename.startswith('./')]
path_orange = [filename for filename in listdir('/content/drive/MyDrive/fruits_360/Training/all_orange/') if not filename.startswith('./')]

#水増しした画像のファイル名を取得
path_extend_banana = [filename for filename in os.listdir('/content/drive/MyDrive/scraping_data/extended_banana/') if not filename.startswith('.')]
path_extend_orange = [filename for filename in os.listdir('/content/drive/MyDrive/scraping_data/extended_orange/') if not filename.startswith('.')]
img_apple = []
img_banana = []
img_orange = []
#画像の読み込み
for i in range(len(path_apple)):
   img = cv2.imread('/content/drive/MyDrive/fruits_360/Training/all_apple/'+ path_apple[i])
   try:
       img = cv2.resize(img,(50,50))
       img_apple.append(img)
   except:
       pass
for i in range(len(path_banana)):
   img = cv2.imread('/content/drive/MyDrive/fruits_360/Training/all_banana/'+ path_banana[i])
   try:
       img = cv2.resize(img,(50,50))
       img_apple.append(img)
   except:
        pass
for i in range(len(path_orange)):
   img = cv2.imread('./content/drive/MyDrive/fruits_360/Training/all_orange/'+ path_orange[i])
   try :
       img = cv2.resize(img,(50,50))
       img_orange.append(img)
   except:
        pass
for i in range(len(path_extend_banana)):
   img = cv2.imread('/content/drive/MyDrive/scraping_data/extended_banana/'+ path_extend_banana[i])
   try :
       img = cv2.resize(img,(50,50))
       img_banana.append(img)
   except:
       pass
for i in range(len(path_extend_orange)):
   img = cv2.imread('/content/drive/MyDrive/scraping_data/extended_orange/'+ path_extend_orange[i])
   try :
       img = cv2.resize(img,(50,50))
       img_orange.append(img)
   except:
       pass

print(img_apple[0])
print(img_banana[0])
print(img_orange[0])
print("終了しました")

```
#説明
* **import os**

OSモジュールを使用。OS（オペレーションシステム）Pythonの標準ライブラリ。
標準とはPythonをインストールした時点で時点で用意されているという意味。
便利なプログラム（パッケージやモジュール）をひとまとめにしたものをライブラリという。

* **import cv2**

CVとはOpenCV,(Computer Vision)の略です。
OpenCVはインテルのComputer Vision（インテルは会社名。コンピューター・ビジョンは、監視カメラやセンサー、エッジサーバー、クラウドに導入する、AI を使って物体を識別し、ビジュアル情報を解釈するテクノロジーです。）向けオープンソースライブラリで、具体的には、画像処理、画像解析、機械学習などが行えます。

OpenCVをPythonで使うためには cv2 モジュールを import する必要があります。（バージョンは関係ありません。）

* **path**

pathを指定します。ファイル名やフォルダ名の一覧を取得したいディレクトリパスを文字列で引数pathに指定します。

* **path_** ・　**path_extend_**

リスト変数 = os.listdir('パス')
フォルダ内のファイルとフォルダの一覧を取得するには、os.listdir()関数を使います。
listdirでディレクトリとファイルの一覧を取得し、それをfor文で一つずつ取り出します。
ファイル名やフォルダ名の一覧を取得したいディレクトリパスを文字列で引数pathに指定します。
ディレクトリ内のファイル名やフォルダ名が一覧でリスト形式で返ります。(但し順番は不定）

* **img_apple = []**

画像ファイルを「apple」から取得。

* **for i in range(len(path_apple)):
   img = cv2.imread**

Pythonのfor文ではrange関数を使ってループをするのが一般的ですが、そのrangeを使ってインデックスを取り出す事が出来ます。
画像を保存するには cv2.imwrite() 関数を使います．

* **img = cv2.resize**

cv2,resizeに入力画像とサイズを設定する

* **try-exceptの使い方**

基本的には try-except文を使用し「例外処理」を行います。try-except構文は以下の通りです。
例外処理を使うことでエラーが発生しても実行が中止することなくそれ以降の処理も行われる

```python

try: 
    例外が発生するかもしれないが、実行したい処理。
except エラー名:
    例外発生時に行う処理
```

* **img_orange.append(img)**

 appendを使用することで、リストを作成後、途中でリストを追加できます。そのリストはリストの最後にしか付加することができません。

リストの指定の位置に付加したいときはどうするのか？　そんなときは、insertを使用します。
リスト名.insert(リストの番号,入れたい値）という風にリストの番号を指定することで指定した番号の前に任意のリストを追加することができます。（リストは0から数えられます）

extendはリストを結合させたいときに使用します。


* **print(img_apple[0])**

このコードに直接的には関係しませんが、写真枚数を確認する場合に使用します。



##結果
[[[255 255 255]
  [255 255 255]
  [255 255 255]
  ...
  [255 255 255]
  [255 255 255]
  [255 255 255]]

 [[255 255 255]
  [255 255 255]
  [255 255 255]
  ...
  [255 255 255]
  [255 255 255]
  [255 255 255]]

 [[255 255 255]
  [255 255 255]
  [255 255 255]
  ...
  [255 255 255]
  [255 255 255]
  [255 255 255]]

 ...

 [[255 254 255]
  [255 255 255]
  [255 255 254]
  ...
  [255 254 255]
  [255 255 255]
  [255 255 255]]

 [[255 255 255]
  [255 255 255]
  [255 255 255]
  ...
  [255 255 255]
  [255 255 255]
  [255 255 255]]

 [[255 255 255]
  [255 255 255]
  [255 255 255]
  ...
  [255 255 255]
  [255 255 255]
  [255 255 255]]]
[[[255 255 255]
  [255 255 255]
  [255 255 255]
  ...
  [255 255 255]
  [255 255 255]
  [255 255 255]]

 [[255 255 255]
  [255 255 255]
  [255 255 255]
  ...
  [255 255 255]
  [255 255 255]
  [255 255 255]]

 [[255 255 255]
  [255 255 255]
  [255 255 255]
  ...
  [255 255 255]
  [255 255 255]
  [255 255 255]]

 ...

 [[255 255 255]
  [255 255 255]
  [255 255 255]
  ...
  [255 255 255]
  [255 255 255]
  [255 255 255]]

 [[255 255 255]
  [255 255 255]
  [255 255 255]
  ...
  [255 255 255]
  [255 255 255]
  [255 255 255]]

 [[255 255 255]
  [255 255 255]
  [255 255 255]
  ...
  [255 255 255]
  [255 255 255]
  [255 255 255]]]
[[[  1 134 247]
  [  2 127 243]
  [  1 125 244]
  ...
  [  2  93 222]
  [  5  90 225]
  [  1  80 220]]

 [[  0 143 245]
  [  1 134 248]
  [  0 119 241]
  ...
  [  1  94 223]
  [  1  79 216]
  [  0  91 222]]

 [[  0 144 249]
  [  0 139 247]
  [  0 128 243]
  ...
  [  1  82 219]
  [  0  80 215]
  [  0  97 225]]

 ...

 [[  0 159 247]
  [  1 163 251]
  [  0 142 243]
  ...
  [  1 135 247]
  [  0 115 239]
  [  2 140 248]]

 [[  0 152 247]
  [  1 151 247]
  [  8 152 254]
  ...
  [  1 140 246]
  [  3 135 248]
  [  0 111 236]]

 [[  0 154 247]
  [  2 142 243]
  [127 199 247]
  ...
  [  0 138 250]
  [  0 142 247]
  [  0 121 239]]]
終了しました

#6.結果のグラフ化
・ヒストグラムを描画するメソッドとして、matplotlib.pyplot.hist を使用します。

```python

import numpy as np
import matplotlib.pyplot as plt
```

・matplotlibはグラフ描画するためのライブラリです。matplotlibを使えば、グラフの描画やデータの可視化が簡単に行えます。
・matplotlib を使うには, matplotlib.pyplot クラスを plt という名前で読み込みます。
・Numpyのarangeメゾットによって、(img_apple + img_banana + img_orange)データを生成し,
これを x としています。NumPyのarray関数　「np.array」 を適用し、x,yのデータ列をplt.plotメソッドに与え、グラフを描画します。


##NumPy 配列の基礎
NumPy 配列の生成
それでは， np.ndarray の生成方法を説明します． N次元配列 np.ndarray は，数学の概念で言えば，1次元の場合はベクトルに，2次元の場合は行列に，そして3次元以上の場合はテンソルに該当します．

np.array() 関数による生成
np.ndarray にもコンストラクタはありますが，通常は， np.array() 関数 1 によって生成します．
https://www.kamishima.net/mlmpyja/nbayes1/ndarray.html

##Pyplotの機能

```
import matplotlib.pyplot as plt
```
・pyplotには、画像表示のメゾットimshow()が用意されています。
・画像読み込みは、matplotlib　image　モジュールのimread()　を利用することができます。



グラフに表示される数値はtraning.h5の数値ではなく、最後のエポックの数値になります。

```python

import os
import cv2
import numpy as np
import matplotlib.pyplot as plt
from keras.utils.np_utils import to_categorical
from keras.layers import Dense, Dropout, Flatten, Input
from keras.applications.vgg16 import VGG16
from keras.models import Model, Sequential
from keras import optimizers
from os import listdir

X = np.array(img_apple + img_banana + img_orange)
y =  np.array([0]*len(img_apple) + [1]*len(img_banana) + [2]*len(img_orange))
rand_index = np.random.permutation(np.arange(len(X)))
X = X[rand_index]
y = y[rand_index]
X_train = X[:int(len(X)*0.8)]
y_train = y[:int(len(y)*0.8)]
X_test = X[int(len(X)*0.8):]
y_test = y[int(len(y)*0.8):]
y_train = to_categorical(y_train)
y_test = to_categorical(y_test)
input_tensor = Input(shape=(50,50, 3))


vgg16 = VGG16(include_top=False, weights='imagenet', input_tensor=input_tensor)
#vgg16 = VGG16(include_top=False, weights='imagenet', input_tensor=input_model.output)


top_model = Sequential()
top_model.add(Flatten(input_shape=vgg16.output_shape[1:]))
top_model.add(Dense(256, activation="sigmoid"))
top_model.add(Dropout(0.5))
top_model.add(Dense(64, activation='sigmoid'))
top_model.add(Dropout(0.5))
top_model.add(Dense(32, activation='sigmoid'))
top_model.add(Dropout(0.5))
top_model.add(Dense(3, activation='softmax'))


model = Model(inputs=vgg16.input, outputs=top_model(vgg16.output))
#model = Model(input=input_model.input, output=top_model(vgg16.output))

for layer in model.layers[:15]:
   layer.trainable = False
model.compile(loss='categorical_crossentropy',
             optimizer=optimizers.SGD(lr=1e-4, momentum=0.9),
             metrics=['accuracy'])


#グラフ用
history = model.fit(X_train, y_train, batch_size=32, epochs=100, verbose=1, validation_data=(X_test, y_test))
score = model.evaluate(X_test, y_test, batch_size=32, verbose=0)
print('validation loss:{0[0]}\nvalidation accuracy:{0[1]}'.format(score))
#acc, val_accのプロット
plt.plot(history.history["accuracy"], label="acc", ls="-", marker="o")
plt.plot(history.history["val_accuracy"], label="val_acc", ls="-", marker="x")
plt.ylabel("accuracy")#y軸のラベル
plt.xlabel("epoch")#x軸のラベル
# 凡例の表示
plt.legend(loc="best")
# プロット表示(設定の反映)
plt.show()

#モデルを保存
model.save("traning.h5")
```

# 説明

*  **import numpy as np**

NumPy はプログラミング言語であるPythonの拡張モジュールです。
NumPyのインストールしたあと、実際にNumpyを使用するには**import numpy as np**を使用します。


*  **import matplotlib.pyplot as plt**

matplotlibを使用する際に必要なライブラリをインポートします。
matplotlibライブラリのpyplot、math、numpyのインポート。


```python

from matplotlib import pyplot
import math
import numpy as np
```

##転移学習

* **from keras.applications.vgg16 import VGG16**

VGG16を使い転移学習を行います。 まず、VGGのモデルのインスタンスを作ります。



* **input_tensor = Input(shape=(32, 32, 3))
vgg16 = VGG16(include_top=False, weights='imagenet', input_tensor=input_tensor)**

input_tersorとして入力の形を与えます。
include_topをfalseにし、VGGの特徴抽出部分のみを用いてそれ以降のモデルは自分で作成したモデルと結合させます。
特徴抽出部分以降に新しく他の層を追加するには、あらかじめVGGとは別のモデル（ここではtop_model）を定義します。


```python

top_model = Sequential()
top_model.add(Flatten(input_shape=vgg16.output_shape[1:]))
top_model.add(Dense(256, activation='relu'))
top_model.add(Dense(10, activation='softmax'))
#入力はvgg.input, 出力は, top_modelにvgg16の出力を入れたもの
model = Model(inputs=vgg16.input, outputs=top_model(vgg16.output))
```

vgg16による特徴抽出部分の重みは更新されると崩れてしまうので以下のようにして固定します。

* **modelの16層目までがvggのモデル**
for layer in model.layers[:15]:
    layer.trainable = False

* **コンパイル・学習は同様に行えますが、ファインチューニングする場合、最適化はSGDで行うと良いです。**

model.compile(loss='categorical_crossentropy',
              optimizer=optimizers.SGD(lr=1e-4, momentum=0.9),
              metrics=['accuracy'])


##モデルの定義

* **KerasのSequentialモデルによるモデルの定義**

model = Sequential()
model.add(層1)
model.add(層2)
︙
各層は以下の例のように定義します。

####全結合層
Dense(units, input_dim=784)

####畳み込み層
Conv2D(filters = 32, kernel_size=(2, 2), strides=(1, 1), padding="same", input_shape=(28, 28, 3))

####プーリング層
MaxPooling2D(pool_size=(2, 2), strides=None)

####平坦化層

Flatten()
活性化関数は次の例のように、各層と同じように扱います。

model.add(Activation('sigmoid'))
Activationに与えられる文字列としては、'sigmoid'、'relu'、'softmax'などがあります。



![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/942550/a29fe724-968f-f0c1-3744-d779157e8ce5.png)



```python

top_model = Sequential()
top_model.add(Flatten(input_shape=vgg16.output_shape[1:]))
top_model.add(Dense(256, activation="sigmoid"))
top_model.add(Dropout(0.5))
top_model.add(Dense(64, activation='sigmoid'))
top_model.add(Dropout(0.5))
top_model.add(Dense(32, activation='sigmoid'))
top_model.add(Dropout(0.5))
top_model.add(Dense(3, activation='softmax'))
```

##精度向上のための手法


ニューラルネットモデルの学習時に、学習データのみに通用する学習（オーバーフィッティング）が発生することがよくあります。
ここではドロップアウトという、入力データをランダムに除去する（0で上書きする）手法を用いてオーバーフィッティングを防ぎます。 ドロップアウトにより、ニューラルネットは特定のニューロンの存在に依存できなくなり、より汎用的な(学習データのみに依存しない)特徴を学習するようになります。

ドロップアウトも通常の層と同じような方法で用いることができます。

* **model.add(Dropout(rate=0.5))**

rateは入力ユニットをドロップする（0で上書きする）割合です。

また、Kerasでは次のようにしてモデルの分類精度を調べることができます。

* **score = model.evaluate(X_test, y_test)**

X_test, y_testは評価用データの入力データと教師データで

##matplotlib・pyplot・plot関数

*  matplotlibライブラリのモジュールのpyplotのplot関数で、以下のグラフを表示します。

```python

plt.plot(history.history["accuracy"], label="acc", ls="-", marker="o")
plt.plot(history.history["val_accuracy"], label="val_acc", ls="-", marker="x")
plt.ylabel("accuracy")#y軸のラベル
plt.xlabel("epoch")#x軸のラベル
#凡例の表示
plt.legend(loc="best")
#プロット表示(設定の反映)
plt.show()
```

**plt.plot(history.history[‘accuracy’])
plt.plot(history.history[‘val_accuracy’])**

「accuracy：訓練データ（train data）の精度」「val_accuracy：検証データ（validation data）での精度」の記録をグラフ上にプロット（描き入れる）。

**plt.ylabel("accuracy")**

タイトルの表記。機械学習モデルの精度。


**plt.xlabel("epoch")**
グラフのX軸（横軸）の表記。エポック数（訓練データを学習させる回数）。

**plt.legend(loc="best")**
ラベル（凡例）の表記。

**plt.show()**
グラフを表示する。




##結果
Downloading data from https://storage.googleapis.com/tensorflow/keras-applications/vgg16/vgg16_weights_tf_dim_ordering_tf_kernels_notop.h5
58892288/58889256 [==============================] - 0s 0us/step
Epoch 1/100
440/440 [==============================] - 15s 17ms/step - loss: 1.3841 - accuracy: 0.2976 - val_loss: 0.9139 - val_accuracy: 0.5749
Epoch 2/100
440/440 [==============================] - 7s 15ms/step - loss: 1.0042 - accuracy: 0.5231 - val_loss: 0.8656 - val_accuracy: 0.5749
Epoch 3/100
440/440 [==============================] - 7s 15ms/step - loss: 0.9650 - accuracy: 0.5679 - val_loss: 0.8311 - val_accuracy: 0.5749
Epoch 4/100
440/440 [==============================] - 7s 15ms/step - loss: 0.9207 - accuracy: 0.5943 - val_loss: 0.8019 - val_accuracy: 0.5749
Epoch 5/100
440/440 [==============================] - 7s 15ms/step - loss: 0.9023 - accuracy: 0.6163 - val_loss: 0.7738 - val_accuracy: 0.5749
Epoch 6/100
440/440 [==============================] - 7s 15ms/step - loss: 0.8851 - accuracy: 0.6196 - val_loss: 0.7458 - val_accuracy: 0.5749
Epoch 7/100
440/440 [==============================] - 7s 15ms/step - loss: 0.8546 - accuracy: 0.6397 - val_loss: 0.7195 - val_accuracy: 0.5749
Epoch 8/100
440/440 [==============================] - 7s 15ms/step - loss: 0.8256 - accuracy: 0.6527 - val_loss: 0.6907 - val_accuracy: 0.7835
Epoch 9/100
440/440 [==============================] - 7s 15ms/step - loss: 0.8005 - accuracy: 0.6719 - val_loss: 0.6611 - val_accuracy: 0.8124
Epoch 10/100
440/440 [==============================] - 7s 15ms/step - loss: 0.7717 - accuracy: 0.6872 - val_loss: 0.6304 - val_accuracy: 0.8346
Epoch 11/100
440/440 [==============================] - 7s 15ms/step - loss: 0.7523 - accuracy: 0.6934 - val_loss: 0.5983 - val_accuracy: 0.8397
Epoch 12/100
440/440 [==============================] - 7s 15ms/step - loss: 0.7315 - accuracy: 0.7110 - val_loss: 0.5672 - val_accuracy: 0.8406
Epoch 13/100
440/440 [==============================] - 7s 15ms/step - loss: 0.6970 - accuracy: 0.7306 - val_loss: 0.5357 - val_accuracy: 0.8426
Epoch 14/100
440/440 [==============================] - 7s 15ms/step - loss: 0.6669 - accuracy: 0.7467 - val_loss: 0.5057 - val_accuracy: 0.8434
Epoch 15/100
440/440 [==============================] - 7s 15ms/step - loss: 0.6499 - accuracy: 0.7517 - val_loss: 0.4764 - val_accuracy: 0.8457
Epoch 16/100
440/440 [==============================] - 7s 15ms/step - loss: 0.6211 - accuracy: 0.7623 - val_loss: 0.4492 - val_accuracy: 0.8451
Epoch 17/100
440/440 [==============================] - 7s 15ms/step - loss: 0.5982 - accuracy: 0.7761 - val_loss: 0.4226 - val_accuracy: 0.8463
Epoch 18/100
440/440 [==============================] - 7s 15ms/step - loss: 0.5822 - accuracy: 0.7763 - val_loss: 0.3970 - val_accuracy: 0.8463
Epoch 19/100
440/440 [==============================] - 7s 15ms/step - loss: 0.5558 - accuracy: 0.7922 - val_loss: 0.3727 - val_accuracy: 0.8465
Epoch 20/100
440/440 [==============================] - 7s 15ms/step - loss: 0.5379 - accuracy: 0.8015 - val_loss: 0.3497 - val_accuracy: 0.8664
Epoch 21/100
440/440 [==============================] - 7s 15ms/step - loss: 0.5062 - accuracy: 0.8162 - val_loss: 0.3282 - val_accuracy: 0.9406
Epoch 22/100
440/440 [==============================] - 7s 15ms/step - loss: 0.4945 - accuracy: 0.8212 - val_loss: 0.3085 - val_accuracy: 0.9702
Epoch 23/100
440/440 [==============================] - 7s 15ms/step - loss: 0.4747 - accuracy: 0.8300 - val_loss: 0.2894 - val_accuracy: 0.9841
Epoch 24/100
440/440 [==============================] - 7s 15ms/step - loss: 0.4537 - accuracy: 0.8365 - val_loss: 0.2721 - val_accuracy: 0.9878
Epoch 25/100
440/440 [==============================] - 7s 15ms/step - loss: 0.4385 - accuracy: 0.8411 - val_loss: 0.2557 - val_accuracy: 0.9920
Epoch 26/100
440/440 [==============================] - 7s 15ms/step - loss: 0.4235 - accuracy: 0.8488 - val_loss: 0.2405 - val_accuracy: 0.9932
Epoch 27/100
440/440 [==============================] - 7s 15ms/step - loss: 0.4036 - accuracy: 0.8627 - val_loss: 0.2264 - val_accuracy: 0.9940
Epoch 28/100
440/440 [==============================] - 7s 15ms/step - loss: 0.3941 - accuracy: 0.8605 - val_loss: 0.2132 - val_accuracy: 0.9949
Epoch 29/100
440/440 [==============================] - 7s 15ms/step - loss: 0.3807 - accuracy: 0.8723 - val_loss: 0.2013 - val_accuracy: 0.9952
Epoch 30/100
440/440 [==============================] - 7s 15ms/step - loss: 0.3681 - accuracy: 0.8742 - val_loss: 0.1906 - val_accuracy: 0.9946
Epoch 31/100
440/440 [==============================] - 7s 15ms/step - loss: 0.3403 - accuracy: 0.8861 - val_loss: 0.1798 - val_accuracy: 0.9969
Epoch 32/100
440/440 [==============================] - 7s 15ms/step - loss: 0.3320 - accuracy: 0.8943 - val_loss: 0.1707 - val_accuracy: 0.9955
Epoch 33/100
440/440 [==============================] - 7s 15ms/step - loss: 0.3324 - accuracy: 0.8913 - val_loss: 0.1615 - val_accuracy: 0.9966
Epoch 34/100
440/440 [==============================] - 7s 15ms/step - loss: 0.3119 - accuracy: 0.8997 - val_loss: 0.1527 - val_accuracy: 0.9969
Epoch 35/100
440/440 [==============================] - 7s 15ms/step - loss: 0.3023 - accuracy: 0.9048 - val_loss: 0.1453 - val_accuracy: 0.9980
Epoch 36/100
440/440 [==============================] - 7s 15ms/step - loss: 0.2975 - accuracy: 0.9054 - val_loss: 0.1382 - val_accuracy: 0.9972
Epoch 37/100
440/440 [==============================] - 7s 15ms/step - loss: 0.2871 - accuracy: 0.9097 - val_loss: 0.1306 - val_accuracy: 0.9980
Epoch 38/100
440/440 [==============================] - 7s 15ms/step - loss: 0.2904 - accuracy: 0.9056 - val_loss: 0.1243 - val_accuracy: 0.9974
Epoch 39/100
440/440 [==============================] - 7s 15ms/step - loss: 0.2743 - accuracy: 0.9153 - val_loss: 0.1183 - val_accuracy: 0.9980
Epoch 40/100
440/440 [==============================] - 7s 15ms/step - loss: 0.2664 - accuracy: 0.9213 - val_loss: 0.1126 - val_accuracy: 0.9977
Epoch 41/100
440/440 [==============================] - 7s 15ms/step - loss: 0.2616 - accuracy: 0.9167 - val_loss: 0.1071 - val_accuracy: 0.9977
Epoch 42/100
440/440 [==============================] - 7s 15ms/step - loss: 0.2566 - accuracy: 0.9200 - val_loss: 0.1023 - val_accuracy: 0.9980
Epoch 43/100
440/440 [==============================] - 7s 15ms/step - loss: 0.2459 - accuracy: 0.9218 - val_loss: 0.0972 - val_accuracy: 0.9980
Epoch 44/100
440/440 [==============================] - 7s 15ms/step - loss: 0.2322 - accuracy: 0.9352 - val_loss: 0.0923 - val_accuracy: 0.9980
Epoch 45/100
440/440 [==============================] - 7s 15ms/step - loss: 0.2221 - accuracy: 0.9346 - val_loss: 0.0882 - val_accuracy: 0.9980
Epoch 46/100
440/440 [==============================] - 7s 15ms/step - loss: 0.2275 - accuracy: 0.9339 - val_loss: 0.0838 - val_accuracy: 0.9983
Epoch 47/100
440/440 [==============================] - 7s 15ms/step - loss: 0.2204 - accuracy: 0.9369 - val_loss: 0.0806 - val_accuracy: 0.9980
Epoch 48/100
440/440 [==============================] - 7s 15ms/step - loss: 0.2092 - accuracy: 0.9417 - val_loss: 0.0760 - val_accuracy: 0.9983
Epoch 49/100
440/440 [==============================] - 7s 15ms/step - loss: 0.2083 - accuracy: 0.9433 - val_loss: 0.0727 - val_accuracy: 0.9983
Epoch 50/100
440/440 [==============================] - 7s 15ms/step - loss: 0.1990 - accuracy: 0.9446 - val_loss: 0.0693 - val_accuracy: 0.9983
Epoch 51/100
440/440 [==============================] - 7s 15ms/step - loss: 0.1853 - accuracy: 0.9527 - val_loss: 0.0661 - val_accuracy: 0.9983
Epoch 52/100
440/440 [==============================] - 7s 15ms/step - loss: 0.1866 - accuracy: 0.9499 - val_loss: 0.0630 - val_accuracy: 0.9983
Epoch 53/100
440/440 [==============================] - 7s 15ms/step - loss: 0.1900 - accuracy: 0.9467 - val_loss: 0.0596 - val_accuracy: 0.9989
Epoch 54/100
440/440 [==============================] - 7s 15ms/step - loss: 0.1855 - accuracy: 0.9493 - val_loss: 0.0569 - val_accuracy: 0.9989
Epoch 55/100
440/440 [==============================] - 7s 15ms/step - loss: 0.1794 - accuracy: 0.9524 - val_loss: 0.0547 - val_accuracy: 0.9989
Epoch 56/100
440/440 [==============================] - 7s 15ms/step - loss: 0.1723 - accuracy: 0.9560 - val_loss: 0.0519 - val_accuracy: 0.9991
Epoch 57/100
440/440 [==============================] - 7s 15ms/step - loss: 0.1723 - accuracy: 0.9523 - val_loss: 0.0496 - val_accuracy: 0.9991
Epoch 58/100
440/440 [==============================] - 7s 15ms/step - loss: 0.1664 - accuracy: 0.9565 - val_loss: 0.0479 - val_accuracy: 0.9991
Epoch 59/100
440/440 [==============================] - 7s 15ms/step - loss: 0.1605 - accuracy: 0.9606 - val_loss: 0.0457 - val_accuracy: 0.9991
Epoch 60/100
440/440 [==============================] - 7s 15ms/step - loss: 0.1573 - accuracy: 0.9582 - val_loss: 0.0437 - val_accuracy: 0.9991
Epoch 61/100
440/440 [==============================] - 7s 15ms/step - loss: 0.1571 - accuracy: 0.9597 - val_loss: 0.0426 - val_accuracy: 0.9991
Epoch 62/100
440/440 [==============================] - 7s 15ms/step - loss: 0.1575 - accuracy: 0.9586 - val_loss: 0.0404 - val_accuracy: 0.9991
Epoch 63/100
440/440 [==============================] - 7s 15ms/step - loss: 0.1553 - accuracy: 0.9581 - val_loss: 0.0387 - val_accuracy: 0.9991
Epoch 64/100
440/440 [==============================] - 7s 15ms/step - loss: 0.1395 - accuracy: 0.9646 - val_loss: 0.0374 - val_accuracy: 0.9991
Epoch 65/100
440/440 [==============================] - 7s 15ms/step - loss: 0.1436 - accuracy: 0.9660 - val_loss: 0.0360 - val_accuracy: 0.9991
Epoch 66/100
440/440 [==============================] - 7s 15ms/step - loss: 0.1433 - accuracy: 0.9594 - val_loss: 0.0344 - val_accuracy: 0.9991
Epoch 67/100
440/440 [==============================] - 7s 15ms/step - loss: 0.1394 - accuracy: 0.9631 - val_loss: 0.0330 - val_accuracy: 0.9991
Epoch 68/100
440/440 [==============================] - 7s 15ms/step - loss: 0.1354 - accuracy: 0.9659 - val_loss: 0.0323 - val_accuracy: 0.9991
Epoch 69/100
440/440 [==============================] - 7s 15ms/step - loss: 0.1273 - accuracy: 0.9688 - val_loss: 0.0306 - val_accuracy: 0.9991
Epoch 70/100
440/440 [==============================] - 7s 15ms/step - loss: 0.1305 - accuracy: 0.9668 - val_loss: 0.0292 - val_accuracy: 0.9991
Epoch 71/100
440/440 [==============================] - 7s 15ms/step - loss: 0.1300 - accuracy: 0.9687 - val_loss: 0.0285 - val_accuracy: 0.9991
Epoch 72/100
440/440 [==============================] - 7s 15ms/step - loss: 0.1257 - accuracy: 0.9689 - val_loss: 0.0274 - val_accuracy: 0.9994
Epoch 73/100
440/440 [==============================] - 7s 15ms/step - loss: 0.1207 - accuracy: 0.9716 - val_loss: 0.0264 - val_accuracy: 0.9991
Epoch 74/100
440/440 [==============================] - 7s 15ms/step - loss: 0.1168 - accuracy: 0.9714 - val_loss: 0.0254 - val_accuracy: 0.9991
Epoch 75/100
440/440 [==============================] - 7s 15ms/step - loss: 0.1196 - accuracy: 0.9703 - val_loss: 0.0248 - val_accuracy: 0.9991
Epoch 76/100
440/440 [==============================] - 7s 15ms/step - loss: 0.1139 - accuracy: 0.9727 - val_loss: 0.0240 - val_accuracy: 0.9991
Epoch 77/100
440/440 [==============================] - 7s 15ms/step - loss: 0.1158 - accuracy: 0.9717 - val_loss: 0.0230 - val_accuracy: 0.9991
Epoch 78/100
440/440 [==============================] - 7s 15ms/step - loss: 0.1092 - accuracy: 0.9751 - val_loss: 0.0221 - val_accuracy: 0.9994
Epoch 79/100
440/440 [==============================] - 7s 15ms/step - loss: 0.1105 - accuracy: 0.9736 - val_loss: 0.0216 - val_accuracy: 0.9991
Epoch 80/100
440/440 [==============================] - 7s 15ms/step - loss: 0.1032 - accuracy: 0.9755 - val_loss: 0.0207 - val_accuracy: 0.9991
Epoch 81/100
440/440 [==============================] - 7s 15ms/step - loss: 0.1066 - accuracy: 0.9746 - val_loss: 0.0201 - val_accuracy: 0.9991
Epoch 82/100
440/440 [==============================] - 7s 15ms/step - loss: 0.1051 - accuracy: 0.9744 - val_loss: 0.0195 - val_accuracy: 0.9994
Epoch 83/100
440/440 [==============================] - 7s 15ms/step - loss: 0.1026 - accuracy: 0.9764 - val_loss: 0.0193 - val_accuracy: 0.9991
Epoch 84/100
440/440 [==============================] - 7s 15ms/step - loss: 0.1006 - accuracy: 0.9750 - val_loss: 0.0184 - val_accuracy: 0.9991
Epoch 85/100
440/440 [==============================] - 7s 15ms/step - loss: 0.1040 - accuracy: 0.9731 - val_loss: 0.0181 - val_accuracy: 0.9994
Epoch 86/100
440/440 [==============================] - 7s 15ms/step - loss: 0.1038 - accuracy: 0.9721 - val_loss: 0.0173 - val_accuracy: 0.9991
Epoch 87/100
440/440 [==============================] - 7s 15ms/step - loss: 0.0989 - accuracy: 0.9763 - val_loss: 0.0169 - val_accuracy: 0.9991
Epoch 88/100
440/440 [==============================] - 7s 15ms/step - loss: 0.0943 - accuracy: 0.9802 - val_loss: 0.0163 - val_accuracy: 0.9991
Epoch 89/100
440/440 [==============================] - 7s 15ms/step - loss: 0.0906 - accuracy: 0.9802 - val_loss: 0.0163 - val_accuracy: 0.9994
Epoch 90/100
440/440 [==============================] - 7s 15ms/step - loss: 0.0904 - accuracy: 0.9792 - val_loss: 0.0158 - val_accuracy: 0.9994
Epoch 91/100
440/440 [==============================] - 7s 15ms/step - loss: 0.0901 - accuracy: 0.9804 - val_loss: 0.0151 - val_accuracy: 0.9994
Epoch 92/100
440/440 [==============================] - 7s 15ms/step - loss: 0.0901 - accuracy: 0.9790 - val_loss: 0.0147 - val_accuracy: 0.9994
Epoch 93/100
440/440 [==============================] - 7s 15ms/step - loss: 0.0839 - accuracy: 0.9831 - val_loss: 0.0145 - val_accuracy: 0.9994
Epoch 94/100
440/440 [==============================] - 7s 15ms/step - loss: 0.0840 - accuracy: 0.9827 - val_loss: 0.0140 - val_accuracy: 0.9991
Epoch 95/100
440/440 [==============================] - 7s 15ms/step - loss: 0.0875 - accuracy: 0.9809 - val_loss: 0.0136 - val_accuracy: 0.9994
Epoch 96/100
440/440 [==============================] - 7s 15ms/step - loss: 0.0771 - accuracy: 0.9838 - val_loss: 0.0133 - val_accuracy: 0.9994
Epoch 97/100
440/440 [==============================] - 7s 15ms/step - loss: 0.0878 - accuracy: 0.9767 - val_loss: 0.0128 - val_accuracy: 0.9994
Epoch 98/100
440/440 [==============================] - 7s 15ms/step - loss: 0.0812 - accuracy: 0.9837 - val_loss: 0.0128 - val_accuracy: 0.9994
Epoch 99/100
440/440 [==============================] - 7s 15ms/step - loss: 0.0799 - accuracy: 0.9824 - val_loss: 0.0122 - val_accuracy: 0.9994
Epoch 100/100
440/440 [==============================] - 7s 15ms/step - loss: 0.0794 - accuracy: 0.9808 - val_loss: 0.0120 - val_accuracy: 0.9994
validation loss:0.011967930011451244
validation accuracy:0.9994316697120667



![ダウンロード.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/942550/2ef5751e-4a06-f9b2-6a8f-a075d9bae640.png)