用于图像分类的 Keras CNN 模型不能很好地泛化
Posted
技术标签:
【中文标题】用于图像分类的 Keras CNN 模型不能很好地泛化【英文标题】:Keras CNN model for image classification does not generalize well 【发布时间】:2019-09-22 15:46:06 【问题描述】:我想在 keras 中实现一个模型,用于基于频谱图的情绪分类(愤怒或非愤怒)。我使用 Friends 的音频数据集生成了频谱图。每个频谱图的长度为 8 秒。我总共有 9117 个训练样本、1006 个验证样本和 2402 个测试样本。
我使用了一个相对简单的 CNN 架构,我尝试了它 + 优化器 + 学习率 + 批量大小的不同组合,但似乎没有一个结果可以很好地概括...损失下降到一定程度,但验证损失增加每个时期。
这是我正在使用的模型:
model = Sequential()
model.add(Convolution2D(filters=32, kernel_size=3, strides=1,input_shape=input_shape, activation='relu', padding="same"))
model.add(MaxPooling2D(pool_size=(2, 2), strides=(2, 2)))
# model.add(ZeroPadding2D((1, 1)))
model.add(Convolution2D(filters=64, kernel_size=3, strides=1, activation='relu', padding="same"))
model.add(MaxPooling2D(pool_size=(2, 2), strides=(2, 2)))
model.add(Convolution2D(filters=128, kernel_size=3, strides=1, activation='relu', padding="same"))
model.add(MaxPooling2D((2, 2), strides=(2, 2)))
model.add(Flatten())
model.add(Dense(128, activation='relu'))
model.add(Dropout(0.5))
model.add(Dense(128, activation='relu'))
model.add(Dropout(0.5))
model.add(Dense(classes, activation='sigmoid')) #output layer
这是我加载图像的方式:
img_rows = 120
img_cols = 160
train_datagen = ImageDataGenerator(rescale=1./255)
validation_datagen = ImageDataGenerator(rescale=1./255)
test_datagen = ImageDataGenerator(rescale=1./255)
train_generator = train_datagen.flow_from_directory(
SPECTOGRAMS_DIRECTORY + TRAIN_SUBDIR,
target_size=(img_cols, img_rows),
batch_size=batch_size,
class_mode='binary')
validation_generator = validation_datagen.flow_from_directory(
SPECTOGRAMS_DIRECTORY + VALIDATION_SUBDIR,
target_size=(img_cols, img_rows),
batch_size=batch_size,
class_mode='binary')
test_generator = test_datagen.flow_from_directory(
SPECTOGRAMS_DIRECTORY + TEST_SUBDIR,
target_size=(img_cols, img_rows),
batch_size=1,
class_mode='binary',
shuffle=False)
input_shape=(img_cols, img_rows, channels)
opt = SGD(lr=0.001)
model.compile(loss='binary_crossentropy',
optimizer=opt,
metrics=['accuracy'])
history = 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,
verbose=2)
##EVALUATE
print("EVALUATE THE MODEL...")
score = model.evaluate_generator(generator=validation_generator,
steps=nb_validation_samples // batch_size)
频谱图如下所示:
正如我所说,我尝试使用不同的批量大小组合 (16,32,64),SGD 的学习率为 0.001,Adam 的学习率为 0.0001,但是对于每种组合,训练损失都会下降,而验证损失会上升.
【问题讨论】:
你可以尝试使用leaky ReLU激活。 【参考方案1】:模型似乎过拟合。您可以尝试以下方法来解决此问题。
如果可能,请尝试收集更多数据,或者您可以使用数据增强技术来增加样本数量。
您可以在 Keras 中使用 dropout 来减少过拟合。 (貌似已经加了dropout,可以试试调值)
谢谢
【讨论】:
以上是关于用于图像分类的 Keras CNN 模型不能很好地泛化的主要内容,如果未能解决你的问题,请参考以下文章
keras构建卷积神经网络(CNN(Convolutional Neural Networks))进行图像分类模型构建和学习
在 keras 中使用 CNN 对图像进行二值分类时正确预测的总数