Python 3.x 为什么这个VAE实现有时会添加sigmoid操作?

Python 3.x 为什么这个VAE实现有时会添加sigmoid操作?,python-3.x,machine-learning,neural-network,autoencoder,chainer,Python 3.x,Machine Learning,Neural Network,Autoencoder,Chainer,我正在使用Chainer框架在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 = s

我正在使用Chainer框架在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
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=False:

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
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)


为什么会有这种额外的乙状结肠功能?它扮演什么角色?为什么要在培训后添加,而不是在培训期间添加?

阅读的注释
F.bernoulli_nll
的输入参数不应为sigmoid,因为函数内部包含sigmoid函数。因此,将隐藏变量馈送到
F.bernoulli_nll
时,指定了
sigmoid=False
。(我对这种混乱有着完全相同的经历。)

我在官方的chainer vae示例中找不到这种
sigmoid
操作。您正在引用哪个存储库?我猜作者想在推理过程中将输出从-1“剪辑”到+1???@corochann我相信Chainer存储库修改了他们的官方示例。这是我能找到的第一个使用我所指结构的存储库: