Keras-从嵌套模型中提取权重的正确方法

问题描述 投票:0回答:2

我有一个嵌套模型,该模型具有输入层,并且在输出之前具有一些最终的密集层。这是它的代码:

image_input = Input(shape, name='image_input')
x = DenseNet121(input_shape=shape, include_top=False, weights=None,backend=keras.backend,
layers=keras.layers,
models=keras.models,
utils=keras.utils)(image_input)
x = GlobalAveragePooling2D(name='avg_pool')(x)
x = Dense(1024, activation='relu', name='dense_layer1_image')(x)
x = BatchNormalization()(x)
x = Dropout(0.5)(x)        
x = Dense(512, activation='relu', name='dense_layer2_image')(x)
x = BatchNormalization()(x)
x = Dropout(0.5)(x)
output = Dense(num_class, activation='softmax', name='image_output')(x)
classificationModel = Model(inputs=[image_input], outputs=[output])

现在,如果要说我想从该模型中提取密集网权重,并进行转移学习到另一个更大的模型,该模型也具有相同的密集网模型嵌套,但在密集网之后还具有其他一些层,例如:

image_input = Input(shape, name='image_input')
x = DenseNet121(input_shape=shape, include_top=False, weights=None,backend=keras.backend,
layers=keras.layers,
models=keras.models,
utils=keras.utils)(image_input)
x = GlobalAveragePooling2D(name='avg_pool')(x)
x = Dense(1024, activation='relu', name='dense_layer1_image')(x)
x = BatchNormalization()(x)
x = Dropout(0.5)(x)        
x = Dense(512, activation='relu', name='dense_layer2_image')(x)
x = BatchNormalization()(x)
x = Dropout(0.5)(x)
x = Dense(256, activation='relu', name='dense_layer3_image')(x)
x = BatchNormalization()(x)
x = Dropout(0.5)(x)
output = Dense(num_class, activation='sigmoid', name='image_output')(x)
classificationModel = Model(inputs=[image_input], outputs=[output])

我只需要做:modelB.load_weights(<weights.hdf5>, by_name=True)?我还应该命名内部密集网吗?如果可以的话?

keras hdf5 transfer-learning
2个回答
1
投票

您可以在使用嵌套模型之前将其放入变量中。一切都变得容易得多:

densenet = DenseNet121(input_shape=shape, include_top=False, 
                       weights=None,backend=keras.backend,
                       layers=keras.layers,
                       models=keras.models,
                       utils=keras.utils)

image_input = Input(shape, name='image_input')
x = densenet(image_input)
x = GlobalAveragePooling2D(name='avg_pool')(x)
......

现在,超级简单:

weights = densenet.get_weights()
another_densenet.set_weights(weights)

已加载的文件

您还可以打印已加载模型的model.summary()。密集的网将是第一层或第二层(您必须检查)。

然后您可以像densenet = loaded_model.layers[i]一样得到它。

然后您可以使用上一个答案中的方法和new_model.layers[i].set_weights(densenet.get_weights())将这些权重转移到新的密集网络中>


1
投票

也许最简单的方法是使用您自己训练的模型,而无需尝试加载模型权重。假设您已经训练了初始模型(从提供的源代码中复制和粘贴,只需对变量名进行最少的编辑即可):

© www.soinside.com 2019 - 2024. All rights reserved.