【问题标题】:Keras different results between predict and predict_generator预测和预测生成器之间的Keras结果不同
【发布时间】:2017-05-17 12:53:10
【问题描述】:

我目前正在使用 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_generator 部分,我从两者得到不同的结果。我仔细检查了一个没有生成器训练的模型,预测的输出是正确的(并且与 predict_generator 的输出非常不同)。 predict 中输入的数据的构造方式与生成器的构造方式相同(也已检查)。

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

谢谢, 尼古拉斯

【问题讨论】:

  • 可能是洗牌引起的。尝试离开您的网络以等待更多时期。
  • 我将 shuffle=False 用于验证生成器。训练是正确的。我也做了 5 和 10 epochs 的测试,结果是一样的。我将尝试在 val_x 中使用 1 张图片以提高可见度
  • 好吧,我只是个白痴... ImageDataGenerator 正在以“奇怪的顺序”获取文件名,这与我手动执行的顺序不同...毕竟看起来不错

标签: keras predict


【解决方案1】:

我认为这个关于 GitHub 上类似问题的评论可能会对某人有所帮助 https://github.com/keras-team/keras/issues/3477#issuecomment-360022086

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

【讨论】:

    猜你喜欢
    • 2021-10-06
    • 2018-11-03
    • 2019-01-02
    • 2018-09-18
    • 2018-01-17
    • 2019-07-25
    • 2021-04-30
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多