我注意到 weight_regularizer 在 Keras 中不再可用,取而代之的是 activity 和 kernel 正则化器。 我想知道:
活动正则化器作为网络输出的函数工作,主要用于规范隐藏单元,而weight_regularizer,顾名思义,作用于权重(例如使它们衰减)。基本上,您可以将正则化损失表示为输出 (
activity_regularizer
) 或权重 (weight_regularizer
) 的函数。
新的
kernel_regularizer
取代了 weight_regularizer
- 尽管从文档中看的不是很清楚。
根据
kernel_regularizer
的定义:
kernel_regularizer:正则化函数应用于
权重矩阵 (参见正则化器)。kernel
和
activity_regularizer
:
activity_regularizer:正则化函数应用于 该层的输出(其“激活”)。 (参见正则化器)。
重要编辑:请注意,activity_regularizer中存在一个错误,仅在 Keras 2.1.4 版本中修复(至少在 Tensorflow 后端)。事实上,在旧版本中,活动正则化函数应用于层的输入,而不是应用于输出(按预期,层的实际激活)。因此,如果您使用旧版本的 Keras(2.1.4 之前),请注意,活动正则化可能无法按预期工作。
您可以在 GitHub
上查看提交这个答案有点晚了,但对未来的读者很有用。
因此,正如人们所说,需求是发明之母。我只有在需要的时候才明白。
上面的答案并没有真正说明差异,因为它们最终都会影响权重,那么对权重本身或层的输出进行惩罚有什么区别?
答案是:我遇到过一个情况,网络的权重又小又好,范围在 [-0.3] 到 [+0.3] 之间。
所以,我实在不能惩罚他们,他们并没有什么问题。内核正则化器是没有用的。然而,该层的输出非常巨大,有 100 个。
请记住,该层的输入也很小,始终小于一。但这些小值与权重相互作用,从而产生大量输出。在这里我意识到我需要的是一个活动正则化器,而不是内核正则化器。有了这个,我会惩罚那些大输出的层,我不在乎权重本身是否很小,我只是想阻止它达到这样的状态,因为这会使我的 sigmoid 激活饱和并导致大量其他问题,例如消失梯度和停滞。
上面有帮助的答案。我想添加我遇到过的另一个用例,并且我已经使用了它。
该用例是在自动编码器的上下文中,您希望将编码的大小限制为较小的数字(例如 10 个单位)。
强制编码大小为 10 个单位的一种方法是简单地制作一个编码层限制为 10 个单位的自动编码器。这是一个硬性限制,但有一些缺点。
获得小尺寸编码的另一种方法是使用活动正则化施加“软限制”。您创建了一个大型编码层(例如 100 个单元),但每当网络激活 100 个可用单元中超过 10 个单元时,您就会对网络进行惩罚。您不关心编码层的权重/内核(因此没有内核正则化);相反,您会惩罚该层的输出/活动,以便将其推向更稀疏的输出/编码。这会导致“稀疏自动编码器”,因为您鼓励网络平均仅使用其可用编码大小的 10%。
我在 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()