前言
简单介绍门控线性单元的结构。
原始论文
《Language Modeling with Gated Convolutional Networks》 提出GLU,2017年(第一版是2016年)
网络结构
下图的结构只是其中一层,可以堆叠。
计算公式
每一层的计算公式如下。
其中:
X代表输入。
W、V、b、c都是要学习的参数。
σ
\sigma
σ在原论文中是sigmoid
函数。
⊗是对应元素相乘(element-wise product),也称为哈达玛积(Hadamard product)。
从公式可以看到,输入X分两路,其中一路的运算结果不做处理,另一路则经过激活函数。
Pytorch文档
torch.nn.GLU(dim=-1)
GLU(a,b)=a⊗σ(b)
(先随便读一下文档,后面有代码示例和详细解释)
参数
dim (int) – the dimension on which to split the input. Default: -1
指定从哪个维度对input进行拆分,默认值:-1
参数形状
Input: (∗1,N,∗2) where * means, any number of additional dimensions
Output: (∗1,M,∗2) where M=N/2
需要说明,如果用pytorch的GLU模型计算原论文中GLU层,需要自己构造a和b两个部分。
代码示例
理解参数dim的作用
1. 不设置dim,使用默认值-1。
>>> m = nn.GLU() # dim默认是-1
>>> input = torch.randn(4, 2)
>>> input
tensor([[ 0.4562, 0.7670],
[ 1.7934, 0.7769],
[-0.3021, -0.1275],
[-1.4728, 0.7495]])
>>> output = m(input)
>>> output
tensor([[ 0.3115],
[ 1.2285],
[-0.1414],
[-1.0001]])
解释:dim=-1,意味着最后一个维度,对于二维矩阵,也就是列的维度,所以是按列拆分。
2. 设置dim=0。
>>> input = torch.randn(4, 3)
>>> m = nn.GLU(dim=0) # dim=0
>>> output = m(input)
>>> output
tensor([[-0.9414, -0.0830, -0.5450],
[-0.1251, -1.1556, 0.6469]])
解释:dim=0,意味着第一个维度,对于二维矩阵,就是行的维度,所以是按行拆分。
根据上面介绍的原理,应该知道,被拆分的那个维度,向量个数必须是偶数,才能平均拆分。如果对一个4*3的矩阵按列拆分,就会报错了。