使用批量训练数据训练多输入Keras神经网络

7

我希望使用Keras训练一个多输入神经网络,使用一批训练数据,但是我无法传递一组输入和输出样本来执行模型的fit或train_on_batch方法。

我的神经网络定义如下:

    i1 = keras.layers.Input(shape=(2,))
    i2 = keras.layers.Input(shape=(2,))
    i3 = keras.layers.Input(shape=(2,))
    i_layer = keras.layers.Dense(2, activation='sigmoid')
    embedded_i1 = i_layer(i1)
    embedded_i2 = i_layer(i2)
    embedded_i3 = i_layer(i3)

    middle_concatenation = keras.layers.concatenate([embedded_i1, embedded_i2, embedded_i3], axis=1)

    out = keras.layers.Dense(1, activation='sigmoid')(middle_concatenation)

    model = keras.models.Model(inputs=[i1, i2, i3], outputs=out)
    model.compile(optimizer='rmsprop', loss='binary_crossentropy', metrics=['accuracy'])

例如,一个成功用于预测输出的输入实例如下所示: [array([[0.1, 0.2]]), array([[0.3, 0.5]]), array([[0.1, 0.3]])] 但是当我尝试使用以下内容训练我的模型时:
    inputs = [[np.array([[0.1, 0.2]]), np.array([[0.3, 0.5]]), np.array([[0.1, 0.3]])],
                     [np.array([[0.2, 0.1]]), np.array([[0.5, 0.3]]), np.array([[0.3, 0.1]])]
                         ]
    outputs = np.ones(len(inputs))
    model.fit(inputs, outputs)

我遇到了这个错误:

ValueError: Error when checking model input: you are passing a list as input to your model, but the model expects a list of 3 Numpy arrays instead. The list you passed was: [[array([[ 0.1,  0.2]]), array([[ 0.3,  0.5]]), array([[ 0.1,  0.3]])], [array([[ 0.2,  0.1]]), array([[ 0.5,  0.3]]), array([[ 0.3,  0.1]])]]

我做错了什么?
如何使用一批输入/输出样本训练多输入神经网络?

谢谢!


我认为你可能需要研究一下merge层,并将三个单独的分支压缩成一个组合网络,否则将把输入合并成一个不会有太大区别。 - DJK
@djk47463 感谢您的提示!我需要三个输入共享它们的权重。因此,我构建了“i_layer”层,将每个输入添加到该层中,然后连接该层的三个输出以构建NN的其余部分。 注:为了简化代码,我刚刚删除了一些内部层。无论如何,您知道如何解决训练问题吗? - Luca Mastrostefano
抱歉,我太快地浏览了代码,没有意识到你已经在做那件事了。 - DJK
2个回答

2
问题在于格式不正确。你不能将列表传递给Keras,只能使用NumPy数组。因此,当你的数据结构如下时:
 inputs = [[np.array([[0.1, 0.2]]), np.array([[0.3, 0.5]]), np.array([[0.1, 0.3]])],
                     [np.array([[0.2, 0.1]]), np.array([[0.5, 0.3]]), np.array([[0.3, 0.1]])]
                         ]

您需要逐个将列表元素传递到模型中。您还需要逐个向模型传递一个输出值。为此,请按以下方式构建您的outputs

outputs = [np.ones(1) for x in inputs]

[array([ 1.]), array([ 1.])]

然后,您可以像这样循环使用fit函数
 for z in range(0,len(inputs)):
     model.fit(inputs[z],outputs[z],batch_size=1)

您也可以将model.fit替换为model.train_on_batch(),请参阅文档

但是,为了避免循环,您可以在inputs列表中存储3个numpy数组,并将单个outputs作为numpy数组。如果您只想一次训练一个批次,则可以设置批处理大小以实现该目的。

inputs = [np.array([[0.1, 0.2],[0.2, 0.1]]), np.array([[0.3, 0.5],[0.5, 0.3]]), np.array([[0.1, 0.3],[0.3, 0.1]])]

outputs = np.ones(inputs[0].shape[0])

model.fit(inputs,outputs,batch_size=1)

2

问题在于您现在正在使用列表的列表作为输入,但keras希望是一个数组的列表。

您需要转换您的列表,使其看起来像[array_inputs_1, array_inputs_2, array_inputs_3],其中每个输入数组都是如果模型只有该输入层,则会传递给模型的输入数组,您只需将它们三个放在一个列表中即可。

使用您的数据,正确的输入应该是:

[np.array([[0.1, 0.2], [0.2, 0.1]]), 
 np.array([[0.3, 0.5], [0.5, 0.3]]), 
 np.array([[0.1, 0.3], [0.1, 0.3]])]

只要这3个输入数组的元素数量相同,keras就知道如何将它们分成批次。


谢谢 @gionni。你是完全正确的。现在它可以工作了! - Luca Mastrostefano

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接