python - 如果 2 个 keras 模型共享层,设置 trainable=False 后要编译哪个模型?
问题描述
我有 2 个需要训练的 keras 模型。假设第一个模型有 5 层。现在我将第一个模型的最后 3 层称为另一个模型。
像这样:
input=Input(shape=(100,))
x1=Dense(50, activation='relu')(input)
x2=Dense(50, activation='relu')(x1)
x3=Dense(50, activation='relu')(x2)
x4=Dense(50, activation='relu')(x3)
output=Dense(10, activation='softmax')(x4)
model1=Model(inputs=input, outputs=output)
model2=Model(inputs=x3, outputs=output)
model1.compile(optimizer='rmsprop', loss='cross_entropy')
model2.compile(optimizer='rmsprop', loss='cross_entropy')
现在由于某种原因,我需要批量训练模型 1,即我不能调用 fit() 方法并在 1 遍中进行训练。
for epoch in range(10):
model1.train_on_batch(x, y).
现在来解决问题。我需要在每个时期内多次切换模型2的训练参数。想想像 GAN 这样的场景。所以我需要在循环内执行此操作
model2.trainable=False // sometimes
model2.trainable=True // other times
但是 keras 表示,在切换模型的可训练参数后,您需要重新编译模型才能使更改生效。但我不明白要编译哪个模型?这些层在模型 1 和模型 2 之间共享。编译它们中的任何一个都可以吗?或者我需要编译它们。
所以我的意思是说以下是否等价?
情况1:
model2.trainable=False
model1.compile(optimizer='rmsprop', loss='cross_entropy')
案例二:
model2.trainable=False
model2.compile(optimizer='rmsprop', loss='cross_entropy')
案例3:
model2.trainable=False
model1.compile(optimizer='rmsprop', loss='cross_entropy')
model2.compile(optimizer='rmsprop', loss='cross_entropy')
解决方案
您需要在训练之前分别编译这两个模型(否则您将一无所获):一个冻结层,另一个没有。如果您只是将输入拟合到输出,则没有理由编译具有冻结层的部分。
此外,如果您尝试使用中间层作为输入定义模型,keras 会抱怨,您需要创建两个模型,然后将它们一个接一个地放入管道中:
input=Input(shape=(100,))
x1=Dense(50, activation='relu')(input)
x2=Dense(50, activation='relu')(x1)
x3=Dense(50, activation='relu')(x2)
aux_model1 = Model(inputs=input, outputs=x3)
x3_input= Input(shape=x3.shape.as_list()[1:])
x4=Dense(50, activation='relu')(x3_input)
output=Dense(10, activation='softmax')(x4)
aux_model2 = Model(inputs=x3_input, outputs=output)
x3 = aux_model1(input)
output = aux_model2(x3)
model1 = Model(inputs=input, outputs=output)
现在编译以训练所有可训练的:
model1.compile(optimizer='rmsprop', loss='cross_entropy')
现在编译以在不可训练的 aux_model2 中训练 w/ 层:
for layer in aux_model2.layers:
layer.trainable=False
model2 = Model(inputs=input, outputs=output)
model2.compile(optimizer='rmsprop', loss='cross_entropy')
然后根据条件训练模型1或模型2:
for epoch in range(10):
if training_layers:
model1.train_on_batch(x, y)
else:
model2.train_on_batch(x, y)
推荐阅读
- c# - 使用接口的委托作为参数类型时逆变无效
- d3.js - 从 D3 中的多级对象创建图表
- f# - 如何将 CsvHelper.CsvWriter 与 F# 选项类型一起使用?
- jupyter-notebook - 如何在不同架构的计算机上创建相同的 conda 环境?
- php - 如何从 url $GET 多个具有相同名称的值?
- android - Android Recycler E/AndroidRuntime:致命异常:主要
- lucene - Lucene - 构建多个模糊选择器单项但条件不同
- reactjs - 括号内的箭头函数 {} 关于反应上下文
- flutter - Flutter - 构建失败,评估项目时出现问题
- tensorflow - TensorFlow2 一直安装相同的版本