简体   繁体   English

model.predict 的 Tensorflow 精度与 model.fit 的最终时期 val_accuracy 不匹配

[英]Tensorflow accuracy from model.predict does not match final epoch val_accuracy of model.fit

I am trying to match the accuracy of a model.predict call to the final val_accuracy of model.fit().我试图将 model.predict 调用的准确性与 model.fit() 的最终 val_accuracy 相匹配。 I am using tf dataset.我正在使用 tf 数据集。

val_ds = tf.keras.utils.image_dataset_from_directory(
    'my_path',
    validation_split=0.2,
    subset="validation",
    seed=38,
    image_size=(SIZE,SIZE),
)

The dataset setup for train_ds is similar. train_ds 的数据集设置类似。 I prefetch both...我都预取...

train_ds = train_ds.prefetch(buffer_size=AUTOTUNE)
val_ds = val_ds.prefetch(buffer_size=AUTOTUNE)

Than I get the labels for the val_ds so I can use them later比我得到 val_ds 的标签,所以我以后可以使用它们

true_categories = tf.concat([y for x, y in val_ds], axis=0)

My model我的 model

inputs = tf.keras.Input(shape=(SIZE, SIZE, 3))
# ... some other layers
outputs = tf.keras.layers.Dense( len(CLASS_NAMES), activation = tf.keras.activations.softmax)(intermediate)
model = tf.keras.Model(inputs, outputs)

Compiles fine编译良好

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

Seems to fit fine看起来很合适

history = model.fit(
  train_ds,
  validation_data=val_ds,
  epochs=10, 
  class_weight=class_weights) #i do weight the classes due to imbalance

The last epoch output最后一个纪元 output

Epoch 10: val_accuracy did not improve from 0.92291 176/176 [==============================] - 191s 1s/step - loss: 0.9876 - accuracy: 0.7318 - val_loss: 0.4650 - val_accuracy: 0.8580 Epoch 10: val_accuracy 没有从 0.92291 176/176 提高 [==============================] - 191s 1s/step -损失:0.9876 - 准确度:0.7318 - val_loss:0.4650 - val_accuracy:0.8580

Now I want to verify the val_accuracy == 0.8580 when I run model.predict()现在我想在运行 model.predict() 时验证 val_accuracy == 0.8580

predictions = model.predict(val_ds, verbose=2 ) 
flattened_predictions =  predictions.argmax(axis=1)
accuracy = metrics.accuracy_score(true_categories, flattened_predictions)
print ("Accuracy = ", accuracy)

Accuracy = 0.7980014275517487准确度 = 0.7980014275517487

I would have expected that to equal the last val accuracy, which was 0.8580, but it is off.我本来希望这等于最后一个 val 精度,即 0.8580,但它已关闭。 My val_ds uses a seed so I should be getting the images in the same order when I shuffle, right?我的 val_ds 使用种子,所以当我洗牌时,我应该以相同的顺序获取图像,对吧? Getting ground truth labels is a pain using datasets, but I think (???) my method is correct.使用数据集获取真实标签很痛苦,但我认为(???)我的方法是正确的。

I only have two classes and when I look at my predictions variable it looks like I am getting probabilities as I would expect, so I think I set up, compiled and fit my model correctly for sparse categorical cross entropy using softmax on my final layer output.我只有两个类,当我查看我的预测变量时,它看起来像我预期的那样得到概率,所以我想我设置、编译并正确拟合了我的 model,以便在我的最后一层 output 上使用 softmax 进行稀疏分类交叉熵.

predictions[:3] #show the first 3 predictions, the values sum to 1.0 as expected

array([[0.42447385, 0.5755262 ], [0.2162129, 0.7837871 ], [0.31917858, 0.6808214 ]], dtype=float32)数组([[0.42447385, 0.5755262], [0.2162129, 0.7837871], [0.31917858, 0.6808214]], dtype=float32)

What am I missing?我错过了什么?

I think this may be because model.fit() takes class weights into account when calculating accuracy, but class weights are not specified when you later verify the accuracy.我认为这可能是因为 model.fit() 在计算精度时考虑了 class 权重,但是在您稍后验证精度时未指定 class 权重。

There's some relevant discussion in the comments after the answer at When writing a custom loss function, should I use tf.reduce_mean, and if so how? 在写自定义损失 function 时,我应该使用 tf.reduce_mean 的答案之后的评论中有一些相关的讨论,如果可以,如何? Does it ever matter? 这有关系吗?

What you are missing is that your validation dataset is shuffled at every iteration.您缺少的是您的验证数据集在每次迭代时都会被打乱。

tf.keras.utils.image_dataset_from_directory has shuffle=True by default. tf.keras.utils.image_dataset_from_directory默认有shuffle=True And that shuffle method for a TensorFlow dataset has an argument reshuffle_each_iteration which is None by default. TensorFlow 数据集的shuffle方法有一个参数reshuffle_each_iteration ,默认为None Therefore it is shuffled everytime.因此,它每次都被洗牌。

The seed=38 parameter is used for tracking the samples that reserved for training and validation separately. seed=38参数用于跟踪分别为训练和验证保留的样本。 In other words, with seed argument we can follow which samples will be used for validation dataset and vice versa.换句话说,通过seed参数,我们可以跟踪哪些样本将用于验证数据集,反之亦然。

As an example:举个例子:

dataset = tf.data.Dataset.range(6)
dataset = dataset.shuffle(6, reshuffle_each_iteration=None, seed=154).batch(2)

print("First time iteration:")
for x in dataset:
    print(x)
print("\n")

print("Second time iteration")  
for x in dataset:
    print(x)

This will print:这将打印:

First time iteration:
tf.Tensor([2 1], shape=(2,), dtype=int64)
tf.Tensor([3 0], shape=(2,), dtype=int64)
tf.Tensor([5 4], shape=(2,), dtype=int64)


Second time iteration
tf.Tensor([4 3], shape=(2,), dtype=int64)
tf.Tensor([0 5], shape=(2,), dtype=int64)
tf.Tensor([2 1], shape=(2,), dtype=int64)

Relevant source code for tf.keras.utils.image_dataset_from_directory can be found here . tf.keras.utils.image_dataset_from_directory的相关源代码可以在这里找到。

If you want to match predictions with their respective labels, then you can loop over the dataset:如果您想将预测与它们各自的标签匹配,那么您可以遍历数据集:

predictions = []
labels = []
for x, y in val_ds:
    predictions.append(np.argmax(model(x), axis=-1))
    labels.append(np.argmax(y, axis=-1)

predictions = np.concatenate(predictions, axis=0)
labels = np.concatenate(labels, axis=0)

Then you can check accuracy.然后你可以检查准确性。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 keras model.fit 输出 - “val_accuracy 从 -inf 提高到 0.29846” - -inf 是什么意思? - keras model.fit output - "val_accuracy improved from -inf to 0.29846" - what does it mean by -inf? 为什么 model.predict() 的精度比具有相同 x_train 的 model.fit() 更差? - Why model.predict() is getting worse accuracy than model.fit() with the same x_train? model.predict 会导致 oom 问题,但 model.fit 不会: - model.predict leads to oom issues, but model.fit does not: 使用 model.predict() 显示准确度和损失 - Show accuracy and loss with model.predict() val_accuracy 不增加 - val_accuracy does not increase 为什么 model.predict() 手动计算的准确度与 model.evaluate() 的准确度不同 - Why accuracy manually calculated by model.predict() is different from model.evaluate()'s accuracy model.evaluate 和 model.predict 之间的准确度差异巨大 - Huge difference between in accuracy between model.evaluate and model.predict for tensorflow CNN model model.predict()和model.fit()做什么? - What do model.predict() and model.fit() do? model.fit vs model.predict-sklearn中的差异和用法 - model.fit vs model.predict - differences & usage in sklearn cnn model 用于二进制分类,86% val_accuracy 总是返回 1 - cnn model for binary classification with 86% val_accuracy always returning 1
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM