为什么这种VAE实施有时会添加S型操作?

时间:2019-01-07 23:01:24

标签: python-3.x machine-learning neural-network autoencoder chainer

我正在使用Chainer框架(link)在Python中构建变体自动编码器(VAE)。我在github上找到了各种可行的示例,并且正在尝试改编其中一个。我已经成功运行了它,并且效果很好,但是仍然有些我不理解的地方。

在以下代码段(定义解码器的行为)中,有一个可选的附加Sigmoid函数:

def decode(self, z, sigmoid=True):
    h = F.leaky_relu(self.ld1(z))
    h = F.leaky_relu(self.ld2(h))
    h = self.ld3(h)
    if sigmoid:
        return F.sigmoid(h)
    else:
        return h

在损失函数中训练为Sigmoid = False的过程中使用此函数:

def lf(x):
    mu, ln_var = self.encode(x)
    batchsize = len(mu)

    # reconstruction loss
    rec_loss = 0
    for l in six.moves.range(k):
        z = F.gaussian(mu, ln_var)
                                                       # ↓here↓
        rec_loss += F.bernoulli_nll(x, self.decode(z, sigmoid=False)) / (k * batchsize)
    self.rec_loss = rec_loss

    # adding latent loss
    self.latent_loss = beta * gaussian_kl_divergence(mu, ln_var) / batchsize
    self.loss = self.rec_loss + self.latent_loss
    chainer.report({'rec_loss': self.rec_loss, 'latent_loss': self.latent_loss, 'loss': self.loss}, observer=self)
    return self.loss

并且在训练后 生成示例时,与Sigmoid = True一起使用(隐式):

z = C.Variable(np.random.normal(0, 1, (self._batchsize, args.dimz)).astype(np.float32))
    with C.using_config('train', False), C.no_backprop_mode():
        xrand = self._model.decode(z)  # ←here
    xrand = np.asarray(xrand.array).reshape(self._batchsize, 3, 18, 11)

为什么要使用这种额外的S型功能?它扮演什么角色?为什么在培训后而不是在培训期间添加它?

1 个答案:

答案 0 :(得分:2)

阅读this documentation的注释。 F.bernoulli_nll的输入参数不应为 Sigmoid ,因为该函数内部包含Sigmoid函数。因此,将隐藏变量提供给F.bernoulli_nll时,将指定sigmoid=False。 (我对这种困惑有完全相同的经历。)