设置Keras模型可训练与使每个层可训练的区别是什么?

3

我有一个Keras顺序模型,其中包含一些密集层。我将整个模型的trainable属性设置为False。但是我发现各个层仍然具有可训练的属性。我需要单独将每个层的trainable属性也设置为False吗?那么将整个模型的trainable属性设置为False的意义是什么?


可能是[不应该在模型下使用model.trainable=False来冻结权重吗?]的重复问题(https://dev59.com/ilYN5IYBdhLWcg3wlZB7)。 - Dr. Snoopy
抱歉,但那并没有明确回答这个问题。 - user257330
1个回答

9
要回答这个问题,您需要查看Keras的源代码,这可能会让您感到惊讶,因为您会意识到: 正如我所说的那样,Keras模型是从Keras层派生而来可能会有些令人惊讶。但是如果你进一步思考,你会发现这是合理的,因为它们具有许多共同的功能(例如,它们都获得一些输入,在其上执行一些计算,产生一些输出,并更新其内部权重/参数)。它们的一个共同属性是“可训练”的属性。现在,当你将模型的“可训练”属性设置为“False”时,它将跳过权重更新步骤。换句话说,它不会检查其底层层的“可训练”属性;相反,首先它会检查自己的“可训练”属性(更准确地说是在“Network”类中),如果它为“False”,则会跳过更新。因此,这并不意味着其底层层的“可训练”属性也被设置为“False”。不这样做有一个很好的理由:一个层的单个实例可以用于多个模型。例如,考虑以下两个具有共享层的模型:
inp = Input(shape=...)

shared_layer = Dense(...)
sout = shared_layer(inp)

m1_out = Dense(...)(sout)
m2_out = Dense(...)(sout)

model1 = Model(inp, m1_out)
model2 = Model(inp, m2_out)

现在,如果我们设置model1.trainable = False,这将冻结整个model1(即训练model1不会更新其底层层的权重,包括shared_layer);然而,shared_layermodel2仍然可训练(即训练model2将更新所有层的权重,包括shared_layer)。另一方面,如果我们设置model1.layers[1].trainable = False,那么shared_layer就被冻结了,因此当训练model1model2时,它的权重不会被更新。这样,您可以拥有更多的控制和灵活性,因此可以构建更复杂的架构(例如GANs)。

我发现了一个代码片段,其中作者首先将所有的layers.trainable = False设置为False,然后将model.trainable=False设置为False,最后调用model.compile。现在,如果我想重复使用已经被冻结权重的层(如上所做),那么我只需要再次调用layers.trainable=True并重复使用这些层,对吗?顺便说一下,感谢您上面的答案,解决了我的初步困惑。 - Harshit Trehan
1
如果您所说的“重用”是指您想要再次使层的权重可训练,那么您是正确的:首先将trainable设置为True,然后编译模型(即调用compile方法)以使此更改生效(否则,层的可训练状态将不会在不编译模型的情况下更改)。 - today

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接