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

时间:2019-03-19 03:50:45

标签: python arrays tensorflow keras

我正在制作一个MLP模型,该模型需要两个输入并产生一个输出。

我有两个输入数组(每个输入一个)和一个输出数组。神经网络具有1个隐藏层和2个神经元。每个数组有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']
)

我尝试了两种方法,两种方法都出错。

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

ValueError:检查输入时出错:预期density_input具有形状(2,)但具有形状为(336,)的数组

第二种方式:

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

ValueError:检查模型输入时出错:传递给模型的Numpy数组列表不是模型预期的大小。预计会看到1个数组,但获得了以下2个数组的列表:

Similar question。但不使用顺序模型。

3 个答案:

答案 0 :(得分:1)

要解决此问题,您有两个选择。

1。使用顺序模型

您可以将两个阵列连接成一个阵列,然后再馈入网络。假设两个数组的形状为(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。使用功能性API。

当模型有多个输入时,这是最推荐的使用方式。

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)

现在,您可以使用第二种尝试拟合模型的方法

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

答案 1 :(得分:0)

正如您所链接的答案中所述,由于所述原因,您不能使用Sequential API。您应该使用Model API,也称为功能性API。从体系结构上讲,您需要为模型定义如何将输入与密集层结合在一起,即如何创建中间层。合并/添加或减去等/构造一个嵌入层等),或者您可能想拥有2个神经网络,每个输入1个,并且只想在最后一层组合输出。以上每种代码均会有所不同。

这是一个可行的解决方案,假设您要将输入合并为形状为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()

您会注意到,此模型将两个输入合并或连接,然后在此之上构建神经网络:

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

如果您还有其他创建中间层的首选方法,则应将Concatenate行替换为代码中的行。

然后您可以编译并拟合模型:

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


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

答案 2 :(得分:0)

上述解决方案包含推荐的方法,但是我仍然遇到一些错误。 所以我尝试了以下方法。

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

Array_1和Array_2的长度相同。

然后像以前一样创建和编译模型。

最后,我使用了:

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

这种方法对我有用。