我正在尝试使用 Keras 和 Python 构建一个简单的二进制图像分类器。每隔一个训练周期,准确性、损失、val_accuracy 和 val_loss 都会返回零。其他时期运行良好,训练进展正常。我正在使用 25000 张独特的图像进行训练,其中包含三组卷积和池化。我对训练/测试图像进行了 90-10 的分割,并且所有图像都被打乱。我目前正在为我的标签和数据使用 Adam 优化器和标准化 ImageDataGenerator。
这是错误:
Epoch 1/20
90/90 ━━━━━━━━━━━━━━━━━━━━ 170s 2s/step - accuracy: 0.9974 - loss: 0.4769 - val_accuracy: 0.7968 - val_loss: 0.9699
Epoch 2/20
90/90 ━━━━━━━━━━━━━━━━━━━━ 0s 1ms/step - accuracy: 0.0000e+00 - loss: 0.0000e+00 - val_accuracy: 0.0000e+00 - val_loss: 0.0000e+00
Epoch 3/20
90/90 ━━━━━━━━━━━━━━━━━━━━ 175s 2s/step - accuracy: 0.9988 - loss: 0.4260 - val_accuracy: 0.8052 - val_loss: 0.9283
Epoch 4/20
90/90 ━━━━━━━━━━━━━━━━━━━━ 0s 728us/step - accuracy: 0.0000e+00 - loss: 0.0000e+00 - val_accuracy: 0.0000e+00 - val_loss: 0.0000e+00
etc...
这是我的模型结构:
model1 = keras.models.Sequential([
keras.layers.Conv2D(16,(3,3), activation='relu', input_shape=(150, 150, 3)),
keras.layers.MaxPooling2D(2,2),
keras.layers.BatchNormalization(),
keras.layers.Conv2D(32,(3,3), activation='relu'),
keras.layers.MaxPooling2D(2,2),
keras.layers.BatchNormalization(),
keras.layers.Conv2D(64,(3,3), activation='relu'),
keras.layers.MaxPooling2D(2,2),
keras.layers.BatchNormalization(),
keras.layers.Flatten(),
keras.layers.Dense(512, activation='relu', kernel_regularizer=regularizers.l2(0.001)),
keras.layers.Dropout(0.2),
keras.layers.Dense(1, activation='sigmoid')
])
model1.compile(optimizer=Adam(learning_rate=0.0002), loss='binary_crossentropy', metrics=['accuracy'])
train_CD = ImageDataGenerator(rescale=1.0/255.)
train_generator_CD = train_CD.flow_from_directory(
'./images/cat_dog/train_data/',
target_size = (150, 150),
batch_size = 250,
class_mode = 'binary')
test_CD = ImageDataGenerator(rescale=1.0/255.)
test_generator_CD = test_CD.flow_from_directory(
'./images/cat_dog/test_data/',
target_size = (150, 150),
batch_size = 250,
class_mode = 'binary')
history1=model1.fit(
train_generator_CD,
validation_data = test_generator_CD,
epochs = 20,
steps_per_epoch = 90,
validation_steps = 10,
callbacks=[myCallback()]
)
问题可能出在你在
model.fit
中同时设置了
steps_per_epoch
和
validation_steps
。 你将
steps_per_epoch
设置为 90,将
validation_steps
设置为 10,这会导致每隔一个周期就出现奇怪的行为。
让我们来分解一下原因:
- steps_per_epoch :这决定了在认为一个周期完成之前从你的训练生成器中提取多少批次。你将其设置为 90,这意味着你的模型将在每个周期中训练 90 批次数据。由于你的批次大小为 250,因此你每个周期将训练 90 * 250 = 22500 张图像。
- validation_steps :这决定了在每个周期结束时从你的验证生成器中提取多少批次来评估指标。你将其设置为 10,这意味着你每个周期将使用 10 批次验证数据。
问题在于,当
validation_steps
小于验证数据中的批次数时,Keras 不会在每个周期都遍历所有验证数据。相反,它仅使用
validation_steps
指定的批次数。在你的情况下,你只有 10 个步骤用于 2500 张验证图像(25000 张图像的 10%),这意味着每 2.5 个周期才会看到整个验证集。
这种不一致的验证采样会导致你在每隔一个周期报告的指标(准确率、损失等)出现不稳定的行为。你在一个周期中看到的零值可能是由于模型仅在有限且可能不具有代表性的验证数据子集上进行评估造成的。
要解决这个问题,你可以尝试以下两种方法之一:
-
删除
validation_steps
参数: 这将强制 Keras 在每个周期结束时使用整个验证集,从而提供更准确和一致的验证指标。
history1=model1.fit(
train_generator_CD,
validation_data=test_generator_CD,
epochs=20,
steps_per_epoch=90,
callbacks=[myCallback()]
)
-
将
validation_steps
设置为覆盖整个验证集: 计算验证集中所需的步骤数,并相应地设置validation_steps
。在你的情况下,你拥有 2500 张验证图像,批次大小为 250,因此你需要 10 个验证步骤:
validation_steps = 2500 // 250
history1=model1.fit(
train_generator_CD,
validation_data=test_generator_CD,
epochs=20,
steps_per_epoch=90,
validation_steps=validation_steps,
callbacks=[myCallback()]
)
通过实施这些更改之一,你应该会看到你的验证指标以更一致且可靠的方式计算,而不会出现每隔一个周期就出现零值的情况。
标签:python,tensorflow,keras,image-classification From: 77668911