简体   繁体   English

Keras model.predict 给出不一致的值

[英]Keras model.predict gives inconsistent values

I have trained a basic classifier when tested on model.evaluate it produces the same metrics every time.model.evaluate上进行测试时,我已经训练了一个基本分类器。评估它每次都会产生相同的指标。

When using model.predict to check the validation data, I get different values each time the model.predict line is run.当使用model.predict检查验证数据时,每次运行model.predict行时都会得到不同的值。 I can't figure out for me why this is happening?我无法弄清楚为什么会这样?

No training is done between each 'model.predict(validation_data)' run.每次“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

try setting shuffle = False in validation_gen and test_gen.尝试在validation_gen 和test_gen 中设置shuffle = False。 Not sure why evaluating gives the same answer but predict does not.不知道为什么评估给出相同的答案,但预测没有。 Maybe evaluate resets the generator and predict doesn't.也许评估会重置生成器而预测不会。 What you normally want is to go through the test samples or validation samples exactly once.您通常想要的是 go 通过测试样品或验证样品恰好一次。 Let's say you have 500 samples.假设您有 500 个样本。 You can set the batch size to say 50 and in the model predict set steps to 10. below is the code to determine the batch size and steps given the number of samples=length such that batch_size X steps = length.您可以将批量大小设置为 50,并在 model 中预测设置步数为 10。下面是确定批量大小和步数的代码,样本数 = 长度,使得 batch_size X 步数 = 长度。 Note if the number of samples is a prime number, the batch size will be 1 and steps will equal length.请注意,如果样本数是素数,则批量大小将为 1,步长将相等。 Term b_max in the code below is an integer denoting the maximum batch size you will allow based on your memory capacity.下面代码中的术语 b_max 是 integer ,表示根据 memory 容量允许的最大批量大小。

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)

Using these values ensures you go through the samples once and the generator ends up back at the beginning.使用这些值可确保您通过样本 go 一次,并且生成器最终回到开头。

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

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM