简体   繁体   English

在 Keras 中训练 model 时出现值错误

[英]Value error while training model in Keras

I tried to train a model to predict ocr in keras.我试图训练一个 model 来预测 keras 中的 ocr。 This is the code snippet where the model tries to fit the data:这是 model 尝试拟合数据的代码片段:

nb_epoch = 8

samples_per_epoch = 3268
nb_val_samples = 842


#save every model using Keras checkpoint
from keras.callbacks import ModelCheckpoint
filepath="checkpoint2/check-{epoch:02d}-{val_loss:.4f}.hdf5"
checkpoint = ModelCheckpoint(filepath= filepath, verbose=1, save_best_only=False)
callbacks_list = [checkpoint]

#Model fit generator
history_object = model.fit(train_generator, 
                           steps_per_epoch= samples_per_epoch,
                           validation_data=validation_generator,
                           validation_steps=nb_val_samples, 
                           epochs=nb_epoch, 
                           verbose=1, 
                           callbacks=callbacks_list)

I ran the cell and the program got stuck at the first epoch and threw the following error:我运行了单元格,程序卡在了第一个 epoch 并抛出了以下错误:

ValueError                                Traceback (most recent call last)
<ipython-input-15-62090a608d4c> in <module>
     20                                      epochs=nb_epoch,
     21                                      verbose=1,
---> 22                                      callbacks=callbacks_list)
.
.
.
 ValueError: Layer sequential_1 expects 1 input(s), but it received 2 input tensors. Inputs received: [<tf.Tensor 'IteratorGetNext:0' shape=(None, None, None, None) dtype=float32>, <tf.Tensor 'IteratorGetNext:1' shape=(None, None) dtype=float32>]

I have just started to build models using keras.我刚刚开始使用 keras 构建模型。 I took this code from a github repo as a learning material.我从 github 存储库中获取此代码作为学习材料。 Kindly help me to solve this issue.请帮我解决这个问题。 thank you so much.太感谢了。

edit: Here is the train_generator code:编辑:这是 train_generator 代码:

batch_size = 16
num_classes = 50

# Start with train generator shared in the class and add image augmentations
def generate_data(samples, target_files,  batch_size=batch_size, factor = 0.1 ):
    num_samples = len(samples)
    from sklearn.utils import shuffle
    while 1: # Loop forever so the generator never terminates
        for offset in range(0, num_samples, batch_size):
            batch_samples = samples[offset:offset+batch_size]
            batch_targets = target_files[offset:offset+batch_size]

            images = []
            targets = []
            for i in range(len(batch_samples)):
                batch_sample = batch_samples[i]
                batch_target = batch_targets[i]
                im = Image.open(batch_sample)
                cur_width = im.size[0]
                cur_height = im.size[1]

                # print(cur_width, cur_height)
                height_fac = 113 / cur_height

                new_width = int(cur_width * height_fac)
                size = new_width, 113

                imresize = im.resize((size), Image.ANTIALIAS)  # Resize so height = 113 while keeping aspect ratio
                now_width = imresize.size[0]
                now_height = imresize.size[1]
                # Generate crops of size 113x113 from this resized image and keep random 10% of crops

                avail_x_points = list(range(0, now_width - 113 ))# total x start points are from 0 to width -113

                # Pick random x%
                pick_num = int(len(avail_x_points)*factor)

                # Now pick
                random_startx = sample(avail_x_points,  pick_num)

                for start in random_startx:
                    imcrop = imresize.crop((start, 0, start+113, 113))
                    images.append(np.asarray(imcrop))
                    targets.append(batch_target)
                    
                    
         # trim image to only see section with road
            X_train = np.array(images)
            y_train = np.array(targets)

            #reshape X_train for feeding in later
            X_train = X_train.reshape(X_train.shape[0], 113, 113, 1)
            #convert to float and normalize
            X_train = X_train.astype('float32')
            X_train /= 255

            #One hot encode y
            y_train = to_categorical(y_train, num_classes)

            yield shuffle(X_train, y_train) 


train_generator = generate_data(train_files, train_targets, batch_size=batch_size, factor = 0.3)
validation_generator = generate_data(validation_files, validation_targets, batch_size=batch_size, factor = 0.3)
test_generator = generate_data(test_files, test_targets, batch_size=batch_size, factor = 0.1)

The reason you got the error is that sklearn shuffle produce a builtin python list as an output, when multiple parameters are given:您收到错误的原因是sklearn shuffle产生一个内置 python 列表作为 output,当给出多个参数时:

import numpy as np
from sklearn.utils import shuffle

>>> shuffle_result = shuffle(np.array([[1, 5], [2, 4]]), np.array([1, 5]))

>>> shuffle_result
[array([[2, 4],
        [1, 5]]),
 array([1, 5])]

>>> type(shuffle_result)
list

>>> type(shuffle_result).__module__
'builtins'

This cause that model.fit "thinks" that you are giving multiple inputs.这导致model.fit “认为”您正在提供多个输入。 Citing docs :引用 文档

x - Input data. x - 输入数据。 It could be:它可能是:

A Numpy array (or array-like), or a list of arrays (in case the model has multiple inputs).一个 Numpy 数组(或类似数组),或 arrays 的列表(如果 model 有多个输入)。
... ...

To solve it a simple casting to python tuple will help:为了解决它,一个简单的转换为 python 元组将有所帮助:

    yield tuple(shuffle(X_train, y_train))

This way you "tell" your model.fit - these are my train x and y , not the list of x .这样你“告诉”你的model.fit - 这些是我的火车xy ,而不是x的列表。


A simplified example:一个简化的例子:

from tensorflow import keras
from tensorflow.keras import layers
import numpy as np
from sklearn.utils import shuffle

def invalid_gen(limit):
    i = 0
    while i < limit:
        i += 1
        yield shuffle(np.array([[1, 5], [2, 4]]), np.array([1, 5]))

def valid_gen(limit):
    i = 0
    while i < limit:
        i += 1
        yield tuple(shuffle(np.array([[1, 5], [2, 4]]), np.array([1, 5])))

def fit_model(generator):
    inputs = keras.Input(shape=(2,))
    outputs = layers.Dense(10)(inputs)
    model = keras.Model(inputs=inputs, outputs=outputs)
    model.compile(loss=keras.losses.SparseCategoricalCrossentropy())
    model.fit(generator)

Calling:来电:

fit_model(invalid_gen(100))

throws an error:抛出错误:

ValueError: Layer model expects 1 input(s), but it received 2 input tensors. Inputs received: [<tf.Tensor 'IteratorGetNext:0' shape=(None, None) dtype=int64>, <tf.Tensor 'ExpandDims:0' shape=(None, 1) dtype=int64>]

But calling:但是调用:

fit_model(valid_gen(100))

works as expected:按预期工作:

100/100 [==============================] - 1s 2ms/step - loss: 9.4709

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

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