Transformer结构
模型结构如下:
论文地址:https://arxiv.org/abs/1706.03762
这里只用到了Encoder的部分:
1.1 subsample
用两层卷积进行降采样:
测试:
结果:
输入维度:(2,1,28,28)
输出维度:(2,2,6,6)
1.2 PositionalEncoding
位置编码
为了使模型能够有效利用序列的顺序特征,我们需要加入序列中各个Token间相对位置或Token在序列中绝对位置的信息。在这里,我们将位置编码添加到编码器和解码器栈底部的输入Embedding。由于位置编码与Embedding具有相同的维度,因此两者可以直接相加。其实这里还有许多位置编码可供选择,其中包括可更新的和固定不变的。
在此项工作中,我们使用不同频率的正弦和余弦函数:
其中pos是位置,i是维度。 也就是说,位置编码的每个维度都对应于一个正弦曲线,其波长形成从2π到10000⋅2π的等比级数。我们之所以选择了这个函数,是因为我们假设它能让模型很容易学会Attend相对位置,因为对于任何固定的偏移量k, PEpos+k可以表示为PEpos的线性函数。
此外,在编码器和解码器堆栈中,我们在Embedding与位置编码的加和上都使用了Dropout机制。在基本模型上,我们使用的比率。
如下所示,位置编码将根据位置添加正弦曲线。曲线的频率和偏移对于每个维度是不同的。
输出结果:
1.3 MultiHeadedAttention
Attention
Attention函数可以将Query和一组Key-Value对映射到输出,其中Query、Key、Value和输出都是向量。 输出是值的加权和,其中分配给每个Value的权重由Query与相应Key的兼容函数计算。
我们称这种特殊的Attention机制为"Scaled Dot-Product Attention"。输入包含维度为dk的Query和Key,以及维度为dv的Value。 我们首先分别计算Query与各个Key的点积,然后将每个点积除以 ,最后使用Softmax函数来获得Key的权重。
在具体实现时,我们可以以矩阵的形式进行并行运算,这样能加速运算过程。具体来说,将所有的Query、Key和Value向量分别组合成矩阵Q、K和V,这样输出矩阵可以表示为:
两种最常用的Attention函数是加和Attention和点积(乘积)Attention,我们的算法与点积Attention很类似,但是的比例因子不同。加和Attention使用具有单个隐藏层的前馈网络来计算兼容函数。虽然两种方法理论上的复杂度是相似的,但在实践中,点积Attention的运算会更快一些,也更节省空间,因为它可以使用高效的矩阵乘法算法来实现。
虽然对于较小的dk,这两种机制的表现相似,但在不放缩较大的dk时,加和Attention要优于点积Attention。我们怀疑,对于较大的dk,点积大幅增大,将Softmax函数推向具有极小梯度的区域(为了阐明点积变大的原因,假设q和k是独立的随机变量,平均值为 0,方差 1,这样他们的点积为 ,同样是均值为 0 方差为dk)。为了抵消这种影响,我们用
来缩放点积。
“多头”机制能让模型考虑到不同位置的Attention,另外“多头”Attention可以在不同的子空间表示不一样的关联关系,使用单个Head的Attention一般达不到这种效果。
其中参数矩阵为 。
这里使用h=8个Head并行的Attention,对每一个Head来说有 ,总计算量与完整维度的单个Head的Attention很相近。
1.不同的head得到多个特征表达
2.将所有特征拼接在一起
3.再一层全连接来降维
代码:
这里用了8个头,,结果:
1.4 feedforward
全连接将多头拼接到一起,保证输入输出维度相同:
隐藏层有1280个神经元,验证结果:
1.5 models
Subsample降采样 MultiHeadedAttention多头注意力
FeedForward全连接
LayerNorm层归一化
Dropout
残差连接
结果:
model = speech_model()
12个blocks参数个数:
1个blocks参数个数:
2 demo
特征提取:
结果:
12个blocks计算之后
结果
将输出结果对应到词典:
得到最终的结果:
代码参考:https://github.com/yang123qwe/end2end_chinese_speech_recognition