【问题标题】:CNN model not learningCNN模型不学习
【发布时间】:2020-09-17 20:36:55
【问题描述】:

我正在构建一个 CNN 模型来对图像进行分类,但是,我猜我的模型没有学习,因为准确度和损失函数的值是恒定的。请参阅下面的代码:

构建图像训练、测试和验证数据集

import pandas as pd
from keras_preprocessing.image import ImageDataGenerator
import numpy as np

#Creating three datasets from the the 3 .txt files.
trainingfile = pd.read_table('data/training.txt', delim_whitespace=True, names=('class', 'image'))
testingfile = pd.read_table('data/testing.txt', delim_whitespace=True, names=('class', 'image'))
validationfile = pd.read_table('data/validation.txt', delim_whitespace=True, names=('class', 'image'))
#Changing target variable type
trainingfile = trainingfile.replace([0, 1, 2], ['class0', 'class1', 'class2'])
testingfile = testingfile.replace([0, 1, 2], ['class0', 'class1', 'class2'])
validationfile = validationfile.replace([0, 1, 2], ['class0', 'class1', 'class2'])

#Data augmentation
datagen=ImageDataGenerator()
train_datagen = ImageDataGenerator( 
    #Apliquem una mica de rotació no gaire ja que generalment les fotografies estaran centrades
    rotation_range=5,
    zoom_range=0.1)

#Final datasets containing the images 
train=train_datagen.flow_from_dataframe(dataframe=trainingfile, directory="data/", x_col="image", y_col="class", class_mode="categorical", target_size=(256,256),color_mode='rgb',batch_size=32)
test=datagen.flow_from_dataframe(dataframe=testingfile, directory="data/", x_col="image", y_col="class", class_mode="categorical", target_size=(256,256),color_mode='rgb',batch_size=32)
#No data augmentation to the validation dataset.
validation=datagen.flow_from_dataframe(dataframe=validationfile, directory="data/", x_col="image", y_col="class", class_mode="categorical", target_size=(256,256),color_mode='rgb', batch_size=32)

CNN 模型

from keras.models import Sequential
from keras.layers import Dense, Conv2D, Flatten, Activation, Dropout, MaxPooling2D, BatchNormalization
from keras.constraints import maxnorm

#Creació del model
model = Sequential()
#1r bloc convolució
model.add(Conv2D(32, kernel_size = (3, 3), activation='relu', input_shape=(256, 256,3)))
model.add(MaxPooling2D(pool_size=(2,2)))
model.add(BatchNormalization())
#2n bloc convolució
model.add(Conv2D(64, kernel_size=(3,3), activation='relu'))
model.add(MaxPooling2D(pool_size=(2,2)))
model.add(BatchNormalization())
#3r bloc convolució
model.add(Conv2D(64, kernel_size=(3,3), activation='relu'))
model.add(MaxPooling2D(pool_size=(2,2)))
model.add(BatchNormalization())
#4t bloc convolució
model.add(Conv2D(96, kernel_size=(3,3), activation='relu'))
model.add(MaxPooling2D(pool_size=(2,2)))
model.add(BatchNormalization())
#5e bloc convolució
model.add(Conv2D(32, kernel_size=(3,3), activation='relu'))
model.add(MaxPooling2D(pool_size=(2,2)))
model.add(BatchNormalization())
#Dropout
model.add(Dropout(0.2))
model.add(Flatten())
model.add(Dense(128, activation='relu'))
#model.add(Dropout(0.3))
model.add(Dense(3, activation = 'softmax'))

from keras import regularizers, optimizers
from keras.optimizers import RMSprop
from keras.callbacks import EarlyStopping
# Compile model
model.compile(optimizer='adam',loss="categorical_crossentropy",metrics=["accuracy"])
# Early stopping
es = EarlyStopping(monitor='val_loss', mode='min', verbose=1,patience=10)

训练模型

h=model.fit_generator(generator=train,
                      validation_data=validation,
                      epochs=50,
                      callbacks=[es])

结果

这是我第一次使用 fit_generator,也许我没有正确使用它?

【问题讨论】:

  • 尝试在fit_generator 方法上使用steps_per_epoch 参数。
  • 我想没有必要,因为它默认使用 len(train)

标签: python machine-learning keras deep-learning conv-neural-network


【解决方案1】:

从结果图像中可以看出,您只训练了 1 个 epoch。这可能是因为 EarlyStopping 过于严格。尝试在 EarlyStopping 回调中添加patience=3

es = EarlyStopping(monitor='val_loss', mode='min', verbose=1, patience=3)

编辑

过拟合示例:

查看此post 以了解有关如何处理过拟合的更多信息。

【讨论】:

  • 布埃纳斯佩德罗,谢谢你阿尤达!我已经修改了代码以运行 50 个 epoch 并且耐心为 10,因为我在 Internet 上看到常见值在 10-100 之间,具体取决于数据集的大小。结果似乎更好,至少线条不再变平。但是,我想现在我需要改进模型,因为我可以看到从 epoch 1 开始的过度拟合,而不是一个好的学习曲线。你有什么建议吗?相应地修改了代码。
  • 请在问题中添加新的学习曲线,以便我了解正在发生的事情。无论如何,我会建议你简化你的模型。首先尝试只使用一个卷积块并检查它是如何训练的。此外,您应该仔细检查数据。输入的值是多少?它们在哪个范围内? [0,1] 或 [0,255]。考虑到神经网络的输入应该总是标准化的。请检查这些事情并告诉我:)
  • 我所指的学习曲线是损失性能。如果我没有错,因为损失验证曲线 > 损失训练,这意味着存在过度拟合(请参阅链接:machinelearningmastery.com/…)。正如您所说,我已将模型简化为一个卷积块,并且它具有相同的行为。关于数据的规范化,据我所知,flow_from_dataframe 会自动对数据进行规范化。我的输入形状是 256 x 256 x 3(宽度、高度、通道 (RGB))的图像。
  • 过拟合不完全是这样。你的学习曲线看起来很正常,一点也不差,从 0.4 到 0.9 acc。验证损失 > 训练损失是正常的。当您的模型继续改进训练数据但验证数据变得更糟时,就会发生过度拟合。您的模型训练良好,直到 25 个 epoch(或多或少)然后它过度拟合(精度降低),如果您对 0.9 的精度感到满意,您可以使用该模型进行预测,如果不是,您可以尝试更改模型的架构(例如添加更多的 dropout 层以防止过度拟合)。
  • 明白!非常感谢!那我会继续努力的! :)
猜你喜欢
  • 1970-01-01
  • 2021-04-15
  • 1970-01-01
  • 2021-09-02
  • 1970-01-01
  • 2019-09-20
  • 2017-11-11
  • 1970-01-01
  • 2018-02-25
相关资源
最近更新 更多