Colab 链接在这里:
数据导入如下
train_ds = tf.keras.preprocessing.image_dataset_from_directory(
main_folder,
validation_split=0.1,
subset="training",
label_mode='categorical',
seed=123,
image_size=(dim, dim))
val_ds = tf.keras.preprocessing.image_dataset_from_directory(
main_folder,
validation_split=0.1,
subset="validation",
label_mode='categorical',
seed=123,
image_size=(dim, dim))
模型训练如下
model = tf.keras.models.Sequential([
tf.keras.layers.experimental.preprocessing.Rescaling(1. / 255),
...
tf.keras.layers.Dense(2, activation='softmax')
])
model.compile(optimizer="adam", loss=tf.keras.losses.CategoricalCrossentropy(), metrics=['accuracy'])
我与获得正确的挣扎predicted categories
和右边true_categories
去工作分类报告:
y_pred = model.predict(val_ds, batch_size=1)
predicted_categories = np.argmax(y_pred, axis=1)
true_categories = tf.concat([y for x, y in val_ds], axis=0).numpy()
true_categories_argmax = np.argmax(true_categories, axis=1)
print(classification_report(true_categories_argmax, predicted_categories))
目前 epoch 的输出与分类报告相矛盾
Epoch 22/75
144/144 [==============================] - 7s 48ms/step - loss: 0.0611 - accuracy: 0.9776 - val_loss: 0.0768 - val_accuracy: 0.9765
模型上的验证集返回
model.evaluate(val_ds)
[==============================] - 0s 16ms/step - loss: 0.0696 - accuracy: 0.9784
[0.06963862478733063, 0.9784313440322876]
而分类报告则大不相同:
precision recall f1-score support
0.0 0.42 0.44 0.43 221
1.0 0.56 0.54 0.55 289
accuracy 0.49 510
macro avg 0.49 0.49 0.49 510
weighted avg 0.50 0.49 0.50 510
您设置label_mode='categorical'
然后这是一个多类分类,您需要softmax
在最后一个密集层中使用激活。因为 softmax 强制输出总和等于 1。您可以将它们解释为概率。有了sigmoid
它就不可能找到主导阶级。它可以不受限制地分配任何值。
我的模型的最后一层:Dense(5, activation = 'softmax')
我的模型损失: loss=tf.keras.losses.CategoricalCrossentropy()
,和你的一样。在这种情况下,标签是单热编码的。
说明:为了演示目的,我使用了 5 类分类,但它遵循相同的逻辑。
y_pred = model.predict(val_ds)
y_pred[:2]
>>> array([[0.28257513, 0.4343998 , 0.18222839, 0.04164065, 0.05915598],
[0.36404607, 0.08850227, 0.15335019, 0.21602921, 0.17807229]],
dtype=float32)
这说明每个类别的概率,例如第一个示例有 43% 的概率属于类别 2。您需要使用argmax
来查找类别索引。
predicted_categories = np.argmax(y_pred, axis = 1)
predicted_categories[:2]
array([1, 0])
我们现在有了预测的类。现在需要获取真正的类。
true_categories = tf.concat([y for x, y in val_ds], axis = 0).numpy() # convert to np array
true_categories[:2]
>>> array([[1., 0., 0., 0., 0.],
[0., 0., 0., 0., 1.]], dtype=float32)
如果您将此输入分类报告,您将获得以下信息:
ValueError: Classification metrics can't handle a mix of multilabel-indicator and multiclass targets
我们还需要做:
true_categories_argmax = np.argmax(true_categories, axis = 1)
true_categories_argmax[:2]
>>> array([0, 4])
现在可以进行比较了。
print(classification_report(true_categories_argmax, predicted_categories))
这应该会产生预期的结果:
precision recall f1-score support
0 0.55 0.43 0.48 129
1 0.53 0.83 0.64 176
2 0.48 0.56 0.52 120
3 0.75 0.72 0.73 152
4 0.66 0.31 0.42 157
编辑:类可能会被改组为tf.keras.preprocessing.image_dataset_from_directory
set shuffle = True
。对于val_ds
尝试设置shuffle = False
. 像这样:
val_ds = tf.keras.preprocessing.image_dataset_from_directory(
main_folder,
validation_split=0.1,
subset="validation",
shuffle = False,
label_mode='categorical',
seed=123,
image_size=(dim, dim))
Edit2:这是我想出的:
prediction_classes = np.array([])
true_classes = np.array([])
for x, y in val_ds:
prediction_classes = np.concatenate([prediction_classes,
np.argmax(model.predict(x), axis = -1)])
true_classes = np.concatenate([true_classes, np.argmax(y.numpy(), axis=-1)])
分类报告:
print(classification_report(true_classes, prediction_classes))
precision recall f1-score support
0.0 0.74 0.81 0.77 1162
1.0 0.80 0.72 0.75 1179
accuracy 0.77 2341
macro avg 0.77 0.77 0.76 2341
weighted avg 0.77 0.77 0.76 2341
本文收集自互联网,转载请注明来源。
如有侵权,请联系 [email protected] 删除。
我来说两句