简体   繁体   English

具有多个输入的 Keras 序列模型

[英]Keras Sequential model with multiple inputs

I am making a MLP model which takes two inputs and produces a single output.我正在制作一个 MLP 模型,它需要两个输入并产生一个输出。

I have two input arrays (one for each input) and 1 output array.我有两个输入数组(每个输入一个)和 1 个输出数组。 The neural network has 1 hidden layer with 2 neurons.神经网络有 1 个隐藏层和 2 个神经元。 Each array has 336 elements.每个数组有 336 个元素。

model0 = keras.Sequential([
keras.layers.Dense(2, input_dim=2, activation=keras.activations.sigmoid, use_bias=True),
keras.layers.Dense(1, activation=keras.activations.relu, use_bias=True),
])

# Compile the neural network #
model0.compile(
    optimizer = keras.optimizers.RMSprop(lr=0.02,rho=0.9,epsilon=None,decay=0),
    loss = 'mean_squared_error',
    metrics=['accuracy']
)

I tried two ways, both of them are giving errors.我尝试了两种方法,它们都给出了错误。

model0.fit(numpy.array([array_1, array_2]),output, batch_size=16, epochs=100)

ValueError: Error when checking input: expected dense_input to have shape (2,) but got array with shape (336,) ValueError:检查输入时出错:预期dense_input具有形状(2,)但得到形状为(336,)的数组

The second way:第二种方式:

model0.fit([array_1, array_2],output, batch_size=16, epochs=100)

ValueError: Error when checking model input: the list of Numpy arrays that you are passing to your model is not the size the model expected. ValueError:检查模型输入时出错:您传递给模型的 Numpy 数组列表不是模型预期的大小。 Expected to see 1 array(s), but instead got the following list of 2 arrays:预计会看到 1 个数组,但得到了以下 2 个数组的列表:

Similar question . 类似的问题 But not using sequential model.但不使用顺序模型。

To solve this problem you have two options.要解决此问题,您有两种选择。

1. Using a sequential model 1. 使用顺序模型

You can concatenate both arrays into one before feeding to the network.在馈入网络之前,您可以将两个数组连接为一个。 Let's assume the two arrays have a shape of (Number_data_points, ), now the arrays can be merged using numpy.stack method.假设两个数组的形状为 (Number_data_points, ),现在可以使用numpy.stack方法合并数组。

merged_array = np.stack([array_1, array_2], axis=1)

model0 = keras.Sequential([
keras.layers.Dense(2, input_dim=2, activation=keras.activations.sigmoid, use_bias=True),
keras.layers.Dense(1, activation=keras.activations.relu, use_bias=True),
])

model0.fit(merged_array,output, batch_size=16, epochs=100)

2. Using Functional API. 2. 使用函数式 API。

This is the most recommened way to use when there are multiple inputs to the model.当模型有多个输入时,这是最推荐使用的方法。

input1 = keras.layers.Input(shape=(1, ))
input2 = keras.layers.Input(shape=(1,))
merged = keras.layers.Concatenate(axis=1)([input1, input2])
dense1 = keras.layers.Dense(2, input_dim=2, activation=keras.activations.sigmoid, use_bias=True)(merged)
output = keras.layers.Dense(1, activation=keras.activations.relu, use_bias=True)(dense1)
model10 = keras.models.Model(inputs=[input1, input2], output=output)

Now you can use the second method you have trying to fit to the model现在您可以使用您尝试适应模型的第二种方法

model0.fit([array_1, array_2],output, batch_size=16, epochs=100)

As in the answer you've linked, you cant be using the Sequential API for the stated reason.与您链接的答案一样,由于所述原因,您不能使用Sequential API。 You should use Model API which is also called the functional API.您应该使用Model API,也称为功能 API。 Architecturally, you need to define to the model how you'll combine the inputs with the Dense layer ie how you want to create the intermediate layer viz.在架构上,您需要为模型定义如何将输入与 Dense 层相结合,即您希望如何创建中间层,即。 merge/add or subtract etc/construct a embedding layer etc), or maybe you want to have 2 neural networks, 1 for each input and only want to combine the output in the last layer.合并/添加或减去等/构建嵌入层等),或者您可能想要 2 个神经网络,每个输入 1 个,并且只想在最后一层合并输出。 The code for each of the above will vary.上述每个的代码都会有所不同。

Here's a working solution assuming you want to merge the inputs into a vector of shape 672 and then construct a neural network on that input:这是一个可行的解决方案,假设您要将输入合并为形状为 672 的向量,然后在该输入上构建神经网络:

import tensorflow as tf
from tensorflow.keras.layers import *
from tensorflow.keras.models import Sequential, Model
from tensorflow.keras.optimizers import Adam, RMSprop
import numpy as np

input1 = Input(shape=(336,))
input2 = Input(shape=(336,))
input = Concatenate()([input1, input2])
x = Dense(2)(input)
x = Dense(1)(x)
model = Model(inputs=[input1, input2], outputs=x)
model.summary()

You'll notice that this model merges or concatenates the two inputs and then constructs a neural network on top of that:你会注意到这个模型合并或连接了两个输入,然后在其上构建了一个神经网络:

Layer (type)                    Output Shape         Param #     Connected to                     
==================================================================================================
input_1 (InputLayer)            (None, 336)          0                                            
__________________________________________________________________________________________________
input_2 (InputLayer)            (None, 336)          0                                            
__________________________________________________________________________________________________
concatenate (Concatenate)       (None, 672)          0           input_1[0][0]                    
                                                                 input_2[0][0]                    
__________________________________________________________________________________________________
dense (Dense)                   (None, 2)            1346        concatenate[0][0]                
__________________________________________________________________________________________________
dense_1 (Dense)                 (None, 1)            3           dense[0][0]                      
==================================================================================================
Total params: 1,349
Trainable params: 1,349
Non-trainable params: 0

If you have some other preferred way to create the intermediate layer, you should replace the Concatenate line with that in the code.如果您有其他首选方法来创建中间层,则应将Concatenate行替换为代码中的行。

You can then compile and fit the model:然后,您可以编译并拟合模型:

model.compile(
    optimizer = RMSprop(lr=0.02,rho=0.9,epsilon=None,decay=0),
    loss = 'mean_squared_error'
)


x1, x2 = np.random.randn(100, 336),np.random.randn(100, 336,)
y = np.random.randn(100, 1)
model.fit([x1, x2], y)

The above solutions contain the recommended approach but I still got some errors.上述解决方案包含推荐的方法,但我仍然遇到一些错误。 So I tried the following.所以我尝试了以下方法。

for count in range (len(array_1)):
    input_array[count][0] = array_1[count]
    input_array[count][1] = array_2[count]

Both Array_1 and Array_2 were the same length. Array_1 和 Array_2 的长度相同。

And then created and compiled the model as before.然后像以前一样创建和编译模型。

Finally for training, I used:最后为了训练,我使用了:

model0.fit(input_array, output_array, batch_size=16, epochs=100, verbose=0)

This approach worked for me.这种方法对我有用。

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

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