赞
踩
transformer网络结构如下图所示:
ViT中用到的只有TRM中的编码端
现在的问题就是,vision 中输入的是图片,但是 TRM 是用来处理自然语言的,那么要怎么把图片融入到 TRM 的 Encoder 中呢?也就是,图片要怎么处理,才可以当作 TRM 的输入?
最简单的方式,就是把图片转化成 NLP 中一个一个的 token,那么怎么转化呢?
这个问题是它会随着图片的长宽成平方级增长(图片是 h
×
\times
× w 的嘛)。
如何处理复杂度问题?:本质上是去解决随着像素增加,复杂度平方级增长的问题。
有很多种改进方式:
但是上面的方式还是太麻烦,所以一个简单的改进方式:图像化整为零,切分 patch 。
也就是说,原来是一个像素点代表一个 token,现在是一大块的 patch 作为一个 token。
以下就是 ViT 的网络结构:
好了,步骤就是这么些步骤了,有问题吗?没有问题。
那么问题来了。第二步中,patch 怎么转化成 token embedding 的???
其实第二步又分为两个小步骤:
重点来咯!
这里 256 映射到 728 用的是 linear 线性层做映射。其实也可以使用一个 16
×
\times
× 16,步长是 16 的卷积来操作这个,只要把卷积核的个数设置为 728,那么输出的维度就是 728。
想象一下(还是假设一个 patch 是 16 × \times × 16)。线性变化是 (256—>728),用卷积操作的话也是 (256—>728),因为一个 patch 是 16 × \times × 16,卷积核大小也是 16 × \times × 16,卷出来就是 1 个数,那么有 728 个卷积核,就是 728 个数了。就相当于把 256 映射到 728 了呗。
(ViT在说的是它不需要使用卷积操作,所以用的是 linear,其实这里用卷积是可以的)
好了,重点又来了!
其中的第三个步骤,又要分为几个小步骤,第三个步骤图拿下来:
第三步又可以分为三个小步骤(看图看图看图,注意 * 号 和 0 那一块,不是从第二步来的哦!):
为什么要加入一个 CLS 符号?
原文中表述如下:
In order to stay as close as possible to the original Transformer model, we made use of an additional [class] token, which is taken as image representation.
简单的意思就是减少对原始 TRM 模型的更改。(不是很懂,好像 BERT 有提到)(后面实验好像表明了,加 CLS 还是不加,效果都是差不多的)
为什么需要位置编码?
transformer 中讲过了。对应到图像中,就是告诉模型,哪个 patch 是在前面的,哪个 patch 是在后面的
使用的一维位置编码,因为二维跟相对的都比较复杂,一维也没有差很多,所以使用的是一维位置编码。
ViT 中使用的 Encoder 其实和原始 TRM 中的 Encoder 是不太一样的,ViT中的 Encoder 如下图所示:
这边,如果输入的图像大小是不一样的,可以采用 resize 的方法弄到一样,所以序列的长度会是一样的,也就没有使用 pad 符号了。(没有 pad 符号在实现的时候就很简单了,同时 SoftMax 的时候,不就不需要对 pad 的部分额外操作了吗,就简单了很多)
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。