反思:CNN和ViT,到底谁更快

文摘   科技   2024-08-20 18:30   福建  
思源Source报道
编辑:seefun
在Vision Transformer流行的这几年,出现了很多常见的误区。比如大家都认为CNN相比于ViT,更适合scale到更大的输入分辨率,但事实并非如此。在Lucas Beyer老哥(ViT作者)的这篇博客介绍到,由于attention kernel已经被各种优化得非常完善了,使得经典ViT模型也能像 CNN一样很好地扩大输入分辨率,甚至效果更好,尤其是显存消耗上。另一个常见误区是,使用ViT必须用正方形或和预训练模型一样的固定的图像输入大小。然而,只需使用支持动态输入大小的ViT实现,如timm或transformers库就可以实现灵活的输入分辨率。(点击"阅读原文"获取原始blog)


概述

计算机视觉现在主要有两种基础网络架构:卷积神经网络(CNN)和视觉transformer(ViT)。CNN通过在图像上滑动其特征提取器(一系列卷积层)来获得最终的低分辨率特征图,进而完成特定任务。与此相对,ViT从一开始就将图像划分为小块,并通过自注意力机制对这些小块进行处理,生成同样低分辨率的最终特征图。

人们常说,由于 O(N**2) 复杂度的自注意力,ViT在高分辨率下并不实用。例如CNN的领军人物Yann LeCun就曾表达过这种担忧:

但是,我认为这种批评是一种未经深思熟虑导致的误区。在实践中,ViT至少可以很好地扩展到1024x1024像素,这足以满足绝大多数图像编码器的使用场景。

在本文中,我将阐述两个主要观点:

  1. ViT能够轻松扩展至至少1024x1024像素的分辨率

  2. 对于绝大多数应用场景而言,此分辨率已经完全足够。


ViTs 在分辨率扩展上的卓越表现

我首先着手对标准ViT和CNN在当前一系列GPU上的推理速度进行量化分析。为了使这次基准测试具有更广泛的适用性,我选择了PyTorch而在一些常见的GPU上执行测试。我采用了timm库中的标准视觉模型,并遵循PyTorch的最佳实践,通过torch.compile来优化性能。我还对数据类型(float32, float16, bfloat16)、注意力机制的实现方式(sdpa_kernel)以及矩阵乘法的精度(set_float32_matmul_precision)进行了全面测试,并为每次测量选取了最佳配置。


在对这些测量结果进行初步审视之后,我相信我们能够达成共识:

  1. ViT在分辨率扩展方面表现出色,至少能够轻松应对1024像素的图像。

  2. 在许多情况下,ViT的运算速度超过了同等规模的CNN,特别是在新一代的GPU上表现更为突出。

  3. 浮点运算次数(FLOPs)并不直接等同于处理速度,这一点在我的论文 [2110.12894] The Efficiency Misnomer 中有所讨论

  4. ViT在开箱即用的状态下内存效率更高。例如,在GTX3070显卡上,它是唯一能够处理超过512像素图像的模型。

  5. 但还有更令人振奋的消息:我们在ViT的原始论文中就已经展示了这些优势。我们在业界率先成功扩展了ResNets: [1912.11370] Big Transfer (BiT): General Visual Representation Learning,并且对于内存限制问题有着深刻的理解。因此,我在附录中特别加入了这一图表,以展示我们的观点和成果。


你真的需要那么高的分辨率吗

我的第二个观点是,人们往往过分关注分辨率、纵横比等细节

我保守地认为,图像可以被拉伸成正方形,并且:

  • 对于自然图像,即大多数照片,224x224像素已经足够

  • 对于照片中的文字、手机屏幕、图表和图形,448x448像素已经足够

  • 对于桌面屏幕和单页文档,896x896像素已经足够 

原文有resize的demo,可以直观理解我们到底需要多大分辨率

http://lucasb.eyer.be/articles/vit_cnn_speed.html

各种resize算法的区别

思源Source,公众号:思源数据科学模型部署精度对不齐?图像Resize暗藏大陷阱!

更高分辨率的存在主要是为了满足人类的审美需求和避免视觉疲劳。然而,计算机视觉模型不受视觉疲劳影响,也不追求美学上的完美。至少在目前,AI尚未具备自我意识。

当然,医学和卫星图像或多页文档等特殊情况除外。我认为这些图像可以被分割成上述尺寸的片段,可能还会结合一些全局特征。尽管我在这些领域并非专家。

最关键的是,始终要像你的模型一样审视你的数据。如果你能够通过仔细观察解决任务,那么你的模型同样能够做到。

分辨率与算力:一个常被忽视的权衡

在讨论分辨率时,人们往往忽略了一个关键点:提升分辨率同样会大幅增加模型的容量。容量是一个不太明确的概念,但普遍认为它是一个由模型规模(以参数计,与分辨率无关)和模型的计算需求(FLOPs)混合而成的指标,而后者会随着分辨率的提升而显著增长。

自2019年的FixRes和BiT以来,提高分辨率以增强性能已成为一种普遍做法。然而,直到2024年的PaliGemma报告,才有人(即作者本人,Lucas Beyer)明确地区分了这两个因素。在该报告中,我们进行了一项实验,比较了在224和448分辨率下的计算性能,并且特别考察了一种先resize到224分辨率,然后再将其缩放至448大小的设置。这种设置虽然使用了448分辨率的计算资源(FLOPs),但保留了224分辨率的原始信息量。因此,这种设置相较于224分辨率设置的任何性能提升,都可以归因于模型容量的增加。

正如我们所见,448分辨率性能提高的很大一部分(但不是全部)来自模型容量的增加。例如,ChartQA结果的改善几乎完全归因于容量的增加,而不是分辨率的提高。


题外话:局部注意力机制

在讨论分辨率和算力的同时,还有一个简单而精妙的机制可以使高分辨率的ViTs更加迅速且内存效率更高:局部注意力。局部注意力机制将图像或特征图划分为不重叠的窗口,每个标记仅在其所属窗口内与其他标记交互。实质上,这相当于将窗口移动到局部注意力操作的批次维度。

UViT和ViTDet论文首次提出了这一概念,并推荐在高分辨率ViT的大多数层中采用局部注意力,只在少数几层中使用全局注意力。更进一步,ViTDet建议通过将预训练时的分辨率设置为窗口大小,将原本在低分辨率(例如224x224)下预训练的ViTs升级至高分辨率。这种ViTDet风格的局部注意力已被Segment Anything(SAM)系列研究成功采纳。

这种方法几乎不会影响模型的性能,同时保持了简洁、优雅和高度兼容性。值得注意的是,我尚未发现对于CNNs有同样简单而有效的替代方案。局部注意力和标记丢弃是ViT简洁性带来的创新思维,这些在CNNs中实现起来将非常复杂。

现在,请回到基准测试图表,重新审视你之前可能忽视的(ViTDet)选项。你会发现,即使在1024x1024像素的分辨率下,采用ViTDet的模型速度也超越了ConvNeXt



最终思考

上述讨论对训练过程同样具有价值。根据我训练这些模型的经验,ViTs在训练过程中同样展现出了更高的内存效率。

速度和可扩展性之外,我们还应考虑不同架构的通用性。近期的文献中有若干观点明确指出,某些方法更适合ViTs而非CNNs,例如"MoCo v3 and SimCLR are more favorable for ViT-B than R50", "This property emerges only when using DINO with ViT architectures, and does not appear with other existing self-supervised methods nor with a ResNet-50"。此外,从Masked AutoEncodersc中衍生出的标记丢弃概念,也仅在具有非重叠补丁的纯ViT架构中可行。在CLIP风格的图像-文本训练中,无论是原始的CLIP论文还是我的未发表实验,都显示出使用ViT编码器相比其他卷积编码器有更优的性能,尽管我们尚未完全理解背后的原因。值得注意的是,这些观点中有两个来自Kaiming He,即ResNets的创造者。

我对架构本身没有特别的偏好,ViT恰好符合我的大多数使用场景。我唯一坚持的是避免无根据的观点,并在发现错误时予以指正。

点击👇关注 “思源数据科学”

👇点个“赞”和“在看”吧

思源数据科学
Towards AGI
 最新文章