我自己的原文哦~https://blog.51cto.com/whaosoft/12327892
#robustlearn
本文提出了「鲁棒关键微调」,通过「微调」对抗训练模型的「非鲁棒关键性模块」,充分利用其冗余能力提升泛化性。
对抗训练(Adversarail Training)增强了模型对抗鲁棒性,但其代价往往是泛化能力的下降。本文提出了**「鲁棒关键微调」** (Robustness Critical Fine-Tuning,RiFT),通过**「微调」** 对抗训练模型的**「非鲁棒关键性模块」**,充分利用其冗余能力提升泛化性。在 CIFAR10、CIFAR100 和 Tiny-ImageNet 数据集上的实验表明RiFT可以提高模型泛化性约 1.5%,同时保持对抗鲁棒性,达到了对抗鲁棒性和泛化能力更好的 trade-off。
论文标题:Improving Generalization of Adversarial Training via Robust Critical Fine-Tuning
文章链接:https://arxiv.org/abs/2308.02533
代码链接:https://github.com/microsoft/robustlearn
文章作者为中国科学院自动化研究所硕士生朱凯捷,指导老师为王晋东、杨戈,其他作者分别来着微软亚洲研究院、香港城市大学。
随着深度学习模型的能力变得越来越强,泛化性和鲁棒性已经成为深度学习领域的核心议题。这两个特性直接关系到模型是否能在真实世界的多样化环境中稳健、准确地执行其任务。
「泛化性」(Generalization)通常指机器学习模型在未见过的新数据上的性能表现。以数据类型进行分类可以细分为为以下两大类:
- 分布内(In-distribution)泛化:模型在与训练数据同分布的测试数据上的性能。这是深度学习算法的基本,其目标是确保模型能够理解和利用在训练集中存在的模式。
- 分布外(Out-of-distribution)泛化:模型在与训练数据有所差异或完全不同分布的数据上的表现。随着技术的发展,这种泛化能力变得尤为重要,因为现实世界中的数据的分布经常存在着不可预见的变化和偏移。

分布内泛化和分布外泛化的一个例子。这里分布外泛化指图片的分布从真实世界的小狗图片偏移到了动漫图片。「鲁棒性」(Robustness)则主要关注模型面对各种挑战时的稳定性和可靠性。尤其是,模型需要在面对潜在的对抗攻击(Adversarial Attack)时仍能保持其性能。对抗鲁棒性(Adversarial Robustness)是其中的一个关键方面,涉及模型在面对输入存在微小的对抗扰动时仍然能够正确分类的能力。

对抗鲁棒性的一个例子。给大熊猫图片加入一个肉眼难以分辨的噪声,模型即将其分类为了"长臂猿"。图片来源:[1]对抗训练的目标是最小化鲁棒损失(Robust Loss, [2]),即:

**对抗鲁棒性和泛化性是否相互矛盾?**泛化性与鲁棒性二者是否可以兼得,目前仍处于争议中。有研究表明[3],即使在线性分类这样简单的问题,泛化性与鲁棒性都不可兼得。下面的表格数据从RobustBench的摘取:可以看出,对抗训练极大的提升了模型的对抗鲁棒性,但代价是降低了模型的分布内泛化性。

现有研究关注于如何在**「对抗训练过程中」**缓解该矛盾:
- 为不同训练数据设计不同的权重 [4]
- 增加无标注数据 [5]
- 修改损失函数 [6]
一个自然的问题是:可否通过 「微调」 对抗训练后的模型来进一步缓解鲁棒性与泛化性的矛盾? 这种解决方案有以下两点优势:
- 高效,如果尝试通过修改对抗训练算法来缓解,则需要重新进行对抗训练,费时费力
- 易用,微调方法可以与任意对抗训练算法结合
模型鲁棒关键性(Module Robust Criticality)
有研究表明,完全微调(Fully fine-tuning,即微调所有层的参数)会破坏模型已学习到的鲁棒特征[7, 8]。这就启发我们要选择那些 「对模型鲁棒性不够"关键"的参数」 进行微调。那么如何界定模型参数对鲁棒性的关键程度呢?
在这里先简要介绍一下loss landscape概念,下图是一个二维的例子。

可以看到,不同的局部极小值,同样的扰动范围,鲁棒损失变化大不相同。「平坦的局部极小意味着对参数进行微小改动不会影响模型鲁棒性。」

可以看出,不同模块对模型鲁棒性的关键程度是不同的。例如,layer2.1.conv2模块在最坏扰动(Worst-case weight perturbation)下对模型鲁棒性的影响极小,鲁棒准确率只下降了2.86%,表明该模块存在 「冗余」 的鲁棒能力。相反,对于layer4.1.conv1模块,最坏情况下的权重扰动会产生很大影响,导致鲁棒性准确性下降了53.03%之多。
基于MRC的定义,我们可以证明,模型在\epsilon\epsilon范围内进行微调,其鲁棒损失值不会超过MRC值。从直观上来说很容易理解,因为MRC就是在求\epsilon\epsilon参数范围鲁棒损失的变化最大值,即求一个最坏情况下的权重扰动。因此,微调所造成的鲁棒损失上升值(通常不太可能和最坏情况下的权重扰动方向一致)一定不会超过MRC的值。
需要注意的是,MRC求解需要同时找到最坏情况下的输入扰动(即对抗样本)和最坏情况下的权重扰动,这样的求解是十分复杂且费时的,本文在求解MRC时做了松弛处理,固定了对抗样本,具体请参见论文。
RiFT: Robust Critical Fine-Tuning
定义完模型的鲁棒关键性后,我们就可以对其进行微调了。

RiFT总共分为3步:
- 「刻画」:刻画不同模块的鲁棒关键性
- 「微调」:对非鲁棒关键性模块进行微调,冻结其他模块的权重
- 「插值」:将微调后的模型参数和原始的对抗训练模型参数进行插值,寻找最优的插值系数
我们在MRC章节提到,如果在给定的\epsilon\epsilon参数范围内对模型进行微调,其鲁棒损失值不会超过MRC值。在第二步,我们没有刻意的约束参数微调的范围,而是选择通过插值来寻找最优的点。
下图是在CIFAR10数据集上对ResNet18不同模块上进行微调然后插值得到的结果,每个点表示微调得到的最终权重与初始对抗训练权重之间的不同插值点。可以看出,只有对非鲁棒性关键模块(layer2.1.conv2)进行微调才能保持模型的鲁棒性。此外,在初始插值阶段,对非鲁棒性关键模块进行微调还可**「提高对抗鲁棒性」**约0.3%。
实验结果
我们使用ResNet18, ResNet34和WideResNet34-10在CIFAR10, CIFAR100以及Tiny-ImageNet上进行了实验,可以看出,经过RiFT微调后,模型的对抗鲁棒性保持几乎不变的同时,能提升模型的分布内以及分布外泛化性约1.5%。

此外,我们还结合了其他对抗训练算法,包括TRADES, MART, AWP以及SCORE。其结果如下。可以看出,我们的方法同时可以结合其他的对抗训练算法,进一步提升对抗训练模型的泛化性。

#TinyGrad
不知道好用吗 发啊反正发现一个小框架哦 还是老外的可能靠谱一些?
最近,天才黑客 George Hotz 开源了一个小型深度学习框架 tinygrad,兼具 PyTorch 和 micrograd 的功能。tinygrad 的代码数量不到 1000 行,目前该项目获得了 GitHub 1400 星。
在深度学习时代,谷歌、Facebook、百度等科技巨头开源了多款框架来帮助开发者更轻松地学习、构建和训练不同类型的神经网络。而这些大公司也花费了很大的精力来维护 TensorFlow、PyTorch 这样庞大的深度学习框架。除了这类主流框架之外,开发者们也会开源一些小而精的框架或者库。比如今年 4 月份,特斯拉人工智能部门主管 Andrej Karpathy 开源了其编写的微型 autograd 引擎micrograd,该引擎还用 50 行代码实现了一个类 PyTorch api 的神经网络库。目前,micrograd 项目的 GitHub star 量达到 1200 星。不久前,天才黑客 George Hotz(乔治 · 霍兹)开源了一个小型Autograd Tensor 库 tinygrad,它介于 PyTorch 和 micrograd 之间,能够满足做深度学习的大部分要求。上线不到一个月,该项目在 GitHub 上已经获得 1400 星。
根据 GitHub 内容,下文对 tinygrad 的安装与使用做了简要介绍。感兴趣的同学也可通过 George Hotz 的 YouTube 视频进行学习。
视频地址:https://www.youtube.com/channel/UCwgKmJM4ZJQRJ-U5NjvR2dg
tinygrad 的安装与使用
「tinygrad 可能不是最好的深度学习框架,但它确实是深度学习框架。」
George 在项目中保证,tinygrad 代码量会永远小于 1000 行。
安装
tinygrad 的安装过程非常简单,只需使用以下命令:
pip3 install tinygrad --upgrade
示例
安装好 tinygrad 之后,就可以进行示例运行,代码如下:
from tinygrad.tensor import Tensor
x = Tensor.eye(3)
y = Tensor([[2.0,0,-2.0]])
z = y.matmul(x).sum()
z.backward()
print(x.grad) # dz/dx
print(y.grad) # dz/dy
使用 torch 的代码如下:
import torch
x = torch.eye(3, requires_grad=True)
y = torch.tensor([[2.0,0,-2.0]], requires_grad=True)
z = y.matmul(x).sum()
z.backward()
print(x.grad) # dz/dx
print(y.grad) # dz/dy
满足对神经网络的需求
一个不错的autograd张量库可以满足你对神经网络 90%的需求。从 tinygrad.optim 添加优化器(SGD、RMSprop、Adam),再编写一些 minibatching 样板代码,就可以实现你的需求。
示例如下:
from tinygrad.tensor import Tensor
import tinygrad.optim as optim
from tinygrad.utils import layer_init_uniform
class TinyBobNet:
def __init__(self):
self.l1 = Tensor(layer_init_uniform(784, 128))
self.l2 = Tensor(layer_init_uniform(128, 10))
def forward(self, x):
return x.dot(self.l1).relu().dot(self.l2).logsoftmax()
model = TinyBobNet()
optim = optim.SGD([model.l1, model.l2], lr=0.001)
# ... and complete like pytorch, with (x,y) data
out = model.forward(x)
loss = out.mul(y).mean()
loss.backward()
optim.step()
支持 GPU
tinygrad 通过 PyOpenCL 支持 GPU。但后向传播暂时无法支持所有 ops。
from tinygrad.tensor import Tensor
(Tensor.ones(4,4).cuda() + Tensor.ones(4,4).cuda()).cpu()
ImageNet inference
「麻雀虽小,五脏俱全。」tinygrad 还能够支持 full EfficientNet,输入一张图像,即可得到其类别。
ipython3 examples/efficientnet.py https://upload.wikimedia.org/wikipedia/commons/4/41/Chicken.jpg
如果你安装了 webcam 和 cv2,则可以使用以下代码:
ipython3 examples/efficientnet.py webcam
注意:如果你想加速运行,设置 GPU=1。
测试
运行以下代码可执行测试:
python -m pytest
此外,乔治 · 霍兹还计划添加语言模型、检测模型,进一步减少代码量、提升速度等。
TODO
- Train an EfficientNet on ImageNet
- Make broadcasting work on the backward pass (simple please)
- EfficientNet backward pass
- Tensors on GPU (a few more backward)
- Add a language model. BERT?
- Add a detection model. EfficientDet?
- Reduce code
- Increase speed
- Add features
#NFNets
通过评估按比例扩大的 NFNets,挑战了 ConvNets 在大规模上表现不如 ViTs 的观点。谁说卷积网络不如ViT?
深度学习的早期成功可归功于卷积神经网络(ConvNets)的发展。近十年来,ConvNets 主导了计算机视觉基准测试。然而近年来,它们越来越多地被 ViTs(Vision Transformers)所取代。
很多人认为,ConvNets 在小型或中等规模的数据集上表现良好,但在那种比较大的网络规模的数据集上却无法与 ViTs 相竞争。
与此同时,CV 社区已经从评估随机初始化网络在特定数据集 (如 ImageNet) 上的性能转变为评估从网络收集的大型通用数据集上预训练的网络的性能。这就提出了一个重要的问题:在类似的计算预算下,Vision Transformers 是否优于预先训练的 ConvNets 架构?
本文,来自 Google DeepMind 的研究者对这一问题进行了探究,他们通过在不同尺度的 JFT-4B 数据集(用于训练基础模型的大型标签图像数据集)上对多种 NFNet 模型进行预训练,从而获得了类似于 ViTs 在 ImageNet 上的性能。
论文地址:https://arxiv.org/pdf/2310.16764.pdf
本文考虑的预训练计算预算在 0.4k 到 110k TPU-v4 核计算小时之间,并通过增加 NFNet 模型家族的深度和宽度来训练一系列网络。本文观察到这一现象,即 held out 损失与计算预算之间存在 log-log 扩展率(scaling law)。
例如,本文将在 JFT-4B 上预训练的 NFNet 从 0.4k 扩展到 110k TPU-v4 核小时(core hours)。经过微调后,最大的模型达到了 90.4% 的 ImageNet Top-1,在类似的计算预算下与预训练的 ViT 相竞争。

可以说,本文通过评估按比例扩大的 NFNets,挑战了 ConvNets 在大规模数据集上表现不如 ViTs 的观点。此外,在足够的数据和计算条件下,ConvNets 仍然具有竞争力,模型设计和资源比架构更重要。
看到这项研究后,图灵奖得主 Yann LeCun 表示:「计算是你所需要的,在给定的计算量下,ViT 和 ConvNets 相媲美。尽管 ViTs 在计算机视觉方面的成功令人印象深刻,但在我看来,没有强有力的证据表明,在公平评估时,预训练的 ViT 优于预训练的 ConvNets。」
不过有网友评论 LeCun,他认为 ViT 在多模态模型中的使用可能仍然使它在研究中具有优势。
来自 Google DeepMind 的研究者表示:ConvNets 永远不会消失。
接下来我们看看论文具体内容。
预训练的 NFNets 遵循扩展定律
本文在 JFT-4B 上训练了一系列不同深度和宽度的 NFNet 模型。
如下图 2 所示,验证损失与训练模型的计算预算呈线性关系,这与使用 Transformer 进行语言建模(Brown et al., 2020; Hoffmann et al., 2022)时观察到的双对数(log-log)扩展定律相匹配。最佳模型大小和最佳 epoch 预算(实现最低验证损失)都会随着计算预算的增加而增加。

下图 3 绘制了 3 个模型在一系列 epoch 预算中观察到的最佳学习率(最大限度地减少验证损失)。研究团队发现对于较低的 epoch 预算,NFNet 系列模型都显示出类似的最佳学习率 𝛼 ≈ 1.6。然而,随着 epoch 预算的增加,最优学习率会下降,并且对于大型模型,最优学习率下降得更快。研究团队表示可以假设最优学习率随着模型大小和 epoch 预算的增加而缓慢且单调地下降,从而在 2 次试验内有效地调整学习率。

值得注意的是,图 2 中一些预训练模型的表现不如预期。研究团队认为出现这种情况是因为如果训练运行被抢占 / 重新启动,那么数据加载 pipeline 不能保证每个训练样本在每个 epoch 都会采样一次,如果训练运行多次重新启动,则可能导致某些训练样本采样次数不足。
NFNet vs ViT
该研究在 ImageNet 上的实验表明:经过微调的 NFNet 与 Vision Transformer 性能相当。
具体来说,该研究在 ImageNet 上微调了预训练 NFNet,并绘制了预训练计算与 Top-1 error 关系图,如上述图 1 所示。
随着计算预算的增加,ImageNet Top-1 准确性不断提高。其中最昂贵的预训练模型是预训练 8 个 epoch 的 NFNet-F7+,ImageNet Top-1 准确率达到了 90.3%,需要大约 110k TPU-v4 核小时进行预训练和 1.6k TPU-v4 核小时进行微调。此外,如果在微调期间额外引入重复增强(repeated augmentation),那么可以实现 90.4% 的 Top-1 准确率。NFNet 从大规模预训练中受益匪浅。
尽管 NFNet 和 ViT 两种模型架构之间存在显著差异,但预训练 NFNet 与预训练 ViT 性能相当。例如,在 JFT-3B 上预训练 210k TPU-v3 核小时后,ViT-g/14 在 ImageNet 上实现了 90.2% 的 Top-1 准确率,在 JFT-3B 上预训练超过 500k TPU-v3 核小时后,ViT-G/14 实现了 90.45% 的 Top-1 准确率。
本文评估了这些模型在 TPU-v4 上的预训练速度,并估计 ViT-g/14 需要 120k TPU-v4 核小时来预训练,而 ViTG/14 则需要 280k TPU-v4 核小时数,SoViT-400m/14 将需要 130k TPU-v4 核小时数。本文使用这些估计来比较图 1 中 ViT 和 NFNet 的预训练效率。研究注意到,NFNet 针对 TPU-v4 进行了优化,在其他设备上评估时表现较差。
最后,本文注意到,预训练的 checkpoints 在 JFT-4B 上实现了最低的验证损失,然而微调后并不总能在 ImageNet 上实现最高的 Top-1 准确率。特别是,本文发现,在固定的预训练计算预算下,微调机制始终倾向于稍大的模型和稍小的 epoch 预算。直观上来说,更大的模型具有更大的容量,因此能够更好地适应新任务。在某些情况下,稍大的学习率(在预训练期间)在微调后也能获得更好的性能。
#NFNet~2
决定一个视觉骨干模型性能的最重要因素是用于训练的计算预算和训练的数据量。超强 ResNet 变体 NFNet (第二集) , 匹敌 ViT 性能的 JFT-4B 大规模预训练
许多研究人员认为 ConvNet 在小型或中等规模的数据集上表现良好,但是在面对超大规模的数据集时不如 Vision Transformer。在本文中作者希望挑战这个观点,通过评估在 JFT-4B (大型有标注数据集,通常用于训练基础模型) 上预训练的 ConvNet。
选取的 ConvNet 模型:NFNet (解读详见如下链接)。NFNet 由于不含 BN 带来的隐式正则化效果 ,除非显式正则化,否则对于像 ImageNet 这样的数据集往往会过拟合 。但是当在极大规模的数据集 (比如本文使用的 JFT-4B) 上进行预训练时,这种正则化可能不仅是不必要的,反而会对性能有损害,因为妨碍了模型将其全部的参数应用于拟合训练集的能力。因此,不含 BN 的 NFNet 天然地适合于超大规模数据集的预训练。
详解超强 ResNet 变体 NFNet:抛弃归一化后,性能却达到了最强!
因此,作者在本文中选取 NFNet 模型家族训练了一系列增加深度和宽度逐渐增加的模型,还观察到 loss 和 compute budget 之间的对数-对数缩放定律 (Log-Log Scaling Law)。在 ImageNet 上进行微调后,NFNet 与计算预算相当的 Vision Transformer 的精度相匹配,NFNet 最强的微调之后模型达到了 90.4% 的 Top-1 精度。
匹敌 ViT 性能的大规模预训练
论文名称: ConvNets Match Vision Transformers at Scale (Arxiv 2023)
论文地址: http://arxiv.org/pdf/2310.16764.pdf
视觉社区从中等规模数据集到超大规模数据集的性能评估
卷积神经网络 (ConvNet) 对于深度学习的许多早期成功有巨大的推动作用。Deep ConvNet 于 20 年前首次商业部署,而 AlexNet 在 2012 年 ImageNet 挑战方面取得了成功。近十年的 ConvNet 主导了计算机视觉基准。但是近年来,它们越来越多地被 Vision Transformer (ViT) 所取代。
同时,计算机视觉社区在评估模型性能时,已经从中等规模数据集 (如 ImageNet) 转向了从网上收集的通用超大规模数据集 (如 JFT-4B) 预训练网络的性能。这就提出了一个重要问题:Vision Transformer 是否优于使用相似计算资源预训练的 ConvNet 架构?
尽管社区中大多数研究人员认为 Vision Transformer 表现出了比 ConvNet 更好的缩放属性,但是几乎没有证据来证明这一点。许多的研究将 ViT 与较弱的 ConvNet 基线 (通常是原始的 ResNet 架构) 进行比较。而最强的 ViT 模型已经使用了超过 500k TPU-v3 core hours 的计算资源,这已经大大超过了用于预训练 ConvNet 的计算预算。
许多研究人员认为 ConvNet 在小型或中等规模的数据集上表现良好,但是在面对超大规模的数据集时不如 Vision Transformer。在本文中作者希望挑战这个观点,通过评估在 JFT-4B (大型有标注数据集,通常用于训练基础模型) 上预训练的 ConvNet。
作者评估的 ConvNet 模型是 NFNet 模型家族,一种与第一个ViT论文同时发布的纯卷积架构。NFNet 由于不含 BN 带来的隐式正则化效果 ,除非显式正则化,否则对于像 ImageNet 这样的数据集往往会过拟合 。但是当在极大规模的数据集 (比如本文使用的 JFT-4B) 上进行预训练时,这种正则化可能不仅是不必要的,反而会对性能有损害,因为妨碍了模型将其全部的参数应用于拟合训练集的能力。因此,不含 BN 的 NFNet 天然地适合于超大规模数据集的预训练。
作者没对模型架构或训练过程进行任何更改 (除了调整学习率或者 Epoch 数等简单的超参数)。作者的计算预算最多为 110k TPU-v4 core hours,并在 JFT-4B 数据集上预训练,该数据集包含来自 30k 类别的大约 4 billion 的有标注图片。
JFT-4B 预训练的 NFNet 服从对数-对数缩放定律
作者在 JFT-4B 上训练一系列不同深度的 NFNet 模型。每个模型都使用余弦衰减学习率计划训练,Epoch 预算在了 0.25 到 8 之间,基本学习率针对每个 Epoch 预算作单独调整。作者在图1中绘制了 JFT-4B 的验证集损失与计算预算之间的关系曲线。
模型: F7 的宽度与 F3 相同,但深度加倍。同样,F3 是 F1 深度的两倍,F1 是 F0 深度的两倍。F3+ 和 F7+ 的深度与 F3 和 F7 相同,但宽度较大。
训练策略: 使用批量大小为 4096 的 Momentum 和 Adaptive Gradient Clipping (AGC) 的 SGD 优化器进行训练,在训练期间使用 224×224 的图像分辨率,在推理时使用 256 × 256。在训练期间从 JFT-4B 中删除了 ImageNet 训练集和验证集中图像的近乎重复的部分。

图1:JFT-4B 的验证集损失与计算预算之间的关系曲线。两个轴都是对数缩放的,每条曲线表示为一系列 Epoch 预算训练的不同模型
作者图1中展示出的趋势是清晰的 TPU-v4 Core Hours 的对数和 JFT-4B 验证集精度之间的线性关系,也就是 TPU-v4 Core Hours 和 JFT-4B 验证集精度之间的对数-对数缩放定律 (Log-Log Scaling Law)。
最佳模型大小和最佳 Epoch 预算 (达到最低验证集损失) 都随着计算预算的增加而增加。作者注意到对于大于约 5k TPU-v4 Core Hours 的整体计算预算而言,最佳的 Epoch 预算大于 1。
如图2所示是不同尺寸的3个模型在不同 Epoch 预算的最优学习率 (最小化验证损失)。所有的模型都显示出相似的最佳学习率:当 Epoch 预算较小时最佳学习率约为1.6,随着计算预算的增加而逐渐减小。对于大模型,最优的学习率下降得更快。在实践中,可以通过假设最优学习率随着模型大小和 Epoch 预算的增加而缓慢单调地下降,从而在2次试验内有效地调整学习率。

图2:不同尺寸的3个模型在不同 Epoch 预算的最优学习率。所有的模型都显示出相似的最佳学习率:当 Epoch 预算较小时最佳学习率约为1.6,随着计算预算的增加而逐渐减小
作者注意到图1中的一些预训练模型的表现不如预期好,比如,不同预训练预算下的 NFNet-F7+ 模型的曲线不够平滑。作者认为这是因为如果训练运行被抢占或者重启,数据加载管道并不能保证每个训练样本在每个 Epoch 中被采样一次,如果多次重新启动训练运行,可能会导致一些训练样本被欠采样。
ImageNet 微调之后的 NFNet 匹配了 Vision Transformer 的性能
在下图3中,作者在 ImageNet 上微调 JFT-4B 上预训练的 NFNets,并根据预训练期间使用的计算预算绘制 Top-1 Error。正则化方法包括 Stochastic Depth,Dropout,和 Sharpness Aware Minimization (SAM)[1],对每个模型进行微调 50 个 Epoch,作者以 384×384 的分辨率进行训练,并在 480×480 上进行评估。

图3:ImageNet Top-1 Error 与 JFT-4B 预训练期间的计算预算之间的关系曲线。两个轴都是对数缩放的,随着预训练期间使用的计算的增加,性能不断提高。最大的模型 (NFNet-F7+) 实现了与具有相似计算预算的预训练 ViT 报告相当的性能
如图3所示,随着计算预算的增加,ImageNet Top-1 的精度不断提高。最昂贵的预训练模型,一个经过 8 个 Epoch 预训练的 NFNet-F7+,实现了 90.3% 的 ImageNet Top-1 精度,同时需要大约 110k TPU-v4 Core Hour 来预训练和 1.6k TPU-v4 Core Hour 进行微调。此外,如果在微调期间额外引入 Repeated Augmentation,就实现了 90.4% 的 Top-1 的精度。
为了观察和比较大规模 JFT-4B 预训练的作用,作者列出了这个结果:在没有额外数据的情况下,NFNet 在 ImageNet 上报告的最佳 Top-1 精度仅为 86.8%,这表明 NFNet 从 JFT-4B 的预训练中受益匪浅。
作者也在 TPU-v4 上评估了这些模型的预训练速度,并估计:
ViT-g/14 需要 120k TPU-v4 Core Hour
ViT-G/14 需要 280k TPU-v4 Core Hour
SoViT-400m/14 需要 130k TPU-v4 Core Hour
注意到 NFNets 是针对 TPU-v4 优化的,估计 NFNet-F7+ 将需要 250 个 TPU-v3 Core Hour 预训练 8 个 Epoch。
最后,作者注意到在 JFT-4B 上实现最低验证集损失的预训练 checkpoint 在微调后并不总是在 ImageNet 上实现最高的 Top-1 精度的。特别是作者发现,在固定的预训练计算预算下,微调总偏爱稍大的模型和略小的 Epoch 预算。
最后讨论
本文最终的结论是:决定一个视觉骨干模型性能的最重要因素是用于训练的计算预算 和训练的数据量。尽管 ViT 在视觉任务上的成功让人印象深刻,但是在本文看来,没有强有力的证据表明预训练的视觉 Transformer 模型的性能在计算预算相当的条件下优于预训练的 ConvNet 模型。
但不可否认的是,Transformer 模型在特定的上下文中具有实际优势,比如能够在多种模态中使用相似的组件的能力。
#NeRF2
NeRF[1]

Figure: An overview of our neural radiance eld scene representation and differentiable rendering procedure. We synthesize images by sampling 5D coordinates (location and viewing direction) along camera rays (a), feeding those locations into an MLP to produce a color and volume density (b), and using volume rendering techniques to composite these values into an image (c). This rendering function is differentiable, so we can optimize our scene representation by minimizing the residual between synthesized and ground truth observed images (d).
具体实现和形式不再展开,其中有两点细节要说明,一点是 Positional Encoding,另一点则是 Coarse-to-Fine,即 Hierarchical Sampling。
Positional Encoding
为什么要引入 Positional Encoding,即人为地引入高频信息,是因为作者发现 MLP 更倾向于学习低频信号,这点在 [2, 3] 中均有理论性的说明,同时 [4] 还给出了 Positional Encoding 能凑效的推导。就我个人而言,MLP 通常由多层的参数矩阵组成,在计算即前传的过程中,还存在着大量的非线性激活,这使得 MLP 具有非常良好的插值性质,能够输出足够平滑的结果(我们老师将之称为 Deep Prior,我个人理解是属于 MLP 的 inductive bias),但这也意味着 MLP 难以捕获到变化剧烈的区域的特征(即高频特征)。对于 Positional Encoding,从一方面来讲,它将欧式空间的样本点投影到频率空间,也就是将点打散了,在欧式空间相近的点在频率空间就会很远。原本 MLP 很难拟合出"狭小"的欧式空间中的剧烈变化。但在 Positional Encoding 将样本点投影到频率空间后,这些"剧烈变化"在频率空间就显得平滑得多, MLP 就能够很轻易地在频率空间拟合出这些变化,但频率空间相较于欧式空间得求解空间大得多,所以 MLP 依旧需要花费大量的时间去拟合。从另一个角度来说,NeRF 想做的事情是表征欧式空间中的一个场,而 Positional Encoding 则是对欧式空间的三个轴分别引入了一组正交基函数,此时 MLP 的任务就可以看作是学习得到这三组正交基函数的系数表示,这个任务相比于让 MLP 去拟合高频特征显然要简单得多。而这也为我们后来解读为什么基于 Multi-Level 的网格特征的 hybrid NeRF 方法能够快速收敛并实现了很好的性能提供了一个解读的角度。
Hierarchical Sampling
很多人疑问为什么一开始的 NeRF 需要 Coarse-to-Fine 策略,甚至需要两个 MLP,一个负责 Coarse,一个负责 Fine,两个 MLP 之前并不共享参数和交流梯度。直白的说就是希望样本点分布在光线与物体相交的表面附近,这样效果会更好,因此 NeRF 的 Hierarchical Sampling 就是对 Coarse 阶段输出的 density 计算 PDF、CDF 然后采样得到 Fine 阶段的样本点。这在测试阶段没有问题,可是,为什么这需要两个 MLP 呢?也许作者是做了实验之后发现一个 MLP 负责 Coarse 和 Fine 并不能取得很好的结果,所以用两个 MLP 分别负责 Coarse 和 Fine 两个阶段(我相信也有不少研究者做了这个实验)。我个人对此的理解是,虽然 CoarseMLP 和 FineMLP 仅在样本点的输入上有所不同(同样的 Positional Encoding 和 MLP)但其样本点的分布本身就决定了各自 MLP 能够在何种程度"看到"低频和高频信号。CoarseMLP 的样本点是光线在 near/far 区间上的均匀采样,这意味着这条光线上样本点的高频信号失真了(远处的也会包含高频信号,后面的 Mip-NeRF 会提及);而 FineMLP 是在表面交点附近的密集采样,这意味着 MLP 能够密集地"感受"到这一段区域的高频信号(尽可能保证不失真)。可以理解为采用不同的采样策略就是施加了不同的"滤波器"。对同一条光线,两组不同的采样使得 MLP "看到"截然不同的两组信号;如果想让一个 MLP 同时处理好这两组截然不同的信号,可能得高超的调参技巧与更大的网络了。至于为什么后面 Mip-NeRF 能用一个 MLP 来做 Coarse-to-Fine,个人认为他解决了上面我说的不同采样策略导致"滤波"行为。
Mip-NeRF[5]
很棒,很本质的一份工作。在结构上仅将 Positional Encoding (PE) 换成了 Integrated Positional Encoding (IPE)。PE 仅考虑了穿过像素中心的光线上离散的样本点在频率空间上的投影。而 IPE 则考虑了穿过像素的视锥在样本点所在的截断视锥在频率空间上的投影分布。而为了更好的表示这一分布,Mip-NeRF 采用了多元高斯(所以采用圆的视锥)进行近似。当考虑一个分布的性质时,我们通常分析其均值、协方差,Mip-NeRF 后续的推导也是在说明,当采用高斯进行近似时,最终我们能以怎样的形式去实现它。

Figure: NeRF (a) samples points x along rays that are traced from the camera center of projection through each pixel, then encodes those points with a positional encoding (PE) γ to produce a feature γ(x). Mip-NeRF (b) instead reasons about the 3D conical frustum defined by a camera pixel. These conical frustums are then featurized with our integrated positional encoding (IPE), which works by approximating the frustum with a multivariate Gaussian and then computing the (closed form) integral E[γ(x)] over the positional encodings of the coordinates within the Gaussian.
Integrated Positional Encoding
先做个简单的总结,Mip-NeRF 提出的 IPE 相较于 PE 不同在于:



Mip-NeRF 准确描述(进行了合理的建模)了像素包含区域随物体远近变化的关系(近大远小)。对像素来说,越远的区域截断视锥越大,即积分区域越大,此时 Encoding 高频部分的均值迅速衰减到 0(等价于 MipMap 的 Prefiltered 的功能),避免了远处样本点的突然出现的高频信号的影响,参考原文 3.1 最后一段的表述。

Figure: Toy 1D visualizations of the positional encoding (PE) used by NeRF (left) and our integrated positional encoding (IPE) (right). Because NeRF samples points along each ray and encodes all frequencies equally, the highfrequency PE features are aliased, which results in rendering artifacts. By integrating PE features over each interval, the high frequency dimensions of IPE features shrink towards zero when the period of the frequency is small compared to the size of the interval being integrated, resulting in anti-aliased features that implicitly encode the size (and in higher dimensions, the shape) of the interval.
NeRF 则没有这个概念(可以理解为相比 Mip-NeRF,NeRF 对深度没有那么敏感)。NeRF 的 PE 会导致同一个点在不同光线/同一光线不同远近上也会产生一样的 Encoding 结果表示这一段光线的特征。当这一样本点处于较远位置,但它又具有高频信号时,则不利于 NeRF 的学习(因为越远的点应当提供越少的信息量,但这种采样编码的结果违背了这一原则,可以理解为编码信号的走样)

Figure: NeRF works by extracting point-sampled positional encoding features (shown here as dots) along each pixel's ray. Those point-sampled features ignore the shape and size of the volume viewed by each ray, so two different cameras imaging the same position at different scales may produce the same ambiguous point-sampled feature, thereby significantly degrading NeRF's performance. In contrast, Mip-NeRF casts cones instead of rays and explicitly models the volume of each sampled conical frustum (shown here as trapezoids), thus resolving this ambiguity.
所以文章 Intro 就指出当数据集中有距离目标物体远近不一以及分辨率不一的图片时,NeRF 就容易产生失真。
得益于 IPE,Mip-NeRF 能够只用一个 MLP 来实现 Coarse-to-Fine,因为此时采样不再会导致信号的失真,MLP "看到" 的是一样的频率信号。
Mip-NeRF 在超分辨率上也有很好的表现。
缺点
Integrated Positional Encoding (IPE) 比 Positional Encoding 运算复杂度稍高(但单个 MLP 在计算资源层面的优势弥补了这一劣势)。
Mip-NeRF 相比 NeRF 能够非常有效且准确地构建 Multi-View 与目标物体的关系,但这也意味着相机标定误差(即相机 Pose 的偏差)会更容易使 Mip-NeRF 产生混淆,出现更严重的失真。很多研究者观察到了这一现象,侧面说明了高质量的 NeRF 重建的前提是实现准确的相机标定,于是研究者们后续提出了一系列的 Self-Calibration 的工作。同理,当拍摄过程中存在运动模糊 (motion blur) 、曝光等噪声时,Mip-NeRF 也会很容易受到影响。只有当图片成像质量高且相机姿态准确时,Mip-NeRF 才能实现非常棒的效果。后续关于 Self-Calibration、deblur 和曝光控制等工作在一定程度上也是通过更改网络和设置使得 NeRF 能够对这些因素鲁棒,增加容错率(减少失真)。
NeRF++[6]
这份工作是 Cornell College 一位 PhD 的一份技术报告。他主要说明了两点:
shape-radiance ambiguity;
提出了一种处理 unbounded 的方式 - inverted sphere parameterization。

Figure: Shape-radiance ambiguity (left) and parameterization of unbounded scenes (right). Shaperadiance ambiguity: our theoretical analysis shows that, in the absence of explicit or implicit regularization, a set of training images can be fit independently of the recovered geometry (e.g., for incorrect scene geometry \hat{S}\hat{S} rather than correct geometry S^*S^* ) by exploiting view-dependent radiance to simulate the effect of the correct geometry. Parameterization of unbounded scenes: with standard parameterization schemes, either (1) only a portion of the scene is modeled (red outline), leading to significant artifacts in background elements, or (2) the full scene is modeled (orange outline), which leads to an overall loss of details due to finite sampling resolution.
Shape-Radiance Ambiguity
个人感觉他的第一点说明不是很好。主要是他举的例子和实际中遇到的问题其实不是很符合。确实如果训练视角非常少且集中的时候,NeRF 会只关注这一小块区域的"渲染效果",而 density 只是 NeRF 的一个副产物,是为 radiance 服务的,所以极有可能 MLP 只生成一个非常糊弄(低频)的 density (Geometry),而专注于捕获极少数 training views 的渲染细节(高频)。当渲染 test views 时,得到的就是 NeRF 糊弄的结果。而作者在原文图2给的例子是将场固定成球的样子后去 finetine radiance field,然后 test view 的 Prediction 是用 GT 的 mask 抠出来的(下图右1)。然而实际中的情况应该是 training view 看到的形状(应当强调一下 training view 也能够一定程度地优化形状,因为好的 Radiance 还是得有好的 Geometry 支撑)和颜色是好的,但 testing view 的形状和颜色都是坏的(这里仅说作者的例子可能举得不是很好,但他的意思传达到了)。

Figure: To demonstrate the shape-radiance ambiguity, we pretrain NeRF on a synthetic dataset where the opacity field \sigma\sigma is optimized to model an incorrect 3D shape (a unit sphere, instead of a bulldozer shape), while the radiance field c is optimized to map the training rays' intersection with the sphere and view directions to their pixel color. In this example, we use 3 MLP layers to model the effects of view-dependence (see the MLP structure in Figure 3), and fit to 50 synthetic training images with viewpoints randomly distributed on a hemisphere. The resulting incorrect solution explains the training images very well (left two images), but fails to generalize to novel test views (right two images).


Figure: NeRF++ applies different parameterizations for scene contents inside and outside the unit sphere.

Mip-NeRF 360[7]
相比于 NeRF++,Mip-NeRF 360 的处理要更高明得多。Mip-NeRF 360 并不需要用两个 MLP 来分别处理内外的情况,个人认为 NeRF++ 在界外的 pos 输入变成四维了,所以需要两个 MLP。
Mip-NeRF 360 相较于 Mip-NeRF 主要是有三大贡献点:

Unbound Processing
关于坐标系的转换,主要是涉及到采样以及 Mip-NeRF 中 Encoding 积分的变换。首先看坐标变换的具体操作,坐标的 contraction 的数学表达如下:

Figure: A 2D visualization of our scene parameterization. We define a \text{contract}(\cdot)\text{contract}(\cdot) operator (Equation 10, shown as arrows) that maps coordinates onto a ball of radius 2 (orange), where points within a radius of 1 (blue) are unaffected. We apply this contraction to mip-NeRF Gaussians in Euclidean 3D space (gray ellipses) similarly to a Kalman filter to produce our contracted Gaussians (red ellipses), whose centers are guaranteed to lie within a ball of radius 2. The design of \text{contract}(\cdot)\text{contract}(\cdot) combined with our choice to space ray intervals linearly according to disparity means that rays cast from a camera located at the origin of the scene will have equidistant intervals in the orange region, as demonstrated here. 参考了 NDC(https://yconquesty.github.io/blog/ml/nerf/nerf_ndc.html#preliminaries) 的思想。

Proposed MLP
相比于 Mip-NeRF,Mip-NeRF 360 除了 NeRF MLP 外又引入了第二个 MLP 参与 Coarse-to-Fine,他称之为 Proposal MLP。Proposal MLP 仅关注 density 的学习,而不关注 radiance。此时,Proposal MLP 的 density 监督信号仅由 NeRF MLP 的 density 通过直方图统计产生。

Figure: A comparison of our model's architecture with mip-NeRF's. Mip-NeRF uses one multi-scale MLP that is repeatedly queried (only two repetitions shown here) for weights that are resampled into intervals for the next stage, and supervises the renderings produced at all scales. We use a "proposal MLP" that emits weights (but not color) that are resampled, and in the final stage we use a "NeRF MLP" to produce weights and colors that result in the rendered image, which we supervise. The proposal MLP is trained to produce proposal weights \hat{w}\hat{w} that are consistent with the NeRF MLP's ww output. By using a small proposal MLP and a large NeRF MLP we obtain a combined model with a high capacity that is still tractable to train.


MERF 里面一句话总结的比较好。
A proposal MLP maps 3D positions to density values, which are converted into probability distributions along rays that are supervised to be consistent with the densities output by the NeRF MLP. These proposal distributions are used in an iterative resampling procedure that produces a small number of samples that are concentrated around visible scene content. This proposal MLP hierarchical sampling strategy is effective for reducing the number of samples along each ray during training. - from MERF
Distortion-based Regularizer

Plenoxel[11]
Plenoxel 是我个人入门 NeRF 看的第一份的工作(那时候看到某个公众号推了个5分钟训 NeRF 的就点进去了,那时候连 NeRF 是什么都不知道),是我 CUDA 入门参考的工作,也是我个人最欣赏的工作。只是时运不济,碰上 Instant-NGP。

Figure: Overview of our sparse Plenoxel model. Given a set of images of an object or scene, we reconstruct a (a) sparse voxel ("Plenoxel") grid with density and spherical harmonic coefficients at each voxel. To render a ray, we (b) compute the color and opacity of each sample point via trilinear interpolation of the neighboring voxel coefficients. We integrate the color and opacity of these samples using (c) differentiable volume rendering, following the recent success of NeRF [26]. The voxel coefficients can then be (d) optimized using the standard MSE reconstruction loss relative to the training images, along with a total variation regularizer.
看 Plenoxel 之前要知道它的前置工作是 PlenOctree[11],也是 Alex Yu 的工作。这里不想做展开,之后可能会在 NeRF 的 Baking 工作总结上。但是在看 Plenoxel 之前最好还是要理解 PlenOctree。
Grid Representation
在 PlenOctree 中,作者发现 Baking 得到的 Octree 也能利用体渲染进行相应的优化,并且优化速度还非常快,那么自然而然诞生就会出一个想法:我能不能一开始以 Baking 的表征(比如网格、八叉树)进行训练呢,训练过程就是 Baking 的过程。Plenoxel 就是这一一种解决方式。
作者发现 Baking 的主要作用反而不是 Raidance 部分的固定,而是 Geometry 部分的固定(思考一下,PlenOctree 的 fine-tune 过程是不改变八叉树结构的,而仅改变八叉树叶节点的值)。这也就意味着,如果我能在训练过程中实现表征的 Geometry 优化,那这个问题基本上就算解决了。而八叉树并不是一个适合进行形状优化的表征,作者就把目光放到了离散的八叉树叶节点,也就是系数网格 (sparse voxel grid) 身上。为了实现直接对稀疏网格进行优化,作者设置了一堆的组件,这也是整个 Plenoxel 的逻辑。

Plenoxel 有个非常妙的方式实现了高效跳点,它仿照了八叉树的建立过程,利用迭代预计算的方式获得了每个 empty grid 能够前进的最大安全距离。具体的实现代码是 misc_kernel.cu 的 accel_dist_prop 函数,注意其中输入的 grid 为 -1 表示为 empty grid。而后在 ray marching 过程中则会在 compute_skip_dist 函数(定义在 render_util.cuh 中)计算最大安全跳点距离。有空的同学可以去看一下这部分的源码,个人觉得非常巧妙,非常简单的实现了 multi-level occupancy grid。
Coarse to Fine

Optimization
由于 Plenoxel 是完全的 explicit 方法,没有用到任何 MLP,这意外着网格点存放的参数的优化是完全独立的。而这很可能会导致训练过程中因为视角分布导致失真问题。想象一下,我某部分网格存了较大(这里的较大不是单纯数值上的大,理解一下)的参数就能够很好的应付训练视角的渲染,而另一部分网格由于前面的这些网格承担了大部分的渲染任务,使得它只存了较少的参数。让我进行新视角合成的时候,这两部分网格参数的割裂感就会以失真的形式展示出来。对于上述问题,Plenoxel 提出了相应的 smooth prior 来处理,通过计算 TV loss 来使相邻网格的值变得平滑。

Unbounded Scenes

Others
在实际的使用中,Plenoxel 可能并不是很好用。一方面,explicit 设计实现不了一种全局的优化,很容易陷入到局部最优解(网格顶点间的特征是孤立的),产生撕裂效果的失真。与之相比,大家还是更倾向于 Hybrid 方案,用离散的特征存储结合小型 MLP 的方式,实现存储和速度还有效果的权衡。
Instant-NGP[14]
这位更是重量级,直接盖过了 Plenoxel 和 DVGO 的风头。有一说一,Hash Encoding 固然是非常有价值的,但 Instant-NGP 最重要的是它的工程价值。虽然 Hash Encoding 确实能极大地加快 NeRF 的训练效率,但是他 project 中展示的几秒的优化速率是基于他高效的 CUDA 配套代码实现的。而北大的唐老哥重实现的 torch-ngp 也说明了在 PyTorch 的配套代码下,就算有 Hash Encoding,NeRF 的训练过程也要几分钟的时间(这是 PyTorch 的问题)。
从总贡献来说,Instant-NGP 一是贡献了 Hash Encoding,另一个则是贡献了基于 Occupancy Grid 的跳点策略。如果硬说的话,这一整套的 CUDA 配套代码应该也算,不过灵活性确实不太好。
Hash Encoding



到此,我们知道了 Hash Encoding 是什么,它做了件什么事情。但这时候有人会问,这不就是将空间规范化成网格,然后网格顶点存特征值嘛,为什么要用 Hash Table 呢,Hash Table 有什么好处呢。现在大家都知道如果用网格存特征,网格自然越密越好,也就是分辨率越高越好。但是网格的个数是分辨率的三次方,分辨率过高时则会极其消耗空间;同时物体的表面可以视作是二维空间嵌入三维空间的一个流形,仅占用很小一部分区域,这就意味着网格中的绝大部分区域是无效的。那有没有方式用较低的空间占用实现高分辨率的网格存储特征呢?Hash Encoding 就是其中一种答案。
正如前面所说,Hash Encoding 需要构建一个 Hash Function 从而建立每个网格顶点坐标到 Hash Table 的索引。而当我怎加网格分辨率时,会出现网格顶点的数量超过 Hash Table 的容量(超过列表长度)的情况,这个时候我们依旧可以建立这样的索引,只是会出现多个网格顶点对应 Hash Table 上同一个值的情况,这就是**哈希冲突 (Hash Collision)**。
但对于 Instant-NGP 来说无所谓,一方面正如上面所说,网格中的绝大部分区域是无效的,如果是无效区域的网格顶点和物体表面附近的网格顶点发生了冲突,那通过梯度反传,Hash Table 中的值(即特征)自然会更加关注物体表面区域,也就是Hash Table 中的特征主要是由物体表面附近的样本贡献的(或者说 Hash Table 的这个特征对恢复物体表面有显著作用),这很符合我们的要求;另一方面,Hash Encoding 是由多个 Hash Table 组成,因此总存在没有被哈希冲突严重影响的有效特征,而 Instant-NGP 后接的 MLP 有能力处理这个哈希冲突,提取正确的特征来恢复目标表征。
以上,我们就理清了 Hash Encoding 的实际操作,可以看到 Hash Encoding 想要解决的最直观的问题就是怎么利用更少的显存实现高分辨率的特征存储。而结合 MLP 以及梯度下降,Hash Encoding 可以自适应地关注有效区域,避免哈希冲突带来的负面影响。
Multiresolution Hash Encoding
那么我们还剩下最后一个问题,为什么要设置 Multi-Resolution。接下来是单纯我个人的分析,大家可以批判地看。回到我一开始对 NeRF 的 Position Encoding 的解读,我认为 Positional Encoding 是对欧式空间的三个轴分别引入了一组正交基函数,MLP 则用来预测这些个基函数的系数。我觉得这一套观点可以套进 Instant-NGP 或者下面会说到的 DVGO 这些个 Hybrid 方法中,它们网格存储的值可以视作是某种基函数在该点的离散采样。高分辨率等同于高采样率,这也就意味着高分辨率的网格可以存取高频基函数的离散点采样结果,相对的低分辨率的网格则存取低频基函数的离散点采样结果。只是相比于给定的一组正交基函数,这些个网格对应的基基本不会是正交的,但确实可以学习可以优化的,这就意味着 MLP 的学习负担被更进一步地降低,整个收敛过程也会更快。
Multi-Resolution 最重要的一点在于引入了合适的归纳偏置 (inductive bias) 来使得不同分辨率的网格能够捕获到相应频率的信息。不过就算没有 Multi-Resoution,网格也在学习过程中存取了不同频率的基函数的网格点采样值。我个人觉得这是一个很好理解 hybrid 方法的角度,希望各位同学可以多多交流。
DVGO[13]
DVGO 真的是时运不济碰上 Instant-NGP。从地位上来说,DVGO 应该是第一篇的 hybrid NeRF 的工作。
DVGO 有几点贡献:
用网格存取特征取代了 Encoding(我个人认为和 Instant-NGP 的 Hash Encoding 是一个性质的,具体分析见上文)。
采用一个网格直接存储了 density 信息,类似于 Mip-NeRF 360 中 Proposal MLP 的作用。
三线性插值后过一个 SoftPlus。
分了两个阶段训练。

Figure: Approach overview. We first review NeRF in Sec. 3. In Sec. 4, we present a novel post-activated density voxel grid to support sharp surface modeling in lower grid resolutions. In Sec. 5, we show our approach to the reconstruction of radiance field with super-fast convergence, where we first find a coarse geometry in Sec. 5.1 and then reconstruct the fine details and view-dependent effects in Sec. 5.2.
Coarse geometry searching

Fine Detail Reconstruction

Figure: Representing a ground-truth function (blue) in a 1D (a) and 2D (b) grid cell using the linear basis (yellow) and a ReLU Fields (pink). The reference has a c1-discontinuity inside the domain that a linear basis cannot capture. A ReLU Field will pick two values 1 and 2, such that their interpolation, after clamping will match the sharp c1-discontinuity in the ground-truth (blue) function.


只是两者的实现不太一样。NeuS 是通过一个可学习的标准差 s 来控制转换函数的带宽。一开始的带宽非常宽,利于学习到整体形状(低频信号),也便于优化。随着学习过程的深度,带宽越来越窄,越来越关注细节的优化(高频信号),Volume Rendering 越来越接近 Surface Rendering 的效果。另外本人更钟意 NeuS 的逻辑和推导,但我们老师却说 VolSDF 的推导更易懂,NeuS 的推导有些问题,可能我的火候还不太到家。
Volume Rendering vs Surface Rendering
NeuS 里面说明了为什么基于 Volume Rendering (NeuS, VolSDF) 的多视角神经隐式场重建相比基于 Surface Rendering (IDR) 的多视角神经隐式场重建要好的一个重要原因是:基于 Surface Rendering 的方法仅关注其与表面的交点部分,而基于 Volume Rendering 的方法的样本是光线上的很多采样点,所以后者能够更合理和全面地对隐式场进行监督。NeuS 给下图所示的例子,以此来说明基于 Volume Rendering 的方法对这种突变 (abrupt) 深度能实现更好的拟合。

Figure: (a) Illustration of the surface rendering and volume rendering. (b) A toy example of bamboo planter, where there are occlusions on the top of the planter. Compared to the state-of-the-art methods, our approach can handle the occlusions and achieve better reconstruction quality.
这里要补充的一点是当前的绝大多数神经隐式 SDF 的表面重建方法会先利用 [10] 提出的几何初始化使得初始的 SDF 表征一个类球形表面,也就是提供一个先验,降低拟合的难度。优化的过程可视作是对这个类球形表面施加变形,使之接近目标物体。而 NeuS 想表达的意思,个人认为是基于 Volume Rendering 能够是这个变形更"深入",因为它能够在当前表面的远处也产生监督,而 Surface Rendering 与之相比则极其容易陷入到当前表面附近的局部最优解。
SDF guided Volume Rendering



通过一系列推导就能得出:

#ConvNets
这里提出 FCMAE 的框架,这种自监督学习技术和架构改进的协同设计产生了一个 ConvNeXt V2 的新模型,它显著提高了纯 ConvNet 在各种识别基准上的性能
1 ConvNeXt V2:使用 MAE 协同设计和扩展 ConvNets
论文名称:ConvNeXt V2: Co-designing and Scaling ConvNets with Masked Autoencoders
论文地址:
https://arxiv.org/pdf/2301.00808.pdf
1.1 背景和动机
在前几十年的突破性研究的基础上,视觉识别领域迎来了大规模视觉表征学习的新时代。大规模预训练视觉模型已经成为表征学习和实现各种各样视觉应用的基本工具。关于视觉表征学习的性能,一般认为受到以下三个主要因素的影响:
使用的神经网络的结构
训练这个神经网络的方法
训练使用的数据
在视觉识别领域,以上三个子领域的进步都有助于模型整体性能的提高。
关于第一点:神经网络架构设计的创新, 一直在表征学习领域发挥着重要作用。卷积神经网络架构 (ConvNets) 对计算机视觉研究产生了重大影响,它通过卷积操作学习通用特征,适用于各种视觉识别任务。近年来,最初为自然语言处理开发的 Transformer 体系结构也很受欢迎,因为它在模型和数据集大小方面有很好的扩展性。
ConvNeXt[1]是视觉架构的范例,它使传统的卷积网络现代化,并证明纯卷积模型也可以是可扩展的体系结构。然而,探索神经网络架构设计空间的最常用方法仍然是通过对 ImageNet 上的监督学习性能进行基准测试。
关于第二点:训练这个神经网络的方法, 视觉表征学习的重点已经从带有标签的有监督学习转向自监督预训练。比如,MAE[2] 在视觉领域的掩蔽语言建模中取得了成功,并迅速成为一种流行的视觉表征学习方法。然而,自监督学习使用的模型架构往往是为有监督学习设置的架构,并假设这个架构是固定的。比如,MAE 使用 Vision Transformer 架构做实验。
因此,在本文中作者希望将架构的设计和自监督学习框架的设计结合起来,但是直接在 MAE 上使用 ConvNeXt 架构是有问题的。因为 MAE 的 Encoder-Decoder 设计是针对 Transformer 这样的序列信息处理能力强的模型设计的,compute-heavy encoder 可以专注于可见的 Patches,从而降低了预训练成本。这种设计可能与使用密集滑动窗口的标准 ConvNets 不兼容。所以,自监督学习的训练目标和架构之间的关系需要明确,否则就不清楚是否能实现最佳性能。经验证据表明,Transformer 和 ConvNet 可能具有不同的特征学习行为,这些行为可能会影响表征的质量。
为此,作者提出协同设计神经网络的架构和掩码自编码器,目的是使基于掩码的自监督学习对 ConvNeXt 模型有效,使得性能接近 Transformer 获得的结果。在设计掩码自编码器时,我们将掩码输入视为一组 Sparse Patches,并使用稀疏卷积仅处理可见部分。在实践中,可以使用稀疏卷积实现 ConvNeXt,并且在 Fine-tuning 时,权重被转换回标准的密集层,而不需要特殊处理。为了进一步提高预训练效率,作者在实现解码器时,也使用 ConvNeXt 块,使整个设计完全卷积化。
本文动机:
基于有监督训练的 ConvNeXt 性能卓越,受最近自监督方法 MAE 的启发,ConvNeXt 的性能还可能受益于 MAE。但是,直接结合这两种技术性能一般,因此本文提出 FCMAE 的框架,这种自监督学习技术和架构改进的协同设计产生了一个 ConvNeXt V2 的新模型,它显著提高了纯 ConvNet 在各种识别基准上的性能。
1.2 自监督学习方法 FCMAE 的初步设计

图1:自监督学习方法 FCMAE 流程
如上图1所示,自监督学习方法 FCMAE 概念上简单,并以完全卷积的方式运行。原始的输入信号被随机 mask,输入 Encoder,希望 Encoder + Decoder 的输出预测 mask 掉的部分。
作者使用 masking ratio 为0.6的随机掩码策略。由于卷积模型具有分层设计,其中特征在不同阶段进行下采样,掩码在最后阶段生成,并递归上采样直至最佳分辨率。作者从原始输入图像中随机去除 60% 的 32×32 Patches,数据增强只使用 Random resized cropping。
Encoder 设计
作者使用 ConvNeXt 作为 Encoder。但是这样做自然产生一个问题:MAE 的一个自然的挑战是防止模型学习到复制和粘贴信息的 shortcuts,因为这样得到的模型没有重建能力。当 Transformer 模型作为 Encoder 时,这个问题很好解决,只需要将可见的 Patches 作为编码器的唯一输入即可。但是当 ConvNets 模型作为 Encoder 时,这个问题不好解决了,因为必须保留二维的图像结构。之前的工作 BEiT,SimMIM 的做法是在输入端引入一些可学习的 masked tokens,这些方法降低了预训练的效率,并导致训练和测试时间不一致,因为在测试时没有 masked tokens。当 masking ratio 很高时,这尤其成问题。
为了解决这个问题,作者从 "稀疏数据的视角" 来观察 masked image,关键的观点是,masked image 可以表示为一个二维稀疏像素阵列。因此可以很自然地想到使用稀疏卷积,以促进 MAE 的训练。在预训练期间,将卷积替换为 submanifold sparse convolution,这使得模型只能在可见数据点上操作;在微调阶段,稀疏卷积层可以转换回标准卷积,而不需要额外的处理。
Decoder 设计
作者使用1个 ConvNeXt Block 作为 Decoder。这在总体上形成了非对称的 Encoder-Decoder 体系结构,因为 Encoder 更重,且具有分层架构。
Reconstruction target 设计
遵循 MAE 的做法,使用重建目标和真值之间的 Mean Squared Error, MSE Loss,作为 Reconstruction target。损失函数仅应用于 masked patches。
作者分别使用 ImageNet-1K (IN1K) 数据集进行800和100个 Epoch 的预训练和微调。
为了理解 FCMAE 框架中使用稀疏卷积的影响,作者首先研究它在掩码图像预训练期间如何影响表征学习的质量。实证研究结果表明,为了达到良好的效果,防止信息泄漏是至关重要的。

图2:使用稀疏卷积的影响
接下来,作者将 FCMAE 与监督学习进行比较。如下图3所示,实验结果如下。有监督训练 100 Epochs 精度是82.7%,有监督训练 300 Epochs 精度是83.8%,FCMAE 进行 800和100个 Epoch 的预训练和微调结果是 83.7%。说明 FCMAE 预训练提供了比随机基线更好的初始化 (82.7→83.7),但它仍然不如在原始监督训练的最佳性能。

图3:FCMAE 与监督学习进行比较
1.3 自监督学习方法 FCMAE 的进一步优化
至此,自监督学习方法 FCMAE 实现了接近有监督学习的性能,但是这与 Transformer + 自监督训练的性能远超有监督训练的结果形成了对比。因此,作者接下来探索自监督学习方法 FCMAE 的进一步优化。
1.3.1 Feature collapse现象
作者首先提出一种新的标准化技术:Global Response Normalization,使 FCMAE 预训练与 ConvNeXt 架构结合起来更加有效。作者首先观察到一种 Feature collapse 现象。如下图4所示,作者可视化了一个 FCMAE 预训练的 ConvNeXt-Base 模型的激活,并注意到一个 Feature collapse 现象,即:有许多死的或饱和的特征映射,激活在通道之间变得多余。这一现象主要在一个 ConvNeXt 块中的 MLP 的 channel expansion 层中观察到。

图4:Feature collapse 现象
1.3.2 特征余弦距离分析

这个距离值越大,特征的多样性越强。反之,距离值越小,特征的冗余性越强。 为了进行分析,作者从 ImageNet-1K 验证集中的不同类别中随机选择1000张图像,并从不同模型的每一层中提取高维特征,包括 FCMAE模型、有监督训练的 ConvNeXt 模型和 MAE 预训练的 ViT 模型。然后计算每个图像的每层距离,并对所有图像的值求平均值。 结果如下图5所示,FCMAE 预训练的 ConvNeXt 模型表现出明显的特征崩溃趋势,与作者从之前的激活可视化中观察到的一致,这促使作者考虑在学习过程中使特征多样化并防止特征崩溃的方法。

图5:特征余弦距离分析
1.3.3 全局响应归一化
缓解特征坍塌的方法,其实就是要增加神经元的多样性。在人类大脑中,有许多促进神经元多样性的机制。
例如,横向抑制 (lateral inhibition[3][4]) 可以帮助增强被激活神经元的反应,增加单个神经元对刺激的对比度和选择性,同时还可以增加整个神经元群体的反应多样性。

图6:全局特征聚合消融实验

GRN 与其他归一化策略的消融实验结果如下图8所示。

图8:GRN 与其他归一化策略的消融实验结果
可以观察到,只有 GRN 可以显著优于监督基线模型。LRN 缺乏全局背景,因为它只对比附近邻居的 channel。BN 沿 Batch 轴在空间上归一化,不适合掩码输入。LN 通过全局均值和方差标准化隐含地鼓励特征竞争,但不像 GRN那样有效。
GRN 与其他 feature gating 的消融实验结果如下图9所示。GRN 类似于一种 feature gating 的方法,作者对比了它和 SE 模块[6],和 CBAM 方法[7]。SE 模块侧重于给 channel 维度的 gating,CBAM 方法侧重于给 spatial 维度的 gating。与它们相比,GRN 更简单,更有效,因为它不需要额外的参数层 (如 MLP)。

图9:GRN 与其他 feature gating 的消融实验结果
最后,作者研究了 GRN 在预训练和微调中的重要性。如下图10所示,从微调中删除 GRN,或者只在微调时添加新初始化的 GRN。无论哪种方式都会观察到显著的性能下降,这表明 GRN 在预训练和微调中的重要性。

图10:GRN 在预训练和微调中的重要性
1.3.4 ConvNeXt V2
ConvNeXt V2 和 ConvNeXt V1 的对比如下图11所示。与 ConvNeXt V1 相比,V2 丢弃了 Layer Scale,并使用了 GRN。从图4的可视化和图5的余弦距离分析中,可以观察到 ConvNeXt V2 有效地缓解了特征崩溃问题。余弦距离值始终较高,表明特征多样性在各层之间保持不变。可视化结果类似于 MAE 预训练的 ViT 模型。

图11:ConvNeXt V2 和 ConvNeXt V1 的对比
如下图12所示为 FCMAE 和 ConvNeXt V2 配合与监督学习进行比较的实验结果,FCMAE 预训练模型可以显著优于300 Epochs 有监督训练的 ConvNeXt 模型。GRN 通过增强特征多样性来提高表征学习的质量。

图12:FCMAE 和 ConvNeXt V2 配合与监督学习进行比较
1.4 实验结果
ImageNet 实验结果
本节展示 FCMAE 预训练框架下的 ConvNeXt V2 架构的实验结果,作者展示了这些设计很好地协同作用。联合设计的作用如下图13所示。
可以发现,在不修改模型架构的情况下,使用 FCMAE 框架对表示学习质量的影响有限。类似地,在监督训练的设置下,GRN 层对性能的影响相当小。然而,两者的结合在微调性能上有显著的改善。这说明模型的架构和学习框架应该一起设计,尤其是在涉及到自监督学习的时候。

图13:架构和训练策略协同设计的重要性
模型的扩展性
ConvNeXt V2 从小到大的模型架构依次是:
Atto (3.7M),Femto (5.2M),Pico (9.1M),Nano (15.6M),Tiny (28M),Base (89M),Large (198M),Huge (659M)
ConvNeXt V2-A: C=40, B=(2, 2, 6, 2)
ConvNeXt V2-F: C=48, B=(2, 2, 6, 2)
ConvNeXt V2-P: C=64, B=(2, 2, 6, 2)
ConvNeXt V2-N: C=80, B=(2, 2, 8, 2)
ConvNeXt V2-T: C=96, B=(3, 3, 9, 3)
ConvNeXt V2-B: C=128, B=(3, 3, 27, 3)
ConvNeXt V2-L: C=192, B=(3, 3, 27, 3)
ConvNeXt V2-H: C=352, B=(3, 3, 27, 3)
与其他自监督方法比较
作者将 FCMAE + ConvNeXt V2 与之前的 MIM 进行了比较,这些方法都是为基于 ViT 的模型设计的。如下图14所示,在所有模型尺寸上都优于用 SimMIM 预训练的 Swin Transformer。但不如使用 MAE 预训练的普通 ViT 模型。

图14:FCMAE 与其他自监督方法的比较
ImageNet-22K intermediate fine-tuning 实验结果
实验包含3步:FCMAE 预训练,ImageNet-22K 微调,ImageNet-1K 微调。 使用 384×384 分辨率的图像进行预训练和微调。结果如图15所示,本文方法使用基于卷积的架构,仅使用公开可用的数据实现了高于 Transformer 模型的精度。

图15:ImageNet-22K intermediate fine-tuning 实验结果
COCO 目标检测和实例分割实验结果
数据集:COCO,模型 Mask R-CNN。实验结果如下图16所示。可以看到,当模型架构从 V1 变为 V2,以及加入 GRN 之后,性能都有提升。在此基础上,当从有监督学习的预训练模型过渡到基于 FCMAE 的自监督学习预训练模型之后,模型性能得到了进一步的提升。

图16:COCO 目标检测和实例分割实验结果
ADE20K 语义分割实验结果
数据集:ADE20K,模型 UperNet。实验结果如下图17所示。结果呈现出与目标检测实验相似的趋势,并且最终模型比 ConvNeXt V1 的模型表现出显著改进,并且性能与 Swin transformer 模型接近。

图17:ADE20K 语义分割实验结果
总结
基于有监督训练的 ConvNeXt 性能卓越,受最近自监督方法 MAE 的启发,ConvNeXt 的性能还可能受益于 MAE。但是,直接结合这两种技术性能一般,因此本文提出 FCMAE 的框架,这种自监督学习技术和架构改进的协同设计产生了一个 ConvNeXt V2 的新模型,它显著提高了纯 ConvNet 在各种识别基准上的性能,使之接近 Transformer 相关的模型。
#Conv2Former ~2
还是来说Conv2Former~~ 上次发了一次~~
一种卷积调制模块,利用卷积来建立关系,这比注意力机制在处理高分辨率图像时更高效,称为 Conv2Former。作者在 ImageNet 分类、目标检测和语义分割方面的实验也表明,Conv2Former 比以前基于 CNN 的模型和大多数基于 Transformer 的模型表现得更好。
Conv2Former:Transformer 风格的卷积网络视觉基线模型
论文名称:Conv2Former: A Simple Transformer-Style ConvNet for Visual Recognition
论文地址:https://arxiv.org/pdf/2211.11943.pdf
以 VGGNet、Inception 系列和 ResNet 系列为代表的 2010-2020 年代的卷积神经网络 (ConvNets) 在多种视觉任务中取得了巨大的进展,它们的共同特点是顺序堆叠多个基本模块 (Basic Building Block),并采用金字塔结构 (pyramid network architecture),但是却忽略了显式建模全局上下文信息的重要性。SENet 模块系列模型突破了传统的 CNN 设计思路,将注意力机制引入到 CNN 中以捕获远程依赖,获得了更好的性能。
自从 2020 年以来,视觉 Transformer (ViTs) 进一步促进了视觉识别模型的发展,在 ImageNet 图像分类和下游任务上表现出比最先进的 ConvNets 更好的结果。这是因为与只进行局部建模的卷积操作相比,Transformer 中的自注意力机制能够对全局的成对依赖进行建模,提供了一种更有效的空间信息编码方法。然而,在处理高分辨率图像时,自注意力机制导致的计算成本是相当大的。
为了解决这个问题,一些 2022 年经典的工作试图回答:如何借助卷积操作,打造具有 Transformer 风格的卷积网络视觉基线模型?
比如 ConvNeXt[1]:将标准 ResNet 架构现代化,并使用与 Transformer 相似的设计和训练策略,ConvNeXt 可以比一些 Transformer 表现得更好。 从原理和代码详解FAIR去年的惊艳之作:全新的纯卷积模型ConvNeXt 再比如 HorNet[2]:通过建模高阶的相互作用,使得纯卷积模型可以做到像 Transformer 一样的二阶甚至更高的相互作用。 精度超越ConvNeXt的新CNN!HorNet:通过递归门控卷积实现高效高阶的空间信息交互 再比如 RepLKNet[3],SLaK[4]:通过 31×31 或者 51×51 的超大 Kernel 的卷积,使得纯卷积模型可以建模更远的距离。 又对ConvNets下手了!详解SLaK:从稀疏性的角度将卷积核扩展到 51×51 到目前为止,如何更有效地利用卷积来构建强大的 ConvNet 体系结构仍然是一个热门的研究课题。
卷积调制模块


ConvNeXt 表明,将 ConvNets 的核大小从3扩大到7可以提高分类性能。然而,进一步增加 Kernel 的大小几乎不会带来性能上的提升,反而会在没有重新参数化的情况下增加计算负担。但作者认为,使 ConvNeXt 从大于 7×7的 Kernel Size 中获益很少的原因是使用空间卷积的方式。对于 Conv2Former,当 Kernel Size 从 5×5 增加到 21×21 时,可以观察到一致的性能提升。这种现象不仅发生在 Conv2Former-T (82.8→83.4) 上,也发生在参数为80M+ 的 Conv2Former-B (84.1→84.5) 上。考虑到模型效率,默认的 Kernel Size 大小可以设置为 11×11。

权重策略的优化: 注意这里作者直接将深度卷积的输出作为权重,对线性投影后的特征进行调制。Hadamard 积之前既没有使用激活层,也没有使用归一化层 (例如 Sigmoid 或 LN 层),如果像 SE 模块那样加一个 Sigmoid 函数,会使性能降低 0.5% 以上。
Conv2Former 整体架构
如下图3所示,与ConvNeXt 和 Swin Transformer 相似,作者的 Conv2Former 也采用了金字塔架构。总共有4个 Stage,每个 Stage 的特征分辨率依次递减。根据模型大小尺寸,一共设计了5个变体:Conv2Former-N,Conv2Former-T, Conv2Former-S, Conv2Former-B,Conv2Former-L。

当可学习参数数量固定时,如何安排网络的宽度和深度对模型性能有影响。原始的 ResNet-50 将每个 Stage 的块数设置为 (3,4,6,3)。ConvNeXt-T 按照 Swin-T 的模式将 Block 数之比更改为 (3,3,9,3),并对较大的模型将 Block 数之比更改为 (1,1,9,1)。Conv2Former 的设置如下图4所示。可以观察到,对于一个小模型 (参数小于30M),更深的网络表现更好。

实验结果
ImageNet-1K 实验分为两种,一种是直接在 ImageNet-1K 上面训练和验证,另一种是先在 ImageNet-22K 上预训练,再在 ImageNet-1K 上微调和验证。
ImageNet-1K 实验设置
数据集:ImageNet-1K 训练 300 Epochs,ImageNet-1K 验证。

ImageNet-22K 实验设置
数据集:ImageNet-22K 预训练 90 Epochs,ImageNet-1K 微调 30 Epochs,ImageNet-1K 验证。
如下图5所示是 ImageNet-1K 实验结果。对于小型模型 (< 30M),与 ConvNeXt-T 和 Swin-T 相比,Conv2Former 分别有 1.1% 和 1.7% 的性能提升。即使 Conv2Former-N 只有 15M 参数和 2.2G FLOPs,其性能也与具有 28M 参数和 4.5G FLOPs 的 SwinT-T 相同。对于其他流行的模型,Conv2Former 也比类似模型尺寸的模型表现更好。Conv2Former-B 甚至比 EfficientNetB7 表现得更好 (84.4% vs . 84.3%),后者的计算量是 Conv2Former 的两倍 (37G vs. 15G)。

图5:ImageNet-1K 实验结果
如下图6所示是 ImageNet-22K 的实验结果。作者遵循 ConvNeXt 中使用的设置来训练和微调模型。与 ConvNeXt 的不同变体相比,当模型尺寸相似时,Conv2Former 都表现得更好。此外,我们可以看到,当在更大的分辨率384×384 上进行微调时,Conv2Former-L 获得了比混合模型 (如 CoAtNet 和 MOAT) 更好的结果,Conv2Former-L 达到了 87.7% 的最佳结果。

图6:ImageNet-22K 实验结果
如下图8所示是关于卷积核大小的消融实验结果。在 大小增加到 21 × 21 之前,性能增益似乎已经饱和。这个结果与 ConvNeXt 得出的结论截然不同,ConvNeXt 得出的结论是,使用大于 7×7 的 Kernel 不会带来明显的性能提升。

图7:onv2Former 对于大卷积核的泛化效果很好
消融实验1:卷积核大小
如下图8所示是关于卷积核大小的消融实验结果。在 Kernel Size 增加到 21 × 21 之前,性能增益已经饱和。这个结果与 ConvNeXt 得出的结论截然不同,ConvNeXt 得出的结论是,使用大于 7×7 的 Kernel Size 不会带来明显的性能提升。这表明 Conv2Former 的做法能比传统方式更有效地利用大 Kernel 的优势。

图8:卷积核大小,融合策略的消融实验结果
消融实验2:不同融合策略的影响

直筒架构实验结果
遵循 ConvNeXt 的做法,作者也训练了 Conv2Former 的直筒架构 (Isotropic Models) 版本,结果如下图9所示。作者将 Conv2Former-IS 和 Conv2Former-IB 的块数设置为18,并调整通道数以匹配模型大小。字母 "I" 表示直筒架构,可以看到,对于 22M 参数左右的小型模型,Conv2Former-IS 比 DeiT-S 的表现要好得多。当将模型尺寸放大到 80M+ 时,Conv2Former-IB 达到了 82.7% 的 Top-1 Accuracy,这也比 ConvNeXt-IB 高 0.7%,比 DeiT-B 高0.9%。

图9:直筒架构实验结果
目标检测实验结果
如下图10所示是不同骨干网络,以 Mask R-CNN 为检测头和 Cascade Mask R-CNN 为实例分割头在 COCO 数据集的实验结果。训练策略遵循 ConvNeXt。对于小模型,使用 Mask R-CNN 框架时,Conv2Former-T 比 SwinT-T 和 ConvNeXt-T 获得了约 2% AP 的改进。

图10:目标检测实验结果
语义分割实验结果
如下图11所示是不同骨干网络,以 UperNet 为分割头在 ADE20k 上的实验结果。对于不同尺度的模型,我们的Conv2Former可以优于Swin Transformer和ConvNeXt。

总结
本文试图回答:如何借助卷积操作,打造具有 Transformer 风格的卷积网络视觉基线模型。本文提出一种卷积调制模块,利用卷积来建立关系,这比注意力机制在处理高分辨率图像时更高效。最终的模型称为 Conv2Former,它通过只使用卷积和 Hadamard 积,简化了注意力机制。卷积调制操作是一种利用大核卷积的更有效的方法。作者在 ImageNet 分类、目标检测和语义分割方面的实验也表明,Conv2Former 比以前基于 CNN 的模型和大多数基于 Transformer 的模型表现得更好。
#Conv2Former
又发现了一个说比Transformer好的,通过充分利用卷积探索一种更高效的编码空域特征的方式:通过组合ConvNet与ViT的设计理念,本文利用卷积调制操作对自注意力进行了简化,进而构建了一种新的ConvNet架构Conv2Former超简Transformer风格ConvNet,比ConvNeXt还秀,媲美VAN

通过充分利用卷积探索一种更高效的编码空域特征的方式:通过组合ConvNet与ViT的设计理念,本文利用卷积调制操作对自注意力进行了简化,进而构建了一种新的ConvNet架构Conv2Former。ImageNet分类、COCO检测以及ADE20K分割任务上的实验结果表明:所提Conv2Former取得了优于主流ConvNet(如ConvNeXt)、ViT(如Swin Transformer)的性能。

核心模块

上图给出了经典模块的架构示意图,从经典的残差模块到自注意力模块,再到新一代卷积模块。自注意力模块可以表示为如下形式:

class ConvMod(nn.Module):
def __init__(self, dim):
super().__init__()
self.norm = LayerNorm(dim, eps=1e-6, data_format='channel_first')
self.a = nn.Sequential(
nn.Conv2d(dim, dim, 1),
nn.GELU(),
nn.Conv2d(dim, dim, 11, padding=5, groups=dim)
)
self.v = nn.Conv2d(dim, dim, 1)
self.proj = nn.Conv2d(dim, dim, 1)
def forward(self, x):
B, C, H, W = x.shape
x = self.norm(x)
a = self.a(x)
v = self.v(x)
x = a * v
x = self.proj(x)
return x
微观设计理念

Normalization and Activations 对于规范化层,作者参考ViT与ConvNeXt采用了Layer Normalization,而非卷积网络中常用的Batch Normalization;对于激活层,作者采用了GELU(作者发现,LN+GELU组合可以带来0.1%-0.2%的性能提升)。
本文实验

上述两表给出了ImageNet分类任务上不同方案的性能对比,从中可以看到:
- 在tiny-size(<30M)方面,相比ConvNeXt-T与SwinT-T,Conv2Former-T分别取得了1.1%与1.7%的性能提升。值得称道的是,Conv2Former-N仅需15M参数量+2.2GFLOPs取得了与SwinT-T(28M参数量+4.5GFLOPs)相当的性能。
- 在base-size方面,相比ConvNeXt-B与SwinT-B,Conv2Former-B仍取得了0.6%与0.9%的性能提升。
- 相比其他主流模型,在相近大小下,所提Conv2Former同样表现更优。值得一提的是,相比EfficientNet-B7,Conv2Former-B精度稍有(84.4% vs 84.3%),但计算量大幅减少(15G vs 37G)。
- 当采用ImageNet-22K预训练后,Conv2Former的性能可以进一步提升,同时仍比其他方案更优。Conv2Former-L甚至取得了87.7% 的优异指标。


上表给出了COCO检测任务上不同方案的性能对比,从中可以看到:
- 在tiny-size方面,相比SwinT-T与ConvNeXt-T,Conv2Former-T取得了2% 的检测指标提升,实例分割指标提升同样超过1%;
- 当采用Cascade Mask R-CNN框架时,Conv2Former仍具有超1%的性能提升。
- 当进一步增大模型时,性能优势则变得更为明显;

上表给出了ADE20K分割任务上的性能对比,从中可以看到:
- 在不同尺度模型下,Conv2Former均具有比SwinT与ConvNeXt更优的性能;
- 相比ConvNeXt,在tiny尺寸方面性能提升1.3%mIoU,在base尺寸方面性能提升1.1%;
- 当进一步提升模型尺寸,Conv2Former-L取得了54.3%mIoU,明显优于Swin-L与ConvNeXt-L。
一点疑惑解析
到这里,关于Conv2Former的介绍也就结束了。但是,心里仍有一点疑惑存在:Conv2Former与VAN的区别到底是什么呢?。

结合作者开源代码,笔者绘制了上图,左图为Conv2Former核心模块,右图为VAN核心模块。两者差别还是比较明显的!
- 虽然大核卷积注意力均是其核心,但Conv2Former延续了自注意力的设计范式,大核卷积注意力是其核心;而VAN则是采用传统Bottleneck设计范式 ,大核卷积注意力的作用类似于SE。
- 从大核卷积内在机理来看,Conv2Former仅考虑了的空域建模,而VAN则同时考虑了空域与通道两个维度;
- 在规范化层方面,Conv2Former采用了Transformer一贯的LayerNorm ,而VAN则采用了CNN一贯的BatchNorm;
- 值得一提的是:两者在大核卷积注意力方面均未使用Sigmoid激活函数。两者均发现:使用Sigmoid激活会导致0.2%左右的性能下降。

为更好对比Conv2Former与VAN的性能,特汇总上表(注:GFLOPs列仅汇总了)在Image输入时的计算量Net-1K上的指标进行了对比,可以看到:在同等参数量前提下,两者基本相当,差别仅在0.1%。此外,考虑到作者所提到的"LN+GELU的组合可以带来0.1%-0.2%的性能提升",两者就算是打成平手了吧,哈哈。
#ViT-4
这也写了3个了 ,本次是 mobile vit~~~
轻量级模型架构 继承ConvNet和Transformer优点的位置敏感的循环卷积 力压苹果Mobile
论文地址:https://arxiv.org/abs/2203.03952
代码地址:https://github.com/hkzhang91/ParC-Net
最近,vision transformers开始显示出令人印象深刻的结果,显着优于基于大型卷积的模型。然而,在移动或资源受限设备的小型模型领域,ConvNet在性能和模型复杂度方面仍然具有自己的优势。研究者提出了ParC-Net,这是一种纯基于ConvNet的骨干模型,通过将vision transformers的优点融合到ConvNet 中,进一步增强了这些优势。

ConvNet与ViT模型图像分类实验结果对比
具体来说,研究者提出了位置感知循环卷积(ParC),这是一种轻量级的卷积运算,它拥有全局感受野,同时产生与局部卷积一样的位置敏感特征。将ParCs和squeeze-exictation ops结合起来形成一个类似于元模型的模型块,它还具有类似于transformers的注意力机制。上述块可以即插即用的方式使用,以替换ConvNets或transformers中的相关块。
实验结果表明,在常见的视觉任务和数据集中,所提出的ParC-Net比流行的轻量级ConvNets和基于vision transformers的模型具有更好的性能,同时具有更少的参数和更快的推理速度。对于ImageNet-1k上的分类,ParC-Net在大约500万个参数的情况下实现了78.6%的top-1准确率 ,节省了11%的参数和13%的计算成本,但准确率提高了0.2%,推理速度提高了23%(基于ARM的Rockchip RK3288)与MobileViT相比,仅使用0.5倍的参数,但与DeIT相比获得了2.7%的准确度。在MS-COCO目标检测和PASCAL VOC分割任务上,ParC-Net也表现出更好的性能。
然而,我们认为ViTs和ConvNets都是不可或缺的,原因如下:
1)从应用的角度来看,ViTs和ConvNets都有其优点和缺点。ViT模型通常具有更好的性能,但通常计算成本高且难以训练。与ViTs相比,ConvNets可能表现出较差的性能,但它们仍然具有一些独特的优势。例如,ConvNets具有更好的硬件支持并且易于训练。此外,正如[Jianyuan Guo, Kai Han, Han Wu, Chang Xu, Yehui Tang, Chunjing Xu, and Yunhe Wang. Cmt: Convolutional neural networks meet vision transformers.]和研究者的实验中总结的那样,ConvNets在移动或边缘设备的小型模型领域仍然占主导地位。
2)从信息处理的角度来看,ViTs和ConvNets都具有独特的特征。ViT擅长提取全局信息,并使用注意力机制从输入数据驱动的不同位置提取信息。ConvNets专注于对局部关系进行建模,并且通过归纳偏置具有很强的先验性。上述分析自然提出了一个问题:我们能否向ViT学习以改进用于移动或边缘计算应用的ConvNet?
ViT论文:https://arxiv.org/abs/2010.11929
ConvNeXt论文:https://arxiv.org/abs/2201.03545
新框架
研究者们取ViT的三个亮点,将纯卷积结构变强。研究者认为,ViT和ConvNet有三个主要区别:ViT更擅长提取全局特征,采用meta-former结构,而且信息集成由数据驱动。ParC的设计思路便是从这三点着手来优化ConvNet。

普通ConvNet和ViT之间的三个主要区别。a)ConvNet常用的Residual block;b)ViT中常用的Meta-Former 结构;c)研究者提出的ParC block。
具体而言,研究人员设计了一种位置信息敏感的循环卷积(Position aware circular convolution, ParC)。这是一种简单有效的轻量卷积运算算子,既拥有像ViT类结构的全局感受野,同时产生了像局部卷积那样的位置敏感特征,能克服依赖自注意力结构提取全局特征的问题。

水平方向的全局循环卷积
可以看到ParC-H沿着通过连接输入的开始和结束生成的圆执行卷积。因此,研究者将提出的卷积命名为循环卷积。提议的ParC引入了三个修改:
- 结合circular padding和大感受野低秩分解卷积核提取全局特征;
- 引入位置嵌入,保证输出特征对于空间位置信息的敏感性;
- 动态插值实时生成尺寸适配的卷积核和位置编码,应对输入分辨率变化情况,这增强了对不同尺寸输入的适应能力。
研究者还将ParC和squeeze exictation结合起来,构建了一个纯卷积结构的meta former结构。该结构舍弃了自注意力硬件支持不友好的操作,但保留了传统Transformer块提取全局特征的特点。研究者还在channel mixer部分引入硬件支持较友好的通道注意力机制,使其纯卷积meta former结构也具备自注意力的特点。
基于ParC结构最终得到的ParC块,可作为一个即插即用的基础单元,替换现有ViT或ConvNet模型中的相关块,从而提升精度,并降低计算成本,有效克服硬件支持的问题。

三种主要的混合结构。(a) serial structure; (b) parallel structure; (c) bifurcate structure。
实验分析

在图像分类实验中,对于ImageNet-1k的分类,ParC-Net使用的参数规模最小(约500万个参数),却实现了最高准确率78.6%。

MobileViT是Apple2022年在国际深度学习顶会ICLR22上提出的轻量级通用ViT模型。同样部署在基于Arm的瑞芯微RK3288芯片上,相较基线模型MobileViT,ParC-Net节省了11%的参数和13%的计算成本,同时准确率提高了0.2%,推理速度提高了23%。

MS-COCO物体检测实验结果

PASCAL VOC分割任务实验结果

研究者将ParC-Net和基线模型MobileVit均部署到自研低功耗芯片DP上进行推理速度测试。从实验结果可以看到,ParC-Net的推理速度能够达到MobileViT速度的3~4倍。
#强化学习之路 | PPO算法的37个实现细节
说明
最近强化学习的风又有点吹起来了,作为曾经的RL从业者,开始翻一些以前的经典资料,温故而知新。这篇复习的是22年的经典博文,细致研究了ppo的一些实现细节,对我当时实现 ppo 给于很大帮助。
iclr-blog-track.github.io/2022/03/25/ppo-implementation-details/
注意
- 以前的rl都集中在序列决策问题上,即怎么最大化累计收益的期望,所以背景大都是游戏和控制相关,例如Atari game, Mujoco等, 与当前(2025年3月)rl在llm中的热度方向不一致。
- 原博文内容也集中以解决"游戏决策"为背景,同时以算法实现细节为基础。
- 本文会根据原博内容进行酌情增减
正文
原文主要目的是:复现官方的PPO实现,在github开源代码中,最终对比选择了 openai 的 baselines\ppo2 作为复现参考。原因如下:
- ppo2 算法在 Atari 和 MuJoCo 的任务上都表现不错
- 包含了LSTM和处理多维离线空间(MultiDiscrete)的一些高级处理,能处理 RTS 游戏(实施策略游戏,例如星际争霸、王者荣耀这种)
ppo 原论文提出了2个算法实现,ppo1 是动态缩放kl,而 ppo2 算法是直接clip,更简单好用。所以 ppo2 才是现在大家更熟知的 ppo 算法实现,以下都默认为 ppo2 算法实现
13个关键实现细节
-
矢量化架构
envs = VecEnv(num_envs=N)
agent = Agent()
next_obs = envs.reset()
next_done = [0, 0, ..., 0] # of length N
for update in range(1, total_timesteps // (N*M)):
data = []
# ROLLOUT PHASE
for step in range(0, M):
obs = next_obs
done = next_done
action, other_stuff = agent.get_action(obs)
next_obs, reward, next_done, info = envs.step(
action
) # step in N environments
data.append([obs, action, reward, done, other_stuff]) # store data# LEARNING PHASE agent.learn(data, next_obs, next_done) # `len(data) = N*M`
- 使用多进程,串行或并行的初始化一个矢量化的环境 envs ,包含了 N 个独立环境。训练时同时获得 N 个 obs ,执行 N 个action,最后获得 N 个 next_obs。其中 next_done 代表各个环境里每一步有没有done。
- 这里面有2个循环
- Rollout phase:每个环境里的 agent 执行 M 步收集数据。
- Learning phase:从上面收集好的数据里学习更新网络参数,数据规模是 N*M 。
矢量化环境的优势很明显:1、并发收集数据更快,学习更快。2、各环境独立保证数据多样性,学习更稳。
这种并发是基操,但困难也很明显:1、很吃cpu,尤其是动作空间或状态空间很大的游戏,而一些重的env有时候很难并发。2、learner的消费可能跟不上生产导致数据浪费,所以要实验配比。
需要理解 next_obs 和 next_done 的角色:done代表是否结束,比如游戏结束或者被截断了。当环境done后,next_obs就是下一个阶段的第一个观测 。这样即使一个episode只执行 M 步,但 ppo 依然能在没法停止或阶段的环境里学习。
上面这个最开始没看懂,后来才理解这个 reset 可能是 env 里面的"原地"reset。
这个不太符合一些游戏设定,因为大部分 reset 是直接回到 env 的"起点",比如王者荣耀ai,在纯粹的游戏设立里,ai done后肯定是回到老家水晶,而不是在原地复活继续 battle。
但为了实现类似功能,一般都会让 ai 自由出生,或者从 env 的某个中间状态 reset(比如半血在中路位置复活),而不是完整受限于游戏进程,这样能减少训练的探索成本。
一个比较普遍的错误实现如下。错误有两处:1、单个env效率很低。2、对于RTS游戏(一个简单epsiode至少1M step)内存不够(相比上面,在采样相同step的数据而言)。
env = Env()
agent = Agent()
for episode in range(1, num_episodes):
next_obs = env.reset()
data = []
for step in range(1, max_episode_horizon):
obs = next_obs
action, other_stuff = agent.get_action(obs)
next_obs, reward, done, info = env.step(action)
data.append([obs, action, reward, done, other_stuff]) # store data
if done:
break
agent.learn(data)
关于 N 和 M 的取值经验:在相同的 N*M 数据需求下,并不是 N 越大越好,相反 M 太小会导致探索太短。因为"shortened experience chunks"和"earlier value bootstrapping."
关于上面说的错误实现,和前面"正确实现"的主要区别在于:done后要不要break。前面的实现是一直走M步,但如果中间某步done=True了,后面全部的done都是True,这样在计算V值时只会计算单步的reward,序列决策的反馈就没有,数据学习效率不高。
不过反过来想,前面的实现或许默认了"done后的step依然生效"这一逻辑,不用管done的值来中断epsiode,代码结构上更统一。
更细节是,平时自己写是 data.append([obs, action, reward, next_obs]),即存储一个完整的 state transition。这样能避免上面的问题,但问题是多存了个next_obs对 mem 不友好。
矢量化的环境天然支持 MARL (多智能体强化学习),兼容性更强。比如1个环境下初始化 N 个player,这样 M 步的数据量就变成了**在同一环境下 N 个 player 执行得到的所有数据。**
- 网络的权重正交初始化、偏差常数初始化
- 源码实现如下:

Atari - CNN

Mujoco-MLP

policy_net \ value_net的不同初始化值
上面CNN、MLP里的正交初始化和 pytroch 自带的 api 实现不太一致,但对性能没什么影响。有一些证据证明orthogonal 相比 Xavier 要好一些。
- Adam 优化器的epsilon参数值
ppo 实现里面的值是 1e-5 ,这和 pytorch (1e-8) 和tf里(1e-7)都不一样,为了保证可复现性保持一致。
- Adam 学习率退火
Atari 的 lr 是从 2.5e-4 随着 step 线性衰减到0,Mujoco 任务里是从 3e-4 线性衰减到 0
- GAE
gae 的提出要晚于 ppo 算法,但它现在是个默认实现,在 gamma 取特殊值时(0 和 1),gae 等效 td 和 mc。而且有证据表现:gae 要比 N-step 的 returns 要好(更好的 trade off 近视和远视)。
- Mini-batch 更新
- 对于上面的N*M 数据,一般会先把数据 shuffle,然后用一个小的 batch_size 分批计算梯度更新网络。
- 一些错误实现:1、直接用全部数据计算,而不是分mini batch_size,2、随机选择 mini-batchs而不是全部学习。
这个 mini batch size 是一个比较重要的参数,在训练初期需要微调来平衡效果和性能。
这个原理其实好理解,首先 N*M 数据总量通常是比较大的,比如 N=20,M=2048 等,不可能全部直接计算梯度去更新网络,所以需要min batch size的概念。
其次,ppo 是 on-policy 算法,学习完的数据只能丢弃重新收集,最好能充分利用数据,所以 mini batchs 能让 ppo "小步快跑"的充分学习,并通过 clip 的方式保证稳定性。
最后,一般数据都是序列收集的,时序关联太强,shuffle 后再 mini batch 对学习更友好
- advantages 归一化
gae 计算完后建议归一化,就是简单的减去均值除以方差。注意是在 mini_batch 里做而不是针对整个数据。
因为是对 mini_batch 计算梯度来更新,所以得在 mini_batch 里用。不过这一细节影响不大。
- clipped surrogate objective
ppo 论文核心细节,有些任务里直接的 cliped 和 trpo 算法最后效果是一样的,但优势在 ppo 实现比 trpo 更简单
- value loss clipping
对 v_net 的 loss 也进行 clipping,不过一些研究表明这个作用不大。注意这里是用 t-1和 t 时刻做对比,下面是不同数值clip 的结果:


value loss clip
这个 value clipp 以前没用过,对于为什么取 max也没很理解。
从上面表格能看出,只有当 v_t 相比 v_t-1 超过 eps 更靠近 v_tar 时,这个 clip 才会实际生效。这个 max操作变相的增加了原来的 loss。
10.entropy loss
原文里为了增加策略随机性,把 policy 的 entropy 也加入 loss 计算,也是常规细节之一。
loss = policy_loss - entropy * entropy_coefficient + value_loss * value_coefficient
- global gradient clipping
把全局参数的 l2_norm 截断到 0.5 内
- debug变量
ppo 实现里有很多用于 debug 的变量,除了上面 3 个 loss,还有以下几个:
- clipfrac: 训练数据里触发 clipped 的比例
- approxkl: 新旧策略的近似 kl 散度,计算上直接用 -logratio.mean() 。关于 kl 散度近似计算可以看这个博文
这两个参数更多是初步调参时需要注意的,尤其用于代码 debug,如果 clipfrac 太多说明策略更新太快,通常是有 bug
- policy_net 和 value_net 网络是否共用 backbone
- ppo 默认实现是共享网络结构,然后分别出 policy_head 和 value_head.
- 原博实现了网络分开实现的代码,最后实测效果明显比 shared 的更好
是否共用 backbone 是 RL 一个常见问题,共用的好处是,节省算力减少开销、共享特征信息。劣势也明显,两个loss 的梯度目标可能并不一致。不过在业务上好像都习惯采用 shared 方式,网络结构影响比想象要小。
9个Atari实现细节
atari游戏实现相关的一些 trick细节,摘取了一些有参考意义的。
- NoopResetEnv:在reset的时候随机进行一定数量的noop操作【0-30】,目的是使游戏开始时的初始状态具有一定的变动。
- MaxAndSkipEnv:默认跳 4 帧执行,4 帧内执行重复动作,收集 4 帧累计的 reward 作为实际 reward,能加速模型收敛,毕竟有时候 env.step 要比 policy_net(state) 计算更快。并且状态选择最后 2 帧的最大值pixel,应对 atari 像素游戏里的怪物特征闪烁(游戏里的闪烁动效)。
- EpisodicLifeEnv:有些游戏里角色有多条命,只有命数到 0 时游戏才结束,这里包装成只要命数-1就算 done。不过其他论文说这个对最终表现有害 。
- FireResetEnv:有些游戏可能需要固定按键作为开始,这里就修改成 reset 后执行action-1 和action-2再继续游戏。不过这个细节好像并没啥作用而且没法追溯设计动机?
- WarpFrame:把 rgb 图像灰度化,然后 resize(210x160 -> 84x84)
- ClipRewardEnv:根据 reward 的正负全部映射到 {+1, 0, -1},这样就能一起学不同的游戏,但这样也会影响模型在具体游戏里一些细致化操作。
- FrameStack:叠帧,默认叠 4 帧,这样能感知移动物体的速度和朝向。
- policy_net 和 vlaue_net 共用网络的 backbone
- pixel 值归一化,除以 255。
9个连续动作空间实现细节 [Mujoco]
- 基于正态分布的连续动作:pg 类算法从正态分布中采样来得到连续性动作 ,所以网络任务就是预测分布的均值和标准差,通常使用"高斯分布"。
- 与状态无关的对数标准差:网络输出均值的logits,而对于标准差输出 log std,初始化为0且和状态无关。
- 独立的动作组合:在很多机器人任务中有不同维度的动作输出,比如向左移动 3.5m和向上运动 4.2m,输出是[,],为了可微,ppo把它们视为概率独立的分布,所以计算动作的概率就是多个动作概率相乘:prob() = prob()* prob().
- 这种设定假设各个维度的动作是完全独立,满足全协方差的高斯分布,但有些任务里面动作之间是耦合,所以也有文章研究非独立的动作选择问题(例如用自回归的策略),这是个开放性问题。
- 分开实现的 policy_net 和 value_net
- 对于连续控制问题,ppo 通常的网络设计是 64 hidden MLP,中间用 tanh 作为激活函数,后面再接两个 head.
和前面讨论的细节一样,实验证明把网络 backbone 分离设计最后效果要更好
- 处理动作越界问题
既然动作是从分布采样得到,必然会遇到越界问题,比如动作范围是 [-10,10],结果采用得到 +12。在实际执行时需要把动作截断在合法范围内,但存储原始动作来计算梯度更新网络。
- 有些研究会在分布采样后面加个可逆压缩函数(如tanh),这样就能兼容动作合法问题。一些研究证明这种方式更好。
- 观测归一化:数据在喂给网络前会对观测值 obs 进行动态归一化,减去 running_mean 再除以 running_std .
注意这里是 moving average normalization
-
观测截断:对 obs归一化后再截断在一个固定区间内,比如代码里是 [-10, 10] 之间。对于obs区间很大的环境会有帮助。
-
奖励缩放:就是计算折扣后再动态归一化
def step_wait(self):
obs, rews, news, infos = self.venv.step_wait()
self.ret = self.ret * self.gamma + rews
obs = self._obfilt(obs)
if self.ret_rms:
self.ret_rms.update(self.ret)
rews = np.clip(rews / np.sqrt(self.ret_rms.var + self.epsilon), -self.cliprew, self.cliprew)
self.ret[news] = 0.
return obs, rews, news, infos -
奖励截断:同前。但是目前对 reward 的 scaling 和 clipping 是否有效没有确凿证据。
5 个 LSTM实现细节
- 权重和偏置初始化为 std=1 和 0。
- hidden & cell 都初始化为 0
- 在 epsiode结尾 reset LSTM的 state
- 使用时序连续的训练数据喂给网络,不能和之前一样 shuffle
- Reconstruct LSTM states during training
MultiDiscrete动作空间细节
基于前面的多维动作空间独立的设定,alphastar和 openai five 都使用 MultiDiscrete 来建模动作空间,例如 openai five 就用了 MultiDiscrete([ 30, 4, 189, 81 ] 。所以最后的动作空间维度是:30 × 4 × 189 × 81 = 1, 837, 080 dimensions
4个辅助实现系列
官方 ppo 没有实现,但是在某些场景下可能有用的 4 个 trick
-
clip range 退火:比如从 0.2 逐渐退火到 0
-
并行梯度更新:多进程并行计算梯度,这样能利用所有可用进程来缩短训练时间。
-
策略优化提前终止:在 actor的 mini batch 中,spinning up 里会在 kl 散度大于阈值后提前结束,而不是跑完固定的 epoch 数。代码里面是 target_kl 默认是 0.01,阈值是 1.5 * 0.01。
-
非法动作 mask:openai five 和 alphastar都用了大量的非法动作 mask,具体实现上就是在 softmax 之前,用规则把invalid_action的 logits 修改成 -inf。 这个论文 证明这种mask 实际是把 invalid action 的梯度置零
logits = torch.where(self.masks, logits, torch.tensor(-1e8).to(device))
invalid_action_mask 是非常常见且有效的 trick,但是mask一般是人为规则写的,会损失策略的一部分探索性
结论建议
一些有用的 debug 方法:
- seed anything:在复现时候可以观察 obs 和 act,对齐各类数值,确保实现没有问题
- 检查 ratio =1:在第一个 epoch 和第一个 mini-batch 更新期间,检查 ratio是否为 1,此时新旧策略相同所以 ratio应该一直是1
- 检查 KL散度:approx_kl 通常应该保持在 0.02 以下,如果过高说明策略更新太快,通常是有 bug
- 检查其他指标:policy loss \ value loss 这些指标,如果是复现代码,检查和官方的是否相近
- 经验法则:检查 ppo算法在 breakout 游戏里能否拿到 400 分,作者发现大部分 ppo实现仓库都没法得到,说明有细节没有对齐。
对于 ppo 研究者的一些建议
- 枚举使用的实现细节。考虑用本文这种方式来列举他们
- 发布源码。开源代码并确保能运行,建议用 poetry 和 pipenv 来管理锁定依赖。很多pip install -e .的代码仓库都没法直接跑。用 docker 管理装好依赖的镜像也是个好办法
- 管理实验。跟踪管理指标、超参数、代码和其他东西,会节省大量时间。商业软件如:Weights and Biases、Neptune, 开源项目:Aim,ClearML,Polyaxon.
- 单文件实现。如果研究需要很多调整,建议有单个文件实现他们,这么做代价是代码重复和难重构。但好处是:1. 更容易总揽全局,直接看到所有算法细节,再去看结构化的 rl仓库就更轻松;2、开发更快;3、更方便性能归因,直接查看文件 diff就行。
异步ppo更好吗?
Asynchronous PPO (APPO)能够增加吞吐量,消除ppo里面等待环境交互采样的空闲时间,提高吞吐量和 gpu、cpu利用率。但 这篇论文 论证了对性能有损害,不过最大的问题是:没有稳定可靠的 appo benchmark 实现。
相反,使用更快的矢量化环境来加速 ppo 更靠谱点,用 envpool 做了对比,发现能比之前快 3 倍。在 pong 上的表现甚至能和 impala 对比。
所以引出一个现实考虑:使异步的 rl 算法例如 impala,还不如想办法让并行环境运行更快。
一些其他研究
- 其他选择:对连续动作使用其他分布,lstm 不同初始化等等
- 值函数优化:ppg 探索了 pi_net 和 v_net更新频率,能否在 ppo里用prioritized experience replay?