【问题标题】:tf.keras model.predict each time provides different valuestf.keras model.predict 每次提供不同的值
【发布时间】:2023-04-07 12:27:01
【问题描述】:

每次我跑:

y_true = np.argmax(tf.concat([y for x, y in train_ds], axis=0), axis=1)
y_pred = np.argmax(model.predict(train_ds), axis=1)

confusion_matrix(y_true, y_pred)

每次的结果都与我的理解不同: y_pred = np.argmax(model.predict(train_ds), axis=1) 每次都不一样。

澄清:我运行单元 1(训练)一次。和单元格 2(推理)几次。

为什么?

代码: 单元格 1 (jupyter)

import numpy as np
import tensorflow as tf
from tensorflow.keras.layers import Input, Conv2D, experimental
from tensorflow.keras.layers import MaxPool2D, Flatten, Dense 
from tensorflow.keras import Model
from tensorflow.keras.losses import categorical_crossentropy
from sklearn.metrics import accuracy_score


image_size = (100, 100)
batch_size = 32

train_ds = tf.keras.preprocessing.image_dataset_from_directory(
    directory,
    label_mode='categorical',
    validation_split=0.2,
    subset="training",
    seed=1337,
    color_mode="grayscale",
    image_size=image_size,
    batch_size=batch_size,
)


inputs = Input(shape =(100,100,1))
x = experimental.preprocessing.Rescaling(1./255)(inputs)
x = Conv2D (filters =4, kernel_size =3, padding ='same', activation='relu')(x)
x = Conv2D (filters =4, kernel_size =3, padding ='same', activation='relu')(x)
x = MaxPool2D(pool_size =2, strides =2, padding ='same')(x)

x = Conv2D (filters =8, kernel_size =3, padding ='same', activation='relu')(x)
x = Conv2D (filters =8, kernel_size =3, padding ='same', activation='relu')(x)
x = MaxPool2D(pool_size =2, strides =2, padding ='same')(x)

x = Flatten()(x)
x = Dense(units = 4, activation ='relu')(x)
x = Dense(units = 4, activation ='relu')(x)
output = Dense(units = 5, activation ='softmax')(x)

model = Model (inputs=inputs, outputs =output)

model.compile(
    optimizer=tf.keras.optimizers.Adam(1e-3),
    loss=categorical_crossentropy,
    metrics=["accuracy"])

model.fit(train_ds, epochs=5)

细胞 2

print (Accuracy:)
y_pred = np.argmax(model.predict(train_ds), axis=1)
print (accuracy_score(y_true, y_pred))

y_pred = np.argmax(model.predict(train_ds), axis=1)
print (accuracy_score(y_true, y_pred))

输出

118/118 [===============================] - 7 秒 57 毫秒/步 - 损失:0.1888 - 准确度: 0.9398

准确度:

0.593

0.586

【问题讨论】:

  • 那么,你没有种下任何种子吗?没有模型保存?
  • 每次都是什么意思?你在运行整个脚本吗?因为在您的代码中,model.predict 只运行一次。
  • 这很难相信,因为您的模型中没有随机分量(如 MC-Dropout),因此您可能需要提供预测结果有何不同(包括值)的证据。
  • 也许你应该把 model.predict 放在它自己的单元格中,以确保其他东西不会干扰,然后多次运行它。
  • 你能用 2 次运行更新问题吗?预测和准确性有何不同?

标签: tensorflow keras tf.keras


【解决方案1】:

据我目前的理解,上述原因是:

tf.keras.preprocessing.image_dataset_from_directory

虽然它的实例是:

type(train_ds)

tensorflow.python.data.ops.dataset_ops.BatchDataset

复制:

首次运行:

[x for x, y in train_ds]

输出:

[<tf.Tensor: shape=(32, 100, 100, 1), dtype=float32, numpy=  array([[[[157.],
          [155.],
          [159.],

第二次运行:

[x for x, y in train_ds]

输出:

[<tf.Tensor: shape=(32, 100, 100, 1), dtype=float32, numpy=  array([[[[ 34.],
          [ 36.],
          [ 39.],
          ...,

可能的解决方案


imgs, y_true = [], []
for img, label in train_ds:
    imgs.append(img)
    y_true.append(label)

imgs = tf.concat(imgs, axis=0)    
y_true = np.argmax(tf.concat(y_true, axis=0), axis=1)

y_pred = np.argmax(model.predict(imgs), axis=1)
print (accuracy_score(y_true, y_pred))

y_pred = np.argmax(model.predict(imgs), axis=1)
print (accuracy_score(y_true, y_pred))

输出

0.944044764
0.944044764

有没有更好的解决方案?

更新 2:

在验证数据集的情况下可能更合适(这里的train_ds 只是例如添加一个参数Shuffle=False


    train_ds = tf.keras.preprocessing.image_dataset_from_directory(
        directory,
        label_mode='categorical',
        validation_split=0.2,
        subset="training",
        seed=1337,
        color_mode="grayscale",
        image_size=image_size,
        batch_size=batch_size,
        Shuffle=False

    )

更新 3:

如果您的 test images 在单独的文件夹中,这可能是最好的选择。

path = 'your path to test folder'


test_generator = ImageDataGenerator().flow_from_directory(
    directory=path,
    class_mode='categorical',
    shuffle=False,
    batch_size=32,
    target_size=(512, 512)
)

test_generator.reset()

这比选项 1 更好,因为它可以在不适合内存 (RAM) 的数据集上工作。

【讨论】:

  • 你发现上面的代码有什么改进吗?
  • @OmarIsmail,刚刚添加了另一个选项。
【解决方案2】:

您确定不会在每次运行代码时再次训练模型吗?如果模型的参数相同,则相同输入的预测结果每次都应该相同。

【讨论】:

  • 代码分成 2 个单元格(在 jupyter 笔记本中)。用于训练的第一个单元格。用于推理的第二个单元格。我运行单元格 (1) 一次和单元格 (2) 几次。
猜你喜欢
  • 1970-01-01
  • 2020-10-22
  • 2021-01-19
  • 1970-01-01
  • 2011-02-20
  • 2020-05-04
  • 1970-01-01
  • 2021-03-05
  • 2014-12-06
相关资源
最近更新 更多