【问题标题】:Implement Custom Activity Regularizer inside Keras在 Keras 中实现自定义活动正则化器
【发布时间】:2025-11-24 11:10:01
【问题描述】:

我正在尝试在Andrew Ng Sparse Autoencoder 的损失函数中实现正则化项。在第 15 页,引入了一个稀疏惩罚项,它根据所有隐藏层单元的 rho 和 rho_hat_j 之间的 Kullback-Leibor (KL) 散度之和计算。 rho 是强制神经元大部分关闭的静态数,rho_hat_j 是整个训练集上神经元 j 的平均输出(激活)。

我正在使用 Keras 来实现自动编码器,我知道 Keras Blog 上提供了有关使用 Keras 构建自动编码器的精彩教程,但我想在 Keras 中使用自定义正则化器来实现所描述的稀疏惩罚项。在 LinkLink 上发现了一些关于这个问题的旧实现,但随着 Keras 1.2.0 版正则化 API 的变化,它们已经被弃用并且不再工作。

所以我试图用这样的东西来实现它:

from keras import backend as K

def kl_divergence(rho, rho_hat):
    return rho * tf.log(rho) - rho * tf.log(rho_hat) + (1 - rho) * tf.log(1 - rho) - (1 - rho) * tf.log(1 - rho_hat)

class SparseActivityRegularizer(Regularizer):

    def __init__(self, p=0.1, sparsityBeta=3):
        self.p = p
        self.sparsityBeta = sparsityBeta

    def __call__(self, x):
        regularization = 0            

        p_hat = K.mean(x, axis=0)
        regularization += self.sparsityBeta * K.sum(kl_divergence(self.p, p_hat))

        return regularization

    def get_config(self):
        return {"name": self.__class__.__name__} 

对吗?!

一个我在任何地方都没有找到的大问题,究竟传递给 callable __ call __ (作为 x 参数)?

我是否正确x是二维张量,每行属于每个神经元,每列属于训练集上的每个样本,每个单元格(i,j)将是训练集样本 j 的神经元 i 的输出?

更新:更短的问题

考虑 Keras 中的 3 层自动编码器,应该如何实现这个整体成本函数?

beta:稀疏惩罚系数(例如 3)

s_2:隐藏层的单元数

rho:固定值(例如 0.2)

m:训练集中的样本数

x_i:训练集的第 i 个样本

a_2_j(x_i):第 i 个训练集样本的第 2 层第 j 个单元的输出

【问题讨论】:

  • 我发现减重也是必要的。如果不使用,则 beta 需要小得多。或者 - 至少在 MNIST 数据集中 - 图像没有重建并且保持模糊。

标签: python keras autoencoder loss-function


【解决方案1】:

您的代码是正确的。但似乎没有任何关于您的自动编码器模型的代码。它只是隐藏层的正则化器。

  1. 由于您定义了活动正则化器,__call__ 函数中的 X 是活动(隐藏层的输出),其形状应为 (?, hidden_​​dim)。 “?”表示样本数,在拟合之前未知。 hidden_dim 是隐藏层中神经元的数量,在我下面的示例中应该是 250。

如果你想构建整体,你应该知道如何定义其他层。这是一个玩具示例。

x_input = Input(shape=(576,))
regularizer = SparseActivityRegularizer(0.1, 6)
encoded = Dense(250, activation='relu', activity_regularizer=regularizer)(x_input)
decoded = Dense(576, activation ='relu')(encoded)
ae = Model(inputs=x_input, outputs=decoded)

然后您可以通过以下方式编译和拟合模型:

ae.compile(optimizer='adam', loss='mse')
ae.fit(x_train, x_train, epochs=1, batch_size=50)

所以整体损失函数由两部分组成:1) 编译模型时分配的 mse 和 2) 定义隐藏层时的活动正则化(在我的示例中为 encoded

【讨论】:

    最近更新 更多