predict和predict_生成器之间的Keras结果不同

predict和predict_生成器之间的Keras结果不同,keras,predict,Keras,Predict,我目前正在使用Keras进行卫星图像分类,我很难使用predict和predict_generator获得正确的预测 在我的代码下面 import os import numpy as np import pandas as pd from keras.optimizers import Adam, SGD from tools import load_val_datas, load_test_datas, make_predictions, make_submissions from ke

我目前正在使用Keras进行卫星图像分类,我很难使用predict和predict_generator获得正确的预测

在我的代码下面

import os
import numpy as np  
import pandas as pd
from keras.optimizers import Adam, SGD
from tools import load_val_datas, load_test_datas, make_predictions, make_submissions
from keras_tools import save_model, load_model

from callbacks import CustomCallbacks
from data_generator import ImageDataGenerator
from model import base_cnn

os.environ['TF_CPP_MIN_LOG_LEVEL'] = '3'

TRAIN_SIZE, VAL_SIZE, TEST_SIZE, TEST_SIZE_ADD = 30000, 10479, 40669, 20522
IMAGE_FIRST_DIM, N_COLORS = 32, 3
IMAGE_SIZE = IMAGE_FIRST_DIM * IMAGE_FIRST_DIM * N_COLORS
LABEL_SIZE = 17
DROPOUT = 0.25
BATCH_SIZE = 96
N_EPOCHS = 2
CHECKPOINTS_FOLDER = "checkpoints/"
MODEL_JSON = "epoch-10.json"
MODEL_H5 = "epoch-10.h5"
TO_LOAD = False

df_train_labels = pd.read_csv("datas/train_labels.csv")
label_dict = df_train_labels.set_index("image_name").T.to_dict("list")

val_x, val_y = load_val_datas(VAL_SIZE, IMAGE_FIRST_DIM, N_COLORS, LABEL_SIZE)

if TO_LOAD:
    model, is_loaded = load_model(CHECKPOINTS_FOLDER + MODEL_JSON, CHECKPOINTS_FOLDER + MODEL_H5)
else:
    model = base_cnn(IMAGE_FIRST_DIM, N_COLORS)

adam = Adam(lr=0.01)
sgd = SGD(lr=0.01, momentum=0.9, decay=0.0005)
model.compile(loss='binary_crossentropy', optimizer=sgd)

my_callbacks = CustomCallbacks()
datagen = ImageDataGenerator(rescale=1./255)
train_generator = datagen.flow_from_directory("datas/train", target_size=(IMAGE_FIRST_DIM, IMAGE_FIRST_DIM),
                                              batch_size=BATCH_SIZE,
                                              class_mode="multilabel", multilabel_classes=label_dict)

val_generator = datagen.flow_from_directory("datas/validation", target_size=(IMAGE_FIRST_DIM, IMAGE_FIRST_DIM),
                                              batch_size=BATCH_SIZE, shuffle=False,
                                              class_mode="multilabel", multilabel_classes=label_dict)

model.fit_generator(train_generator, steps_per_epoch=TRAIN_SIZE/BATCH_SIZE, epochs=N_EPOCHS,
                    verbose=2)
save_model(model, MODEL_JSON, MODEL_H5)

from time import time
st = time()
p_valid = model.predict_generator(val_generator, steps=VAL_SIZE/BATCH_SIZE, pickle_safe=True)
print("time: ", time() - st)
print(p_valid)
from sklearn.metrics import fbeta_score
print(fbeta_score(val_y, np.array(p_valid) > 0.2, beta=2, average='samples'))

st = time()
p_valid1 = model.predict(val_x)
print("time: ", time() - st)
print(type(p_valid1))
print(fbeta_score(val_y, np.array(p_valid1) > 0.2, beta=2, average='samples'))
我正在使用另一个版本的ImageDataGenerator,它可以处理多标签(我已经检查了实现,数据看起来在批处理中正确加载)

问题来自于predict和predict_生成器部分,我从这两个部分得到了不同的结果。我用一个没有生成器的模型进行了双重检查,predict的输出是正确的(与predict_生成器的输出非常不同)。predict中输入的数据以与发电机相同的方式构造(也进行了检查)

谢谢,
Nicolas

我认为这篇关于GitHub上类似问题的评论可能会对某些人有所帮助


predict()和predict_generator()的输出实际上是相同的,但它们看起来不同,因为它们的标签不同。您正在为predict()提供标签,predict_generator()正在从训练数据的目录结构中推断标签(因为它使用了来自_目录()的flow_,而不是flow())。

这可能是由于混洗造成的。请尝试离开您的网络,等待更多的时间。我为验证生成器设置了shuffle=False。训练是正确的。我还做了5个和10个时代的测试,结果是一样的。我将尝试在val_x中使用一个图像,以获得更多的可视性,这可能与以下内容相关:?好吧,我只是个白痴。。。ImageDataGenerator正在以“奇怪的顺序”获取文件名,这与我手动执行的操作不同。。。毕竟看起来不错
Using TensorFlow backend.
validation images loaded in 0.01 seconds
validation labels loaded in 0.00 seconds


Found 30000 images belonging to 1 classes.
Found 10479 images belonging to 1 classes.
Epoch 1/2
63s - loss: 0.2762
Epoch 2/2
66s - loss: 0.2288
time:  22.098024606704712
beta_score: 0.667686382255
time:  3.3181281089782715
beta_score: 0.740394519272