python - 图像分类模型中非常高的过拟合
问题描述
我是 CNN 开发的初学者,在大学任务中,我的任务是为食品创建图像分类器。我使用的数据集是Recipes5k。它有101类食物:
我正在使用与 Tensorflow 配对的 Google Colab 来实现这一点,并且一直在关注Tensorflow 的图像分类初学者教程。
到目前为止,一切都清晰易懂,但在训练我的模型时遇到了一个问题:与训练准确度 (90%+) 相比,验证准确度非常低 (10-11%) . 我怀疑这可能是由于模型的过度拟合。到目前为止,我已经尝试了图像增强技术并将 dropout 应用于模型。这没有按预期工作,仅将准确率提高了约 5%。我在下面发布了必要的代码片段:
数据增强层:
data_augmentation = keras.Sequential(
[
layers.experimental.preprocessing.RandomFlip("horizontal",
input_shape=(img_height,
img_width,
3)),
layers.experimental.preprocessing.RandomRotation(0.1),
layers.experimental.preprocessing.RandomZoom(0.1),
]
)
模型:
model = Sequential([
data_augmentation,
layers.experimental.preprocessing.Rescaling(1./255),
layers.Conv2D(16, 3, padding='same', activation='relu'),
layers.MaxPooling2D(),
layers.Conv2D(32, 3, padding='same', activation='relu'),
layers.MaxPooling2D(),
layers.Conv2D(64, 3, padding='same', activation='relu'),
layers.MaxPooling2D(),
layers.Dropout(0.3),
layers.Flatten(),
layers.Dense(128, activation='relu'),
layers.Dense(num_classes)
])
型号总结:
Model: "sequential_2"
_________________________________________________________________
Layer (type) Output Shape Param #
=================================================================
sequential_1 (Sequential) (None, 224, 224, 3) 0
_________________________________________________________________
rescaling_2 (Rescaling) (None, 224, 224, 3) 0
_________________________________________________________________
conv2d_3 (Conv2D) (None, 224, 224, 16) 448
_________________________________________________________________
max_pooling2d_3 (MaxPooling2 (None, 112, 112, 16) 0
_________________________________________________________________
conv2d_4 (Conv2D) (None, 112, 112, 32) 4640
_________________________________________________________________
max_pooling2d_4 (MaxPooling2 (None, 56, 56, 32) 0
_________________________________________________________________
conv2d_5 (Conv2D) (None, 56, 56, 64) 18496
_________________________________________________________________
max_pooling2d_5 (MaxPooling2 (None, 28, 28, 64) 0
_________________________________________________________________
dropout (Dropout) (None, 28, 28, 64) 0
_________________________________________________________________
flatten_1 (Flatten) (None, 50176) 0
_________________________________________________________________
dense_2 (Dense) (None, 128) 6422656
_________________________________________________________________
dense_3 (Dense) (None, 101) 13029
=================================================================
Total params: 6,459,269
Trainable params: 6,459,269
Non-trainable params: 0
_________________________________________________________________
训练 250 个 epoch 后的结果
Epoch 250/250
121/121 [==============================] - 3s 25ms/step - loss: 0.2564 - accuracy: 0.9270 - val_loss: 17.6184 - val_accuracy: 0.1202
我可以使用哪些其他技术来提高模型的准确性?
更新:我遵循 Gerry P 的建议并编辑了我的最后一个密集层以使用 softmax 激活。1250 个 epoch 的训练结果显示训练准确度增加较慢,验证准确度增加约 5-6%。这改进了我的模型,但它仍然是一个非常低的准确度。
解决方案
对于您的最后一个密集层,将其更改为
layers.Dense(num_classes, activation='softmax')
model.compile()
使用中
loss='categorical_crossentropy'
如果您的标签是一种热编码。如果它们是整数,则使用
loss='sparse_categorical_crossentropy'
推荐阅读
- python - 过滤列表中的列表以获取所有第二个数字
- java - Spring Boot 之前从不同的模块加载 bean
- css - Flex 列环绕块不拉伸
- java - Android - 检查数据库中的一行是否存在
- ssas - 在 MDX 中计算取消订单的百分比
- r - 不能在 r 中做条形图
- mongoose - 条件依赖或字段内容
- java - 要求用户在不关闭程序的情况下输入双精度而不是字符串
- ruby-on-rails - 2 个带有索引 category_id 的相似表 - Postgres 生成的 2 个不同查询
- java - Java EBean 播放框架。findOne() 不工作?如何返回一个对象而不是 findList()?