Keras-具有多个输入滤波器的CNN

时间:2020-04-26 17:21:25

标签: python tensorflow keras

我正在尝试使用keras,并且尝试实施深度学习来预测对患者运动的评估。但是,我已经停留了很长时间,试图使用自定义生成器来适应网络。

意图: 假设我们有患者要接受检查。每个病人都必须做9个运动,而他(她)是被照相机捕获的。对我们来说,输入的是时间上的21个点(每个3个暗点)的序列。带有用于时间戳的另一列,这意味着一个包含64(21 * 3 + 1)列的表。每个时间步长均由表中的一行值表示。
因此,每个病人由九张桌子代表。因此,我尝试实现的网络应以九张可变长度的表格作为输入,并输出对患者的评估(这是一个数字)。
我遵循了一些指南,最后得到了以下内容。

def get_base_model(input_len, fsize, width):
    input_seq = tf.keras.layers.Input(shape=(input_len, width))

    nb_filters = 10

    convolved = tf.keras.layers.Conv1D(
        nb_filters,
        fsize,
        padding="same",
        activation="tanh"
    )(input_seq)
    processed = tf.keras.layers.GlobalMaxPooling1D()(convolved)

    compressed = tf.keras.layers.Dense(50, activation="tanh")(processed)
    compressed = tf.keras.layers.Dropout(0.3)(compressed)
    model = tf.keras.models.Model(inputs=input_seq, outputs=compressed)

    return model

def main_model(inputs_lens, fsizes=[8, 16, 24]):
    width = Misc.COUNT_OF_POINTS * 3 + 1

    inputs = []
    for i in range(Misc.COUNT_OF_EXERCISES):
        inputs.append(tf.keras.layers.Input(shape=(inputs_lens[i], width)))

    base_nets = []
    for i in range(Misc.COUNT_OF_EXERCISES):
        # TODO down-sampling?
        base_nets.append(get_base_model(inputs_lens[i], fsizes[0], width))

    embeddings = []
    for i in range(Misc.COUNT_OF_EXERCISES):
        embeddings.append(base_nets[i](inputs[i]))

    merged = tf.keras.layers.Concatenate()(embeddings)
    out = tf.keras.layers.Dense(1, activation='sigmoid')(merged)
    model = tf.keras.models.Model(inputs=inputs, outputs=out)

    return model

然后我按如下方式使用它。

        n_outputs = 1
        n_epochs = 10
        batch_size = 1

        inputs_lens = []
        for i in range(Misc.COUNT_OF_EXERCISES):
            inputs_lens.append(patients.get_max_row_count()) // TODO

        net = main_model(inputs_lens)
        net.compile(optimizer='rmsprop', loss='mse', metrics=['accuracy'])

        generator = Generator(patients)

        net.fit(
            generator,
            epochs=n_epochs,
            steps_per_epoch=generator.__len__(),
            verbose=2)

问题: 据我所知,我需要用元组(x,y)拟合网络,其中y是一批结果-一组评估数字,而x是一批输入-形状为batch_size * exercise_count *的数组时间步长*值。我还准备了一个生成器,提供了批处理:

print(generator。 getitem (0)[0] .shape)//(32,9,678,64)->(批处理大小,练习,步骤,值)
print(generator。 getitem (0)[1] .shape)//(32,)->(batch_size,)。

但是,网似乎只期望3维。当我尝试运行它时,发生以下错误:

ValueError:conv1d层的输入0与该层不兼容:预期ndim = 3,找到的ndim = 4。收到完整形状:[无,无,无,无]

伴随警告:

警告:tensorflow:使用输入Tensor(“ input_1:0”,shape =(None,678,64),dtype = float32)的形状(None,678,64)构造模型,但在输入的形状不兼容(无,无,无,无)。
警告:tensorflow:为输入Tensor(“ input_10:0”,shape =(None,678,64),dtype = float32)构造了形状为(None,678,64)的模型,但是在不兼容的输入上调用了该模型形状(无,无,无,无)。

净摘要:

print(net.summary())

Model: "model_9"
__________________________________________________________________________________________________
Layer (type)                    Output Shape         Param #     Connected to                     
==================================================================================================
input_1 (InputLayer)            [(None, 678, 64)]    0                                            
__________________________________________________________________________________________________
input_2 (InputLayer)            [(None, 678, 64)]    0                                            
__________________________________________________________________________________________________
input_3 (InputLayer)            [(None, 678, 64)]    0                                            
__________________________________________________________________________________________________
input_4 (InputLayer)            [(None, 678, 64)]    0                                            
__________________________________________________________________________________________________
input_5 (InputLayer)            [(None, 678, 64)]    0                                            
__________________________________________________________________________________________________
input_6 (InputLayer)            [(None, 678, 64)]    0                                            
__________________________________________________________________________________________________
input_7 (InputLayer)            [(None, 678, 64)]    0                                            
__________________________________________________________________________________________________
input_8 (InputLayer)            [(None, 678, 64)]    0                                            
__________________________________________________________________________________________________
input_9 (InputLayer)            [(None, 678, 64)]    0                                            
__________________________________________________________________________________________________
model (Model)                   (None, 50)           5680        input_1[0][0]                    
__________________________________________________________________________________________________
model_1 (Model)                 (None, 50)           5680        input_2[0][0]                    
__________________________________________________________________________________________________
model_2 (Model)                 (None, 50)           5680        input_3[0][0]                    
__________________________________________________________________________________________________
model_3 (Model)                 (None, 50)           5680        input_4[0][0]                    
__________________________________________________________________________________________________
model_4 (Model)                 (None, 50)           5680        input_5[0][0]                    
__________________________________________________________________________________________________
model_5 (Model)                 (None, 50)           5680        input_6[0][0]                    
__________________________________________________________________________________________________
model_6 (Model)                 (None, 50)           5680        input_7[0][0]                    
__________________________________________________________________________________________________
model_7 (Model)                 (None, 50)           5680        input_8[0][0]                    
__________________________________________________________________________________________________
model_8 (Model)                 (None, 50)           5680        input_9[0][0]                    
__________________________________________________________________________________________________
concatenate (Concatenate)       (None, 450)          0           model[1][0]                      
                                                                 model_1[1][0]                    
                                                                 model_2[1][0]                    
                                                                 model_3[1][0]                    
                                                                 model_4[1][0]                    
                                                                 model_5[1][0]                    
                                                                 model_6[1][0]                    
                                                                 model_7[1][0]                    
                                                                 model_8[1][0]                    
__________________________________________________________________________________________________
dense_9 (Dense)                 (None, 1)            451         concatenate[0][0]                
==================================================================================================
Total params: 51,571
Trainable params: 51,571
Non-trainable params: 0
__________________________________________________________________________________________________

感谢您的帮助。

1 个答案:

答案 0 :(得分:0)

我对神经网络的pytorch框架比较熟悉,但是我认为基本层逻辑是以相同的方式定义的。我相信您遇到的问题是在使用Conv1D中。转换层不是非常直观,但是会分解成这样:

  • Conv1D需要[batch_size,n_feat_vecs,feat_vec_idx]输入。它用于沿一维特征向量进行卷积(一维内核),并且批次中的每个项目都有n_feat_vecs个。因此,您的输入是3维
  • Conv2D需要[batch_size,n_feat_maps,feat_map_row,feat_map_column]输入。它用于沿2D特征图进行卷积(2D内核),并且对于批次中的每个项目,您都有这些2D特征图的n_feat_maps。因此,输入是4维的。

现在,对于您的情况,您的输入当前为4维,因此此输入与Conv-1D不兼容。您可以通过以下两种方式处理此问题:

  • 使用Conv2D -不需要任何输入重新格式化,但是在Conv图层之后,您将必须使用重塑操作以将结果格式化为密集图层可以接受的形式。使用2D卷积将使内核跨越一个值的单个时间步长和多个时间步长同时卷积。如果您有理由相信时间步之间的时间关系包含内核卷积可利用的有用信息,那么这就是方法。
  • 使用Conv1D -或者,您可能决定不希望同时跨时间步长和值对2D内核进行卷积。在这种情况下,您可能需要将4D输入向量展平为3个维度,这可能是通过沿一个维度堆叠所有时间步长的所有值来实现的。这将防止模型通过分别处理不同的时间步来学习时间步之间的一些时间相关性核。展平操作应类似于inputs.reshape(batch_size,n_exercises,-1)

您可以决定其中的哪一项将对您的特定任务更有用,并且可能提供更多信息。希望这会有所帮助!

相关问题