python - 历史和预测中的 TensorFlow Accuracy 不匹配
问题描述
我尝试用 Xception 网络做一些迁移学习,在训练过程中,结果看起来不错:
Epoch 1/50
34/34 [==============================] - 357s 9s/step - loss: 1.6063 - categorical_accuracy: 0.3968 - val_loss: 1.1356 - val_categorical_accuracy: 0.5428
Epoch 2/50
34/34 [==============================] - 370s 9s/step - loss: 1.0475 - categorical_accuracy: 0.6025 - val_loss: 1.0545 - val_categorical_accuracy: 0.6580
Epoch 3/50
34/34 [==============================] - 386s 10s/step - loss: 0.9220 - categorical_accuracy: 0.6655 - val_loss: 1.0960 - val_categorical_accuracy: 0.6059
Epoch 4/50
24/34 [====================>.........] - ETA: 1:17 - loss: 0.9283 -
但经过预测,结果更糟:
from sklearn.metrics import classification_report, confusion_matrix
print(confusion_matrix(true_categories_argmax, predictions_argmax))
print(classification_report(true_categories_argmax, predictions_argmax))
[[29 25 1 18 3 4]
[33 27 1 18 1 13]
[ 4 1 0 1 0 0]
[21 18 1 6 1 4]
[ 1 5 0 5 1 0]
[10 11 0 6 0 0]]
precision recall f1-score support
0 0.30 0.36 0.33 80
1 0.31 0.29 0.30 93
2 0.00 0.00 0.00 6
3 0.11 0.12 0.11 51
4 0.17 0.08 0.11 12
5 0.00 0.00 0.00 27
accuracy 0.23 269
macro avg 0.15 0.14 0.14 269
weighted avg 0.22 0.23 0.23 269
为什么准确率是前面所说的准确率的一半?
这里的代码:
image_size = (299,299)
batch_size = 32
train_ds = tf.keras.preprocessing.image_dataset_from_directory(
"Bilder_sortiert",
validation_split=0.2,
labels="inferred",
subset="training",
seed=1337,
image_size=image_size,
batch_size=batch_size,
label_mode='categorical',
)
validation_ds = tf.keras.preprocessing.image_dataset_from_directory(
"Bilder_sortiert",
validation_split=0.2,
subset="validation",
seed=1337,
image_size=image_size,
batch_size=batch_size,
label_mode='categorical',
labels="inferred",
)
batch_size = 32
train_ds = train_ds.prefetch(buffer_size=32)
validation_ds = validation_ds.prefetch(buffer_size=32)
data_augmentation = keras.Sequential(
[
layers.experimental.preprocessing.RandomFlip(), #"horizontal"
layers.experimental.preprocessing.RandomRotation(0.1),#0.1
]
)
base_model = keras.applications.Xception(
weights="imagenet", # Load weights pre-trained on ImageNet.
input_shape=(299, 299, 3),
include_top=False,
) # Do not include the ImageNet classifier at the top.
# Freeze the base_model
base_model.trainable = False
# Create new model on top
inputs = keras.Input(shape=(299, 299, 3))
x = data_augmentation(inputs)
# Pre-trained Xception weights requires that input be normalized
# from (0, 255) to a range (-1., +1.), the normalization layer
# does the following, outputs = (inputs - mean) / sqrt(var)
norm_layer = keras.layers.experimental.preprocessing.Normalization()
mean = np.array([127.5] * 3)
var = mean ** 2
# Scale inputs to [-1, +1]
x = norm_layer(x)
norm_layer.set_weights([mean, var])
x = base_model(x, training=False)
x = keras.layers.GlobalAveragePooling2D()(x)
x = keras.layers.Dropout(0.4)(x) # Regularize with dropout
outputs = keras.layers.Dense(6,activation='softmax')(x)
model = keras.Model(inputs, outputs)
model.summary()
"""
## Train the top layer
"""
model.compile(
optimizer=keras.optimizers.Adam(0.01),
loss=tf.keras.losses.categorical_crossentropy,
metrics=["categorical_accuracy"],
)
epochs = 50
model.fit(train_ds, epochs=epochs, validation_data=validation_ds)
hist=model.history.history
base_model.trainable = True
model.summary()
model.compile(
optimizer=keras.optimizers.Adam((1e-5)),#(1e-5), # Low learning rate
loss=tf.keras.losses.categorical_crossentropy,
metrics=["categorical_accuracy"],
)
epochs = 10
model.fit(train_ds, epochs=epochs, validation_data=validation_ds)
"""
After 10 epochs, fine-tuning gains us a nice improvement here.
"""
zeit=time.time()-start
print("Fitting took ",zeit," seconds")
x1=np.linspace(1,50)
x2=np.linspace(50,96,45)
ca=model.history.history["categorical_accuracy"]
ca.append(hist["categorical_accuracy"][-1])
vca=model.history.history["val_categorical_accuracy"]
plt.plot(x1,hist["categorical_accuracy"],label="dense training")
plt.plot(x1,hist["val_categorical_accuracy"],label="dense validation")
plt.plot(x2,ca[0:45],label="fine tuning training")
plt.plot(x2,vca[0:45],label="fine tuning validation")
plt.xlabel("Epochs")
plt.ylabel("Accuracy")
plt.legend()
model_eval=model
#val_inputs = tf.concat([x for x, y in validation_ds], axis=0)
predictions=model_eval.predict(validation_ds)
predictions_argmax=np.argmax(predictions, axis = 1)
true_categories = tf.concat([y for x, y in validation_ds], axis=0)
true_categories_argmax=np.argmax(true_categories, axis = 1)
print(true_categories.shape[0]," images in validation data")
print("Confusion Matrix")
from sklearn.metrics import classification_report, confusion_matrix
print(confusion_matrix(true_categories_argmax, predictions_argmax))
print(classification_report(true_categories_argmax, predictions_argmax))
我希望准确度应该与上次打印的 val_acc 大致相同。对于其他人来说,这似乎也是一个问题,但我认为没有人找到一个好的解决方法: https ://github.com/keras-team/keras/issues/10014
解决方案
推荐阅读
- android - 无法从新设备上的 NotificationListenerService 获取通知图标
- javascript - 如何使用标准 JavaScript 取消选中所有 asp.net 复选框?
- python - 如何将一个列表的元素与另一个大小不同的列表的元素相乘?
- python - 在 Python 中打开库文件时是否应该使用 with 语句
- flutter - 更改换行到下一行的项目的位置
- java - 如何获取当前请求的 URI?
- typescript - 这不是您要查找的 tsc 命令
- sql-server - 更改索引而不是表的权限
- php - PHP在嵌套多维数组中重复以组合某些值
- ios - 复制/粘贴没有格式的纯文本