質問編集履歴
2
実行結果と疑問点を更新しました。
title
CHANGED
|
@@ -1,1 +1,1 @@
|
|
|
1
|
-
データ拡張
|
|
1
|
+
データ拡張した場合、自作画像の予測正解率を上げるには?
|
body
CHANGED
|
@@ -1,7 +1,20 @@
|
|
|
1
1
|
初学者です。
|
|
2
|
-
MNISTデータを学習させた畳込みニューラルネットワークモデルを用いて、自作画像を予測してみました。
|
|
2
|
+
MNISTデータを学習させた畳込みニューラルネットワークモデルを用いて、自作画像を予測してみました。
|
|
3
|
+
回答者様のご助言のもと、[こちらのサイト](https://qiita.com/PoodleMaster/items/54c184d9f2f70cc011d0)を参考にさせていただき、データ拡張を試しました。結果、予測の正解率は上がりましたが、まだ不安定です。
|
|
3
|
-
どなたかアドバイスをお願いしてもよろしいでしょうか。
|
|
4
|
+
現状、減数させたMNISTデータを拡張して、自作画像の予測正解率を安定して上げたいと考えていますが、以下3点の疑問点があります。どなたかアドバイスをお願いしてもよろしいでしょうか。
|
|
4
5
|
|
|
6
|
+
■疑問点
|
|
7
|
+
・適切なepochsの設定方法
|
|
8
|
+
・モデル保存の必要性(CallBack設定?)※参照サイトでは保存していました。
|
|
9
|
+
・以下プログラムの「model.fit_generator」以降を複数回実行した場合、正解率が(大きく)異なる理由
|
|
10
|
+
※特に、減数させたMNISTを拡張した場合
|
|
11
|
+
※実行状況:Jupyter notebookで、以下プログラムのmodel.fit_generatorから複数回実行した場合、accuracyが1回前の実行の状態を引き続いて実行される?ことはあるのでしょうか。model.fit_generatorから2回目実行した時、既にaccuracyが高い気がします(以下参照)
|
|
12
|
+
|
|
13
|
+

|
|
14
|
+
|
|
15
|
+
----------------------------------------------------
|
|
16
|
+
本稿の詳細を示します。
|
|
17
|
+
|
|
5
18
|
以下の質問の続きです。
|
|
6
19
|
[画像認識の正解率が低い原因が分からない](https://teratail.com/questions/291520)
|
|
7
20
|
|
|
@@ -17,35 +30,38 @@
|
|
|
17
30
|
|
|
18
31
|
■結果
|
|
19
32
|
データ数↑=損失↓正確度↑=正解率↑となりました。
|
|
20
|
-
|
|
33
|
+
MNISTデータが少ない場合でも、データを拡張して8~9割の正解率が得られるようになりました。
|
|
21
|
-
どのような理由が考えられるのでしょうか。
|
|
22
|
-
なお、データ拡張の条件を変えてみましたが、正解率が1割ぐらい上下する程度の違いでした。
|
|
23
34
|
|
|
24
|
-
各MNISTデータ数に対し、データ拡張
|
|
35
|
+
各MNISTデータ数に対し、データを拡張して実行した結果
|
|
25
|
-

|
|
26
37
|
|
|
27
|
-
上記のloss, accuracy(for test data)の際の自作画像10ファイルの予測結果と予測確率
|
|
28
|
-

|
|
29
|
-
|
|
30
38
|
```# program
|
|
31
39
|
# import library
|
|
32
|
-
# for learning
|
|
33
|
-
from tensorflow import keras
|
|
34
|
-
from tensorflow.keras import datasets, layers, models
|
|
35
|
-
from tensorflow.keras.layers import Dense, Conv2D, Flatten, Dropout, MaxPooling2D
|
|
36
|
-
from tensorflow.keras.models import Sequential
|
|
37
|
-
from tensorflow.keras.preprocessing.image import ImageDataGenerator
|
|
38
|
-
# for predict
|
|
39
|
-
import
|
|
40
|
+
import keras
|
|
41
|
+
import matplotlib.pyplot as plt
|
|
42
|
+
import numpy as np
|
|
40
43
|
import os
|
|
41
|
-
import
|
|
44
|
+
import pandas as pd
|
|
45
|
+
import seaborn as sn
|
|
46
|
+
import shutil
|
|
47
|
+
import tensorflow as tf
|
|
42
|
-
from
|
|
48
|
+
from datetime import datetime, timedelta, timezone
|
|
43
|
-
from
|
|
49
|
+
from keras import backend as ke
|
|
50
|
+
from keras.callbacks import Callback, ModelCheckpoint, EarlyStopping
|
|
51
|
+
from keras.datasets import mnist
|
|
52
|
+
from keras.layers import Dense, Dropout, Activation, Flatten, Conv2D, MaxPooling2D, BatchNormalization
|
|
53
|
+
from keras.models import Sequential
|
|
54
|
+
from keras.optimizers import RMSprop
|
|
55
|
+
from keras.preprocessing.image import ImageDataGenerator
|
|
56
|
+
from keras.utils import np_utils
|
|
57
|
+
from sklearn.metrics import confusion_matrix
|
|
58
|
+
from sklearn.model_selection import train_test_split
|
|
59
|
+
from tqdm import tqdm
|
|
44
60
|
|
|
45
61
|
# MNIST 読込み
|
|
46
62
|
mnist=keras.datasets.mnist
|
|
47
63
|
(x_train,y_train),(x_test,y_test)=mnist.load_data()
|
|
48
|
-
|
|
64
|
+
(x_train,y_train),(x_test,y_test)=(x_train[:80],y_train[:80]),(x_test[:20], y_test[:20])
|
|
49
65
|
#(x_train,y_train),(x_test,y_test)=(x_train[:160],y_train[:160]),(x_test[:40], y_test[:40])
|
|
50
66
|
#(x_train,y_train),(x_test,y_test)=(x_train[:800],y_train[:800]),(x_test[:200], y_test[:200])
|
|
51
67
|
#(x_train,y_train),(x_test,y_test)=(x_train[:8000],y_train[:8000]),(x_test[:2000], y_test[:2000])
|
|
@@ -56,85 +72,116 @@
|
|
|
56
72
|
print("x_train",x_train.shape)
|
|
57
73
|
print("x_test",x_test.shape)
|
|
58
74
|
|
|
59
|
-
#
|
|
75
|
+
# model
|
|
60
76
|
model = Sequential()
|
|
61
|
-
model.add(Conv2D(
|
|
77
|
+
model.add(Conv2D(64, (3, 3), input_shape=(28,28,1), padding='same'))
|
|
78
|
+
BatchNormalization(axis=-1)
|
|
79
|
+
model.add(Activation('relu'))
|
|
80
|
+
model.add(Conv2D(64, (3, 3), padding='same'))
|
|
81
|
+
BatchNormalization(axis=-1)
|
|
82
|
+
model.add(Activation('relu'))
|
|
62
83
|
model.add(MaxPooling2D(pool_size=(2,2)))
|
|
84
|
+
model.add(Dropout(0.20))
|
|
63
|
-
model.add(Conv2D(
|
|
85
|
+
model.add(Conv2D(64, (3, 3), padding='same'))
|
|
86
|
+
BatchNormalization(axis=-1)
|
|
87
|
+
model.add(Activation('relu'))
|
|
64
|
-
model.add(Conv2D(
|
|
88
|
+
model.add(Conv2D(64, (3, 3), padding='same'))
|
|
89
|
+
BatchNormalization(axis=-1)
|
|
90
|
+
model.add(Activation('relu'))
|
|
65
91
|
model.add(MaxPooling2D(pool_size=(2,2)))
|
|
66
|
-
model.add(Dropout(0.
|
|
92
|
+
model.add(Dropout(0.20))
|
|
93
|
+
model.add(Conv2D(128, (3, 3), padding='same'))
|
|
94
|
+
BatchNormalization(axis=-1)
|
|
95
|
+
model.add(Activation('relu'))
|
|
67
96
|
model.add(Flatten())
|
|
68
|
-
model.add(Dense(
|
|
97
|
+
model.add(Dense(64, activation='relu'))
|
|
69
|
-
model.add(Dropout(0.25))
|
|
70
|
-
model.add(Dense(10,activation='softmax'))
|
|
98
|
+
model.add(Dense(10, activation='softmax'))
|
|
71
99
|
model.summary()
|
|
72
100
|
|
|
73
|
-
# model compile
|
|
101
|
+
# model compile
|
|
74
102
|
model.compile(optimizer='adam',
|
|
75
103
|
loss='sparse_categorical_crossentropy',
|
|
76
104
|
metrics=['accuracy'])
|
|
77
|
-
model.fit(x_train,y_train,epochs=5)
|
|
78
105
|
|
|
106
|
+
# model fit
|
|
107
|
+
model.fit(x_train,y_train,epochs=40)
|
|
108
|
+
|
|
79
109
|
# evoluate for test data
|
|
80
110
|
loss,acc=model.evaluate(x_test,y_test,verbose=2)
|
|
81
|
-
print('accuracy:',acc)
|
|
111
|
+
print('loss:','{:.3f}'.format(loss),'accuracy:','{:.3f}'.format(acc))
|
|
82
112
|
|
|
83
|
-
#
|
|
113
|
+
# ImageDataGenerator
|
|
84
|
-
datagen=ImageDataGenerator(
|
|
114
|
+
datagen = ImageDataGenerator(
|
|
115
|
+
featurewise_center=False,
|
|
116
|
+
samplewise_center=False,
|
|
117
|
+
featurewise_std_normalization=False,
|
|
118
|
+
samplewise_std_normalization=False,
|
|
119
|
+
zca_whitening=False,
|
|
120
|
+
rotation_range=10,
|
|
85
|
-
|
|
121
|
+
width_shift_range=0.1,
|
|
86
|
-
|
|
122
|
+
height_shift_range=0.1,
|
|
87
|
-
|
|
123
|
+
zoom_range=[2.0,0.1],
|
|
124
|
+
horizontal_flip=False,
|
|
125
|
+
vertical_flip=False)
|
|
126
|
+
datagen.fit(x_train)
|
|
88
127
|
|
|
89
|
-
# learn
|
|
90
|
-
|
|
128
|
+
datagent = ImageDataGenerator(
|
|
91
|
-
|
|
129
|
+
featurewise_center=False,
|
|
92
|
-
|
|
130
|
+
samplewise_center=False,
|
|
93
|
-
|
|
131
|
+
featurewise_std_normalization=False,
|
|
94
|
-
|
|
132
|
+
samplewise_std_normalization=False,
|
|
133
|
+
zca_whitening=False,
|
|
95
|
-
|
|
134
|
+
rotation_range=10,
|
|
135
|
+
width_shift_range=0.1,
|
|
136
|
+
height_shift_range=0.1,
|
|
137
|
+
zoom_range=[2.0,0.1],
|
|
138
|
+
horizontal_flip=False,
|
|
96
|
-
|
|
139
|
+
vertical_flip=False)
|
|
140
|
+
datagent.fit(x_test)
|
|
97
141
|
|
|
142
|
+
# parameter
|
|
143
|
+
# [sample] / [iteration] = [batch size]
|
|
144
|
+
# train : 80 / 5 = 16
|
|
145
|
+
# test : 20 / 2 = 10
|
|
146
|
+
|
|
147
|
+
# train : 160 / 10 = 16
|
|
148
|
+
# test : 40 / 5 = 8
|
|
149
|
+
|
|
150
|
+
# train : 800 / 50 = 16
|
|
151
|
+
# test : 200 / 10 = 20
|
|
152
|
+
|
|
153
|
+
# train : 8000 / 250 = 32
|
|
154
|
+
# test : 2000 / 125 = 16
|
|
155
|
+
|
|
156
|
+
# train : 60,000 / 500 = 120
|
|
157
|
+
# test : 10,000 / 200 = 50
|
|
158
|
+
|
|
159
|
+
epochs = 1000
|
|
160
|
+
iteration_train = 5
|
|
161
|
+
iteration_test = 2
|
|
162
|
+
batch_size_train = int(x_train.shape[0] / iteration_train)
|
|
163
|
+
batch_size_test = int(x_test.shape[0] / iteration_test)
|
|
164
|
+
|
|
165
|
+
gen_train_flow = datagen.flow(x_train, y_train, batch_size=batch_size_train)
|
|
166
|
+
gen_test_flow = datagent.flow(x_test, y_test, batch_size=batch_size_test)
|
|
167
|
+
history = model.fit(gen_train_flow,
|
|
168
|
+
steps_per_epoch=iteration_train,
|
|
169
|
+
epochs=epochs,
|
|
170
|
+
validation_data=gen_test_flow,
|
|
171
|
+
validation_steps=iteration_test)#,
|
|
172
|
+
#callbacks=callbacks)
|
|
173
|
+
|
|
98
174
|
# evoluate for test data
|
|
99
175
|
loss,acc=model.evaluate(x_test,y_test,verbose=2)
|
|
100
|
-
print('accuracy:',acc)
|
|
176
|
+
print('loss:','{:.3f}'.format(loss),'accuracy:','{:.3f}'.format(acc))
|
|
101
177
|
|
|
178
|
+
# graph for training
|
|
179
|
+
acc=history.history['accuracy']#acc
|
|
180
|
+
val_acc=history.history['val_accuracy']#val_acc
|
|
181
|
+
epochs=range(1,len(acc)+1)
|
|
182
|
+
plt.plot(epochs,acc,'b',label='Training accuracy')
|
|
183
|
+
plt.plot(epochs,val_acc,'r',label='Val accuracy')
|
|
102
|
-
|
|
184
|
+
plt.legend()
|
|
103
|
-
|
|
185
|
+
plt.show()
|
|
104
|
-
predname = ['pred0','pred1','pred2','pred3','pred4','pred5','pred6','pred7','pred8','pred9']
|
|
105
186
|
|
|
106
|
-
# predict
|
|
107
|
-
DIR = "phototest1"
|
|
108
|
-
files = os.listdir(DIR)
|
|
109
|
-
images = [] # for list
|
|
110
|
-
labels = []
|
|
111
|
-
preds = []
|
|
112
|
-
scores = []
|
|
113
|
-
predicts = []
|
|
114
|
-
for file in files:
|
|
115
|
-
file_path = os.path.join(DIR, file)
|
|
116
|
-
img = Image.open(file_path)
|
|
117
|
-
img = img.convert('L')
|
|
118
|
-
img = ImageOps.invert(img) # invertion
|
|
119
|
-
img = img.resize((28,28))
|
|
120
|
-
x = np.asarray(img, dtype='float32')
|
|
121
|
-
x2 = x/255
|
|
122
|
-
images.append(x2)
|
|
123
|
-
x2 = x2.reshape(-1,28,28,1)
|
|
124
|
-
predict = model.predict(x2)
|
|
125
|
-
predicts.append(predict)
|
|
126
|
-
|
|
127
|
-
# for print
|
|
128
|
-
label = int(file[0])
|
|
129
|
-
pred = int(np.argmax(predict))
|
|
130
|
-
score = round(np.max(predict) * 100,2)
|
|
131
|
-
labels.append(label)
|
|
132
|
-
preds.append(pred)
|
|
133
|
-
scores.append(score)
|
|
134
|
-
if label == pred:
|
|
135
|
-
answer = '〇'
|
|
136
|
-
else:
|
|
137
|
-
answer = '×'
|
|
138
|
-
print("ans",answer,truename[label],predname[pred],"probability",'{:.1f}%'.format(score))
|
|
139
|
-
|
|
140
187
|
```
|
1
結果とプログラムを更新しました。
title
CHANGED
|
@@ -1,1 +1,1 @@
|
|
|
1
|
-
データ拡張で正解率が上がらない
|
|
1
|
+
データ拡張で予測正解率が上がらない原因が分からない
|
body
CHANGED
|
@@ -1,30 +1,46 @@
|
|
|
1
1
|
初学者です。
|
|
2
|
-
MNISTデータを学習させた畳込みニューラルネットワークモデルを用いて、自作画像
|
|
2
|
+
MNISTデータを学習させた畳込みニューラルネットワークモデルを用いて、自作画像を予測してみました。でも、データ拡張をしても、予測の正解率は変わりませんでした。
|
|
3
|
+
どなたかアドバイスをお願いしてもよろしいでしょうか。
|
|
3
4
|
|
|
4
5
|
以下の質問の続きです。
|
|
5
6
|
[画像認識の正解率が低い原因が分からない](https://teratail.com/questions/291520)
|
|
6
7
|
|
|
7
|
-
MNISTデータ数を
|
|
8
|
+
MNISTデータ数を増やしながら「データ拡張なし・あり」を試しました。
|
|
8
|
-
自作画像は、0-9の10ファイル(10クラス分類)です。
|
|
9
|
+
予測に使った自作画像は、0-9の10ファイル(10クラス分類)です。
|
|
9
|
-
結果は、testデータの損失・正確度
|
|
10
|
+
結果は、testデータの損失・正確度と、自作画像を予測させた時の正解率です。
|
|
10
|
-
|
|
11
|
+
正解率=(正解数/10ファイル)×100(%)。
|
|
11
12
|
恥ずかしながら、プログラムは適切かどうか分かりません。間違いがあれば、ご指摘頂けると幸いです。
|
|
12
13
|
|
|
14
|
+
■予測させる自作画像
|
|
15
|
+
0,1,2,3,4,5,6,7,8,9の自作画像 (28ピクセル×28ピクセルで手書きしたpngファイル)10files
|
|
13
|
-
|
|
16
|
+

|
|
14
|
-
データ数↑=損失↓正確度↑=正解率↑となりました。おおよそ予想される結果が得られましたが、データを拡張しても、それほど正解率は上がりませんでした。データ拡張の条件を変えてみましたが、正解率が1割ぐらい上下する程度の違いでした。どのような理由が考えられるのでしょうか。
|
|
15
17
|
|
|
16
|
-
|
|
17
|
-
|
|
18
|
+
■結果
|
|
19
|
+
データ数↑=損失↓正確度↑=正解率↑となりました。
|
|
20
|
+
おおよそ予想される結果が得られましたが、データを拡張しても、それほど正解率は上がりませんでした。
|
|
21
|
+
どのような理由が考えられるのでしょうか。
|
|
22
|
+
なお、データ拡張の条件を変えてみましたが、正解率が1割ぐらい上下する程度の違いでした。
|
|
18
23
|
|
|
24
|
+
各MNISTデータ数に対し、データ拡張なし・ありで実行した結果
|
|
19
|
-

|
|
20
26
|
|
|
27
|
+
上記のloss, accuracy(for test data)の際の自作画像10ファイルの予測結果と予測確率
|
|
28
|
+

|
|
29
|
+
|
|
21
30
|
```# program
|
|
22
31
|
# import library
|
|
32
|
+
# for learning
|
|
23
33
|
from tensorflow import keras
|
|
24
34
|
from tensorflow.keras import datasets, layers, models
|
|
25
35
|
from tensorflow.keras.layers import Dense, Conv2D, Flatten, Dropout, MaxPooling2D
|
|
26
36
|
from tensorflow.keras.models import Sequential
|
|
27
37
|
from tensorflow.keras.preprocessing.image import ImageDataGenerator
|
|
38
|
+
# for predict
|
|
39
|
+
import glob
|
|
40
|
+
import os
|
|
41
|
+
import numpy as np
|
|
42
|
+
from PIL import Image, ImageOps
|
|
43
|
+
from numpy import as array
|
|
28
44
|
|
|
29
45
|
# MNIST 読込み
|
|
30
46
|
mnist=keras.datasets.mnist
|
|
@@ -83,4 +99,42 @@
|
|
|
83
99
|
loss,acc=model.evaluate(x_test,y_test,verbose=2)
|
|
84
100
|
print('accuracy:',acc)
|
|
85
101
|
|
|
102
|
+
# classname
|
|
103
|
+
truename = ['true0','true1','true2','true3','true4','true5','true6','true7','true8','true9']
|
|
104
|
+
predname = ['pred0','pred1','pred2','pred3','pred4','pred5','pred6','pred7','pred8','pred9']
|
|
105
|
+
|
|
106
|
+
# predict
|
|
107
|
+
DIR = "phototest1"
|
|
108
|
+
files = os.listdir(DIR)
|
|
109
|
+
images = [] # for list
|
|
110
|
+
labels = []
|
|
111
|
+
preds = []
|
|
112
|
+
scores = []
|
|
113
|
+
predicts = []
|
|
114
|
+
for file in files:
|
|
115
|
+
file_path = os.path.join(DIR, file)
|
|
116
|
+
img = Image.open(file_path)
|
|
117
|
+
img = img.convert('L')
|
|
118
|
+
img = ImageOps.invert(img) # invertion
|
|
119
|
+
img = img.resize((28,28))
|
|
120
|
+
x = np.asarray(img, dtype='float32')
|
|
121
|
+
x2 = x/255
|
|
122
|
+
images.append(x2)
|
|
123
|
+
x2 = x2.reshape(-1,28,28,1)
|
|
124
|
+
predict = model.predict(x2)
|
|
125
|
+
predicts.append(predict)
|
|
126
|
+
|
|
127
|
+
# for print
|
|
128
|
+
label = int(file[0])
|
|
129
|
+
pred = int(np.argmax(predict))
|
|
130
|
+
score = round(np.max(predict) * 100,2)
|
|
131
|
+
labels.append(label)
|
|
132
|
+
preds.append(pred)
|
|
133
|
+
scores.append(score)
|
|
134
|
+
if label == pred:
|
|
135
|
+
answer = '〇'
|
|
136
|
+
else:
|
|
137
|
+
answer = '×'
|
|
138
|
+
print("ans",answer,truename[label],predname[pred],"probability",'{:.1f}%'.format(score))
|
|
139
|
+
|
|
86
140
|
```
|