Keras:核和活动正则化器的区别

102

我注意到在Keras中不再有weight_regularizer,而是有activitykernel regularizer。

我想知道:

  • kernelactivity regularizers的主要区别是什么?
  • 我能否使用activity_regularizer代替weight_regularizer
3个回答

96
活动正则化器作用于网络输出的函数上,主要用于正则化隐藏层,而权重正则化器是作用于权重上的(例如使它们衰减)。基本上你可以把正则化损失表达为输出的函数(activity_regularizer)或者权重的函数(weight_regularizer)。

新的内核正则化器替换了权重正则化器,虽然从文档中并不是很清楚。

从内核正则化器的定义中可以看出:

内核正则化器:应用于内核权重矩阵的正则化器函数(参见正则化器)。

以及活动正则化器:

活动正则化器:应用于层输出(其“激活”)的正则化器函数(参见正则化器)。

Important Edit: 请注意,在 Keras 的2.1.4版本之前存在一个 activity_regularizer 的错误(至少在 Tensorflow 后端中),只有在Keras 2.1.4版本中修复。实际上,在较旧的版本中,活动正则化器函数被应用于层的输入,而不是应用于输出(即层的实际激活,如预期)。因此,如果您使用的是旧版本的Keras(2.1.4之前),则活动正则化可能无法按预期工作。

您可以在GitHub上查看提交记录。

五个月前,François Chollet 修复了活动正则化器的 bug,并将其包含在 Keras 2.1.4 中。


你确定要将 kernel_regularizer 替换为 weight_regularizer 吗? - Simone
3
我发现很多例子使用kernel_regularizer,但是没有使用activity_regularizer的例子。您能否评论一下activity_regularizer的用例? - Milad M
1
你为什么想要规范化隐藏层的输出?是因为和我们将输入归一化到范围(-1,1)或(0,1)的原因相同吗?也就是为了使输入到后续层更小,以帮助SGD过程? - Nagabhushan Baddi
1
@NagabhushanBaddi 请看这个答案:https://datascience.stackexchange.com/a/15195/32811 - Michele Tonutti
你在哪里找到关于kernel_regularizer或activity_regularizer的文档?在keras.io上所谓的“文档”根本没有说明它是什么,而python中的help()也毫无用处,只含有模糊的引用,说它是其他东西的子类或实例。 - Finncent Price
1
@FinncentPrice 我只能假设它曾经存在,现在不再存在了。 - Michele Tonutti

77

这个回答可能有点晚,但对未来的读者很有用。 正如他们所说,需要是发明之母。只有在需要时,我才理解它的重要性。
上面的回答并没有真正说明区别,因为两者都会影响权重,那么惩罚权重本身和层输出之间有什么区别呢?
以下是答案:我遇到了一个情况,网络的权重很小,范围在[-0.3]到[+0.3]之间。
所以,我真的不能惩罚它们,它们没有任何问题。核正则化器是无用的。然而,该层的输出非常大,达到100个单位。
请记住,该层的输入也很小,始终小于1。但是,这些小值与权重以某种方式交互,产生了这些巨大的输出。在这里,我意识到我需要的是一种活动正则化器,而不是核正则化器。通过这样做,我惩罚了该层的大输出,我不在乎权重本身是否小,我只是想阻止它达到这种状态,因为这使我的sigmoid激活饱和并引起大量其他问题,如消失梯度和停滞。


3
真正直观。 - Sarang Manjrekar
1
Clipnorm也很有帮助。 - Ishrak

2
以上回答很有帮助。我想补充一个我遇到过的用例,并且我也使用过它。
这个用例是在自编码器的背景下,你想要将编码的大小限制在一个小的数量上(比如说10个单元)。
一种强制编码大小为10个单元的方法是简单地创建一个编码层只有10个单元的自编码器。这是一个硬性限制,但也有一些缺点。
另一种获取小尺寸编码的替代方法是使用“活动正则化”来施加一个“软性限制”。你创建一个大的编码层(例如100个单元),但是当它激活超过100个可用单元中的10个单元时,你对网络进行惩罚。你不关心编码层的权重/核心(因此没有核心正则化);相反,你惩罚该层的输出/活动,以使其朝着更稀疏的输出/编码方向推进。这将导致一个“稀疏自编码器”,因为你鼓励网络平均只使用其可用编码大小的10%。

这个用例的Keras示例在这里:https://github.com/ageron/handson-ml3/blob/main/17_autoencoders_gans_and_diffusion_models.ipynb,书中有更详细的内容。

PyTorch中我的训练循环的草图:

autoencoder = torch.nn.Sequential(encoder, decoder)

for epoch in range(n_epochs):
  for X_in in train_data:
    X_recon = autoencoder(X_in)
    
    #For a basic autoencoder, the loss is simply MSE:
    mse_loss = torch.nn.MSELoss()(X_recon, X_in)
    
    #For a sparse autoencoder using activity regularisation,
    #  add a loss term penalising too many active outputs:
    codings = encoder(X) #get the activations from the coding layer
    activity_regularisation_l1_loss = codings.abs().sum()

    total_loss = mse_loss + 1e-3 * activity_regularisation_l1_loss

    optimizer.zero_grad()
    total_loss.backward()
    optimizer.step()
  

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