作者:Ta-Ying Cheng,牛津大学博士研究生,Medium技术博主,多篇文章均被平台官方刊物Towards Data Science收录
图源:Unsplash
目前卷积神经网络(CNN)已经成为了在计算机视觉和图像相关任务中深度网络的主要技术支柱。因其与传统的多层感知器(MLP)相比,在二维邻域感知和平移同变性方面具有显著优势。然而,最近在自然语言处理领域刮起了一阵新趋势,越来越多的人开始用Transformer来取代循环神经网络(RNN),而这也让CV从业者对Transformer的潜力感到非常好奇。
不久前的ICLR 2021*刚好就有一篇论文探讨了Transformer在CV领域的应用前景,并率先提出了“视觉Transformer”的概念,与基于卷积的模型形成鲜明对比。
本文将带大家深入探讨Transformer的概念,特别是视觉Transformer及其与卷积的比较。我们还将简单介绍如何在PyTorch上训练Transformer。
*注:国际学习表征会议(ICLR)是世界顶级的深度学习会议。
卷积网络有什么优势?
为什么卷积网络在计算机视觉领域如此受欢迎?答案就在于卷积的固有性质。卷积核能够将图片内临近像素的特征聚集在一起,使模型能够在学习过程中将这些特征统筹起来。此外,当我们在图像中移动卷积核时,核经过任何地方都能将矩阵内的特征用于分类(称为平移同变性,translation equivariance)。因此,卷积网络无需考虑特征在图像中的位置就能提取特征,在过去几年中让图像分类任务出现了重大进展。
但既然卷积网络已经如此强大,我们为什么还需要Transformer呢?
自然语言处理中的Transformer
图 1. Transformer中的尺度变换点乘注意力机制和多头注意力机制. 源: https://arxiv.org/abs/1706.03762.
Transformer首先在自然语言处理领域提出,论文为“Attention Is All You Need”(《你只是需要有点注意力而已》)。传统的NLP方法(如RNNs和LSTMs)在计算任何预测时都会考虑到短语内附近的词。然而,由于每次出现新的输入时算法都需要考虑到之前已经出现的所有输入,因此模型的预测速度并不算快。
Transformer则利用了“注意力”这一概念。“注意力”某种程度上其实就是矢量词之间的相关性,模型利用这种相关性来计算出最终的预测结果。由于一个词与其他词的相关性独立于其他词之间的相关性,模型得以对所有词进行同时计算。由此,Transformer进一步优化了深度网络的计算逻辑。通过同时考虑所有的词及其相关性,其实际性能明显优于传统的递归方法。
此外,Transformer还加入了“多头注意力”(multi-headed attention)机制,可以多次并行运行注意力机制,并将分离的向量串联成最终的输出结果。
视觉领域的注意力转向
图 2. 视觉Transformer的Pipeline. 图像被切分为块,并被压平以模仿序列的结构. 源: https://arxiv.org/abs/2010.11929.
既然Transformer能让自然语言处理更上一层楼,一个自然的想法即是把这种进步带到像计算机视觉这样的领域中去。我们找到了一篇关于视觉Transformer(ViT)的论文。ViT将图像划分为一个个的块(patch),并将这些块转换为向量(embedding),然后放到序列当中(模拟NLP中的向量)找到彼此之间的相关性。
上手试验
在本节中,我们将亲手试验已经充分预训练过的的视觉Transformer,并在各种数据集上测试其能力。值得注意的是,ViT的原始论文做过大量研究,发现ViT只有在预训练的数据集达到非常大的规模时才会胜过卷积网络。因此,如果你手头上的算力相当有限,效果可能并不会非常显著。
数据集
为了能够充分试验ViT的能力和适用性,我们需要用多个不同的数据集进行测试。格物钛开放数据集平台免费提供了CV领域众多著名数据集,不仅下载速度非常快,还能直接使用格物钛提供的SDK集成到自己的代码中,加速数据获取和模型迭代。
在PyTorch中使用ViT
前面已经提到过,ViT需要规模极大的数据集才能训练出优秀的特征提取效果来,因此训练过程非常困难。不过,现在GitHub上已经有很多repo提供已经搭建和训练好的ViT模型。为了能够快速见识到ViT的力量,我们将使用lucidrains提供的模型。
首先我们需要在pip中安装vit-pytorch:
pip install vit-pytorch
一定要确保Pytorch和Torchvision的版本已是最新。
""" Import the necessary libraries """ import torch from vit_pytorch import ViT
导入了我们需要的库之后,我们可以用如下代码创建一个ViT:
""" Create a visual transformer, declaring the number of classes, image size, etc. Make sure that image_size is divisible by patch_size. """ v = ViT( image_size = 256, patch_size = 32, num_classes = 1000, dim = 1024, depth = 6, heads = 16, mlp_dim = 2048, dropout = 0.1, emb_dropout = 0.1 )
如果仅仅需要用ViT来进行推理(inference),使用以下代码即可:
""" Feed in the image as a standard image model of size (batch, 3, image_size, image_size) The output will be in the dimension of (batch_size, num_classes) """ preds = v(img)
如果你真的很想尝试自己去进一步训练ViT,可以参考这篇文章中介绍的方法,通过“蒸馏”(distillation)来进行训练,减少所需的数据量。前述的vit-pytorch仓库里即有提及相关代码。
结果
图 2. ViT在多个大型数据集上的结果. 源: https://arxiv.org/abs/2010.11929.
ViT的原始论文已经可以让我们看到,ViT的性能可以非常突出,但前提是一定要用非常大型的数据集进行预训练,且预训练所需要的算力之多也是极为惊人。
结语
近年来,计算机视觉领域一直在不断改进Transformer,使其能够更加适应图像处理乃至三维点云任务的需要。最近的ICCV 2021亦出现了如云Transformer和Swin Transformer(会议最佳论文奖得主)这样的优秀文章,表明注意力机制已然成为图像处理的新趋势。
更多信息请访问格物钛官网