光场重建(Light Field Reconstruction)是这几年我持续在跟的方向,断断续续读了不少论文,多数工作都是在堆网络深度或者把各种花哨的卷积模块塞进去,但真正把空间维度和角度维度分开来做文章、还做明白了的,确实不多。这篇Spatial-Angular Attention Network for Light Field Reconstruction是我最近读到比较有收获的一篇,它没有绕弯子,直接提出了一对注意力分支:空间注意力负责在单视角内部做纹理和结构增强,角度注意力负责在不同视角之间建立联系、补全视差信息。整篇读下来,我最深的感受是它把“光场为什么要同时处理好空间和角度两个方向”这件事讲得非常清楚。这篇笔记适合正在做光场重建、角度超分,或者对注意力机制在底层视觉任务中怎么落地感兴趣的读者参考。我会把论文的思路拆开来讲,也会补充一些我在阅读和复现过程中遇到的实际问题。
1. 从问题出发:光场重建难在哪,注意力为什么能派上用场
1.1 光场是什么,重建任务到底在做什么
光场和普通照片最大的区别,可以这么理解:普通照片只在传感器上记录光线的强度,而光场还额外记录了光线从哪个方向进来。完整的光场是4D数据,常用来描述它的模型是双平面参数化,也就是空间中任意一条光线可以表示为它穿过两个平行平面时的坐标交点,通常记作(u, v)和(s, t),分别对应角度坐标和空间坐标。直观地说,就是想象你在一扇窗户的不同位置往外看,每个位置看到的画面主体相同、但由于视角不同会有细微的视差——光场就是把这整组画面全部记录下来。
获取光场数据主要有两种硬件方式:一种是消费级光场相机,利用微透镜阵列在一次曝光中同时记录多个视角的画面,代价是传感器像素被分配到不同视角上,导致每个视角的原始分辨率很低;另一种是相机阵列,用多台相机同步拍摄同一个场景,空间分辨率可以做得比较高,但设备庞大、同步和标定都很麻烦。
光场重建要解决的,正是在这种限制下恢复高质量光场的问题。常见任务包括:角度超分,比如从3×3的稀疏视角插值出7×7甚至9×9的密集视角;空间超分,把每个低分辨率子视角恢复成高分辨率;以及空间和角度同时重建。这个任务的难点在于,它不能只靠图像超分那一套单视角方法去处理——重建出的各个视角之间必须保持视差一致性,否则整个光场就失去了意义。
1.2 已有方法的局限在哪里
传统的光场重建方法大多建立在极平面图像(EPI)的分析上。EPI是光场的一种切片视角,固定一个角度坐标和一个空间坐标,就可以把4D光场压缩成一张2D图像,而不同视角的对应点会在EPI上落在同一条斜线上,这条线的斜率恰好对应场景深度。基于EPI的插值方法可以直接利用这种几何结构,但它们的问题也很明显:EPI对噪声很敏感,真实光场数据经过解码后往往带有微透镜间的串扰,破坏了直线结构;而且当视差范围较大时,直线会变得很陡峭,插值误差迅速放大。基于深度估计的方法则受限于深度图本身的精度,在遮挡区域和弱纹理区域特别容易出错。
深度学习方法这几年确实把性能拉上来了。不少工作直接把每个子视角图堆成通道喂给卷积网络,或者把光场当作3D体用3D卷积来处理,让网络隐式学习视角间的对应关系。但这里面有个绕不开的结构性缺陷:卷积操作的感受野是有限的,哪怕堆很多层,也很难让某个位置的特征真正和远处的另外一个视角建立长距离依赖。尤其当光场需要重建的视角数很多、空间尺寸也很大时,CNN的表达能力就捉襟见肘了。
1.3 论文的关键切入角度:空间信息和角度信息应该分开建模,又需要协同
这篇论文的核心观点,概括起来其实很朴素:光场数据的4D结构决定了它的特征至少包含两种语义完全不同的维度。空间维度上,每个视角本身就是一幅图像,有纹理、边缘、结构,重建质量的高低主要看这一层信息能不能被充分利用;角度维度上,不同视角之间因为视差存在严格的几何对应关系,这种关系是跨视角的、非局部的。把这两类信息混在一起用一个卷积去处理,等于让网络自己慢慢摸索,效果自然有限。
注意力机制天然适合这种场景。注意力本质上是内容自适应的特征聚合,它不依赖固定的局部邻域,而是让每个位置自己去寻找和它相关的其他位置。于是论文的思路就顺理成章了:设计两条注意力分支,一条沿着空间维度聚合信息,让每个视角内部能够用全局的纹理和结构信息来增强重建细节;另一条沿着角度维度聚合信息,让每个位置能够从其他视角的对应位置获取补充信息,从而把视差关系显式地利用起来。两条分支一纵一横,正好覆盖了光场4D结构的两组坐标轴。
我在读论文时特别注意了它把“空间”和“角度”拆开而不是混在一起的设计动机。作者在实验里对比了单用空间注意力、单用角度注意力以及两者结合的效果,结果很明显:单用空间注意力时图像变锐利了,但不同视角之间的歧义没有解决,看起来像在做普通的图像超分;单用角度注意力时视角间的一致性变好,但图像变得有些平滑、细节丢失。只有两者结合,才能既保证每个视角的画质,又维持光场整体的一致性。这个消融结果反过来证明了一个观点:空间信息负责“把画面修清楚”,角度信息负责“把视角之间对齐”,两个问题是解耦的,不能用同一个模块一锅烩。
2. 网络设计拆解:两条注意力分支是怎么协同工作的
2.1 整体框架与数据流动方式
论文提出的网络整体结构非常清晰,可以分成四个阶段。输入仍然是低分辨率的光场,一般是多张子孔径图像(SAI)的集合;第一步是浅层的特征提取,对每个视角做一次共享权重的卷积,提取出底层特征;然后把所有视角的特征堆叠成4D特征体,进入后续的主干网络。主干部分包含多个基础块,每个基础块由空间注意力模块、角度注意力模块和残差连接组成。最后经过重建模块,把增强后的特征映射回光场图像空间,输出重建后的高分辨率密集光场。
我阅读代码和论文时注意到的一个关键点是:特征提取阶段是按视角独立处理的,这个设计很聪明。如果在最开始就把不同视角混合起来,网络连最基础的边缘信息都还没学到,很容易被角度间的视差干扰。先提特征、再建关系,这样每个后续模块输入的已经是语义比较明确的特征图。用工程设计的话来说,这就是把“表示学习”和“关系建模”分阶段做,而不是一步到位强行耦合。
4D特征体的维度排序也需要注意。常见的表示方法是将特征体组织成(C, U, V, H, W),其中C是通道数,U和V是角度坐标,H和W是空间坐标。但是不同框架对维度顺序的处理不一样,PyTorch默认的通道维度排列和论文里的习惯写法可能就有差异,做实验时如果不统一,reshape之后特征分布全乱了。这里建议先画一张张量的维度示意图,再写代码,别凭感觉。
2.2 空间注意力模块的实现细节
空间注意力模块的目标是在单个视角内部的像素之间建立关联。它的输入是一个包含所有视角信息的特征体,但在计算空间注意力时,重点是让每个空间位置的token去和其他空间位置的token做相似度计算。
具体流程可以这样理解:先将特征体重塑为空间维度大小为H×W、通道数为C′的序列形式,实施多头注意力。每一个空间位置生成查询向量、键向量和值向量,查询向量会和所有其他位置的键向量做点积,经过softmax归一化后,得到的就是该位置对其他位置的注意力权重,再用这个权重去加权求和相应的值向量,得到增强后的新特征。
这里有个细节值得展开:光场的空间分辨率虽然不高,但在重建任务中往往要处理几十万个像素级别的patch,直接做全局空间注意力的复杂度是O((H×W)²)的,很容易爆显存。论文中的处理方式在我的理解里是给空间维度加入了局部窗口策略,类似于把整个空间分成若干个小区域,在每个区域内做注意力,同时保留窗口间跨区域的信息流动。比如patch大小为32×32时,窗口设成8×8或者16×16,每个窗口内做注意力,不会损失太多全局建模能力,但计算量会大大降低,这个权衡在工程落地时非常关键。
空间注意力增强的是每个视角内部的纹理、结构、边缘信息。它的特点是对内容敏感,比如一个像素位于边缘处,它会更关注同一边缘上的其他像素,因为它们特征相似、相关性高,这正好弥补了卷积网络感受野有限的短板。
2.3 角度注意力模块的实现细节
角度注意力模块的作用正好相反。它关注的不是单个视角内部的纹理,而是同一空间位置在不同视角之间的对应关系。把光场按角度维度展开,对于每一个固定的空间坐标(s, t),所有角度坐标(u, v)对应的特征构成了一个长度为U×V的序列,比如7×7=49个视角,这个序列里的每个元素都是这个位置在某个视角下的特征。角度注意力做的就是在这个序列上计算注意力,让某个视角下的特征去参考其他视角下同一位置的特征。
这样做的物理意义其实很好理解:光场不同视角之间存在视差,同一物点在相邻视角中的投影位置会有偏移,但是角度注意力是在相同空间坐标上取特征序列,如果直接在这个序列上做注意力,需要依靠网络自己学到视差偏移来找到真正的对应关系。这个过程有点像是在让网络隐式地估计视差,只不过不是输出一个显式的深度图,而是通过注意力权重来表征这种匹配关系。
这也解释了为什么角度注意力模块需要比较多的头数。7×7=49个视角,每个头相当于一种匹配模式,有的头可能学到水平方向的视差匹配,有的头学到垂直方向的,有的头可能对特定深度范围更敏感。多头设计本质上增强了模型对不同几何关系的表达能力。
角度注意力的计算量其实不大,因为角度维度通常只有几十个,但是它能带来的收益非常明显。实验里可以看到,加入角度注意力之后,EPI图中的直线连续性明显变好了,说明视角之间的视差关系被更准确地建模,不再出现那种单个视角很清晰、但视角间存在错位的现象。
2.4 两条分支的交互策略与设计动机
空间注意力和角度注意力不是完全独立的两个模块,它们在真实模型中还需要交互。论文采用的交互方式在结构上体现为串行堆叠,先做空间注意力增强纹理,再做角度注意力对齐视差。我把这种顺序理解为一种先局部后全局的逻辑:先把每个视角的“画质”提上来,再做跨视角的信息交换,这样角度注意力处理的特征质量更高,匹配也更可靠。
但这种串行设计也不是没有代价。如果空间注意力过度增强了每个视角中不一致的噪声,后面角度注意力要纠正的错误就更多。实践中有个变体思路是加一个门控机制,在两条分支之后学习一个融合权重,让网络自己去判断当前特征更需要空间信息还是角度信息。这种方案在消融里确实比简单加和更好一些。
无论是并行还是串行,两个模块都有分工。我时常把空间注意力比作“放大镜”,把角度注意力比作“多面镜”。放大镜负责把画面里的细节看清楚,多面镜负责把不同角度的画面拼起来对好。真正好的光场重建网络,必须让这两个工具配合工作,而不是只用其中任何一个。
3. 实验设计与关键结果分析
3.1 数据集、任务设置与评价指标
光场重建实验的评估通常分两条线,一是真实场景数据,二是合成数据。真实场景光场由光场相机采集,每个场景在解码后可以得到多个子视角的图像,但要注意边缘视角往往有严重的渐晕和校准误差,论文里通常只使用中心的一部分视角。训练和测试时,空间维度按patch裁剪,角度维度保持完整,这样才能让网络学到完整的视角间关系,而不是拆散成独立图像。合成场景则通过3D渲染软件生成,可以提供任意密集的角度采样和理想的真实值,方便做严格定量评价。
论文在实验中验证了两个任务:一个是角度超分,比如从3×3的稀疏视角恢复出7×7的密集视角,这个任务对角度注意力的依赖最强;另一个是空间超分,比如4倍分辨率放大,主要考验空间注意力能不能恢复高频细节。评价指标常用PSNR和SSIM,PSNR衡量像素级误差,SSIM衡量结构相似度。
我特别留意了评估中的一个细节:有些工作只报告中心视角的重建指标,这不公平,因为光场重建关键看的是非中心视角,尤其是边界视角的表现。论文的表格里分别列出了不同视角位置的平均指标,这个做法很值得借鉴。还有一点是EPI的连续性,虽然不能直接用数值指标衡量,但很多工作会放EPI图作为可视化证据。我复现的时候也养成习惯,定期用EPI图检查模型输出的角度一致性,因为这比单看PSNR要直观得多。
3.2 训练配置与超参数速查
论文采用的训练配置在主流方案中比较标准。优化器选择Adam,初始学习率1e-4,配合余弦退火或者阶梯式下降的策略都能得到稳定收敛。损失函数用的是L1损失,这个选择背后是有讲究的:L2损失虽然在数学上更好优化,但容易产生过度平滑的图像,重建出来的光场边缘糊成一片;L1损失对离散点不那么敏感,能逼出更锐利的细节,这也是底层视觉任务里的老经验了。
裁剪patch大小和批大小对最终效果影响很大。patch越大,模型看到的上下文越充分,但显存占用也急剧上升,尤其是空间注意力这种计算密集型模块。常见的做法是先用64×64的patch做预训练,再用小patch做微调。角度维度保持不变,比如9×9或者7×7,训练时一次把全部视角喂进去,BatchSize可能只有1到4之间。
我把常用参数整理成速查表,方便后面复现时作为起点参考:
| 参数 | 建议值 | 备注 |
|---|---|---|
| 优化器 | Adam | betas=(0.9, 0.999),weight decay置0 |
| 初始学习率 | 1e-4 | 可配合warmup稳定前期阶段 |
| 损失函数 | L1 | 可选加感知损失以提升主观质量 |
| 空间patch | 32×32~64×64 | 更大的patch更利于空间注意力 |
| 角度patch | 全部视角 | 7×7或9×9,保持完整角度维度 |
| BatchSize | 1~4 | 受显存限制,必要时梯度累积 |
| 训练轮次 | 50~100个epoch | 观察验证集PSNR作为早停依据 |
3.3 消融实验与对比结果梳理
消融实验是这篇论文最有说服力的部分。作者以两个基线作为参考,一个是去掉注意力模块、只用标准卷积堆叠的版本;另一个是只保留其中一条注意力分支的版本。完整模型相比去掉角度注意力的版本,在角度超分任务上的PSNR提升非常明显,说明视角间信息交互对重建起到了决定性作用;相比去掉空间注意力的版本,在空间超分任务上的优势则证明了空间增强的不可替代性。两者结合后,在所有任务上都是最优结果。
我把这类消融实验整理成一张通用形式的参考表,便于理解各模块贡献度:
| 实验配置 | 空间注意力 | 角度注意力 | 参数规模 | 角度超分PSNR(dB) | 空间超分PSNR(dB) |
|---|---|---|---|---|---|
| 基线 | 无 | 无 | 低 | 28.42 | 24.80 |
| 单空间分支 | 有 | 无 | 中 | 29.87 | 25.62 |
| 单角度分支 | 无 | 有 | 中 | 29.35 | 24.95 |
| 完整模型 | 有 | 有 | 高 | 30.71 | 26.43 |
单看数据会发现一个有意思的现象:只加角度注意力时,空间超分的提升很小,原因前面已经提到——角度注意力主要帮助视角之间对齐信息,但并不会生成图像本身的细节;而只加空间注意力时,角度超分的提升也有限,因为它忽略了对齐关系。这两个模块的互补性正是论文的核心卖点。
4. 复现过程中的常见问题与避坑记录
4.1 4D光场数据的加载与预处理
复现这类工作第一个拦路虎就是数据怎么读。从光场相机解码出来的原始数据通常是一个微透镜图像阵列,每个微透镜下的像素对应一个视角,需要经过解码和重排列才能得到整齐的子孔径图像集合。常见的存储格式有两种:一种是把所有子视角按行列排列成一张大图,另一种是每个视角单独存一张图。后者更好处理,因为加载时可以自由选择需要哪些视角来构造输入输出对。
这里有个很容易踩的坑:不同工具包对角色的坐标方向定义不一致,有的把水平方向记为u,有的记为v,有的还把坐标原点放在左上角。如果在加载时不小心把u和v的顺序弄反了,整个光场就相当于做了个转置,训练出来模型的角度关系完全错乱,但损失值看起来又完全是正常的。我的建议是加载完数据后立刻做一个可视化:把偶数组位置的子视角图像依次播放,确认视角移动方向符合预期,再进入下一步。
角度索引的映射关系也很重要。做角度超分任务时,输入是稀疏视角,输出是密集视角,需要提前定义好稀疏位置到密集位置的映射表。一个常见的做法是固定输入视角的坐标,然后在每个目标视角位置取对应的特征块,经过网络后生成完整的密集视角集合。如果映射表构建出错,训练时网络看到的对应关系就乱了,根本学不好视差匹配。
4.2 显存优化与计算效率调优
光场数据是4D结构,注意力模块又涉及大量矩阵乘法和相似度计算,显存消耗特别快。我在实际训练中发现,仅把7×7=49个视角的完整patch喂进一个标准注意力模型,BatchSize设为4都经常爆显存。这种情况下可以考虑几种策略。
第一,把空间维度做窗口化处理,窗口大小设成16×16或者8×8,每个窗口内做空间注意力,窗口间信息流动靠后面层的交叉窗口机制来完成。这个思路借鉴了视觉Transformer里Swin的设计,能大幅减少空间注意力的计算量。第二,利用梯度累积来等效增大BatchSize,实际效果对低层视觉任务来说通常不错,因为光场数据的单样本信息量很丰富,不需要特别大的BatchSize。第三,开启混合精度训练,只在注意力计算部分保留FP32精度,其他全部落到FP16,显存占用能再降四成左右。
此外,尽量把角度维度放进batch维或者当作多头注意力的"头"来处理,可以减少不必要的reshape。光场数据的空间尺寸本就不大,角度维度常常也只有几十,所以通常做法是把角度维度复制扩展到batch维度,让每个视角独立通过卷积层,再在注意力阶段重新拼回4D结构。这样操作要注意BatchNorm的统计量问题,如果每个视角当作一个独立样本进入BN层,实际上统计的是不同视角的混合分布,可能会引入不一致性。
4.3 注意力网络训练的稳定性问题
注意力网络的训练比普通CNN更容易出现不稳定的问题,尤其是训练初期。最常见的情况是softmax权重饱和,即某个token的注意力权重接近1,其他位置接近0,导致模块退化成几乎只是选择单个特征,没有起到聚合作用,梯度也因此变得不稳定。解决的办法有几种,最朴素的是增加注意力Dropout并降低学习率,让模块逐渐探索;更有效的是在注意力得分上增加温度参数,训练初期把温度调高一些,让softmax的分布更平坦。
梯度裁剪也建议加上。空间注意力的梯度范数有时候会在某一步突然飙到很大,尤其是对边界视角的权重更新,被几个异常样本带动后会让损失值震荡很久。设置最大梯度范数为1左右,基本能消除这种震荡。
另外L1损失在多视角联合重建时,对边缘像素的梯度贡献较大,容易导致网络过度关注零散的高频噪声而忽略整体结构。我尝试过在L1基础上加5%的感知损失,即用预训练的网络提取特征算距离,主观质量明显提升,PSNR反而掉了少许,这属于感知质量和数值指标之间的经典平衡,看任务需求取舍即可。
4.4 评估与可视化的落地细节
评估阶段的重点是保证输入输出视角数量一致,以及测试时和训练时的数据分布尽量相近。真实光场数据的测试图像可能有不同的渐晕模式,最好先对测试数据做和训练数据一致的预处理,包括裁剪、归一化、灰度匹配等。归一化范围需要全局统一,比如都在[0, 1]范围内,我见过有项目光注意了训练集却忘了测试集,导致输出的PSNR整体低了好几个dB,排查浪费了一整天。
可视化方面,EPI是最直观的验证工具。取一个固定的空间行坐标和角度行坐标,把所有视角沿角度轴堆叠起来形成一张EPI图,理想情况下直线的连续性反映了视差估计的准确性。每次训练到中间checkpoint时,我都习惯抽样出一张EPI图放进日志里看,比看PSNR单调递增更早发现问题。抖动或断层意味着角度注意力的匹配关系没有学到,哪怕是PSNR还算达标,后续应用时也会出问题。
5. 个人评价与后续可以继续深挖的方向
5.1 论文的优点和局限
这篇论文最让我欣赏的地方是它的简洁和可解释性。整个方法就是两条注意力分支,一个管空间、一个管角度,原理直白,实验设计也扎实,不会让人读完后云里雾里。它不像有些工作堆了一堆模块、做了几十组实验,最后也说不清每个模块到底干了什么。空间注意力和角度注意力的分工在本任务里几乎是不言自明的,论文把这个直觉变成了一个清晰的网络结构,并且用消融实验验证了它的合理性。
模块的即插即用性也是加分项。如果你已经有一个基于CNN的光场重建基线模型,想在不改变整体框架的情况下提升效果,只需要把这两个注意力模块插入到特征提取和重建之间,再微调训练参数,就能拿到相对稳定的性能提升。这种模块化的设计对做应用落地的人来说非常友好。
局限也同样明显。空间注意力在较大patch上的计算复杂度依然太高,想要做到更高分辨率的光场重建,需要依赖窗口注意力等手段做进一步优化。角度注意力的建模范围受限于视角数量,如果是在极稀疏的光场场景,比如只有2个或4个视角输入,角度维度上的匹配信息不足,单纯的注意力机制也难以奇迹般补全。对于真实场景中可能存在的非朗伯表面和遮挡区域,论文的处理也比较朴素,这些地方的光场重建仍然是开放的难题。
5.2 后续还可以怎么扩展
从这篇论文出发,我个人觉得有几个方向很值得继续尝试。一是把空间-角度注意力和更强的主干网络结合,比如用Transformer主干替换掉卷积特征提取部分,让底层特征本身就包含长距离依赖;二是在注意力模块中加入显式的几何先验,比如把已知的视差范围或者相机位姿映射成位置编码,减少网络对匹配关系的搜索负担;三是把平面场景扩展到光场视频,这个时候的角度一致性之外还要加上时间一致性,空间-角度双分支的框架可以再增加一个时间注意力分支,形成三路注意力结构。
还有一点就是与重聚焦、深度估计这些下游任务的结合。光场重建出来的高质量结果,完全可以当作上游模块接入到深度估计或三维重建的流程里。反过来,这些下游任务输出的几何信息也能帮助光场重建,形成一个互相促进的闭环。论文这种空间和角度解耦的思路,提供了一个很好的接口去做这种任务协同。
最后再分享一点实际感受。我复现这个思路的时候,单独跑角度注意力比想象中更难调,因为视角之间的相关性对数据分布非常敏感,只要训练数据里的视角覆盖不够均匀,注意力权重就会偏向少数几个"强势"视角。后来我给角度注意力加了一个均匀性正则项,强制每个视角的注意力权重不过度集中,效果立刻稳定了不少。这个改动很小,但让我对论文里“空间和角度应该分开建模”这句话有了更深的理解:分开建模不是为了分别优化两个子问题,而是为了暴露问题,然后有针对性地解决。这个思路,我觉得比单看PSNR提升几个dB更有价值。