【问题标题】:Keras Dense models with shared weights具有共享权重的 Keras Dense 模型
【发布时间】:2021-06-04 15:50:28
【问题描述】:

我想在 keras 中创建一个具有共享权重的 Dense 模型。我的方法如下所述。我有一个名为dense 的密集网络。 dense_x、dense_y 和 dense_z 应该共享权重(即使用 dense)。然后将这三个网络的输出连接起来并馈入另一个密集网络。

但是,不知何故,这种方法不起作用。如何正确使用共享权重?

num_nodes = 310
input_tensor_x = Input(shape=(310,))
input_tensor_y = Input(shape=(310,))
input_tensor_z = Input(shape=(310,))

dense = Dense(num_nodes)
dense = BatchNormalization()(dense)
dense = Activation('relu')(dense)
dense = Dropout(0.4)(dense)

dense = Dense(num_nodes // 2)
dense = BatchNormalization()(dense)
dense = Activation('relu')(dense)
dense = Dropout(0.4)(dense)

dense = Dense(num_nodes // 4)
dense = BatchNormalization()(dense)
dense = Activation('relu')(dense)
dense = Dropout(0.4)(dense)

dense_x = dense(input_tensor_x) #<=== shared above dense network
dense_y = dense(input_tensor_y) #<=== shared above dense network
dense_z = dense(input_tensor_z) #<=== shared above dense network
merge_layer = tf.keras.layers.Concatenate()([dense_x, dense_y, dense_z])

merged_nodes = 3*(num_nodes // 4) // 2
dense2 = Dense(merged_nodes)(merge_layer)
dense2 = BatchNormalization()(dense2)
dense2 = Activation('relu')(dense2)
dense2 = Dropout(0.4)(dense2)

dense2 = Dense(merged_nodes // 2)(dense2)
dense2 = BatchNormalization()(dense2)
dense2 = Activation('relu')(dense2)
dense2 = Dropout(0.4)(dense2)

output_tensor = Dense(3, activation='softmax')(dense2)

fcnn_model = Model(inputs=[input_tensor_x, input_tensor_y, input_tensor_z], outputs=output_tensor)
opt = Adam(lr=learning_rate)
fcnn_model.compile(loss='categorical_crossentropy',
                  optimizer=opt, metrics=['accuracy', tf.keras.metrics.AUC()])

【问题讨论】:

    标签: python tensorflow keras neural-network tf.keras


    【解决方案1】:

    最简单的方法是在顶部初始化共享层,然后将下面的层传递给它们。注意不要覆盖它们。

    我初始化了一个Dense 层和一个BatchNormalization,因为它们是唯一具有可训练权重的层

    num_nodes = 310
    input_tensor_x = Input(shape=(310,))
    input_tensor_y = Input(shape=(310,))
    input_tensor_z = Input(shape=(310,))
    
    def shared_dense(inp):
        
        dense = Dense(num_nodes)(inp)
        dense = BatchNormalization()(dense)
        dense = Activation('relu')(dense)
        dense = Dropout(0.4)(dense)
    
        dense = Dense(num_nodes // 2)(dense)
        dense = BatchNormalization()(dense)
        dense = Activation('relu')(dense)
        dense = Dropout(0.4)(dense)
    
        dense = Dense(num_nodes // 4)(dense)
        dense = BatchNormalization()(dense)
        dense = Activation('relu')(dense)
        dense = Dropout(0.4)(dense)
    
        return Model(inp, dense, name='shared_dense')
    
    shared_dense = shared_dense(Input(shape=(310,)))
    dense_x = shared_dense(input_tensor_x) #<=== shared 
    dense_y = shared_dense(input_tensor_y) #<=== shared 
    dense_z = shared_dense(input_tensor_z) #<=== shared 
    
    merge_layer = Concatenate()([dense_x, dense_y, dense_z])
    
    merged_nodes = 3*(num_nodes // 4) // 2
    dense2 = Dense(merged_nodes)(merge_layer)
    dense2 = BatchNormalization()(dense2)
    dense2 = Activation('relu')(dense2)
    dense2 = Dropout(0.4)(dense2)
    
    dense2 = Dense(merged_nodes // 2)(dense2)
    dense2 = BatchNormalization()(dense2)
    dense2 = Activation('relu')(dense2)
    dense2 = Dropout(0.4)(dense2)
    
    output_tensor = Dense(3, activation='softmax')(dense2)
    
    fcnn_model = Model(inputs=[input_tensor_x, input_tensor_y, input_tensor_z], 
                       outputs=output_tensor)
    fcnn_model.compile(loss='categorical_crossentropy',
                      optimizer=Adam(lr=1e-3), 
                       metrics=['accuracy', tf.keras.metrics.AUC()])
    

    【讨论】:

    • 感谢您的编辑。是的,这正是我想要的。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-03-31
    • 2020-12-05
    • 1970-01-01
    • 2017-05-26
    • 2019-10-22
    相关资源
    最近更新 更多