培训多输入Keras NN与批处理训练数据

问题描述:

我想用Keras训练一批训练数据的多输入NN,但我无法将一组输入和输出样本传递给在模型上执行拟合train_on_batch培训多输入Keras NN与批处理训练数据

我NN被定义为以下:

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]])]] 

我在做什么错?
如何使用一批输入/输出样本来训练多输入NN?

谢谢!

+0

我想你可能想看看[合并](https:// keras。io/layers/merge /)图层,并将三个独立的分支凝聚到一个组合网络中,否则将您的输入合并为一个 – DJK

+0

@ djk47463感谢您的提示!我需要三个输入来分享他们的权重。因此,我构建了图层'i_layer',将每个输入添加到此图层,然后连接此图层的三个输出以构建NN的其余部分。 注:我只是删除了一些内部图层,以简化代码。 无论如何,你知道如何解决列车问题吗? –

+0

对不起我放弃了代码快,没有意识到你已经在做 – DJK

问题只是格式不正确。你可以不通过列表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.])] 

然后你可以遍历这样

for z in range(0,len(inputs)): 
    model.fit(inputs[z],outputs[z],batch_size=1) 

的拟合函数,你也可以用model.train_on_batch()而不是取代model.fit,看到docs

然而,为了避免循环,你可以在你的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) 

现在的问题是,你现在使用列表作为输入,虽然keras需要一个数组列表。

你需要转换你的列表中,这样它看起来像[array_inputs_1, array_inputs_2, array_inputs_3],其中每个输入数组是输入数组,你会通过该模型,如果它有只输入层,你只要把他们的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会知道如何艾德里安分成批次。

+0

谢谢@gionni。 你是完全正确的。现在它工作了! –