Keras Плотные модели с общим весом

#python #tensorflow #keras #neural-network #tf.keras

#python #тензорный поток #keras #нейронная сеть #тф.керас

Вопрос:

Я хотел бы создать плотную модель в keras с общими весами. Мой подход описан ниже. У меня есть одна плотная сеть 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()])
 

Ответ №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()])
 

Комментарии:

1. Спасибо за правки. Да, это именно то, что я искал.