【问题标题】:Attribute Error when calling 'predict_generator' from loaded Keras model从加载的 Keras 模型调用“predict_generator”时出现属性错误
【发布时间】:2020-01-08 12:20:03
【问题描述】:

我已经训练了一个用于对图像进行分类的双输入神经网络,并将权重保存到 hdf5 文件中。

我现在正在尝试加载此网络并使用“predict_generator”来查看它在我的测试集上的表现如何。但是,在调用“predict_generator”时,我收到以下错误:

Traceback (most recent call last):
   File "load_cnn.py", line 75, in <module>
     pred = loaded_model.predict_generator(test_gen, steps=36, verbose=1)
   File 
"/home/ppxjm4/anaconda3/envs/ML/lib/python3.7/site-packages/keras/legacy/interfaces.py", 
line 91, in wrapper
     return func(*args, **kwargs)
   File 
"/home/ppxjm4/anaconda3/envs/ML/lib/python3.7/site-packages/keras/engine/training.py", 
line 1772, in predict_generator
     verbose=verbose)
   File 
"/home/ppxjm4/anaconda3/envs/ML/lib/python3.7/site-packages/keras/engine/training_generator.py", 
line 503, in predict_generator
     batch_size = x[0].shape[0]
AttributeError: 'list' object has no attribute 'shape'

我很困惑为什么它在这里抱怨,在训练期间调用“fit_generator()”似乎工作得很好。

这是我产生错误的代码:

import os
import pandas as pd
import numpy as np

import keras
from keras import optimizers
from keras.utils import to_categorical
from keras.layers import Input, Dense, Flatten, Dropout, Conv2D, MaxPooling2D, GlobalAveragePooling2D, Activation, concatenate
from keras.layers.advanced_activations import LeakyReLU
from keras.layers.normalization import BatchNormalization
from keras.models import Model
from keras.callbacks import ModelCheckpoint, ReduceLROnPlateau

from keras_preprocessing.image import ImageDataGenerator

train_df = pd.read_pickle("collated_data.pkl")
train_df = train_df.sample(frac=1)

data_gen = ImageDataGenerator(rescale=1./255)

from keras.models import model_from_json

json_file = open('model.json', 'r')
loaded_model_json = json_file.read()
json_file.close()

loaded_model = model_from_json(loaded_model_json)
loaded_model.load_weights("weights.best.hdf5")

print("loaded model from disk!")

loaded_model.compile(loss='categorical_crossentropy', optimizer='Adadelta', metrics=['accuracy'])

def generator_multiple(generator, dataframe, mode, batch_size, img_height, img_width):

    if mode == 'train':

        genX1 = generator.flow_from_dataframe(
            dataframe=dataframe[:79000], x_col='reconstruction', y_col='label', class_mode='categorical',
            batch_size=batch_size, shuffle=False, target_size=(img_height, img_width), color_mode='grayscale')

        genX2 = generator.flow_from_dataframe(
            dataframe=dataframe[:79000], x_col='observation', y_col='label', class_mode='categorical',
            batch_size=batch_size, shuffle=False, target_size=(img_height, img_width), color_mode='grayscale')

    if mode == 'validate':

        genX1 = generator.flow_from_dataframe(
            dataframe=dataframe[79000:85000], x_col='reconstruction', y_col='label', class_mode='categorical',
            batch_size=batch_size, shuffle=False, target_size=(img_height, img_width), color_mode='grayscale')

        genX2 = generator.flow_from_dataframe(
            dataframe=dataframe[79000:85000], x_col='observation', y_col='label', class_mode='categorical',
            batch_size=batch_size, shuffle=False, target_size=(img_height, img_width), color_mode='grayscale')

    if mode == 'test':

        genX1 = generator.flow_from_dataframe(
            dataframe=dataframe[85000:], x_col='reconstruction', y_col=None, class_mode=None,
            batch_size=batch_size, shuffle=False, target_size=(img_height, img_width), color_mode='grayscale')

        genX2 = generator.flow_from_dataframe(
            dataframe=dataframe[85000:], x_col='observation', y_col=None, class_mode=None,
            batch_size=batch_size, shuffle=False, target_size=(img_height, img_width), color_mode='grayscale')

    while True:
        X1i = genX1.next()
        X2i = genX2.next()
        yield [[X1i[0], X2i[0]], X2i[1]]


test_gen = generator_multiple(data_gen, dataframe=train_df, mode='test', batch_size=36,
                               img_height=100, img_width=100)

pred = loaded_model.predict_generator(test_gen, steps=36, verbose=1)

predicted_class_indices = np.argmax(pred, axis=1)
labels = (train_gen.class_indices)
labels = dict((v,k) for k,v in labels.items())
predictions = [labels[k] for k in predicted_class_indices]

filenames=test_gen.filenames
results=pd.DataFrame({"Filename":filenames,
                      "Predictions":predictions})
results.to_csv("results.csv",index=False)

【问题讨论】:

  • 如果您运行完全相同的代码,只使用fit_generator 而不是predict_generator,会发生什么?
  • 以防万一,yield [[X1i[0], X2i[0]] 也不起作用,对吧?
  • @NatthaphonHongcharoen 这给了我一个不同的错误,即输入尺寸不是预期的
  • @TheGuywithTheHat 尺寸对我来说是不正确的,因为我没有给出任何标签,所以只更改那行代码。但是,如果我更改该行并使用“测试”生成器,一切正常,这表明加载模型不是问题
  • 什么是type(generator_multiple.next()[0][0])

标签: python pandas tensorflow machine-learning keras


【解决方案1】:

我的问题的解决方案是在使用生成器向模型提供测试数据时修改其输出。当 y_col 和 class_mode 设置为 None 时,flow_from_dataframe 方法产生不同维度的数据。

def generator_multiple(generator, dataframe, batch_size, img_height, img_width):

    genX1 = generator.flow_from_dataframe(
        dataframe=dataframe, x_col="reconstruction", y_col=None, class_mode=None,
        batch_size=batch_size, shuffle=False, target_size=(img_height, img_width), color_mode='grayscale')

    genX2 = generator.flow_from_dataframe(
        dataframe=dataframe, x_col="observation", y_col=None, class_mode=None,
        batch_size=batch_size, shuffle=False, target_size=(img_height, img_width), color_mode='grayscale')

    while True:
        X1i = genX1.next()
        X2i = genX2.next()
        yield [X1i, X2i]

【讨论】:

    【解决方案2】:

    如果您的模型有 1 个以上的输入,我建议您尝试从生成器中生成 dict 而不是列表,这是 keras it self 的示例(fit_generator() 的文档字符串):

    def generate_arrays_from_file(path):
        while True:
            with open(path) as f:
                for line in f:
                    # create numpy arrays of input data
                    # and labels, from each line in the file
                    x1, x2, y = process_line(line)
                    yield ({'input_1': x1, 'input_2': x2}, {'output': y})
    
    model.fit_generator(generate_arrays_from_file('/my_file.txt'),
                        steps_per_epoch=10000, epochs=10)
    

    更多信息,这里是keras's github

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2021-04-17
      • 1970-01-01
      • 2020-07-26
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2019-03-26
      • 1970-01-01
      相关资源
      最近更新 更多