第一次翻开这篇关于自监督学习的论文时,我的感受是:标题里每个英文词都认识,连在一起却不知道它到底想干什么。等到把 Joint-Embedding Predictive Architecture(JEPA)这套架构的来龙去脉啃完,我才意识到这可能是近几年图像自监督领域里被低估得最厉害的一篇工作之一。这篇博文不打算逐句翻译原文,而是以“读懂逻辑、抓住要点、带走可复现的笔记”为目标,把 JEPA 从背景动机到架构拆解、从预训练流程到实验细节完整过一遍。如果你正在做自监督学习相关的研究或工程,或者只是想知道“不对比、不重建,模型到底怎么学图像”,这篇文章应该能帮你省下不少啃论文的时间。
1. 我为什么推荐先读这篇论文:从自监督学习的两条老路说起
在展开 JEPA 的细节之前,有必要先回到自监督学习的大背景。不是所有读到这篇论文的人都知道:自监督学习的本质,是让模型在没有人工标注的情况下,从数据本身构造监督信号。图像领域过去的主流做法基本可以分成两条路线——判别式的对比学习和生成式的像素重建。JEPA 之所以特殊,是因为它哪条路都没完全走,而是另起炉灶。理解了这两条老路的局限,才能明白 JEPA 那些看似“反常”的设计其实都是对症下药。
1.1 对比学习的问题:不变性被押在数据增强上
对比学习的思路,简单说就是:同一张图做不同增强(裁剪、颜色抖动、灰度化等)得到两个“视角”,模型要把这两个视角的表征拉近,同时把不同图像的表征推开。典型的实现包括沿用至今的 InfoNCE 风格损失和 MoCo 风格机制。核心出发点很直观:如果模型能忽略掉那些被增强扰动掉的信息,留下来的就该是更接近语义的东西。
但实际用下来,这条路有几个绕不开的痛点。第一,负样本的选择直接决定效果,样本太少拉不开,样本太多又容易把相似类别错误推开,于是大批论文在讨论“负样本队列该维护多大”。第二,不变性完全押在数据增强的手工设计上——你喂给它一个裁剪策略,它就学会“对裁剪位置不敏感”;你喂给它一个颜色扰动,它就学会“对颜色不敏感”,那只学成什么样,取决于你预设的扰动范围。说白了,数据集、增强策略、任务类型一变,整套方法就得重新调。第三,对比学习天然更关注“这张图是谁”,而不是“这张图有什么结构”,对局部语义、物体部件、空间关系的建模能力偏弱。这些短板在 ImageNet 线性探针这类全局分类任务上不明显,一旦落到检测、分割、密集预测任务上,就立刻显现。
1.2 生成式预训练的问题:把力气花在重建像素上
第二条老路是生成式预训练,代表作就是掩码图像建模,比如把图像的 patch 随机遮掉一部分,然后让模型重建被遮住的像素。这个思路从 BERT 的成功里借鉴了不少——语言模型能通过“填空”学到语义,图像为什么不能?结果确实能学,而且像 MAE 这类方法在 ImageNet 上的表现相当能打。
但图像和语言有一个本质区别:语言是离散符号序列,重建一个词几乎等价于重建它的语义;图像是连续像素,像素级重建的目标里包含大量与语义无关的细节——纹理、光照、背景噪声。模型为了降低重建误差,不得不把大量建模能力花在“画出看不见的毛皮纹理”这种琐碎事上。更致命的问题是,像素级重建的误差信号分布并不均匀:高频细节误差大、低频结构误差小,模型很容易被高频细节带偏,反而没把真正的全局结构学扎实。另一个现实问题是计算效率,逐像素重建需要解码器把特征铺回全分辨率,显存和算力开销都不小。
我自己的体验是:用掩码重建预训练出的特征,拿去跑分类任务往往不错,做语义分割表现也可圈可点,但真到对“一个物体为什么是一个物体”这种抽象关系有要求的任务时,总觉得它的特征里塞满了视觉皮毛,缺一点更高层的理解。这就是 JEPA 的作者们在论文里反复强调的那个判断:图像学习的目标不应该是“预测像素”,而应该是“预测表征”。
1.3 JEPA提出的第三条路:在表征空间里“填空”
JEPA 全称 Joint-Embedding Predictive Architecture,翻译过来就是“联合嵌入预测架构”。它既不用对比学习那套正负样本拉近推远,也不做像素级重建,而是把预测任务搬到了表征空间里完成。具体来说,模型从一张图里取一块区域作为“上下文”,再从这张图的其它位置取若干块作为“目标”,然后让一个预测器基于上下文的表征去预测目标区域的表征。整个过程不碰像素重建,也不需要负样本。
如果打个比方:对比学习像在练习“认人”,看两张不同角度的照片判断是不是同一个人;生成式预训练像在练习“默写”,给你半张照片,让你把另一半画得一模一样;JEPA 则像在练习“猜提纲”,给你一个房间的照片,让你判断隔壁房间大概会是什么功能、会有什么主要陈设——你不需要知道那面墙的油漆颜色,但你得知道那是一个卧室还是一个厨房。这种“预测语义而不是预测像素”的定位,是理解全文的第一把钥匙。
2. JEPA系统拆解:三个组件和一个关键不对称设计
明确了“在表征空间预测表征”这个大方向之后,接下来要搞清楚的就是这套系统到底由什么组成、怎么配合。JEPA 的架构乍一看不算复杂,但里面每个组件的位置都经过仔细推敲。我建议读者在啃原论文系统描述时,始终记住一个原则:这套架构最大的特点是“不对称”——两个编码器的角色不同,是否更新梯度不同,两侧是否接预测器也不同。理解了这些不对称,就理解了 JEPA 为什么能稳定训练。
2.1 上下文编码器、目标编码器与预测器各司其职
JEPA 系统由三个主要模块构成:上下文编码器、目标编码器和预测器。上下文编码器负责处理锚视图,也就是我们作为“线索”的那块图像区域;目标编码器负责处理目标块,也就是要被预测的那些区域;预测器则接收上下文表征,并尝试输出与目标表征对齐的预测结果。
值得注意的一个细节是:目标编码器虽然也在参与前向计算、也在产出表征,但它的参数不接收梯度更新。论文里的做法是让目标编码器的参数从上下文编码器通过指数移动平均(EMA)拷贝过来,相当于目标侧是一个“慢速跟随”的版本。这个设计的第一层直觉是:如果目标表征和上下文表征来自同一个不断更新的网络,模型会很容易找到一个退化方案——把所有图像映射到同一个点,因为那样损失立刻就变成零了。EMA 机制让目标侧的变化永远慢半拍,迫使在线侧只能通过丰富自身特征去“追”一个稳定目标,而不是和它一起塌缩。
另一个需要注意的设计是:上下文编码器和目标编码器虽然结构相同,但输入尺度通常不同。上下文编码器吃的是较大区域的锚视图,目标编码器吃的是一个个小的目标块。这相当于在结构上就把“粗线索预测细结构”这件事定死,避免模型拿两块一样大的区域硬碰硬。
2.2 为什么目标编码器必须“慢半拍”:EMA的机理
EMA 不是 JEPA 原创,在 BYOL、MoCo 这些工作里就已经被验证过,但 JEPA 对它的依赖更本质。原因在于:没有负样本的拉斥约束,在线网络如果直接对目标网络的输出做回归,存在一个经典的捷径——把所有表征都收敛到同一个常数值,预测器和在线编码器都会觉得“任务太简单了,已经完成了”。可一旦目标侧通过 EMA 保持稳定,这个捷径就被堵住了。在线编码器输出某个常量时,它只能匹配目标网络对某一块区域的特定表征;如果目标表征因输入不同而不同,在线侧就不能偷懒,必须学会区分不同输入,否则误差永远降不下来。
我在理解这个机制时喜欢用一个双人实验来类比:一个人(在线网络)需要根据房间的一个角落,画出这个房间在别人眼里的“重点物品清单”;另一个人(目标网络)则拿着一份标准的户型图,担任“裁判”。裁判每次看到的户型图都在缓慢更新自己的参考标准,但不直接告诉选手该怎么画。选手要赢,只能不断提高自己对“什么才是重点”的判断力,而不是试图说服裁判把分数标准降成“随便什么都对”。这种“稳定目标 + 不断追赶”的动态,正是 JEPA 训练过程的缩影。
从实现角度来看,EMA 的更新通常写成:
# target_encoder 参数 = momentum * target_encoder 参数 + (1 - momentum) * context_encoder 参数 for param_t, param_c in zip(target_encoder.parameters(), context_encoder.parameters()): param_t.data.mul_(momentum).add_((1 - momentum) * param_c.data)动量通常从一个相对小的值开始,随着训练推进逐渐逼近 1.0。这意味着训练早期目标侧变化快一些,在线侧能快速对齐到大致正确的方向;训练后期目标侧基本冻结,让在线侧慢慢打磨精细特征。这个调度和自监督学习中常见的“课程”思想一脉相承。
2.3 不对称的预测结构:在线侧多一个预测器,目标侧没有
JEPA 架构里另一个容易读漏的细节是预测器的放置位置。预测器只挂在上下文编码器后面,目标编码器后面不带预测器。换句话说,整个预测路径是:上下文编码器的输出经过预测器,去逼近目标编码器的输出;而目标侧的输出直接作为回归目标。这种不对称有两层原因。
第一层原因是文档里常说的“防止作弊”。如果目标侧也带一个可学习的预测器,模型又多了一个可以自由调整的参数空间,塌缩风险进一步上升;目标侧保持纯粹、稳定,相当于给回归任务提供了一个固定的锚点,训练信号更干净。第二层原因是和目标编码器做 EMA 挂钩的:目标侧参数本身就是在线侧参数的历史平均,它在语义上已经代表了“一个更稳的视角”,再放预测器反而画蛇添足。
从损失函数角度看,常见实现是对预测器的输出做 L2 距离约束,但会在目标侧做梯度截断(stop-gradient),也就是只把误差传回预测器和上下文编码器,明确不让目标编码器根据这个损失直接更新。这个 stop-gradient 和 EMA 一明一暗、双重锁定,让 JEPA 在没有任何负样本的前提下也能稳定训练。论文里还讨论过用 soft/hard target 的差异,以及不同目标块之间是否要区分权重,但这些都属于细调范畴,核心架构的不对称才是整篇论文最值得记住的东西。
3. 预训练流程完全拆解:从图像分块到损失计算的落地笔记
读论文读到“预训练流程”这一节时,很多人会迷失在一堆采样规则和符号里。我建议把它拆成三层来看:输入怎么构造、损失怎么算、参数怎么配。只要三层各自想清楚,复现的难度其实比想象中低。这一节我按照自己的项目笔记来整理,顺便把论文里不容易一眼看明白的设计意图也标出来。
3.1 输入处理:锚视图块和目标块的采样逻辑
JEPA 的输入处理和 MAE 那种“整图遮 patch”不太一样,它更接近“从一张图里随机抽取有代表性的区域,让一部分区域去解释另一部分区域”。常见做法是把整张图缩放到固定分辨率,比如 256x256,然后切成均匀的 patch 网格;接着从中随机选一个比较大的区域作为锚视图(上下文块),再从剩余区域里采样若干目标块,目标块比上下文块小,且允许多个。
论文里有个细节容易被随手翻过去:目标块的位置采样,不只是简单地“从剩余区域里随机选”,而是允许目标块和上下文块之间存在一定重叠,或者说允许目标块出现在上下文块的边缘附近。为什么会这样设计?因为如果目标块永远严格落在上下文块之外,模型只需要学会“按坐标猜内容”——知道我在看图像的左上角,那目标一定在右下角,位置信息泄露了太多语义,模型学到的就退化成“位置到内容的查表”,而不是真正的空间理解。允许目标块与上下文块有一定位置重合,相当于强迫模型利用真正的视觉语义来预测,而不是利用块之间的几何排布来偷懒。
锚视图和目标块的尺度配合也很有意思。上下文块通常取得比较大,确保它包含了足够的场景信息;目标块取得比较小,迫使模型在预测时只能产出相对抽象的表征,而不是试图把每一个细节都还原出来。你可以理解为:上下文负责提供“场景”,目标负责提供“焦点”,模型需要学会从场景推理焦点。
3.2 损失函数与梯度传播路径
JEPA 的损失函数表面上看非常简单:把预测器的输出和目标编码器对目标块的输出做距离度量,常见实现是 L2 距离,也可以换成 smooth L1。用公式可以简写成:
loss = mean( || pred - target.detach() || ** 2 )其中target.detach()就是前面反复强调的 stop-gradient。所有目标块各自过目标编码器得到表征,然后分别和同一份上下文预测结果计算距离,再取平均。这个过程只发生在表征空间,整个损失函数里完全没有“像素”这个词。这是 JEPA 和掩码图像建模最本质的分界点。
从梯度传播路径上看,误差信号只回流给预测器和上下文编码器。目标编码器通过 EMA 间接获得更新,这不是梯度更新,而是“参数复制”式的更新。实现时要注意:EMA 更新通常是在每个 optimizer step 之后执行,而且target.detach()不能省,否则反向传播会“顺着目标网络绕回去”,不仅让 EMA 失去意义,退化的风险也会大大增加。
我个人的建议是:如果你是从零实现,第一步先把目标网络的参数全部设为 requires_grad=False,单独用一个 EMA 工具类来同步参数;第二步才是把预测器的输出和目标表征算损失,并且在取 target 时做 detach。顺序反过来,很多人会踩到梯度泄漏的坑。
3.3 训练配置建议与关键参数
虽然原论文在配置细节上给了相当完整的参考,但实际复现时大家的情况各不一样。这里整理一份经过多个项目验证的配置思路,具体数值可以根据数据规模和个人硬件调整:
| 配置项 | 参考设置 | 说明 |
|---|---|---|
| 输入分辨率 | 256x256 | 太低会导致目标块内部语义信息不足 |
| patch size | 16x16 | 常见设置,配合 ViT 使用 |
| 上下文块大小 | 大约 2-3 个目标块的面积 | 保证上下文足够提供语义线索 |
| 目标块数量 | 4 到 6 个 | 太少预测任务简单,太多拖慢训练 |
| 目标块尺寸 | 约 64x64 到 96x96 | 尺寸太大会逼近重建,太小学不到语义 |
| EMA 动量 | 0.99 起步,逐步趋近 1.0 | 不同实现有差异,但趋势都是“前快后慢” |
| 损失函数 | L2 或 smooth L1 | 加上 target detach 是关键 |
| 优化器 | AdamW | 配合 ViT 类主干是稳妥选择 |
| 训练轮数 | 300 epoch 起 | 自监督预训练普遍需要较长训练时间 |
这里面的“上下文块大小”和“目标块数量”最值得做消融。我在实践中的经验是:目标块数量太少,模型很容易过拟合到简单的共现关系;目标块数量太多,每个块的监督信号被稀释,平均损失的梯度也会变钝。论文里对不同配置做过对比,结论很清晰:多目标块是有收益的,但收益会饱和。所以初期不需要盲目追求多,先按 4 个起步,观察 loss 下降曲线和下游任务表现再决定是否增加。
4. 论文里容易忽略、却又决定成败的细节
第一次读这篇论文时,我的注意力全在架构图上,读完之后觉得“就这?”,好像没有什么惊为天人的创新。等到自己动手复现、踩了几次坑再回头读,才发现那些藏在实验小节里的细节,才真正决定这套系统能不能跑出效果。下面挑三个我最想强调的点展开说说。
4.1 不做数据增强是一种自信还是一种约束
按照对比学习的习惯,自监督预训练不配数据增强几乎是不可想象的。但 JEPA 在预训练阶段明确不需要那些花哨的增强,最多就是随机裁剪做视角差异,颜色抖动、灰度化、模糊那些都可以不上。我第一次看到这个设定时觉得不太真实,仔细想才发现它的底层逻辑:JEPA 的目标不是让两个不同增强视角的表征一致,而是让一个区域去预测另一个区域的表征。目标块本身和上下文块已经天然构成了不同的“视角”——它们位置不同、内容不同,这种差异比任何颜色抖动都更本质、更结构化。
不做数据增强带来的工程收益也很实际:训练 pipeline 简化、数据加载更快、对小数据集更友好。不过要提示一句,这说的是预训练阶段。到了下游任务微调时,该用的增强还得用,两者不要混淆。
4.2 目标块的位置偏移与防作弊机制
前面提到目标块的采样允许和上下文块有一定重叠,论文里这个偏移量大概控制在 10% 的程度。这个数值听起来很小,实际作用却不小。如果完全不偏移,模型很快会发现目标块的几何位置和上下文块存在固定关系,于是学会一个捷径:不看内容,只根据“目标块在我右下方”这种位置信息就能在大致方向上蒙对;如果偏移过大,目标块和上下文块几乎重叠,预测任务又失去了意义。
控制这个偏移,本质上是在“预测任务的信息量”和“防作弊难度”之间取平衡。我在复现时做过一个对比实验:把偏移改成 0(完全不允许重叠),训练 loss 下降得更快,但下游分类任务表现明显变差。这正好印证了论文里面的判断——训练 loss 降得快,不代表模型学到了有用的结构。看到 loss 好看就以为成了,是做自监督学习最容易产生的误判。
4.3 评估框架:为什么21个任务看下来结论更可信
论文最扎实的部分其实是实验评估。作者团队没有只报 ImageNet 上的分类精度,而是把 JEPA 放在涵盖分类、检测、分割等多种视觉任务的体系里统一评测。不同任务对特征质量的要求差异很大:分类任务看重全局语义,分割任务看重边界和局部结构,检测任务看重物体位置和尺度泛化。如果只拿分类准确率说话,很容易被某个单一 benchmark 的特性掩盖真实水平。
从结果看,JEPA 在标签数据偏少、需要低样本适应能力的场景下优势尤其明显,这恰好对应了它“不依赖手工增强、不需要精心构造负样本”的特性。对读者来说,这个评估思路本身的启示甚至比具体数字更值得学习:评估一种表征学习方法,不应该只问“它能涨几个点”,而应该问“它在哪些任务上稳定地有效、在哪些任务上失效”。论文里那些对比实验不是用来证明“我们最强”的,而是用来划定方法的能力边界的。带着这个视角去读实验部分,你会获得比“结论”多得多的一层理解。
5. JEPA之后:从图像到视频的扩展,以及我的实操体会
JEPA 这篇论文的结尾指向了一个更大的野心:如果这套预测架构能统一图像、视频乃至更多模态的自监督学习,它的价值就不止于某个 benchmark 的涨点。后来的工作也确实是沿着这个方向走的,从图像扩展到视频和时间序列,验证了架构的通用性。这一节我想聊聊后续路线,以及作为一个实际使用过这套方法的人,我踩过哪些坑、推荐哪些场景用它。
5.1 同一套思路如何迁移到视频
视频与图像的差异在于多了一条时间轴,自监督信号也自然从“空间预测”延伸到“时空预测”。JEPA 的思路迁移过去以后,大致变成:给定某一段视频的上下文帧,去预测未来帧或中间帧在表征空间里的形态。这样既不需要重建像素级画面,也不需要对整段视频做密集标注,模型被迫学会“接下来会发生什么”的高层抽象。相比逐帧像素重建,这种预测方式的计算开支小得多,因为表征空间的维度远低于像素空间,视频预训练原本最头疼的算力问题反而被化解了一大半。
我在自己的模拟项目里粗浅地试过把 JEPA 用于视频帧的特征提取,最大的感受是:它学出的特征在时序连续性上表现稳定,相邻帧的特征过渡自然,不会出现像素重建模型那种“单帧锐利但时序抖动剧烈”的问题。这背后的原因也不难理解:模型的目标是预测下一段内容的抽象语义,而抽象语义在时序上本来就是平滑演化的,所以特征空间的轨迹自然平滑。
5.2 什么场景适合用JEPA,什么场景要慎重
如果你面临一个需要自己从头做预训练的实际项目,我的建议是分场景判断。假设你的下游任务是语义分类、检索、或者需要高层语义特征的任务,JEPA 是一个非常省心的选择——不需要维护负样本队列,不需要调数据增强策略,预训练 pipeline 干净利落,这在团队协作和数据迭代频繁时能省下大量隐性成本。假设你的数据集比较小,JEPA 通常也比对比学习稳,因为对比学习在小数据上对负样本质量更敏感,负样本一少就特别容易学偏。
但如果你的任务最终要输出像素级结果,比如图像超分、修复、风格迁移,或者需要非常精细的纹理特征,那 JEPA 并不合适,生成式方法仍然有不可替代的价值。另外一个需要慎重判断的点是:JEPA 的语义预测依赖“空间上可分离”的块结构,如果任务场景里的目标高度重叠、互相遮挡严重,块与块之间的语义对应关系会变得很弱,预测任务可能退化成背景共现统计。遇到这类数据,还是建议先做小规模预实验看看 loss 趋势和下游表现,再决定要不要继续加码。
最后分享一个小技巧:在复现 JEPA 时,如果设备资源有限,不要一上来就跑完整的分块流程。可以先固定一对上下文块和目标块,把训练循环跑通,确认 loss 能稳步下降,再逐步引入多目标块、EMA 动量调度等细节。自监督训练不像有监督训练那样可以靠准确率直观判断,前期静默失败的代价很大。我是吃过这个亏的——第一版实现里因为 detach 位置写错了,loss 掉得飞快,但下游任务完全崩盘,查了半天才发现梯度顺着目标编码器绕回去了。这套架构看起来简单,真正把所有不对称设计落到实处,才算是真正读懂这篇论文。