【问题标题】:Keras Sequential model with multiple inputs具有多个输入的 Keras 顺序模型
【发布时间】:2019-08-09 12:43:51
【问题描述】:

我正在制作一个 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: 检查输入时出错:预期的 dense_input 的形状为 (2,) 但得到的数组的形状为 (336,)

第二种方式:

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

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

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

【问题讨论】:

    标签: python arrays tensorflow keras


    【解决方案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)
    
    

    【讨论】:

    • 当我尝试第一种方法时,我收到错误ValueError: Error when checking input: expected dense_input to have shape (672,) but got array with shape (1,)。这是合并后的数组的样子:length 672 shape (672,)
    • 当我尝试第二种方法时,我收到错误ValueError: Error when checking input: expected input_1 to have shape (336,) but got array with shape (1,)。每个单独数组的形状如下:Array_1 Type & Shape: <class 'numpy.ndarray'> (336,) Array_2 Type & Shape: <class 'numpy.ndarray'> (336,)
    • print(array_1.shape)print(array_2.shape) 的结果是什么?每个数组的数字特征是什么?
    • Array_1 is (336,) 的形状与Array_2 相同。
    • 你不能总是连接。尺寸可能不对齐。
    【解决方案2】:

    在您链接的答案中,由于所述原因,您不能使用Sequential API。您应该使用Model API,它也称为功能 API。在架构上,您需要在模型中定义如何将输入与 Dense 层相结合,即您希望如何创建中间层,即。合并/添加或减去等/构建嵌入层等),或者您可能想要 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'
    )
    
    
    x1, x2 = np.random.randn(100, 336),np.random.randn(100, 336,)
    y = np.random.randn(100, 1)
    model.fit([x1, x2], y)
    

    【讨论】:

    • 感谢您提供完整的运行示例。
    【解决方案3】:

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

    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)
    

    这种方法对我有用。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-02-06
      • 2021-08-13
      • 2022-01-08
      • 1970-01-01
      • 2019-03-31
      • 1970-01-01
      相关资源
      最近更新 更多