编码解码
有哪些编码解码
基于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| 00⋯01 1×n× a1,1a2,1⋮an−1,1an,1a1,2a2,2⋮an−1,2an,2⋯⋯⋯⋯⋯a1,m−1a2,m−1⋮an−1,m−1an,m−1a1,ma2,m⋮an−1,man,m n×m= b1b2⋯bm−1bm
其他的编码方式很多,核心思想就是空间变换,也就是矩阵变换,如公式所示,将
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维度是并行的,上下文信息的相关性相对没有那么高,只在特定任务中才具有高度相关性