loss = torch.mean((z_q.detach()-z)**2) + self.beta * torch.mean((z_q - z.detach()) ** 2) z_q是codebook 找到的最接近z的向量. z是encoder生成的向量. L对z求导 = 2(z_q.detach()-z)*(-1)=2(z - z_q.detach()) # 这个部分对于encoder做了训练. L对z_q求导=2(z_q - ...
VQ-VAE 2中提出了一个滑动平均的训练方法,声称能稳定训练,同时也论证了其与直接训练loss是等价的。如...
commitment loss也比较简单,直接计算encoder的输出和对应的量化得到的embedding向量的L2误差: 注意这里的sg是作用在embedding向量上,这意味着这个约束只会影响encoder。 综上,VQ-VAE共包含三个部分的训练loss:reconstruction loss,VQ loss,commitment loss。 其中reconstruction loss作用在encoder和decoder上,VQ loss用来...
VQ-VAE使用的方法是Straight-Through Estimator,即直通估计。简单来说,就是前向传播的时候用Zq来算loss,反向传播的时候使用Z的梯度。 公式中的sg操作其实在Pytorch中很好实现,在PyTorch里,(x).detach()就是sg(x),它的值在前向传播时取x,反向传播时取0。所以上述公式对应的代码为 L = x - decoder(z_e + ...
randn(16, 10) # Example input loss = model(x) loss.backward() 总结 VQ-VAE 很巧妙地借助了 NLP 中 tokenize 的思想,先将一张图像切分成小的 patch(NLP 中的分词),然后将让每个小 patch 给映射到离散的值(查词表),然后获取这个离散值在嵌入空间(也称 Codebook)中对应的 embedding 向量。这个 ...
其中第一项为解码器的重构损失(regression loss) ;第二项为正则项,用KL散度来使Encoder---后验概率 和 先验 分布近似,通常 假设为多元标准正太分布,该项主要防止VAE坍塌到一个点,毕竟是生成模型。 而VQVAE和VAE主要不同:Encoder输出是离散的,而不是连续的隐变量z。 1...
loss = q_latent_loss + self._commitment_cost * e_latent_loss 最后确保梯度可以直接从解码器流向编码器。 quantized = inputs + (quantized - inputs).detach() 从数学上讲,左右两边是相等的(+输入和-输入将相互抵消)。在反向传播过程中,.detach部分将被忽略 ...
在solver.py中,最主要的逻辑如下所示,其中的self.G(x)即是Code 1所示的forward()逻辑,对于其输出的解码器输出out,构建重建损失,对重建损失loss_rec和其他俩对齐损失loss_e1和loss_e2进行加和后得到loss,对loss进行梯度计算(注意此时需要将retain_graph设置为True,以保留叶子节点的梯度,具体作用见博文[6])。注意...
第一项相等于固定z,让zq靠近z,第二项则反过来固定zq,让z靠近zq。注意这个“等价”是对于反向传播(求梯度)来说的,对于前向传播(求loss)它是原来的两倍。根据我们刚才的讨论,我们希望“让zq去靠近z”多于“让z去靠近zq”,所以可以调一下最终的loss比例: ...
可以看到是 L1 loss 来监督重建的坐标值,第二项则是 VQ-VAE 中的 commitment loss,目的是鼓励 Encoder 的输出尽量接近 codebook 中的特征,防止 Encoder 预测的结果频繁在各个 codebook 特征之间跳动。 Class Head 训练好了姿态版本的 VQ-VAE,我们真正需要的其实只是 codebook 和 Decoder,原来的 Encoder 就可以扔掉...