一、课程导论:为什么要在MobileViT中使用自注意力机制?
1.1 从CNN到Transformer:我踩过的坑
做计算机视觉的朋友都知道,CNN统治这个领域快十年了。我自己从2016年开始做图像分类,那时候ResNet就是神一样的存在。但有个问题一直困扰我——感受野太小。
你想想看,一个3×3的卷积核,一次只能看到周围9个像素。想看到全局?那就得堆几十层。我当年训练一个152层的ResNet,显存直接爆了。后来我就在想:有没有一种机制,能让模型一眼看到全局?
这时候,自注意力机制出现了。它最早在NLP领域大杀四方,比如BERT、这些。我一开始觉得「这玩意儿跟CV有啥关系?」直到我读到ViT(Vision Transformer)那篇——原来图像也能切成patch,然后用自注意力做全局建模。
核心矛盾:CNN擅长局部特征提取,但全局依赖需要深层堆叠;自注意力天生全局,但计算量是O(n²),图像像素太多根本扛不住。
1.2 MobileViT的诞生背景:轻量级模型的困境
移动端模型,比如MobileNet、ShuffleNet,它们用深度可分离卷积把参数量压得很低。但我在实际项目中遇到过一个问题:在图像分割任务上,轻量CNN的精度总是上不去。
为什么?因为分割需要像素级的上下文理解。比如你要区分「路」和「人行道」,只看局部纹理是不够的,你得知道整条路的走向。CNN的局部性在这里成了短板。
那直接把ViT搬过来行不行?不行。ViT的参数量动辄上亿,手机根本跑不动。我记得有一次尝试在手机上部署ViT,推理一张图要3秒,直接被产品经理怼回来了。
所以MobileViT的思路很直接:把CNN的轻量高效,和Transformer的全局建模,结合起来。说白了就是——用CNN做局部特征提取,用自注意力做全局信息融合。
| 模型 | 优势 | 劣势 |
|---|---|---|
| CNN(MobileNet) | 计算量小,适合移动端 | 感受野有限,全局建模弱 |
| Transformer(ViT) | 全局自注意力,精度高 | 计算量大,不适合移动端 |
| MobileViT | 两者兼顾,轻量+全局 | 结构稍复杂,训练需技巧 |
1.3 核心思想:局部-全局-局部
MobileViT的核心流程,我总结成三个词:局部编码 → 全局交互 → 局部融合。
具体来说:
- 第一步:用标准卷积提取局部特征。这一步跟MobileNet一样,轻量快速。
- 第二步:把特征图切成一个个小patch,每个patch内部做自注意力。注意,这里不是对整个图做注意力,而是对每个patch内部做。这样计算量就从O(n²)降到了O(p²),其中p是patch大小。
- 第三步:把注意力处理后的特征重新拼回特征图,再用卷积做局部融合。
嗯,这里要注意:patch的大小是关键。我刚开始调参时,patch设成2×2,效果跟纯CNN差不多;设成8×8,计算量又上去了。后来发现4×4是个不错的平衡点。
我的经验:MobileViT的patch大小建议从4×4开始调。如果任务对细节要求高(比如分割),可以试试2×2;如果对速度要求高,可以试试8×8。
1.4 知识体系总览:一张图看懂
下面这张图,是我自己画的MobileViT知识体系。你可以把它当作整个课程的地图。
1.5 为什么自注意力在MobileViT中有效?
我刚开始也怀疑:在轻量模型里加自注意力,会不会得不偿失?后来做了几组对比实验,发现确实有效。原因有三:
- 弥补CNN的视野缺陷。CNN堆到20层,有效感受野也只有理论值的一小部分。自注意力一步到位,直接看到全局。
- 参数效率高。自注意力的参数量主要来自QKV投影,跟特征图大小无关。对于小模型来说,这个开销可以接受。
- 适合多尺度。MobileViT的patch机制天然支持多尺度特征。我在做分割任务时,不同patch大小能捕捉不同尺度的目标。
避坑指南:我曾经在训练MobileViT时,直接把学习率设成跟CNN一样,结果loss震荡得很厉害。后来发现,自注意力模块需要更小的学习率(建议1e-4起步),并且要用warmup。这个细节后面会详细讲。
1.6 本章小结
说白了,MobileViT就是用CNN的骨架,加上Transformer的灵魂。它解决了轻量模型「看得近」的问题,又没引入太多计算量。
我个人觉得,这个思路在未来几年会越来越重要。毕竟移动端设备越来越强,用户对精度的要求也越来越高。你不能总拿「手机算力不够」当借口——MobileViT给出了一个很漂亮的答案。
下一章,我们会从CNN的基础开始,把深度可分离卷积讲透。这是理解MobileViT的基石,别跳过。