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

Keras-从嵌套模型中提取权重的正确方法,keras,hdf5,transfer-learning,Keras,Hdf5,Transfer Learning,我有一个嵌套模型,它有一个输入层,在输出之前有一些最终的密集层。下面是它的代码: 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

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

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])
现在,如果我想从该模型中提取densenet权重,并将学习转移到另一个更大的模型,该模型也嵌套了相同的densenet模型,但在密集网络之后还有一些其他层,例如:

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\u权重(,by\u name=True)
?我还应该给内部的densenet命名吗?如果是这样的话,怎么做?

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

image\u input=input(shape,name='image\u input')
# ... 中间层省略
x=BatchNormalization()(x)
输出=辍学(0.5)(x)
model_output=densite(num_类,activation='softmax',name='image_output')(输出)
较小的模型=模型(输入=[image\u input],输出=[model\u output])
为了将此模型的训练权重用于更大的模型,我们可以简单地声明另一个使用训练权重的模型,然后将新定义的模型用作更大模型的组件

new_model = Model(image_input, output) # Model that uses trained weights

main_input = Input(shape, name='main_input')
x = new_model(main_input)
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)
final_model = Model(inputs=[main_input], outputs=[output])

如果有什么不清楚的地方,我非常乐意详细说明。

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

image\u input=input(shape,name='image\u input')
# ... 中间层省略
x=BatchNormalization()(x)
输出=辍学(0.5)(x)
model_output=densite(num_类,activation='softmax',name='image_output')(输出)
较小的模型=模型(输入=[image\u input],输出=[model\u output])
为了将此模型的训练权重用于更大的模型,我们可以简单地声明另一个使用训练权重的模型,然后将新定义的模型用作更大模型的组件

new_model = Model(image_input, output) # Model that uses trained weights

main_input = Input(shape, name='main_input')
x = new_model(main_input)
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)
final_model = Model(inputs=[main_input], outputs=[output])

如果有什么不清楚的地方,我很乐意详细说明。

在使用嵌套模型之前,可以将其放入变量中。 做任何事情都变得容易多了:

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\u model.layers[i]
那样获得它


然后,您可以使用上一个答案中的方法和
new\u model.layers[i]将这些权重转移到新的密集网络中。设置\u权重(densenet.get\u weights())

在使用嵌套模型之前,您可以将其放入变量中。 做任何事情都变得容易多了:

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\u model.layers[i]
那样获得它


然后,您可以使用上一个答案中的方法和
new\u model.layers[i].set\u weights(densenet.get\u weights())

我知道您要做什么,但很抱歉,我不太清楚,我使用了一个检查点,保存了modelA的权重(和模型)。我只有一个先前实验的hdf5文件。我能否将此文件中的权重加载到新的densenet?如下所示:另一个\u densenet.load\u权重('hdf5File.hdf5')。ModelA中嵌套了一个Denset。请检查更新的答案。只要你保证新的密集网络与旧的密集网络具有相同的层名称,你的建议也会起作用。我同意,但我必须以某种方式实例化modelA。例如,现在我没有这个加载模型,只有hdf5文件。从文件中加载模型a谢谢!我假设这是加载模型的正确方法:我知道您要去哪里,但很抱歉,我不太清楚,我使用了一个检查点,保存了modelA的权重(和模型)。我只有一个先前实验的hdf5文件。我能否将此文件中的权重加载到新的densenet?如下所示:另一个\u densenet.load\u权重('hdf5File.hdf5')。ModelA中嵌套了一个Denset。请检查更新的答案。只要你保证新的密集网络与旧的密集网络具有相同的层名称,你的建议也会起作用。我同意,但我必须以某种方式实例化modelA。例如,现在我没有这个加载模型,只有hdf5文件。从文件中加载模型a谢谢!我假设这是加载模型的正确方法: