質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

ただいまの
回答率

87.34%

プログラム実行後、model.fitから複数回実行する場合にaccuracyが高いことについて

解決済

回答 1

投稿

  • 評価
  • クリップ 0
  • VIEW 721

score 22

この質問を改めて質問させていただきます。
Jupyter notebookでデータ拡張した場合の予測正解確率を調べています。
以下のプログラムを複数回実行すれば、その都度、予測正解率は異なるは思いますが、毎回大きく異なります。また、プログラムを最後まで1度実行したあと、(Jupyterを閉じずに)model.fitから2回目(複数回)を実行した時、既にaccuracyが高いように思われます(以下参照)。この場合、accuracyが1回前の学習状態を引き続いて実行される?ことはあるのでしょうか。

1回目と2回目の結果

# import library
import keras
import matplotlib.pyplot as plt
import numpy as np
import os
import pandas as pd
import seaborn as sn
import shutil
import tensorflow as tf
from datetime import datetime, timedelta, timezone
from keras import backend as ke
from keras.callbacks import Callback, ModelCheckpoint, EarlyStopping
from keras.datasets import mnist
from keras.layers import Dense, Dropout, Activation, Flatten, Conv2D, MaxPooling2D, BatchNormalization
from keras.models import Sequential
from keras.optimizers import RMSprop
from keras.preprocessing.image import ImageDataGenerator
from keras.utils import np_utils
from sklearn.metrics import confusion_matrix
from sklearn.model_selection import train_test_split
from tqdm import tqdm

# MNIST 読込み
mnist=keras.datasets.mnist
(x_train,y_train),(x_test,y_test)=mnist.load_data()
(x_train,y_train),(x_test,y_test)=(x_train[:80],y_train[:80]),(x_test[:20], y_test[:20])
#(x_train,y_train),(x_test,y_test)=(x_train[:160],y_train[:160]),(x_test[:40], y_test[:40])
#(x_train,y_train),(x_test,y_test)=(x_train[:800],y_train[:800]),(x_test[:200], y_test[:200])
#(x_train,y_train),(x_test,y_test)=(x_train[:8000],y_train[:8000]),(x_test[:2000], y_test[:2000])
x_train=x_train.reshape(x_train.shape[0],28,28,1)
x_test=x_test.reshape(x_test.shape[0],28,28,1)
x_train=x_train/255
x_test=x_test/255
print("x_train",x_train.shape)
print("x_test",x_test.shape)

# model
model = Sequential()
model.add(Conv2D(64, (3, 3), input_shape=(28,28,1), padding='same'))
BatchNormalization(axis=-1)
model.add(Activation('relu'))
model.add(Conv2D(64, (3, 3), padding='same'))
BatchNormalization(axis=-1)
model.add(Activation('relu'))
model.add(MaxPooling2D(pool_size=(2,2)))
model.add(Dropout(0.20))
model.add(Conv2D(64, (3, 3), padding='same'))
BatchNormalization(axis=-1)
model.add(Activation('relu'))
model.add(Conv2D(64, (3, 3), padding='same'))
BatchNormalization(axis=-1)
model.add(Activation('relu'))
model.add(MaxPooling2D(pool_size=(2,2)))
model.add(Dropout(0.20))
model.add(Conv2D(128, (3, 3), padding='same'))
BatchNormalization(axis=-1)
model.add(Activation('relu'))
model.add(Flatten())
model.add(Dense(64, activation='relu'))
model.add(Dense(10, activation='softmax'))
model.summary()

# model compile
model.compile(optimizer='adam',
              loss='sparse_categorical_crossentropy',
              metrics=['accuracy'])

# model fit
model.fit(x_train,y_train,epochs=40)

# evoluate for test data
loss,acc=model.evaluate(x_test,y_test,verbose=2)
print('loss:','{:.3f}'.format(loss),'accuracy:','{:.3f}'.format(acc))

# ImageDataGenerator
datagen = ImageDataGenerator( 
    featurewise_center=False,
    samplewise_center=False, 
    featurewise_std_normalization=False, 
    samplewise_std_normalization=False, 
    zca_whitening=False,  
    rotation_range=10, 
    width_shift_range=0.1, 
    height_shift_range=0.1,  
    zoom_range=[2.0,0.1], 
    horizontal_flip=False, 
    vertical_flip=False)  
datagen.fit(x_train) 

datagent = ImageDataGenerator(
    featurewise_center=False,
    samplewise_center=False,  
    featurewise_std_normalization=False, 
    samplewise_std_normalization=False,  
    zca_whitening=False,  
    rotation_range=10, 
    width_shift_range=0.1,  
    height_shift_range=0.1,
    zoom_range=[2.0,0.1],
    horizontal_flip=False,
    vertical_flip=False)
datagent.fit(x_test)

# parameter
# [sample] / [iteration] = [batch size]
# train : 80 / 5 = 16
# test  : 20 / 2 = 10

# train : 160 / 10 = 16
# test  :  40 /  5 = 8

# train : 800 / 50 = 16
# test  : 200 / 10 = 20

# train : 8000 / 250 = 32
# test  : 2000 / 125 = 16

# train : 60,000 / 500 = 120
# test  : 10,000 / 200 = 50

epochs = 1000
iteration_train = 5
iteration_test = 2
batch_size_train = int(x_train.shape[0] / iteration_train)
batch_size_test = int(x_test.shape[0] / iteration_test)


#プログラムを最後まで1度実行したあと、Jupyterを閉じずにここから2回目(複数回)を実行する


gen_train_flow = datagen.flow(x_train, y_train, batch_size=batch_size_train) 
gen_test_flow  = datagent.flow(x_test, y_test, batch_size=batch_size_test) 
history = model.fit(gen_train_flow,
                    steps_per_epoch=iteration_train,
                    epochs=epochs,
                    validation_data=gen_test_flow,
                    validation_steps=iteration_test)#,
                    #callbacks=callbacks)

# evoluate for test data
loss,acc=model.evaluate(x_test,y_test,verbose=2)
print('loss:','{:.3f}'.format(loss),'accuracy:','{:.3f}'.format(acc))

# graph for training
acc=history.history['accuracy']#acc
val_acc=history.history['val_accuracy']#val_acc
epochs=range(1,len(acc)+1)
plt.plot(epochs,acc,'b',label='Training accuracy')
plt.plot(epochs,val_acc,'r',label='Val accuracy')
plt.legend()
plt.show() 
  • 気になる質問をクリップする

    クリップした質問は、後からいつでもマイページで確認できます。

    またクリップした質問に回答があった際、通知やメールを受け取ることができます。

    クリップを取り消します

  • 良い質問の評価を上げる

    以下のような質問は評価を上げましょう

    • 質問内容が明確
    • 自分も答えを知りたい
    • 質問者以外のユーザにも役立つ

    評価が高い質問は、TOPページの「注目」タブのフィードに表示されやすくなります。

    質問の評価を上げたことを取り消します

  • 評価を下げられる数の上限に達しました

    評価を下げることができません

    • 1日5回まで評価を下げられます
    • 1日に1ユーザに対して2回まで評価を下げられます

    質問の評価を下げる

    teratailでは下記のような質問を「具体的に困っていることがない質問」、「サイトポリシーに違反する質問」と定義し、推奨していません。

    • プログラミングに関係のない質問
    • やってほしいことだけを記載した丸投げの質問
    • 問題・課題が含まれていない質問
    • 意図的に内容が抹消された質問
    • 過去に投稿した質問と同じ内容の質問
    • 広告と受け取られるような投稿

    評価が下がると、TOPページの「アクティブ」「注目」タブのフィードに表示されにくくなります。

    質問の評価を下げたことを取り消します

    この機能は開放されていません

    評価を下げる条件を満たしてません

    評価を下げる理由を選択してください

    詳細な説明はこちら

    上記に当てはまらず、質問内容が明確になっていない質問には「情報の追加・修正依頼」機能からコメントをしてください。

    質問の評価を下げる機能の利用条件

    この機能を利用するためには、以下の事項を行う必要があります。

回答 1

checkベストアンサー

0

毎回予測精度が大きく異なる点については、使うデータ量が少なすぎることが一因だと思います。

(x_train,y_train),(x_test,y_test)=(x_train[:80],y_train[:80]),(x_test[:20], y_test[:20])

テストデータが20件しかなければ、1個の正当の差で5%も精度が変わります。また、これだけ小さい量ですと、十分な汎化性能が得られていないことが原因だと思います。

次に、学習を引き継ぐかどうかですが、引き継ぎます。モデルの重みは、モデルを作成した段階(レイヤを追加した段階)で初期化されるので、その後、fitを繰り返せば、重みを引き継いだまま学習されます。

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2021/03/05 02:21 編集

    ご回答をどうもありがとうございます!。ずっと疑問に思っていたことなので、ご回答をうれしく思います。
    もとのMNISTが少なくても「拡張」すれば、正解率が安定して高くなるかと思いましたが、そこまでは期待できないようで。やはり、オリジナルデータの質・量は予測に影響するし、テストデータのaccuracyが高いからと言って、自作画像の予測正解率が高くなるわけではないと、素人が基本中の基本を確認した思いです。
    あと、すみません。もしよろしければ、ご意見をお伺いさせてください。私が参考にさせて頂いたプログラムや他のサイトさんでは、モデルを「保存」していました。このモデル保存の必要性が、よくわかりません。。例えば今回のように、学習データが少ない時や予測正解率が不安定な時(十分な汎化性能が得られない時)などは、実行の度にモデルを保存しておいて、あとでベストなモデル(予測確率がより高くなった時のモデル)を使用して予測する…な感じなのでしょうか。
    あと、基本的に、今回の質問のように、1回最後まで実行したあとでmodel.fit以降を何度も繰り返した実行結果は、正確な評価ではない(参照してはいけない)?ですよね。。そうなると、モデルやepochなどをぐじゃぐじゃ試して適切な値を探すのが、ますます大変になりそうです。。

    キャンセル

  • 2021/03/05 06:28

    モデルの保存の用途は簡単に言うと2つ存在すると思います。
    1つ目は学習が長時間に及ぶ場合、途中経過を保存しておき、バックアップを残しておくためです。
    2つ目は学習済モデルを別のアプリケーションに使用するためです。例えば、手書き画像の認識モデルを完成させたら、OCRのような用途で使用することが考えられますが、その際に毎回0から学習させるのは非効率です。そのため、学習済モデルを保存しておき、利用します。また、1つ目と少し被りますが、新たな学習データが手に入った際に、1から学習しなおさず、学習済モデルに対して追加学習することも多いです。

    次に、評価についてですが、fitを繰り返すことはepochs数を増やすことに相当するので、そこまで問題にはならないと思います。ただし、評価が正確ではないというのは正しい部分もあり、学習ごとのtestセットのAccで見てしまうと、testセットに過剰に適合しているだけの可能性があります。対策としては、データセットをtrain,valid,testの3分割にする方法がよく用いられます。

    学習の安定性・正当性という意味では、もし余力があれば、cross-valdationやearly-stoppingなどと呼ばれる手法についても学んでみるとよいかもしれません。

    キャンセル

  • 2021/03/06 03:47

    ご回答をどうもありがとうございます!。有益なアドバイス、感謝しかありません。
    モデルの保存の用途のご説明、とてもイメージできました。とりあえず、今回の例では、モデル保存不要で問題ないように思われます。モデル保存の有無は、気になっていたことの一つで、ようやく納得できました。
    評価のご説明も、まさに聞きたかったことでした。「fitを繰り返すことはepochs数を増やすこと」、すっきりです。実は、今回、teratailで質問する前に、stackoverflowで同じ質問をしたのですが、うまいこと意図を伝えることができず、なんだか別の問題の回答?を得てしまいました。結局、その回答(リンク先の質問を含め)の真意を理解することができず、、いずれにしても私の力不足です。
    https://stackoverflow.com/questions/66394376/running-multiple-times-is-there-any-impact-to-accuracy-of-image-classification/66407857#66407857
    本当に色々と勉強になりました。最後に頂いたアドバイスについて、少しずつ見てみたいと思います。どうもありがとうございました。

    キャンセル

15分調べてもわからないことは、teratailで質問しよう!

  • ただいまの回答率 87.34%
  • 質問をまとめることで、思考を整理して素早く解決
  • テンプレート機能で、簡単に質問をまとめられる

関連した質問

同じタグがついた質問を見る