Transformer之Token的通俗理解

编码解码

有哪些编码解码

基于Transformer的模型,衍生出三大流派:

第一个是Encoder-Only,以Bert为代表的模型,对语言进行双向预测(即同时能预测上文和下文),使用了对输入进行mask遮罩的Masked Language Model(MLM)和双语句输入判断是否连续Next Sentence Prediction(NSP),由于其主要是针对文本分类和问答类任务,所以Encoder的能力至关重要第二个是Decoder-Only,以GPT为代表的模型,目标是通过自回归预测,给定一个条件文本,学习其语言模式、语义和顺序,达到生成连续语言的目的,其任务本质更关注于预测输出,所以对Decoder的能力要求更高第三个是Encoder-Decoder,大家常用的模型,在图像中更为常见

虽然由Encoder-Only和Decoder-Only,但是其实其模型中还是包含编码或者解码器的

为什么编码解码?

要解释为什么编码和解码,首先要搞明白编码和解码中的码是什么码。 在人类语言中,有如下特征

人类语言是一种符号,即利用一种符号表达语义,例如:"笑脸"就是☺,“雨伞”就是☂人类语言还是一种上下强相关的连续符号的表达,即用多个符号表达出物质和运动的信息

这些语言除了统计学规律,是不具备任何数学计算的能力的,所以,需要利用一定的映射方法,将其映射为数学语言,比如:数字或者矩阵。在计算机中,对这个符号的表达是Token,给Token分配ID(将其数字化或者矩阵化)的映射过程叫做Tokenizer,然后就可以利用距离等Measurement计算Token之间的关联度。

如何编码?

1. 标记编码

将Token映射到一个一维空间上,一个token和一个数字一一对应

优点:方便快捷缺点:所有编码都在一个维度上,分布过于稠密,很难在数学上计算其高维度的距离(各种相似度,每个角度的相似度所占有的维度高度和维度数目是不同的)

2. one-hot编码

one-hot编码,就是一个

1

×

n

1 \times n

1×n的矩阵,其中只包含一个

1

1

1,其余都是

0

0

0,这就意味着,任意两个Token之间都是正交的。

优点:在样本不是很大的时候,简单便于计算(欧式空间的计算相对简单)缺点:由于每个样本都是正交的,对于复杂相似度计算不友好(例如:苹果和小米,其除了都是植物,还都是品牌);且当样本巨大时,存储压力将会非常大(维度灾难),因为语义信息是利用维度表达的

3. 空间变换

0

0

0

1

1

×

n

×

a

1

,

1

a

1

,

2

a

1

,

m

1

a

1

,

m

a

2

,

1

a

2

,

2

a

2

,

m

1

a

2

,

m

a

n

1

,

1

a

n

1

,

2

a

n

1

,

m

1

a

n

1

,

m

a

n

,

1

a

n

,

2

a

n

,

m

1

a

n

,

m

n

×

m

=

b

1

b

2

b

m

1

b

m

\Bigg| \begin{matrix} 0 & 0 & \cdots & 0 & 1 \\ \end{matrix} \Bigg|_{1\times n} \times \left| \begin{matrix} a_{1,1} & a_{1,2} & \cdots & a_{1,m-1} & a_{1, m} \\ a_{2,1} & a_{2,2} & \cdots & a_{2,m-1} & a_{2, m} \\ \vdots & \vdots & \cdots & \vdots & \vdots \\ a_{n-1,1} & a_{n-1,2} & \cdots & a_{n-1,m-1} & a_{n-1, m} \\ a_{n,1} & a_{n,2} & \cdots & a_{n,m-1} & a_{n, m} \end{matrix} \right|_{n \times m}= \Bigg| \begin{matrix} b_1 & b_2 & \cdots & b_{m-1} & b_{m} \end{matrix} \Bigg|

​0​0​⋯​0​1​

​1×n​×

​a1,1​a2,1​⋮an−1,1​an,1​​a1,2​a2,2​⋮an−1,2​an,2​​⋯⋯⋯⋯⋯​a1,m−1​a2,m−1​⋮an−1,m−1​an,m−1​​a1,m​a2,m​⋮an−1,m​an,m​​

​n×m​=

​b1​​b2​​⋯​bm−1​​bm​​

其他的编码方式很多,核心思想就是空间变换,也就是矩阵变换,如公式所示,将

n

n

n维度的词向量降维到

m

m

m维度。 也就是将one-hot为

0

0

0的维度填充,然后刨除部分维度,实现降维,使得编码结果对语义的信息表达不仅限于维度,还可以通过维度的长度表达。 “黑色向量”和“灰色向量”代表不同的词向量,而“橘色向量”代表两个词向量之间的相似度,这样的好处从图中就可以看出来

极大降低了词向量的维度,非常有利于缓解维度灾难词向量之间的多维度相似度可以充分表达

总结一下,就是把单词之类的语言,从one-hot形式的高维表达,通过矩阵变换实现降维,这个过程称作嵌入(Embedding),让词向量的表达维度更饱满且不会有浪费维度

Word2Vec

首先解释为什么不能用Encoder-Decoder的模型(原因和GAN是相同的),因为输入和输出是相同的,模型在训练中会什么都不做,导致模型崩溃,这样根本无法解析出词向量。 而word2vec实际上是一种对海量文本的统计关系的表达,是一种客观的向量。

CBOW和Skip-Gram为什么没有激活层:

其核心都是做向量的空间变化(几何角度看)或者是向量求和与向量分解,这里面没有非线性的需要。

那么只做向量求和与向量分解,为什么不用数学公式直接算?

如果说梯度反向传播的计算复杂度是

O

(

n

)

\mathop{O}(n)

O(n),那么求矩阵的逆(设计分解,需要求逆)的计算复杂度就是

O

(

n

3

)

\mathop{O}(n^3 )

O(n3)

CBOW

其核心思想就是利用上文和下文预测中间这个词

w

o

r

d

i

\mathop{word_i}\limits^{\longrightarrow}

wordi​⟶​。

详细如图,CBOW就是将一个要寻找的词向量

w

o

r

d

i

\mathop{word_i}\limits^{\longrightarrow}

wordi​⟶​的前后各两个词汇

w

o

r

d

i

2

\mathop{word_{i-2}}\limits^{\longrightarrow}

wordi−2​⟶​、

w

o

r

d

i

1

\mathop{word_{i-1}}\limits^{\longrightarrow}

wordi−1​⟶​和

w

o

r

d

i

+

1

\mathop{word_{i+1}}\limits^{\longrightarrow}

wordi+1​⟶​、

w

o

r

d

i

+

2

\mathop{word_{i+2}}\limits^{\longrightarrow}

wordi+2​⟶​作为训练数据送入网络训练,将结果进行求和,可以得到一个预测向量

w

o

r

d

p

r

e

d

\mathop{word_{pred}}\limits^{\longrightarrow}

wordpred​⟶​,就可以和

w

o

r

d

i

\mathop{word_i}\limits^{\longrightarrow}

wordi​⟶​这个标签计算损失

l

o

s

s

loss

loss,保证了输入和输出之间的差异,这样才不会让网络崩溃。

Skip-Gram

其核心思想就是利用词

w

o

r

d

i

\mathop{word_i}\limits^{\longrightarrow}

wordi​⟶​预测其上下文.

根据上面对CBOW的描述,很容易理解Skip-Gram,就是就是把一个词

w

o

r

d

i

\mathop{word_i}

wordi​送入网络,得到词向量

w

o

r

d

i

1

\mathop{word_{i-1}}\limits^{\longrightarrow}

wordi−1​⟶​、

w

o

r

d

i

+

1

\mathop{word_{i+1}}\limits^{\longrightarrow}

wordi+1​⟶​等偶数个词汇的词向量,然后解码分别去跟

w

o

r

d

i

1

\mathop{word_{i-1}}

wordi−1​和

w

o

r

d

i

+

1

\mathop{word_{i+1}}

wordi+1​做损失函数的计算

编码后的嵌入向量的部分理解

NLP和CV中的异同

共同点:

在NLP中: 如果具有一个

[

B

,

N

,

C

]

[B, N, C]

[B,N,C]的高维词向量(可能经过特征提取,可能没有),其中

N

N

N是代表不同的词语的数目,而

C

C

C是具体的语义,所有通道的值共同构成一个词语的计算机语义在CV中:如果一个

[

B

,

C

,

H

,

W

]

[B, C, H, W]

[B,C,H,W]的图像要用Transformer,需要转换成

[

B

,

N

=

H

×

W

,

C

]

[B, N=H \times W, C]

[B,N=H×W,C]的形式,N是并行的像素点数,而C是这个patch_embedding的计算机语义,例如,某个patch中是一只眼睛,那么就有

[

B

,

N

i

,

C

]

[

B

,

N

,

C

]

其中

N

i

{

0

,

1

,

,

N

}

[B, N_i, C] \in [B, N, C] 其中 N_i \in \{0, 1, \cdots, N\}

[B,Ni​,C]∈[B,N,C]其中Ni​∈{0,1,⋯,N},也就是说全部通道共同构成一个patch的语义,而patch就像NLP中的词语

不同点:

在NLP中,

N

N

N维度的词语是串行的,上下文中具有高度相关性;在CV中,

N

N

N维度是并行的,上下文信息的相关性相对没有那么高,只在特定任务中才具有高度相关性