python - keras 分类器错误评估而学习很棒
问题描述
有小数据集
找到属于 2 个类别的 1836 张图像。找到属于 2 个类别的 986 个图像。
模型的标准架构
image_generator = ImageDataGenerator(
rescale=1./255,
validation_split=0.35
)
train_data_gen = image_generator.flow_from_directory(
directory=directory,
target_size=(IMG_SHAPE, IMG_SHAPE),
subset='training',
)
val_data_gen = image_generator.flow_from_directory(
directory=directory,
target_size=(IMG_SHAPE, IMG_SHAPE),
subset='validation',
)
---
model = tf.keras.models.Sequential([
tf.keras.layers.Conv2D(32, (3, 3), activation='relu', input_shape=(IMG_SHAPE, IMG_SHAPE, 3)),
tf.keras.layers.MaxPooling2D(2, 2),
tf.keras.layers.Conv2D(64, (3, 3), activation='relu'),
tf.keras.layers.MaxPooling2D(2, 2),
tf.keras.layers.Conv2D(128, (3, 3), activation='relu'),
tf.keras.layers.MaxPooling2D(2, 2),
tf.keras.layers.Conv2D(128, (3, 3), activation='relu'),
tf.keras.layers.MaxPooling2D(2, 2),
tf.keras.layers.Flatten(),
tf.keras.layers.Dense(512, activation='relu'),
tf.keras.layers.Dense(2, activation='softmax'),
])
model.compile(
optimizer='adam',
loss='categorical_crossentropy',
metrics=['accuracy']
)
BATCH_SIZE = 128
EPOCHS = 7
total_train, total_val = train_data_gen.samples, val_data_gen.samples
steps_per_epoch = int(np.ceil(total_train / float(BATCH_SIZE)))
validation_freq = int(np.ceil(total_val / float(BATCH_SIZE)))
history = model.fit(
train_data_gen,
epochs=EPOCHS,
steps_per_epoch=steps_per_epoch,
validation_data=val_data_gen,
validation_freq=validation_freq
)
获得完美的指标
Epoch 1/7
15/15 [==============================] - 66s 4s/step - loss: 1.0809 - accuracy: 0.4917
Epoch 2/7
15/15 [==============================] - 56s 4s/step - loss: 0.3475 - accuracy: 0.8729
Epoch 3/7
15/15 [==============================] - 60s 4s/step - loss: 0.1113 - accuracy: 0.9583
Epoch 4/7
15/15 [==============================] - 58s 4s/step - loss: 0.1987 - accuracy: 0.9109
Epoch 5/7
15/15 [==============================] - 59s 4s/step - loss: 0.1127 - accuracy: 0.9438
Epoch 6/7
15/15 [==============================] - 60s 4s/step - loss: 0.0429 - accuracy: 0.9854
Epoch 7/7
15/15 [==============================] - 49s 3s/step - loss: 0.0542 - accuracy: 0.9812
但是在我评估它之后,我完全偏向于一流的结果
它仅在我运行 1 个 epoch 时才有效,但缺乏准确性
评估代码
def make_pred(model, labled_dataset, IMG_SHAPE, img_path) -> LabelName:
def make_image(img_path):
# img = img_path.resize((IMG_SHAPE, IMG_SHAPE), Image.ANTIALIAS)
img = image.load_img(img_path, target_size=(IMG_SHAPE, IMG_SHAPE))
img = image.img_to_array(img)
return np.expand_dims(img, axis=0)
pred_id: List[List] = np.argmax(model.predict(make_image(img_path)), axis=1)
all_labels = list(labled_dataset.class_indices.keys())
return all_labels[int(pred_id)]
它有什么问题?
我应该在评估之前缩小源图像吗?
解决方案
我相信你需要做两件事。一种是调整您希望预测的图像的大小,然后像对训练图像所做的那样重新调整图像的大小。我还建议您设置 validation_freq=1 以便您可以设置验证损失和准确性的趋势。这使您可以查看模型相对于过度拟合等的表现。如果训练损失继续下降,但在以后的时期您的验证损失开始增加,您可以检测模型是否过度拟合。如果您看到过度拟合,请在密集的 512 节点密集层之后添加一个 Dropout 层。文档在这里。预测准确度应该接近最后一个时期的验证准确度。我还建议您考虑使用 keras 回调 ModelCheckpoint。文档在这里。将其设置为监控验证损失并保存具有最低验证损失的模型。然后加载保存的模型进行预测。最后,我发现使用可调整的学习率是有效的。keras 回调 ReduceLROnPlateau 使这很容易做到。文档在这里。设置它以监控验证丢失。如果在(参数耐心)耐心的 epoch 数之后验证损失未能减少,回调将自动将学习率降低一个因子(参数因子)。我使用因子=.5 和耐心=1。这允许您最初使用较大的学习率,并根据需要降低学习率,这样收敛速度会更快。在您的 val_data_gen 中设置 shuffle=False 中的另一件事,因此每次都以相同的顺序处理验证图像。
推荐阅读
- mule - XML 到 JSON 数据映射 - xml 的子类(子类)未显示为与 mule dataweave 中的 JSON 映射
- neural-network - 如何将 2 个 sklearn 模型保存在一个文件中
- powerbi - 无法使用 restapi 连接到 Power bi?
- postgresql - PostgreSQL:光栅到矢量的转换
- scala - 如何在 Scala 中弃用外部库?
- javascript - 如何使用 Typescript 在 Cypress 中向 .contains 添加超时?
- go-ethereum - bootnode -writeaddress 命令的输出长度是 64 字节,而不是预期的 128 字节,为什么?
- validation - Flutter:如何避免验证器中的特殊字符
- android - 获取孩子firebase android的数量并将所有孩子放在String arrayList中
- symfony - symfony phpunit 令牌存储