JEPA4Japan · 教程

附录 B——完整张量形状表

1,913字 6分钟阅读 #LeVJEPA#JEPA#视频自监督学习#SIGReg

从 [B,T,C,H,W] 到全局/局部视图、稀疏 token、[CLS]、projector 与 SIGReg 输入逐项核对。

课程进度 课程大纲 已发布 34/34 课

第 0 部分——先拿到地图

  1. 01 第 0 章——开始之前:这门课承诺什么 已发布
  2. 02 第 1 章——同一段视频,两扇不同的窗 已发布
  3. 03 第 2 章——沿着 Yann LeCun 的科研路线走一遍 已发布
  4. 04 第 3 章——别被名字绕晕:JEPA 家族树 已发布

第 1 部分——为什么简单目标会学会看视频

  1. 05 第 4 章——视频可以自己出题 已发布
  2. 06 第 5 章——保留意思,不重画每个像素 已发布
  3. 07 第 6 章——两张卡要相同,但不能全变成白纸 已发布
  4. 08 第 7 章——SIGReg:从许多影子检查一团点云 已发布
  5. 09 第 8 章——只用一行目标函数读懂 LeVJEPA 已发布

第 2 部分——把一段视频送进单编码器

  1. 10 第 9 章——全局视图与局部视图怎样配对 已发布
  2. 11 第 10 章——把视频切成时空小方块 已发布
  3. 12 第 11 章——一台编码器、一个投影头、一张摘要卡 已发布
  4. 13 第 12 章——一次完整前向传播 已发布
  5. 14 第 13 章——为什么扔掉 95% 反而更会看 已发布
  6. 15 第 14 章——块因果注意力:同一帧互看,未来不能偷看 已发布
  7. 16 第 15 章——RoPE、逐帧 token 与意外长出的密集特征 已发布

第 3 部分——会读实验,才算读懂论文

  1. 17 第 16 章——四组消融究竟回答了什么 已发布
  2. 18 第 17 章——相同轮数不等于相同花费 已发布
  3. 19 第 18 章——ImageNet、K400、SSv2 各考什么 已发布
  4. 20 第 19 章——把论文结果记成一本账 已发布
  5. 21 第 20 章——哪些结论现在还不能说 已发布

第 4 部分——从官方仓库到自己的实验

  1. 22 第 21 章——官方仓库地图 已发布
  2. 23 第 22 章——Walking Tours:十段长视频怎样变成训练数据 已发布
  3. 24 第 23 章——读懂默认配置并启动训练 已发布
  4. 25 第 24 章——先跑一个不会骗人的冒烟测试 已发布
  5. 26 第 25 章——不用训练:加载公开权重提取特征 已发布
  6. 27 第 26 章——在自己的视频上做冻结评估 已发布

第 5 部分——把表征接回世界模型路线

  1. 28 第 27 章——重要边界:LeVJEPA 不是规划器 已发布
  2. 29 第 28 章——怎样把 LeVJEPA 接到下一代世界模型 已发布
  3. 30 第 29 章——十个从入门到论文级的研究项目 已发布

附录——随用随查的技术背包

  1. 31 附录 A——最低限度数学工具箱 已发布
  2. 32 附录 B——完整张量形状表 当前课程
  3. 33 附录 C——术语表与论文时间线 已发布
  4. 34 附录 D——复现与审阅检查清单 已发布

给每个张量贴一张货运单

  1. 视频箱B,T,C,H,W
  2. 多扇窗全局一张,局部 V 张
  3. patch每帧切成 16×16
  4. 稀疏 token训练只留 5%
  5. 摘要卡V+1,B,K
形状表是传送带的货运单:每过一道门,都先核对箱子里有几层。

一只行李箱先按“旅客—时间—颜色—高度—宽度”摆放,进安检前却要改成“旅客—颜色—时间—高度—宽度”。若标签换了、箱子却没有换位置,机器仍会运行,只是把 16 帧误当成 16 个颜色通道。

这类错误最麻烦的地方在于,它未必立刻报错。“5D tensor”还不是一份够用的说明;给每一维写上名字,再在第一批数据上断言形状、类型和值域,才能知道箱子真的换过位置。

先办好符号护照

符号含义论文/公开配方中的常见值
B每个设备上的 batch 大小仓库默认 96;全局有效 batch 另算
V每段视频的局部视图数论文多数受控比较 4;仓库默认 10
T输入帧数16
C颜色通道3
Hg,Wg全局视图高、宽224,224
Hl,Wl局部视图高、宽96,96
P空间 patch 边长16
τtubelet 的时间长度默认 1,即逐帧 token 化
DViT 隐藏宽度ViT-B 为 768;ViT-L checkpoint 为 1024
Kprojector 输出维数256
ρtoken 丢弃率0.95
MSIGReg 随机方向数1024
QSIGReg 积分节点数17

“论文常用值”和“官方仓库默认值”不是同一列配置。尤其 V=4 与 V=10 都可能正确,必须同时说明实验协议。

第一段传送带:加载器到多视图

单个 episode 中抽出的原始片段通常是:

[T,C,H_raw,W_raw]

多视图变换对同一组 T 帧做空间裁剪。组成 batch 后,公开加载器给出:

名称形状说明
global_frame[B,T,C,224,224]一张近全局、无局部光度增强的视图
local_frames[B,V,T,C,96,96]V 张独立空间裁剪并做光度增强的视图

进入编码器前,main.py 用 einops.rearrange 改变轴顺序:

global_video = rearrange(global_frame, "b t c h w -> b c t h w")
local_video = rearrange(local_frames, "b v t c h w -> (b v) c t h w")

于是全局输入为 [B,C,T,224,224],局部输入为 [B·V,C,T,96,96]。把视图并入 batch 维能让同一编码器一次处理所有局部窗口;输出后再拆回 B,V,D。

第二段:切 patch 之前先数格子

τ=1 时,每个 token 只跨一帧;每个空间 patch 是 16×16:

全局 patch 数 = 16 × (224/16) × (224/16) = 16 × 14 × 14 = 3136
局部 patch 数 = 16 × ( 96/16) × ( 96/16) = 16 ×  6 ×  6 =  576

patch embedding 后、加入 [CLS] 前:

分支训练前的 patch token形状
全局3136[B,3136,D]
局部576[B·V,576,D]

若 τ=2,时间槽减半为 8;这会改变 token 数和每个 token 覆盖的时间范围。LeVJEPA 默认选择 τ=1,而 V-JEPA/VideoMAE 的 tubelet=2 属于另一套配方,替换后应当明确标成模型变化。

第三段:95% 丢弃把序列变多短

官方代码用:

keep_len = round(N_patches × (1 - ρ))

每个样本独立产生随机保留集合:

分支原 patch保留 patch加 [CLS] 后的序列长度
全局3136round(156.8)=157158
局部576round(28.8)=2930

这只是训练形状。评估和推理时不丢 token,所以公开 ViT-L 权重在 16×224×224 输入上返回 3136+1=3137 个 token。训练时的 158 与 checkpoint 输出的 3137 一旦混用,后续 dense feature 代码就会错位。

第四段:编码器、[CLS] 与 projector

训练时:

global_tokens : [B,     158,D]   # 默认丢弃率下
local_tokens  : [B·V,    30,D]
global_cls    : [B,       1,D]
local_cls     : [B,       V,D]
concat cls    : [B,     V+1,D]
projected z   : [B,     V+1,K]

代码用 embeddings[:, :1] 保留全局嵌入 [B,1,K];广播后与全部 [B,V+1,K] 比较。全局与自己相减的那一项恒为零,但仍被包含在平均值中,这与论文公式和官方代码一致。

SIGReg 前又把轴换成:

[B,V+1,K] -> [V+1,B,K]

这样它会为每个视图位置单独检查 B 个样本组成的分布,而不是把同一视频的多个相关视图当成额外独立样本。

第五段:SIGReg 内部还要换一次轴

设输入为 [S,B,K],其中 S=V+1:

步骤形状含义
随机单位方向 A[K,M]M=1024 支手电筒
投影 z @ A[S,B,M]每个样本在每个方向上的影子
乘积分节点[S,B,M,Q]Q=17 个频率
cos/sin batch 均值[2,S,M,Q]经验特征函数实部与虚部
与高斯指纹的误差[S,M,Q]每个视图、方向、节点的差
最终 loss[]对视图、方向、节点加权平均

分布式 all-reduce 聚合的是 [2,S,M,Q] 的经验特征函数,不是把所有 [B,K] 嵌入直接传来传去。这解释了论文所说的通信量基本不随 batch 与嵌入维数增长。

到站:发布权重的推理接口

官方 Hugging Face 模型期望:

pixel_values: [B,C,T,H,W]

对 [1,3,16,224,224],ViT-L/16 的公开接口报告:

last_hidden_state: [1,3137,1024]  # CLS + 16×14×14 patch
pooler_output:     [1,1024]       # CLS

单张图像若按模型卡重复为 16 帧,输出仍是视频 token 序列;这不代表模型看到了运动。重复帧只是一种让视频编码器接收静态图像的适配方式。

把五条断言留在测试里

assert global_frame.ndim == 5 and global_frame.shape[1:3] == (16, 3)
assert local_frames.ndim == 6 and local_frames.shape[2:4] == (16, 3)
assert global_frame.shape[-2:] == (224, 224)
assert local_frames.shape[-2:] == (96, 96)
assert torch.isfinite(loss).all()

还应打印归一化前后的 dtype/min/max/mean/std。形状正确但把 uint8 0..255 直接送入期望归一化浮点输入,同样会产生“能运行的错误”。

货运单的原始凭据

LeVJEPA arXiv v1 方法与附录给出符号和架构;固定快照中的 main.py、module.py 与 data/loader.py定义可执行形状;固定版本的模型卡定义 checkpoint 接口。

三张不能贴反的标签

  1. 加载器是 [B,T,C,H,W],编码器是 [B,C,T,H,W]。
  2. 95% 丢弃只发生在训练;推理会返回全部 3137 个 token。
  3. SIGReg 的 batch 维是不同视频样本,不是同一视频的视图数。

查一遍货运单

  1. 为什么局部视图进入编码器时是 [B·V,C,T,96,96]?
  2. 全局训练序列为何是 158,而公开 checkpoint 输出为何是 3137?
  3. 把 [B,V+1,K] 直接当 [B(V+1),K] 做 SIGReg 有什么概念风险?
箱子应当怎样摆
  1. 视图维临时并入 batch,所有局部窗口由同一编码器并行处理;之后再拆回。
  2. 前者随机保留 157 个 patch 再加 CLS;后者处于评估模式,不丢 3136 个 patch。
  3. 它会把同一视频的强相关视图当成独立人群成员,改变所估计的分布与有效样本量。