2017-09-07 19 views
3

私は分類したい2つのクラスの20000の白黒画像を含むデータセットを持っています(天気予報や株価チャートのような画像なので、事前にネットワークを使うことはできません) 。データセットは、 トレーニング用の18000個のイメージとテスト用の2000個のイメージに分割されています。私はKeras畳み込みニューラルネットワークを使ってそれを訓練しています。トレーニングセットで96%の精度 が得られましたが、テストセットで得られた結果は良くありません(50エポック後に82-83%で固まってしまいます)。私はそれが過剰適合のためかもしれないと思う。 あなたは私にこの問題を解決する何かを提案できますか?私はあなたに見えるように最終的な出力とコードを残す。CNNオーバーフィッティング(出力とコード付き)

281/281 [=============] - 132秒 - 損失:0.1024 - acc:0.9612 - val_loss:0.5836 - val_acc:0.8210

from keras.layers.normalization import BatchNormalization 
from keras.preprocessing.image import ImageDataGenerator 
from keras.models import Sequential 
from keras.layers import Conv2D, MaxPooling2D, ZeroPadding2D 
from keras.layers import Activation, Dropout, Flatten, Dense 
from keras import backend as K 
from keras.optimizers import SGD, RMSprop, Adam 
from keras.callbacks import ModelCheckpoint 


filepath="weights/weights-improvement-{epoch:02d}-{val_acc:.4f}.hdf5" 
checkpoint = ModelCheckpoint(filepath, monitor='val_acc', verbose=1, save_best_only=True, mode='max') 
callbacks_list = [checkpoint] 


img_width, img_height = 100, 1296 

train_data_dir = 'dataset/train' 
validation_data_dir = 'dataset/validation' 
nb_train_samples = 18000 
nb_validation_samples = 2000 
epochs = 100 
batch_size = 64 

input_shape = (img_width, img_height, 1) 

model = Sequential() 

model.add(Conv2D(32, (3, 3), input_shape=input_shape)) 
model.add(Activation('relu')) 
model.add(MaxPooling2D(pool_size=(2, 2))) 

model.add(ZeroPadding2D((1, 1))) 
model.add(Conv2D(32, (3, 3))) 
model.add(Activation('relu')) 
model.add(MaxPooling2D(pool_size=(2, 2))) 
model.add(Dropout(0.1)) 

model.add(ZeroPadding2D((1, 1))) 
model.add(Conv2D(64, (3, 3))) 
model.add(Activation('relu')) 
model.add(MaxPooling2D(pool_size=(2, 2))) 
model.add(Dropout(0.2)) 

model.add(ZeroPadding2D((1, 1))) 
model.add(Conv2D(128, (3, 3))) 
model.add(Activation('relu')) 
model.add(MaxPooling2D(pool_size=(2, 2))) 
model.add(Dropout(0.3)) 

model.add(ZeroPadding2D((1, 1))) 
model.add(Conv2D(256, (3, 3))) 
model.add(Activation('relu')) 
model.add(MaxPooling2D(pool_size=(2, 2))) 
model.add(Dropout(0.4)) 

model.add(ZeroPadding2D((1, 1))) 
model.add(Conv2D(512, (3, 3))) 
model.add(Activation('relu')) 
model.add(MaxPooling2D(pool_size=(2, 2))) 
model.add(Dropout(0.5)) 

model.add(Flatten()) 

model.add(Dense(256)) 
model.add(Activation('relu')) 
model.add(BatchNormalization()) 
model.add(Dropout(0.5)) 

model.add(Dense(256)) 
model.add(Activation('relu')) 
model.add(BatchNormalization()) 
model.add(Dropout(0.5)) 

model.add(Dense(1)) 
model.add(Activation('sigmoid')) 

model.compile(loss='binary_crossentropy', 
       optimizer=Adam(lr=0.001), 
       metrics=['accuracy']) 

model.save('model.h5') 

train_datagen = ImageDataGenerator(
    rescale=None, 
) 

test_datagen = ImageDataGenerator(rescale=None) 

train_generator = train_datagen.flow_from_directory(
    train_data_dir, color_mode='grayscale', 
    target_size=(img_width, img_height), 
    batch_size=batch_size, 
    class_mode='binary') 

validation_generator = test_datagen.flow_from_directory(
    validation_data_dir, color_mode='grayscale', 
    target_size=(img_width, img_height), 
    batch_size=batch_size, 
    class_mode='binary') 

model.fit_generator(
    train_generator, 
    steps_per_epoch=nb_train_samples // batch_size, 
    epochs=epochs, 
    validation_data=validation_generator, 
    validation_steps=nb_validation_samples // batch_size,callbacks=callbacks_list) 

答えて

2

あなたが原因いくつかの大規模な畳み込み層と二つの大きな完全に接続された層に、あなたのネットワーク - のパラメータの膨大な数を持っています。これはオーバーフィッティングにつながる可能性があります。私は彼らのサイズを減らすことを提案し、多分いくつかの層を完全に取り除くでしょう。

+1

私はこの点についていくつかの混乱があると思います。私は別の質問から引用するhttps://stackoverflow.com/questions/42528639/keras-cnn-training-accuracy-is-good-but-test-accuracy-is-very-low:「より浅いモデルは、より小さなネットワークからの恩恵はトレーニング時間の改善だけです」と述べています。これは、私が最後の2つのコンバレイヤーと1つの完全に接続されたレイヤーを取り除き、トレーニングaccが同じであったが、最も良いバリデーションaccは0.78になりました。 –

+0

@AlejandroRuiz、それは真実かもしれませんが、OPがこの大規模なネットワークをサポートするデータを持っていなければ、入力データを記憶し過ぎるので、一般化することはできません。だからこそあなたは小さいから始まり、覗き見を始めるのに比べて構築するのです – DJK

+0

私は途中でOPです。私はあなたが言うものを見ますが、私はなぜ彼らがない場合(0.78)よりも3層以上で、より良い検証精度(0.83)を得るのか理解しません。 –

1

オーバーフィットの問題があるので、正規化を試してみてください。あなたは各層を正規の人に付けることができます。私は通常、今度はカーネル正規化子と呼ばれる体重定規を使用します。 Kerasの正式文書はhttps://keras.io/regularizers/

で見つけることができますが、正解を最初に使ってみてください。また、より多くの訓練データを有することは、過適合を低減するのにも役立つが、より多くの訓練データを出すことは必ずしも可能ではない。

関連する問題