【问题标题】:Keras model.predict gives inconsistent valuesKeras model.predict 给出不一致的值
【发布时间】:2021-01-04 18:51:53
【问题描述】:

model.evaluate 上测试时,我训练了一个基本分类器,它每次都会产生相同的指标。

当使用model.predict 检查验证数据时,每次运行model.predict 行时我都会得到不同的值。我不明白为什么会这样?

在每次“model.predict(validation_data)”运行之间不进行任何训练。

# -*- coding: utf-8 -*-
"""
Spyder Editor

This is a temporary script file.
"""
import tensorflow as tf
import math 
import tensorflow_hub as hub
import numpy as np
import matplotlib.pyplot as plt
from tensorflow import keras
from tensorflow.keras import layers
from sklearn.metrics import roc_curve
from tensorflow.keras.preprocessing.image import ImageDataGenerator



train_examples = 425
test_examples = 245
validation_examples = 245
# train_examples = 20
# test_examples = 20
# validation_examples = 20
img_height = img_width = 224
batch_size = 32
epochs = 100

#create matrices to store training accuracy data for multiple epochs
val_store = []
test_store = []
train_store = []

#loop over n epochs to determine number of epochs required to avoid overfitting
#for epoch_tot in range(1,25):

#NasNet
model = keras.Sequential([
    hub.KerasLayer("https://tfhub.dev/google/imagenet/nasnet_mobile/feature_vector/4",
    trainable = True),
    layers.Dense(1, activation = "sigmoid"),
    ])

# model = keras.models.load_model('isic_model2/')

train_datagen = ImageDataGenerator(
    rescale = 1.0/255,
    rotation_range = 15,
    zoom_range = (0.95, 0.95),
    horizontal_flip = True,
    vertical_flip = True,
    data_format = "channels_last",
    dtype = tf.float32,
    )

validation_datagen = ImageDataGenerator(rescale=1.0/255, dtype=tf.float32)
test_datagen = ImageDataGenerator(rescale=1.0/255, dtype=tf.float32)

train_gen = train_datagen.flow_from_directory(
    "ClassifierData/Training/",
    target_size = (img_height, img_width),
    batch_size=batch_size,
    color_mode = "rgb",
    class_mode = "binary",
    shuffle = True,
    seed = 123,
    )

validation_gen = validation_datagen.flow_from_directory(
    "ClassifierData/Validation/",
    target_size = (img_height, img_width),
    batch_size=batch_size,
    color_mode = "rgb",
    class_mode = "binary",
    shuffle = True,
    seed = 123,
    )
    
test_gen = test_datagen.flow_from_directory(
    "ClassifierData/Test/",
    target_size = (img_height, img_width),
    batch_size=batch_size,
    color_mode = "rgb",
    class_mode = "binary",
    shuffle = True,
    seed = 123,
    )

METRICS = [
    keras.metrics.BinaryAccuracy(name="accuracy"),
    keras.metrics.Precision(name="precision"),
    keras.metrics.Recall(name="recall"),
    keras.metrics.AUC(name='auc'),
    ]
    
model.compile(
    optimizer = keras.optimizers.Adam(lr=3e-4),
    loss = [keras.losses.BinaryCrossentropy(from_logits=False)],
    metrics = METRICS,
    )

# model_checkpoint_callback = tf.keras.callbacks.ModelCheckpoint(
#     filepath = ("checkpoints1"),
#     monitor = 'val_auc',
#     save_freq = 'epoch',
#     verbose = 1,
#     )


history = model.fit(
    train_gen,
    epochs=epochs,
    verbose = 1,
    steps_per_epoch = train_examples // batch_size,
    validation_data=validation_gen,
    validation_steps=validation_examples // batch_size,
    callbacks = [keras.callbacks.ModelCheckpoint("isic_model4")]
    #callbacks = [model_checkpoint_callback],
    )

    
def plot_roc(labels, data):
    predictions = model.predict(data)
    fp, tp, _ = roc_curve(labels, predictions)
    
    plt.plot(100*fp, 100*tp)
    plt.xlabel("False positives [%]")
    plt.ylabel("True positives [%]")
    plt.show()
    
test_labels = np.array([])
num_batches = 0

for _, y in test_gen:
    test_labels = np.append(test_labels, y)
    num_batches += 1
    if num_batches == math.ceil(test_examples / batch_size):
        break

plot_roc(test_labels, test_gen)
val_eval = model.evaluate(validation_gen, verbose = 1)
test_eval = model.evaluate(test_gen, verbose=1)        
train_eval = model.evaluate(train_gen, verbose=1)


#plot auc against number of epochs
train_loss = history.history['loss']
val_loss   = history.history['val_loss']
train_acc  = history.history['auc']
val_acc    = history.history['val_auc']
train_prec = history.history['precision']
val_prec = history.history['val_precision']

xc         = range(epochs)
plt.figure()
plt.plot(xc, train_acc)
plt.plot(xc, val_acc)
plt.figure()
plt.plot(xc, train_loss)
plt.plot(xc, val_loss)

#Save important data to csv
import pandas
df = pandas.DataFrame(data={"train_loss": train_loss,
                            "val_loss": val_loss,
                            'train_acc': train_acc,
                            'val_acc' : val_acc,
                            'train_prec': train_prec,
                            'val_prec': val_prec,
                            'xc' : xc
                            })
df.to_csv("./accuracy.csv", sep=',',index=False)

val_predict1 = model.evaluate(validation_datagen, verbose = 1)
val_predict2 = model.evaluate(validation_datagen, verbose = 1)
y_true_labels = history.classes

【问题讨论】:

    标签: python tensorflow machine-learning keras deep-learning


    【解决方案1】:

    尝试在 validation_gen 和 test_gen 中设置 shuffle = False。不知道为什么评估给出相同的答案,但预测没有。可能评估会重置生成器,而预测不会。您通常想要的是只检查一次测试样本或验证样本。假设您有 500 个样本。您可以将批量大小设置为 50,并在模型中预测设置步数为 10。下面是确定批量大小和步数的代码,样本数 = 长度,使得 batch_size X 步数 = 长度。请注意,如果样本数是素数,则批量大小将为 1,步长将相等。下面代码中的术语 b_max 是一个整数,表示基于内存容量允许的最大批量大小。

    batch_size=sorted([int(length/n) for n in range(1,length+1) if length % n ==0 and length/n<=b_max],reverse=True)[0]  
    steps=int(length/batch_size)
    

    使用这些值可确保您遍历样本一次,然后生成器从头返回。

    【讨论】:

    • 通过更改 shuffle = False 解决。我猜结果实际上并不是错误的,只是每次我运行 predict 时都重新排序。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-02-05
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多