Tensorflow val_sparse_categorical_accuracy 不会随着训练而改变

Posted

技术标签:

【中文标题】Tensorflow val_sparse_categorical_accuracy 不会随着训练而改变【英文标题】:Tensorflow val_sparse_categorical_accuracy not changing with training 【发布时间】:2022-01-19 03:31:22 【问题描述】:

答案贴在下面

编辑:

我已将问题与MobileNetV3Large 的使用隔离开来。如果我使用像 Flatten->Dense(relu)->Dense() 这样的粗略顺序模型,那么验证数和训练数会发生变化。

原来的问题也用MobileNetV2复制。

所以我想问题变成了,“为什么 MobileNetV2 和 MobileNetV3 会产生异常的验证行为?”

原始问题

我在调用 Model.fit 时无法理解验证指标的行为。

我已将其简化为一个极其简单的测试用例(代码在底部)。

一个包含 30 个类别的 30 个示例的最小数据集,每个类别一个示例。是的,我知道这是退化的,会立即导致过度训练。 用于稀疏分类的MobileNetV3Large 模型。 我使用与训练完全相同的数据集进行验证。 (是的,这在现实生活中是一个糟糕的想法,但它很好地说明了我的问题)。

当我运行Model.fit 时,结果如下:

Dataset length: 30
Total categories: 30
Epoch 1/3
1/2 [==============================] - 15s 4s/step - loss: 3.6924 - sparse_categorical_accuracy: 0.0667 - val_loss: 3.4012 - val_sparse_categorical_accuracy: 0.0333
Epoch 2/3
2/2 [==============================] - 0s 234ms/step - loss: 3.2896 - sparse_categorical_accuracy: 0.1000 - val_loss: 3.4012 - val_sparse_categorical_accuracy: 0.0333
Epoch 3/3
2/2 [==============================] - 0s 234ms/step - loss: 2.9317 - sparse_categorical_accuracy: 0.2333 - val_loss: 3.4012 - val_sparse_categorical_accuracy: 0.0333

损失函数和稀疏分类准确度表明模型正在训练,但val_sparse_categorical_accuracy 顽固地保持在 0.0333(又名 1/30)。我只展示了前 3 个 epoch,但从过度训练到训练精度为 1.0,这一直是正确的。

此外,经过训练,我发现Model.predict 将为所有 30 个输入产生几乎相同的输出。

我的期望是,由于我使用 与训练完全相同的数据集进行验证,因此验证指标应该以与训练指标平行的方式变化(给予或接受批处理和序列效应)。

我的问题是: 为什么根据验证或predict,我的模型训练指标会发生变化,而模型似乎并未实际进行训练?

import datasets
import tensorflow as tf
import tensorflow.keras.applications as applications

print(tf.version.VERSION)

INPUT_SHAPE = (264, 189, 3)

train_dataset = tf.data.experimental.load(
    datasets.dataset_path('reified.dataset'))
print(f'Dataset length: len(train_dataset)')

labels = set([label.numpy() for _, label in train_dataset])
categories = len(labels)
print(f'Total categories: categories')

classifier_model = tf.keras.applications.MobileNetV3Large(
    classes=categories,
    include_top=True,
    weights=None,
    include_preprocessing=True,
    input_shape=INPUT_SHAPE)

train_dataset = train_dataset.shuffle(1024).batch(20)
classifier_model.compile(
    optimizer=tf.keras.optimizers.Adam(),
    loss=tf.keras.losses.SparseCategoricalCrossentropy(from_logits=False),
    metrics=[tf.keras.metrics.SparseCategoricalAccuracy()])

history = classifier_model.fit(train_dataset,
                               epochs=3,
                               validation_data=train_dataset)

复制粘贴复制案例 从教程修改: Basic classification

# TensorFlow and tf.keras
import tensorflow as tf

# Helper libraries
import numpy as np
import tensorflow.keras.applications as applications

INPUT_SHAPE = (32, 32, 3)

fashion_mnist = tf.keras.datasets.fashion_mnist

(train_images, train_labels), (test_images,
                               test_labels) = fashion_mnist.load_data()
# Pad the images out to 32x32 three-channel grayscale.
test_images = np.repeat(
    np.expand_dims(np.pad(test_images, ((0, 0), (0, 4), (0, 4))), 3), 3, 3)
train_images = np.repeat(
    np.expand_dims(np.pad(train_images, ((0, 0), (0, 4), (0, 4))), 3), 3, 3)

model = tf.keras.applications.MobileNetV3Large(classes=10,
                                               include_top=True,
                                               weights=None,
                                               input_shape=INPUT_SHAPE)

model.compile(
    optimizer='adam',
    loss=tf.keras.losses.SparseCategoricalCrossentropy(from_logits=False),
    metrics=['accuracy'])

model.fit(train_images,
          train_labels,
          epochs=10,
          validation_data=(test_images, test_labels))

test_loss, test_acc = model.evaluate(test_images, test_labels, verbose=2)

【问题讨论】:

这是怎么回事 - datasets.dataset_path('reified.dataset') @M.Innat,它只是映射到存储数据集的文件路径。 如何重现上述问题? 刚刚添加了一个可复制的复制案例和一个编辑。我已将问题与 MobileNetV3Large 的使用隔离开来,但还没有弄清楚 MobileNetV3Large 是什么导致了这种奇怪的行为。 在你上面的fashion-mnist中,你有没有发现异常的训练行为?因为我得到了大约 80% 的测试准确率。这不是您显示的静态验证分数。你有没有发现相同的? 【参考方案1】:

问题似乎是在模型上设置训练模式。

如果您将MobileNetV3Large 模型更改为子模型,验证行为将按预期工作,其中重要的细节是设置training=True

没有training=True,验证行为是错误的。

inputs = tf.keras.Input(INPUT_SHAPE)
model = tf.keras.applications.MobileNetV3Large(classes=10,
                                               include_top=True,
                                               weights=None,
                                               input_shape=INPUT_SHAPE)
outputs = model(inputs, training=True)
model = tf.keras.Model(inputs, outputs)

【讨论】:

以上是关于Tensorflow val_sparse_categorical_accuracy 不会随着训练而改变的主要内容,如果未能解决你的问题,请参考以下文章

如何让 Tensorflow Profiler 在 Tensorflow 2.5 中使用“tensorflow-macos”和“tensorflow-metal”工作

python [test tensorflow] test tensorflow installation #tensorflow

关于tensorflow的显存占用问题

java调用tensorflow训练好的模型

tensorflow新手必看,tensorflow入门教程,tensorflow示例代码

tensorflow 如何在线训练模型