我正在尝试在Andrew Ng Sparse Autoencoder的损失函数中实现正则化项。在第15页上,引入了稀疏罚分项,它是根据所有隐藏层单元的rho和rho_hat_j之间的Kullback-Leibor(KL)散度之和计算得出的。 rho是静态数,其迫使神经元大部分处于关闭状态,rho_hat_j是整个训练集上神经元j的平均输出(激活)。
我正在使用Keras来实现自动编码器,我知道Keras Blog上有一篇关于使用Keras构建自动编码器的很棒的教程,但是我想在Keras中使用自定义正则化器来实现描述的稀疏度惩罚术语。在Link,Link上找到了有关此问题的一些旧实现,但是由于自1.2.0版以来在Keras上对正则化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__}
对吗?!
我在任何地方都找不到的一个大问题,到底是什么传递给可调用的__调用__(作为x参数)?
我纠正x是二维张量,每行属于每个神经元,每列属于训练集上的每个样本,并且每个单元格(i,j)将输出神经元i作为训练集的样本j ?
更新:简短问题
在Keras中考虑一个3层自动编码器,应如何实现这一总体成本函数?
beta:稀疏罚分系数(例如3)
s_2:隐藏层中的单位数
rho:固定值(例如0.2)
m:训练集中的样本数
x_i:第i个训练集样本
a_2_j(x_i):第i个训练集样本的第2层第j个单元的输出
答案 0 :(得分: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
)