繁体   English   中英

为什么当我使用更多的 epoch 来训练我的 CNN 时,我的测试准确率会下降

[英]Why my test accuracy falls when i use more epochs for training my CNN

我的 CNN 有问题。 我将我的模型训练了 50 个 epochs(使用了 BN,Dropouts),测试准确率达到了 92%。 在那之后,我再次训练了完全相同的网络,但训练了 100 个 epoch,使用相同的调整和泛化技术,我的测试集的准确率下降到 79%。 由于我的数据集很小,我使用了数据增强(水平和垂直翻转)。 我无法解释这一点,有人可以帮忙吗?

import numpy as np 
import tensorflow as tf
from numpy.random import seed
seed(1)

tf.compat.v1.set_random_seed(2)
from tensorflow.python.client import device_lib
print(device_lib.list_local_devices())
import tensorflow as tf
sess = tf.compat.v1.Session(config=tf.compat.v1.ConfigProto(log_device_placement=True))
gpu_options = tf.GPUOptions(allow_growth=True)
session = tf.InteractiveSession(config=tf.ConfigProto(gpu_options=gpu_options))
import os
os.environ['KERAS_BACKEND']='tensorflow'


import keras
from tensorflow.keras.models import Sequential
from tensorflow.keras.callbacks import Callback, ModelCheckpoint, ReduceLROnPlateau
from tensorflow.keras.layers import Dense, Dropout, Activation, Flatten, BatchNormalization
from tensorflow.keras.layers import Conv2D,MaxPooling2D
from keras.utils import np_utils
from tensorflow.keras.optimizers import SGD,Adam
from tensorflow.keras.metrics import categorical_crossentropy
from keras.preprocessing.image import ImageDataGenerator
from tensorflow.keras.layers import BatchNormalization
import matplotlib as plt
from matplotlib import pyplot as plt
from sklearn.metrics import confusion_matrix
import itertools

keras.initializers.glorot_normal(seed=42)

train_path='C:/Users/Panagiotis Gkanos/Desktop/dataset/40X/train'
train_batches=ImageDataGenerator(rescale=1./255,horizontal_flip=True,
vertical_flip=True).flow_from_direct ory(train_path,
                                                  target_size=[400,400],
                                                  classes=['malignant','benign'],
                                                  class_mode='categorical',batch_size=40)

valid_path='C:/Users/Panagiotis Gkanos/Desktop/dataset/40X/valid'
valid_batches=ImageDataGenerator(rescale=1./255).flow_from_directory(valid_path,
                                                  target_size=[400,400],
                                                  classes=['malignant','benign'],
                                                  class_mode='categorical',batch_size=20)

test_path='C:/Users/Panagiotis Gkanos/Desktop/dataset/40X/test'
test_batches=ImageDataGenerator(rescale=1./255).flow_from_directory(test_path,
                                                  target_size=[400,400],
                                                  classes=['malignant','benign'],
                                                  class_mode='categorical',batch_size=20)


model=Sequential()

model.add(Conv2D(16,(3,3),strides=2,padding='same',input_shape=(400,400,3)))
model.add(Activation('relu'))
model.add(BatchNormalization())
model.add(Conv2D(16,(3,3),strides=1,padding='same'))
model.add(Activation('relu'))
model.add(BatchNormalization())
model.add(Conv2D(16,(3,3),strides=1,padding='same'))
model.add(Activation('relu'))
model.add(BatchNormalization())
model.add(MaxPooling2D(pool_size=(2, 2),strides=2))



model.add(Conv2D(32,(3,3),strides=1,padding='same'))
model.add(Activation('relu'))
model.add(BatchNormalization())
model.add(Conv2D(32,(3,3),strides=1,padding='same'))
model.add(Activation('relu'))
model.add(BatchNormalization())
model.add(Conv2D(32,(3,3),strides=1,padding='same'))
model.add(Activation('relu'))
model.add(BatchNormalization())
model.add(MaxPooling2D(pool_size=(2, 2),strides=2))



model.add(Conv2D(64,(3,3),padding='same'))
model.add(Activation('relu'))
model.add(BatchNormalization())
model.add(MaxPooling2D(pool_size=(2, 2),strides=2))



model.add(Conv2D(128,(3,3),padding='same'))
model.add(Activation('relu'))
model.add(BatchNormalization())
model.add(MaxPooling2D(pool_size=(2, 2),strides=2))



model.add(Flatten())
model.add(Dense(256,activation='relu'))
model.add(Dropout(0.3))
model.add(Dense(128,activation='relu'))

model.add(Dropout(0.3))

model.add(Dense(2,activation='softmax'))
model.summary()

#learn_control = ReduceLROnPlateau(monitor='val_acc', patience=5,
                             # verbose=1,factor=0.2, min_lr=1e-7)

model.compile(optimizer=Adam(lr=0.001),loss='categorical_crossentropy',metrics=['accuracy'])
history=model.fit_generator(train_batches,steps_per_epoch=20 ,validation_data=valid_batches,
                        validation_steps=8 ,epochs=100)
#,callbacks=[learn_control])

model.evaluate(test_batches)

def plot_loss(history):
    train_loss=history.history['loss']
    val_loss=history.history['val_loss']
    x=list(range(1,len(val_loss)+1))
    plt.plot(x,val_loss,color='red',label='validation loss')
    plt.plot(x,train_loss,label='training loss')
    plt.xlabel('Epoch')
    plt.ylabel('Loss')
    plt.title('Loss vs. Epoch')
    plt.legend()
    plt.show()

def plot_accuracy(history):
    train_acc=history.history['acc']
    val_acc=history.history['val_acc']
    x=list(range(1,len(val_acc)+1))
    plt.plot(x,val_acc,color='red',label='validation acc')
    plt.plot(x,train_acc,label='training acc')
    plt.xlabel('Epoch')
    plt.ylabel('Accuracy')
    plt.title('Accuracy vs. Epoch')
    plt.legend()
    plt.show()

plot_loss(history)

plot_accuracy(history)

这就是所谓的“过拟合”。 如果您的网络在 50 个 epoch 时有更好的测试性能,您可能想就此打住。

在这种情况下,可能是因为数据集很小,网络将无法找到适合所有情况的通用模式。 相反,它适合训练数据中的小重复细节。

例如,如果您要训练 CNN 执行动物分类、鸟类或狗分类,则仅使用训练集中的蓝色鸟类和训练集中的各种颜色的狗。 如果你用一张蓝色以外的任何颜色的鸟图片来测试你的网络,它很可能会被归类为狗,因为你的网络了解到所有蓝色都是鸟,其他所有都是狗,而不是学习什么特征是鸟类独有的,哪些特征是狗独有的。

简而言之,您可能只需要一个更大、更多样化的数据集。 您还可以实施提前停止,这将在网络过度拟合数据之前停止训练。 否则你可以尝试其他形式的正则化,但这是一个很难克服的问题。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM