【问题标题】:Tensorflow 2.0: How to implement a network with fusion at feature level?Tensorflow 2.0:如何在特征层面实现融合网络?
【发布时间】:2020-03-30 00:46:48
【问题描述】:

我正在尝试在 tensorflow 中实现一个用于预测任务的小型模型,其中两个信号作为输入,它们分别通过几层,然后在后面的层中组合以生成输出预测。本质上,该模型是这样工作的:

(Signal A) -> [L 1] -> [L 2] -> ... -> [L k] 
                                            \
                                             \
                                               -> [L k+1] ->...-> [Final Layer] -> Output
                                             /
                                            /
(Signal B) -> [L 1] -> [L 2] -> ... -> [L k]

其中 [L i] 是网络的不同层。在融合之前,网络的第一部分对于两个信号都是相同的。在 tensorflow 2.0 中实现这个模型的正确方法是什么?我相信在这种情况下顺序不是一个选项,但我可以通过功能 API 来实现,还是应该通过模型子类化?从我读到的内容来看,这两种方法似乎差别不大。

【问题讨论】:

    标签: python deep-learning tensorflow2.0


    【解决方案1】:

    这是您的模型在功能API中的模板,您可以根据需要更改层。

    您的基本模型(两者通用)-

    from tensorflow.keras.layers import Input, Conv1D, Concatenate, MaxPooling1D, Flatten, Dense, GlobalMaxPooling1D, subtract, BatchNormalization
    from tensorflow.keras.models import Model
    from tensorflow.keras.regularizers import l1, l2
    from tensorflow.keras.optimizers import Adam
    import tensorflow.keras.backend as K
    
    # baseline model
    
    input_shape = (256, 1) # assuming your signals have length 256, 1 channel
    
    # conv base model
    sig_input = Input(input_shape)
    cnn1 = Conv1D(64,3,activation='relu',input_shape=input_shape, kernel_regularizer=l2(2e-4))(sig_input)
    mp1 = MaxPooling1D()(cnn1)
    mp1 = BatchNormalization()(mp1)
    cnn2 = Conv1D(128,3,activation='relu', kernel_regularizer=l2(2e-4))(mp1)
    mp2 = MaxPooling1D()(cnn2)
    mp2 = BatchNormalization()(mp2)
    cnn3 = Conv1D(128,3,activation='relu', kernel_regularizer=l2(2e-4))(mp2)
    mp3 = MaxPooling1D()(cnn3)
    mp3 = BatchNormalization()(mp3)
    cnn4 = Conv1D(256,3,activation='relu', kernel_regularizer=l2(2e-4))(mp3)
    mp4 = MaxPooling1D()(cnn4)
    mp4 = BatchNormalization()(mp4)
    flat = Flatten()(mp4)
    embed = Dense(64, activation="sigmoid")(flat)
    
    conv_base = Model(sig_input, embed)
    
    conv_base.summary()
    

    网络摘要:

    Model: "model_2"
    _________________________________________________________________
    Layer (type)                 Output Shape              Param #   
    =================================================================
    input_6 (InputLayer)         [(None, 256, 1)]          0         
    _________________________________________________________________
    conv1d_12 (Conv1D)           (None, 254, 64)           256       
    _________________________________________________________________
    max_pooling1d_12 (MaxPooling (None, 127, 64)           0         
    _________________________________________________________________
    batch_normalization_12 (Batc (None, 127, 64)           256       
    _________________________________________________________________
    conv1d_13 (Conv1D)           (None, 125, 128)          24704     
    _________________________________________________________________
    max_pooling1d_13 (MaxPooling (None, 62, 128)           0         
    _________________________________________________________________
    batch_normalization_13 (Batc (None, 62, 128)           512       
    _________________________________________________________________
    conv1d_14 (Conv1D)           (None, 60, 128)           49280     
    _________________________________________________________________
    max_pooling1d_14 (MaxPooling (None, 30, 128)           0         
    _________________________________________________________________
    batch_normalization_14 (Batc (None, 30, 128)           512       
    _________________________________________________________________
    conv1d_15 (Conv1D)           (None, 28, 256)           98560     
    _________________________________________________________________
    max_pooling1d_15 (MaxPooling (None, 14, 256)           0         
    _________________________________________________________________
    batch_normalization_15 (Batc (None, 14, 256)           1024      
    _________________________________________________________________
    flatten_3 (Flatten)          (None, 3584)              0         
    _________________________________________________________________
    dense_3 (Dense)              (None, 64)                229440    
    =================================================================
    Total params: 404,544
    Trainable params: 403,392
    Non-trainable params: 1,152
    

    二次融合网络——

    
    left_input = Input(input_shape)
    right_input = Input(input_shape)
    
    # encode each of the two inputs into a vector with the base conv model
    encoded_l = conv_base(left_input)
    encoded_r = conv_base(right_input)
    
    
    
    fusion = Concatenate()([encoded_l,encoded_r]) # this can be any other fusion method too
    
    prediction = Dense(1, activation='sigmoid')(fusion)
    
    twin_net = Model([left_input,right_input],prediction)
    
    optimizer = Adam(0.001)
    
    twin_net.compile(loss="binary_crossentropy",optimizer=optimizer)
    
    twin_net.summary()
    
    __________________________________________________________________________________________________
    Layer (type)                    Output Shape         Param #     Connected to                     
    ==================================================================================================
    input_7 (InputLayer)            [(None, 256, 1)]     0                                            
    __________________________________________________________________________________________________
    input_8 (InputLayer)            [(None, 256, 1)]     0                                            
    __________________________________________________________________________________________________
    model_2 (Model)                 (None, 64)           404544      input_7[0][0]                    
                                                                     input_8[0][0]                    
    __________________________________________________________________________________________________
    concatenate (Concatenate)       (None, 128)          0           model_2[1][0]                    
                                                                     model_2[2][0]                    
    __________________________________________________________________________________________________
    dense_4 (Dense)                 (None, 1)            129         concatenate[0][0]                
    ==================================================================================================
    Total params: 404,673
    Trainable params: 403,521
    Non-trainable params: 1,152
    

    【讨论】:

    • 很好的答案!不过,有一个小细节我想更好地理解。对于conv_base ,您使用sig_input = Input(input_shape) 启动模型。以后在创建encoded_l和encoded_r的时候,为什么还要用conv_base(Input(input_shape))创建呢?
    • 哦,还有另一个问题:假设我使用 numpy 数组作为输入,我应该如何组织对 Model.fit 的输入?目前,我的输入是一个 (N, S, V) numpy 数组,其中 N 是样本数,S 是信号数,V 是信号的维数。我应该如何重塑它以作为输入传递给 twin_net ?
    • 在函数式API中,每次创建Model实例都需要至少有一个Input层。所以,conv_base 是两个信号的子模型或公共模型,但它是一个模型,所以它需要输入,同样在最终架构中,我们设计了另一个具有公共 conv_base 子模型的模型,所以我们在这里也需要输入。
    • 我认为这可能不正确,N = 样本数,S!= 信号数,样本数和信号数似乎相同。我认为您的意思是,N = 样本数,S = 每个信号中的时间步数,V = 信号的维度或每个时间步的特征。如果这是您的输入形状,则无需重新调整形状,因为这是模型想要的确切输入 numpy 数组形状。
    • 对不起,我表达得很糟糕。样本我的意思是“训练示例”,我习惯称它们为样本,但对于信号来说,这是一个不好的词选择。在一个具体的例子中,我有大约 100 万个训练样本(所以 N = 1M),每个由 2 个信号组成(所以 S = 2),每个由 150 个特征组成(所以 V = 150。它们是以 5Hz 采样的 30 秒信号)。在这种情况下,我有input_shape = (150, 1)(我使用重塑层)。我尝试向模型输入 (N, S, V) numpy 数组,但出现 tensorflow 错误!
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2018-01-22
    • 2019-02-28
    • 1970-01-01
    • 1970-01-01
    • 2013-07-23
    • 2018-09-01
    • 1970-01-01
    相关资源
    最近更新 更多