创建多通道网络:“连接”对象没有“形状”属性

bio*_*ent 4 python neural-network deep-learning keras tensorflow

我正在尝试按如下方式制作多输入模型,但在定义以下内容时遇到问题:

  1. 每个单独输入的实际输入形状
  2. 什么时候应该使用 flatten
  3. 将我的两个独立模型连接在一起

我想建立这样的东西:

-First Dense Layer-      - First Dense layer -
         |                        |
         |                        |
Second Dense layer          Second Dense layer
                      |
                      |
            Final Dense layer (Single Output)
Run Code Online (Sandbox Code Playgroud)

但是,在运行模型时出现以下错误:

AttributeError: 'Concatenate' object has no attribute 'shape'
Run Code Online (Sandbox Code Playgroud)

我的代码

def build_nn_model(x_input1_train, x_input2_train):
    
    """
    Creates the a multi-channel ANN, capable of accepting multiple inputs.

    :param: none
    :return: the model of the ANN with a single output given
    """

    x_input1= np.expand_dims(x_input1,1)

    # define two sets of inputs for models
    input1= Input(shape = (x_input1.shape[1], 1))
    input2= Input(shape = (x_input2.shape[1], 1))

    # The first branch operates on the first input
    x = Dense(units = 128, activation="relu")(input1)
    x = BatchNormalization()(x)
    
    x = Dense(units = 128, activation="relu")(x)
    x =Flatten()(x)
    x = BatchNormalization()(x)  
    
    x = Model(inputs=input1, outputs=x)

    # The second branch operates on the second input
    y = Dense(units = 128, activation="relu")(input2)
    y = BatchNormalization()(y)
    
    y = Dense(units = 128, activation="relu")(y)
    y =Flatten()(y)
    y = BatchNormalization()(y)  
    
    y = Model(inputs=inp_embeddings, outputs=y)
    
    # combine the output of the two branches
    combined = Concatenate([x.output, y.output])
    
    # Apply a FC layer and then a regression activation on the combined outputs
    #z = Dense(2, activation="relu")(combined)
    #z = Dense(1, activation="linear")(z)
    
    outputs = Dense(128, activation='relu')(combined)
    #out = Dropout(0.5)(out)
    outputs = Dense(1)(out)

    # The model will accept the inputs of the two branches and then output a single value
    model = Model(inputs = [x.input, y.input], outputs = out)

    #model = Model(inputs=[x.input, y.input], outputs=z)

    # Compile the NN
    model.compile(loss='mse', optimizer = Adam(lr = 0.001), metrics = ['mse'])

    # ANN Summary
    model.summary()
    
    return model
Run Code Online (Sandbox Code Playgroud)

输入1

array([55., 46., 46., ..., 60., 60., 45.])
Run Code Online (Sandbox Code Playgroud)

形状: (2400,)

输入2

array([[-2.00370455, -2.35689664, -1.96147382, ...,  2.11014128,
         2.59383321,  1.24209607],
       [-1.97130549, -2.19063663, -2.02996445, ...,  2.32125568,
         2.27316046,  1.48600614],
       [-2.01526666, -2.40440917, -1.94321752, ...,  2.15266657,
         2.68460488,  1.23534095],
       ...,
       [-2.1359458 , -2.52428007, -1.75701785, ...,  2.25480819,
         2.68114281,  1.75468981],
       [-1.95868206, -2.23297167, -1.96401751, ...,  2.07427239,
         2.60306072,  1.28556955],
       [-1.80507278, -2.62199521, -2.08697271, ...,  2.34080577,
         2.48254585,  1.52028871]])>
Run Code Online (Sandbox Code Playgroud)

形状: (2400, 3840)

Mar*_*ani 9

您需要将括号添加到Concatenate图层。它是Concatenate()([x.output, y.output])

您还可以在不使用展平操作的情况下编写模型。你的数据是二维的,所以你不需要做奇怪的操作。您需要使用 flatten 从 3D(或更大尺寸)传递到 2D,但在您的情况下,您可以从 2D 开始而没有问题

这里有一个完整的例子

n_sample = 2400
X1 = np.random.uniform(0,1, (n_sample,))  # (2400,)
X2 = np.random.uniform(0,1, (n_sample,3840))  # (2400,3840)
Y = np.random.uniform(0,1, (n_sample,))  # (2400,)

input1= Input(shape = (1, ))
input2= Input(shape = (3840, ))

# The first branch operates on the first input
x = Dense(units = 128, activation="relu")(input1)
x = BatchNormalization()(x)
x = Dense(units = 128, activation="relu")(x)
x = BatchNormalization()(x)
x = Model(inputs=input1, outputs=x)

# The second branch operates on the second input (Protein Embeddings)
y = Dense(units = 128, activation="relu")(input2)
y = BatchNormalization()(y)
y = Dense(units = 128, activation="relu")(y)
y = BatchNormalization()(y)  
y = Model(inputs=input2, outputs=y)

# combine the output of the two branches
combined = Concatenate()([x.output, y.output])

out = Dense(128, activation='relu')(combined)
out = Dropout(0.5)(out)
out = Dense(1)(out)

# The model will accept the inputs of the two branches and then output a single value
model = Model(inputs = [x.input, y.input], outputs = out)
model.compile(loss='mse', optimizer = Adam(lr = 0.001), metrics = ['mse'])

model.fit([X1,X2], Y, epochs=3)
Run Code Online (Sandbox Code Playgroud)

这里的笔记本