在Keras内实施自定义活动正则器

时间:2018-08-19 14:31:11

标签: python keras autoencoder loss-function

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

我正在使用Keras来实现自动编码器,我知道Keras Blog上有一篇关于使用Keras构建自动编码器的很棒的教程,但是我想在Keras中使用自定义正则化器来实现描述的稀疏度惩罚术语。在LinkLink上找到了有关此问题的一些旧实现,但是由于自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层自动编码器,应如何实现这一总体成本函数?

Sparse Autoencoder Cost Function

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

s_2:隐藏层中的单位数

rho:固定值(例如0.2)

m:训练集中的样本数

x_i:第i个训练集样本

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

1 个答案:

答案 0 :(得分: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