视觉特征-自监督02-掩码像素预测建模01:MAE(MAE中的Mask Vector):共享可学习掩码向量的形状、初始化、位置编码、解码重建、梯度学习、训练流程与推理用途详解及其与可见上下文的交互机制1. Mask Vector 在 MAE 中到底是什么MAE,即掩码自编码器(Masked Autoencoder, MAE),预训练时会随机删除图像中的大部分 Patch,只把剩余的可见 Patch 送入编码器(Encoder),然后由解码器(Decoder)根据可见信息重建被删除的 Patch。其中,掩码向量(Mask Vector)的作用不是保存被遮挡 Patch 的真实内容,而是作为 Decoder 中“这里存在一个 Patch,但其内容未知”的可学习占位表示。因此最核心的定义是:MaskVector=缺失Patch的共享、可学习占位向量\boxed{\text{Mask Vector}=\text{缺失 Patch 的共享、可学习占位向量}}MaskVector=缺失Patch的共享、可学习占位向量它不是:MaskedPatch的真实像素表示\text{Masked Patch 的真实像素表示}MaskedPatch的真实像素表示也不是:Encoder对MaskedPatch得到的编码\text{Encoder 对 Masked Patch 得到的编码}Encoder对MaskedPatch得到的编码因为 Masked Patch 根本不会进入 Encoder。2. Masked Patch、Mask Vector 与 Mask Token 的区别这三个概念需要严格区分。被掩码图像块(Masked Patch)是原始图像中真实存在、随后被随机删除的 Patch。例如:[P0,P1,P2,P3,P4,P5,P6,P7][P_0,P_1,P_2,P_3,P_4,P_5,P_6,P_7][P0,P1,P2,P3,P4,P5,P6,P7]假设只保留:P1,P3P_1,P_3P1,P3那么其余 6 个都是 Masked Patches。而模型内部真正保存的是一个可训练参数:m\mathbf mm它就是掩码向量(Mask Vector)。当 Decoder 需要为 6 个缺失位置补充占位 Token 时,会把同一个m\mathbf mm复制 6 次:[m,m,m,m,m,m][\mathbf m,\mathbf m,\mathbf m,\mathbf m,\mathbf m,\mathbf m][m,m,m,m,m,m]这些复制后的实例才可以称为掩码标记(Mask Tokens)。因此关系是:一个MaskVector→复制得到多个MaskTokens\boxed{\text{一个 Mask Vector}\rightarrow\text{复制得到多个 Mask Tokens}}一个MaskVector→复制得到多个MaskTokens而不是:一个MaskedPatch→一个独立MaskVector\text{一个 Masked Patch}\rightarrow\text{一个独立 Mask Vector}一个MaskedPatch→一个独立MaskVector3. Mask Vector 的形状与参数规模设 Decoder 的隐藏维度为DDD_DDD,则:m∈RDD\mathbf m\in\mathbb R^{D_D}m∈RDD在 PyTorch 实现中通常保存为:self.mask_token=nn.Parameter(torch.zeros(1,1,decoder_embed_dim))因此其张量形状为:[1,1,DD]\boxed{[1,1,D_D]}[1,1,DD]以 MAE ViT-L/16 的典型配置为例:DE=1024D_E=1024DE=1024DD=512D_D=512DD=512所以 Mask Vector 为:[1,1,512]\boxed{[1,1,512]}[1,1,512]真正参与学习的本质上只是一个 512 维向量:m=[m1,m2,…,m512]\mathbf m=[m_1,m_2,\ldots,m_{512}]m=[m1,m2,…,m512]因此,即使一张图片有 147 个缺失 Patch,也不是学习:147×512147\times512147×512组独立参数,而始终只学习同一个:1×1×5121\times1\times5121×1×512的向量。这也是共享(Shared)的含义。4. 为什么 Mask Vector 属于 Decoder,而不是 Encoder以输入尺寸224×224224\times224224×224、Patch Size 为16×1616\times1616×16为例:L=22416×22416=196L=\frac{224}{16}\times\frac{224}{16}=196L=16224×16224=196当掩码比例(Mask Ratio)为 75% 时:Lvisible=196×0.25=49L_{\mathrm{visible}}=196\times0.25=49Lvisible=196×0.25=49Lmasked=196−49=147L_{\mathrm{masked}}=196-49=147Lmasked=196−49=147MAE 最重要的结构特点是:196→49\boxed{196\rightarrow49}196→49即 196 个 Patch 中,只有 49 个可见 Patch 进入 Encoder。147 个 Masked Patches 会被直接删除,因此 Encoder 实际处理的是:[Pi1,Pi2,…,Pi49][P_{i_1},P_{i_2},\ldots,P_{i_{49}}][Pi1,Pi2,…,Pi49]而不是:[m,Pi1,m,Pi2,…][\mathbf m,P_{i_1},\mathbf m,P_{i_2},\ldots][m,Pi1,m,Pi2,…]因此:MaskVector从来不进入Encoder\boxed{\text{Mask Vector 从来不进入 Encoder}}MaskVector从来不进入EncoderMAE 使用的是非对称编码器—解码器(Asymmetric Encoder-Decoder)结构:Encoder 只处理少量真实可见 Patch;Decoder 才恢复完整 Patch 序列并处理 Mask Tokens。这样可以显著降低预训练阶段 Encoder 的计算量。5. Mask Vector 在什么时候出现Mask Vector 出现在:Encoder完成之后,Decoder正式计算之前\boxed{\text{Encoder 完成之后,Decoder 正式计算之前}}Encoder完成之后,Decoder正式计算之前以 ViT-L/16 为例,Encoder 输出包含 CLS Token:[B,50,1024][B,50,1024][B,50,1024]其中:50=1+4950=1+4950=1+49随后通过解码器投影层(Decoder Projection):1024→5121024\rightarrow5121024→512得到:[B,50,512][B,50,512][B,50,512]暂时去掉 CLS Token 后,可见 Patch 表示为:[B,49,512][B,49,512][B,49,512]与此同时,模型保存的 Mask Vector:[1,1,512][1,1,512][1,1,512]被复制为:[B,147,512][B,147,512][B,147,512]于是:[B,49,512]+[B,147,512]→[B,196,512][B,49,512]+[B,147,512]\rightarrow[B,196,512][B,49,512]+[B,147,512]→[B,196,512]这一步才第一次让 Mask Tokens 进入完整 MAE 数据流。6.ids_restore为什么是 Mask Vector 工作的关键环节之一随机 Mask 时,可见 Patch 通常经过随机打乱和筛选。因此,Decoder 不能简单地把 147 个 Mask Tokens 接到 49 个可见 Tokens 后面直接计算,因为此时它们还没有对应回原始图像位置。MAE 使用ids_restore保存随机排列的逆置换,并通过torch.gather把 Token 恢复到原始 Patch 顺序。例如 Encoder 得到的可见表示为:[Z3,Z1][Z_3,Z_1][Z3,Z1]加入 6 个 Mask Tokens 后暂时为:[Z3,Z1,m,m,m,m,m,m][Z_3,Z_1,\mathbf m,\mathbf m,\mathbf m,\mathbf m,\mathbf m,\mathbf m][Z3,Z1