在定义新的Keras图层时,add_loss()的功能是什么?

时间:2019-12-04 11:02:43

标签: python keras neural-network autoencoder

我指的是CelebA数据集的此变体自动编码器代码in github。像往常一样有一个编码器和解码器。编码器输出x,用于获取对数方差和后验分布的均值。现在,重新参数化技巧为我们提供了已编码的

z = sigma * u + mean

其中u来自均值= 0和方差= 1的正态分布。我可以在代码中找到所有这些。但是,在“ ScaleShift”类(这是一个新的keras层)中,我不明白为什么我们使用 add_loss(lodget)。我检查了Keras documentation for writing your own layers,似乎没有必要为层定义损耗。我对这条线的功能感到困惑。

#new keras layer
class ScaleShift(Layer):
    def __init__(self, **kwargs):
        super(ScaleShift, self).__init__(**kwargs)
    def call(self, inputs):
        z, shift, log_scale = inputs
        #reparameterization trick
        z = K.exp(log_scale) * z + shift
        #what are the next two lines doing?
        logdet = -K.sum(K.mean(log_scale, 0))
        self.add_loss(logdet)
        return z

#gets the mean parameter(z_shift) from x, and similarly the log variance parameter(z_log_scale)
z_shift = Dense(z_dim)(x)
z_log_scale = Dense(z_dim)(x)
#keras lambda layer, spits out random normal variable u of same dimension as z_shift
u = Lambda(lambda z: K.random_normal(shape=K.shape(z)))(z_shift)
z = ScaleShift()([u, z_shift, z_log_scale])

x_recon = decoder(z)
x_out = Subtract()([x_in, x_recon])

recon_loss = 0.5 * K.sum(K.mean(x_out**2, 0)) + 0.5 * np.log(2*np.pi) * np.prod(K.int_shape(x_out)[1:])
#KL divergence loss
z_loss = 0.5 * K.sum(K.mean(z**2, 0)) - 0.5 * K.sum(K.mean(u**2, 0))
vae_loss = recon_loss + z_loss

vae = Model(x_in, x_out)
#VAE loss to be optimised 
vae.add_loss(vae_loss)
vae.compile(optimizer=Adam(1e-4))

0 个答案:

没有答案