VQ-VAE(Neural Discrete Representation Learning)论文解读及实现

pytorch 实现git地址
论文地址:Neural Discrete Representation Learning

1 论文核心知识点

  • encoder
    将图片通过encoder得到图片点表征
    如输入shape [32,3,32,32]
    通过encoder后输出 [32,64,8,8] (其中64位输出维度)

  • 量化码本
    先随机构建一个码本,维度与encoder保持一致
    这里定义512个离散特征,码本shape 为[512,64]

  • encoder 码本中向量最近查找
    encoder输出shape [32,64,8,8], 经过维度变换 shape [32 * 8 * 8,64]
    在码本中找到最相近的向量,并替换为码本中相似向量
    输出shape [3288,64],维度变换后,shape 为 [32,64,8,8]

  • decoder
    将上述数据,喂给decoder,还原原始图片

  • loss
    loss 包含两部分
    a . encoder输出和码本向量接近
    b. 重构loss,重构图片与原图片接近

在这里插入图片描述

2 论文实现

2.1 encoder

encoder是常用的图片卷积神经网络
输入x shape [32,3,32,32]
输出 shape [32,128,8,8]


    def __init__(self, in_dim, h_dim, n_res_layers, res_h_dim):
        super(Encoder, self).__init__()
        kernel = 4
        stride = 2
        self.conv_stack = nn.Sequential(
            nn.Conv2d(in_dim, h_dim // 2, kernel_size=kernel,
                      stride=stride, padding=1),
            nn.ReLU(),
            nn.Conv2d(h_dim // 2, h_dim, kernel_size=kernel,
                      stride=stride, padding=1),
            nn.ReLU(),
            nn.Conv2d(h_dim, h_dim, kernel_size=kernel-1,
                      stride=stride-1, padding=1),
            ResidualStack(
                h_dim, h_dim, res_h_dim, n_res_layers)

        )

    def forward(self, x):
        return self.conv_stack(x)

2.2 VectorQuantizer 向量量化层

  • 输入:
    为encoder的输出z,shape : [32,64,8,8]
  • 码本维度:
    encoder维度变换为[2024,64],和码本embeddign shape [512,64]计算相似度
  • 相似计算:使用 ( x − y ) 2 = x 2 + y 2 − 2 x y (x-y)^2=x^2+y^2-2xy (xy)2=x2+y22xy计算和码本的相似度
  • z_q生成
    然后取码本中最相似的向量替换encoder中的向量
  • z_1维度:
    得到z_q shape [2024,64],经维度变换 shape [32,64,8,8] ,维度与输入z一致
  • 损失函数:
    使 z_q和z接近,构建损失函数
    在这里插入图片描述

decoder 层

decoder层比较简单,与encoder层相反
输入x shape 【32,64,8,8】
输出shape [32,3,32,32]

class Decoder(nn.Module):
    """
    This is the p_phi (x|z) network. Given a latent sample z p_phi 
    maps back to the original space z -> x.

    Inputs:
    - in_dim : the input dimension
    - h_dim : the hidden layer dimension
    - res_h_dim : the hidden dimension of the residual block
    - n_res_layers : number of layers to stack

    """

    def __init__(self, in_dim, h_dim, n_res_layers, res_h_dim):
        super(Decoder, self).__init__()
        kernel = 4
        stride = 2

        self.inverse_conv_stack = nn.Sequential(
            nn.ConvTranspose2d(
                in_dim, h_dim, kernel_size=kernel-1, stride=stride-1, padding=1),
            ResidualStack(h_dim, h_dim, res_h_dim, n_res_layers),
            nn.ConvTranspose2d(h_dim, h_dim // 2,
                               kernel_size=kernel, stride=stride, padding=1),
            nn.ReLU(),
            nn.ConvTranspose2d(h_dim//2, 3, kernel_size=kernel,
                               stride=stride, padding=1)
        )

    def forward(self, x):
        return self.inverse_conv_stack(x)

2.3 损失函数

损失函数为重构损失和embedding损失之和

  • decoder 输出为图片重构x_hat
  • embedding损失,为encoder和码本的embedding近似损失
  • 重点:(decoder计算损失时,由于中间有取最小值,导致梯度不连续,因此decoder loss 不能直接对encocer推荐进行求导,采用了复制梯度的方式: z_q = z + (z_q - z).detach(),及
    for i in range(args.n_updates):
        (x, _) = next(iter(training_loader))
        x = x.to(device)
        optimizer.zero_grad()

        embedding_loss, x_hat, perplexity = model(x)
        recon_loss = torch.mean((x_hat - x)**2) / x_train_var
        loss = recon_loss + embedding_loss

        loss.backward()
        optimizer.step()
### uView 框架中输入框与键盘的配置及常见问题解决方案 #### 输入框与键盘结合使用案例 对于验证码输入场景,`uview-ui` 提供了 `CodeInput` 组件用于接收用户输入的验证码,并通过自定义键盘来增强用户体验。为了实现这一功能,可以利用 `Keyboard` 和 `CodeInput` 这两个组件配合工作。 ```html <u-code-input ref="codeinput" @finish="handleFinish"></u-code-input> <u-keyboard mode="number" @change="onChange" @confirm="onConfirm"></u-keyboard> ``` 当用户完成所有字符填写时触发 `@finish` 事件;而 `mode="number"` 表示只允许数字键入,同时监听按键变化 (`@change`) 及确认操作(`@confirm`) 来更新验证码状态[^1]。 #### 解决 Android 设备 H5 页面输入框被软键盘遮挡的问题 针对某些安卓设备上可能出现的H5页面底部输入框被弹起的虚拟键盘覆盖的情况,可以通过调整 CSS 样式以及 HTML 属性设置来改善体验: - 设置 `<meta>` 标签内的 viewport 参数以确保页面缩放比例合适; - 使用 JavaScript 动态计算并调整输入区域位置; - 或者采用第三方库如 `fastclick` 去除 tap 延迟现象从而提高响应速度。 此外,在实际开发过程中也可以尝试给 body 添加如下样式防止滚动条突然消失带来的布局错乱: ```css body { overflow-anchor: none; } ``` 此方案适用于大多数情况下的输入框显示不全问题[^2]。 #### 处理 iOS 特定版本下搜索框内图标干扰占位符文字的现象 在iOS特定版本(例如 IOS 15),如果设置了 `type="search"` 类型,则可能会出现默认搜索引擎图标遮盖住 placeholder 文字的情形。对此可通过CSS隐藏该装饰元素的方式加以规避: ```css [type="search"]::-webkit-search-decoration { display: none; } ``` 上述代码片段能够有效移除不必要的视觉元素,使界面更加简洁明了[^3]。 #### 关于 Vue.js 中双向绑定数据类型的注意事项 当处理复杂的数据结构比如对象数组作为选项列表时,需要注意正确指定属性名来进行数据绑定。如果不慎直接将整个对象赋值给了某个字段,那么最终呈现出来的可能是 `[object Object]` 字样而非预期的内容。因此建议按照官方文档指导明确指出具体要使用的成员变量名称,像下面这样书写模板语句即可避免此类错误发生: ```vue <template> <!-- 正确做法 --> <el-option :value="item.projectId">{{ item.name }}</el-option> <!-- 错误示范 --> <el-option>{{ item }}</el-option> <!-- 不应如此编写 --> </template> ``` 以上措施有助于保证应用程序逻辑清晰无误地运行[^4]。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值