用lamp搭wordpress關(guān)鍵詞排名優(yōu)化技巧
?
?
目錄
🍔 編碼器介紹
🍔 前饋全連接層
2.1 前饋全連接層
2.2 前饋全連接層的代碼分析
2.3 前饋全連接層總結(jié)
🍔 規(guī)范化層
3.1 規(guī)范化層的作用
3.2 規(guī)范化層的代碼實(shí)現(xiàn)
3.3 規(guī)范化層總結(jié)
🍔 子層連接結(jié)構(gòu)
4.1 子層連接結(jié)構(gòu):
4.2 子層連接結(jié)構(gòu)的代碼分析
4.3 子層連接結(jié)構(gòu)總結(jié)
🍔 編碼器層
5.1 編碼器層的作用
5.2 編碼器層的代碼分析
5.3 編碼器層總結(jié)
🍔 編碼器
6.1 編碼器的作用
6.2 編碼器的代碼分析
6.3 編碼器總結(jié)
?
學(xué)習(xí)目標(biāo)
🍀 了解編碼器中各個(gè)組成部分的作用.
🍀 掌握編碼器中各個(gè)組成部分的實(shí)現(xiàn)過(guò)程.
🍔 編碼器介紹
編碼器部分:?* 由N個(gè)編碼器層堆疊而成 * 每個(gè)編碼器層由兩個(gè)子層連接結(jié)構(gòu)組成 * 第一個(gè)子層連接結(jié)構(gòu)包括一個(gè)多頭自注意力子層和規(guī)范化層以及一個(gè)殘差連接 * 第二個(gè)子層連接結(jié)構(gòu)包括一個(gè)前饋全連接子層和規(guī)范化層以及一個(gè)殘差連接。
🍔 前饋全連接層
2.1 前饋全連接層
-
在Transformer中前饋全連接層就是具有兩層線性層的全連接網(wǎng)絡(luò).
-
前饋全連接層的作用:
- 考慮注意力機(jī)制可能對(duì)復(fù)雜過(guò)程的擬合程度不夠, 通過(guò)增加兩層網(wǎng)絡(luò)來(lái)增強(qiáng)模型的能力.
2.2 前饋全連接層的代碼分析
# 通過(guò)類PositionwiseFeedForward來(lái)實(shí)現(xiàn)前饋全連接層
class PositionwiseFeedForward(nn.Module):def __init__(self, d_model, d_ff, dropout=0.1):"""初始化函數(shù)有三個(gè)輸入?yún)?shù)分別是d_model, d_ff,和dropout=0.1,第一個(gè)是線性層的輸入維度也是第二個(gè)線性層的輸出維度,因?yàn)槲覀兿M斎胪ㄟ^(guò)前饋全連接層后輸入和輸出的維度不變. 第二個(gè)參數(shù)d_ff就是第二個(gè)線性層的輸入維度和第一個(gè)線性層的輸出維度. 最后一個(gè)是dropout置0比率."""super(PositionwiseFeedForward, self).__init__()# 首先按照我們預(yù)期使用nn實(shí)例化了兩個(gè)線性層對(duì)象,self.w1和self.w2# 它們的參數(shù)分別是d_model, d_ff和d_ff, d_modelself.w1 = nn.Linear(d_model, d_ff)self.w2 = nn.Linear(d_ff, d_model)# 然后使用nn的Dropout實(shí)例化了對(duì)象self.dropoutself.dropout = nn.Dropout(dropout)def forward(self, x):"""輸入?yún)?shù)為x,代表來(lái)自上一層的輸出"""# 首先經(jīng)過(guò)第一個(gè)線性層,然后使用Funtional中relu函數(shù)進(jìn)行激活,# 之后再使用dropout進(jìn)行隨機(jī)置0,最后通過(guò)第二個(gè)線性層w2,返回最終結(jié)果.return self.w2(self.dropout(F.relu(self.w1(x))))
-
ReLU函數(shù)公式: ReLU(x)=max(0, x)
-
ReLU函數(shù)圖像:
?
- 實(shí)例化參數(shù):
d_model = 512# 線性變化的維度
d_ff = 64dropout = 0.2
- 輸入?yún)?shù):
# 輸入?yún)?shù)x可以是多頭注意力機(jī)制的輸出
x = mha_result
tensor([[[-0.3075, 1.5687, -2.5693, ..., -1.1098, 0.0878, -3.3609],[ 3.8065, -2.4538, -0.3708, ..., -1.5205, -1.1488, -1.3984],[ 2.4190, 0.5376, -2.8475, ..., 1.4218, -0.4488, -0.2984],[ 2.9356, 0.3620, -3.8722, ..., -0.7996, 0.1468, 1.0345]],[[ 1.1423, 0.6038, 0.0954, ..., 2.2679, -5.7749, 1.4132],[ 2.4066, -0.2777, 2.8102, ..., 0.1137, -3.9517, -2.9246],[ 5.8201, 1.1534, -1.9191, ..., 0.1410, -7.6110, 1.0046],[ 3.1209, 1.0008, -0.5317, ..., 2.8619, -6.3204, -1.3435]]],grad_fn=<AddBackward0>)
torch.Size([2, 4, 512])
- 調(diào)用:
ff = PositionwiseFeedForward(d_model, d_ff, dropout)
ff_result = ff(x)
print(ff_result)
- 輸出效果:
tensor([[[-1.9488e+00, -3.4060e-01, -1.1216e+00, ..., 1.8203e-01,-2.6336e+00, 2.0917e-03],[-2.5875e-02, 1.1523e-01, -9.5437e-01, ..., -2.6257e-01,-5.7620e-01, -1.9225e-01],[-8.7508e-01, 1.0092e+00, -1.6515e+00, ..., 3.4446e-02,-1.5933e+00, -3.1760e-01],[-2.7507e-01, 4.7225e-01, -2.0318e-01, ..., 1.0530e+00,-3.7910e-01, -9.7730e-01]],[[-2.2575e+00, -2.0904e+00, 2.9427e+00, ..., 9.6574e-01,-1.9754e+00, 1.2797e+00],[-1.5114e+00, -4.7963e-01, 1.2881e+00, ..., -2.4882e-02,-1.5896e+00, -1.0350e+00],[ 1.7416e-01, -4.0688e-01, 1.9289e+00, ..., -4.9754e-01,-1.6320e+00, -1.5217e+00],[-1.0874e-01, -3.3842e-01, 2.9379e-01, ..., -5.1276e-01,-1.6150e+00, -1.1295e+00]]], grad_fn=<AddBackward0>)
torch.Size([2, 4, 512])
2.3 前饋全連接層總結(jié)
-
學(xué)習(xí)了什么是前饋全連接層:
- 在Transformer中前饋全連接層就是具有兩層線性層的全連接網(wǎng)絡(luò).
-
學(xué)習(xí)了前饋全連接層的作用:
- 考慮注意力機(jī)制可能對(duì)復(fù)雜過(guò)程的擬合程度不夠, 通過(guò)增加兩層網(wǎng)絡(luò)來(lái)增強(qiáng)模型的能力.
-
學(xué)習(xí)并實(shí)現(xiàn)了前饋全連接層的類: PositionwiseFeedForward
- 它的實(shí)例化參數(shù)為d_model, d_ff, dropout, 分別代表詞嵌入維度, 線性變換維度, 和置零比率.
- 它的輸入?yún)?shù)x, 表示上層的輸出.
- 它的輸出是經(jīng)過(guò)2層線性網(wǎng)絡(luò)變換的特征表示.
🍔 規(guī)范化層
3.1 規(guī)范化層的作用
- 它是所有深層網(wǎng)絡(luò)模型都需要的標(biāo)準(zhǔn)網(wǎng)絡(luò)層,因?yàn)殡S著網(wǎng)絡(luò)層數(shù)的增加,通過(guò)多層的計(jì)算后參數(shù)可能開始出現(xiàn)過(guò)大或過(guò)小的情況,這樣可能會(huì)導(dǎo)致學(xué)習(xí)過(guò)程出現(xiàn)異常,模型可能收斂非常的慢. 因此都會(huì)在一定層數(shù)后接規(guī)范化層進(jìn)行數(shù)值的規(guī)范化,使其特征數(shù)值在合理范圍內(nèi).
3.2 規(guī)范化層的代碼實(shí)現(xiàn)
# 通過(guò)LayerNorm實(shí)現(xiàn)規(guī)范化層的類
class LayerNorm(nn.Module):def __init__(self, features, eps=1e-6):"""初始化函數(shù)有兩個(gè)參數(shù), 一個(gè)是features, 表示詞嵌入的維度,另一個(gè)是eps它是一個(gè)足夠小的數(shù), 在規(guī)范化公式的分母中出現(xiàn),防止分母為0.默認(rèn)是1e-6."""super(LayerNorm, self).__init__()# 根據(jù)features的形狀初始化兩個(gè)參數(shù)張量a2,和b2,第一個(gè)初始化為1張量,# 也就是里面的元素都是1,第二個(gè)初始化為0張量,也就是里面的元素都是0,這兩個(gè)張量就是規(guī)范化層的參數(shù),# 因?yàn)橹苯訉?duì)上一層得到的結(jié)果做規(guī)范化公式計(jì)算,將改變結(jié)果的正常表征,因此就需要有參數(shù)作為調(diào)節(jié)因子,# 使其即能滿足規(guī)范化要求,又能不改變針對(duì)目標(biāo)的表征.最后使用nn.parameter封裝,代表他們是模型的參數(shù)。self.a2 = nn.Parameter(torch.ones(features))self.b2 = nn.Parameter(torch.zeros(features))# 把eps傳到類中self.eps = epsdef forward(self, x):"""輸入?yún)?shù)x代表來(lái)自上一層的輸出"""# 在函數(shù)中,首先對(duì)輸入變量x求其最后一個(gè)維度的均值,并保持輸出維度與輸入維度一致.# 接著再求最后一個(gè)維度的標(biāo)準(zhǔn)差,然后就是根據(jù)規(guī)范化公式,用x減去均值除以標(biāo)準(zhǔn)差獲得規(guī)范化的結(jié)果,# 最后對(duì)結(jié)果乘以我們的縮放參數(shù),即a2,*號(hào)代表同型點(diǎn)乘,即對(duì)應(yīng)位置進(jìn)行乘法操作,加上位移參數(shù)b2.返回即可.mean = x.mean(-1, keepdim=True)std = x.std(-1, keepdim=True)return self.a2 * (x - mean) / (std + self.eps) + self.b2
- 實(shí)例化參數(shù):
features = d_model = 512
eps = 1e-6
- 輸入?yún)?shù):
# 輸入x來(lái)自前饋全連接層的輸出
x = ff_result
tensor([[[-1.9488e+00, -3.4060e-01, -1.1216e+00, ..., 1.8203e-01,-2.6336e+00, 2.0917e-03],[-2.5875e-02, 1.1523e-01, -9.5437e-01, ..., -2.6257e-01,-5.7620e-01, -1.9225e-01],[-8.7508e-01, 1.0092e+00, -1.6515e+00, ..., 3.4446e-02,-1.5933e+00, -3.1760e-01],[-2.7507e-01, 4.7225e-01, -2.0318e-01, ..., 1.0530e+00,-3.7910e-01, -9.7730e-01]],[[-2.2575e+00, -2.0904e+00, 2.9427e+00, ..., 9.6574e-01,-1.9754e+00, 1.2797e+00],[-1.5114e+00, -4.7963e-01, 1.2881e+00, ..., -2.4882e-02,-1.5896e+00, -1.0350e+00],[ 1.7416e-01, -4.0688e-01, 1.9289e+00, ..., -4.9754e-01,-1.6320e+00, -1.5217e+00],[-1.0874e-01, -3.3842e-01, 2.9379e-01, ..., -5.1276e-01,-1.6150e+00, -1.1295e+00]]], grad_fn=<AddBackward0>)
torch.Size([2, 4, 512])
- 調(diào)用:
ln = LayerNorm(features, eps)
ln_result = ln(x)
print(ln_result)
- 輸出效果:
tensor([[[ 2.2697, 1.3911, -0.4417, ..., 0.9937, 0.6589, -1.1902],[ 1.5876, 0.5182, 0.6220, ..., 0.9836, 0.0338, -1.3393],[ 1.8261, 2.0161, 0.2272, ..., 0.3004, 0.5660, -0.9044],[ 1.5429, 1.3221, -0.2933, ..., 0.0406, 1.0603, 1.4666]],[[ 0.2378, 0.9952, 1.2621, ..., -0.4334, -1.1644, 1.2082],[-1.0209, 0.6435, 0.4235, ..., -0.3448, -1.0560, 1.2347],[-0.8158, 0.7118, 0.4110, ..., 0.0990, -1.4833, 1.9434],[ 0.9857, 2.3924, 0.3819, ..., 0.0157, -1.6300, 1.2251]]],grad_fn=<AddBackward0>)
torch.Size([2, 4, 512])
3.3 規(guī)范化層總結(jié)
-
學(xué)習(xí)了規(guī)范化層的作用:
- 它是所有深層網(wǎng)絡(luò)模型都需要的標(biāo)準(zhǔn)網(wǎng)絡(luò)層,因?yàn)殡S著網(wǎng)絡(luò)層數(shù)的增加,通過(guò)多層的計(jì)算后參數(shù)可能開始出現(xiàn)過(guò)大或過(guò)小的情況,這樣可能會(huì)導(dǎo)致學(xué)習(xí)過(guò)程出現(xiàn)異常,模型可能收斂非常的慢. 因此都會(huì)在一定層數(shù)后接規(guī)范化層進(jìn)行數(shù)值的規(guī)范化,使其特征數(shù)值在合理范圍內(nèi).
-
學(xué)習(xí)并實(shí)現(xiàn)了規(guī)范化層的類: LayerNorm
- 它的實(shí)例化參數(shù)有兩個(gè), features和eps,分別表示詞嵌入特征大小,和一個(gè)足夠小的數(shù).
- 它的輸入?yún)?shù)x代表來(lái)自上一層的輸出.
- 它的輸出就是經(jīng)過(guò)規(guī)范化的特征表示.
🍔 子層連接結(jié)構(gòu)
4.1 子層連接結(jié)構(gòu):
-
如圖所示,輸入到每個(gè)子層以及規(guī)范化層的過(guò)程中,還使用了殘差鏈接(跳躍連接),因此我們把這一部分結(jié)構(gòu)整體叫做子層連接(代表子層及其鏈接結(jié)構(gòu)),在每個(gè)編碼器層中,都有兩個(gè)子層,這兩個(gè)子層加上周圍的鏈接結(jié)構(gòu)就形成了兩個(gè)子層連接結(jié)構(gòu).
-
子層連接結(jié)構(gòu)圖:
?
?
4.2 子層連接結(jié)構(gòu)的代碼分析
# 使用SublayerConnection來(lái)實(shí)現(xiàn)子層連接結(jié)構(gòu)的類
class SublayerConnection(nn.Module):def __init__(self, size, dropout=0.1):"""它輸入?yún)?shù)有兩個(gè), size以及dropout, size一般是都是詞嵌入維度的大小, dropout本身是對(duì)模型結(jié)構(gòu)中的節(jié)點(diǎn)數(shù)進(jìn)行隨機(jī)抑制的比率, 又因?yàn)楣?jié)點(diǎn)被抑制等效就是該節(jié)點(diǎn)的輸出都是0,因此也可以把dropout看作是對(duì)輸出矩陣的隨機(jī)置0的比率."""super(SublayerConnection, self).__init__()# 實(shí)例化了規(guī)范化對(duì)象self.normself.norm = LayerNorm(size)# 又使用nn中預(yù)定義的droupout實(shí)例化一個(gè)self.dropout對(duì)象.self.dropout = nn.Dropout(p=dropout)def forward(self, x, sublayer):"""前向邏輯函數(shù)中, 接收上一個(gè)層或者子層的輸入作為第一個(gè)參數(shù),將該子層連接中的子層函數(shù)作為第二個(gè)參數(shù)"""# 我們首先對(duì)輸出進(jìn)行規(guī)范化,然后將結(jié)果傳給子層處理,之后再對(duì)子層進(jìn)行dropout操作,# 隨機(jī)停止一些網(wǎng)絡(luò)中神經(jīng)元的作用,來(lái)防止過(guò)擬合. 最后還有一個(gè)add操作, # 因?yàn)榇嬖谔S連接,所以是將輸入x與dropout后的子層輸出結(jié)果相加作為最終的子層連接輸出.return x + self.dropout(sublayer(self.norm(x)))
- 實(shí)例化參數(shù)
size = 512
dropout = 0.2
head = 8
d_model = 512
- 輸入?yún)?shù):
# 令x為位置編碼器的輸出
x = pe_result
mask = Variable(torch.zeros(8, 4, 4))# 假設(shè)子層中裝的是多頭注意力層, 實(shí)例化這個(gè)類
self_attn = MultiHeadedAttention(head, d_model)# 使用lambda獲得一個(gè)函數(shù)類型的子層
sublayer = lambda x: self_attn(x, x, x, mask)
- 調(diào)用:
sc = SublayerConnection(size, dropout)
sc_result = sc(x, sublayer)
print(sc_result)
print(sc_result.shape)
- 輸出效果:
tensor([[[ 14.8830, 22.4106, -31.4739, ..., 21.0882, -10.0338, -0.2588],[-25.1435, 2.9246, -16.1235, ..., 10.5069, -7.1007, -3.7396],[ 0.1374, 32.6438, 12.3680, ..., -12.0251, -40.5829, 2.2297],[-13.3123, 55.4689, 9.5420, ..., -12.6622, 23.4496, 21.1531]],[[ 13.3533, 17.5674, -13.3354, ..., 29.1366, -6.4898, 35.8614],[-35.2286, 18.7378, -31.4337, ..., 11.1726, 20.6372, 29.8689],[-30.7627, 0.0000, -57.0587, ..., 15.0724, -10.7196, -18.6290],[ -2.7757, -19.6408, 0.0000, ..., 12.7660, 21.6843, -35.4784]]],grad_fn=<AddBackward0>)
torch.Size([2, 4, 512])
4.3 子層連接結(jié)構(gòu)總結(jié)
-
什么是子層連接結(jié)構(gòu):
- 如圖所示,輸入到每個(gè)子層以及規(guī)范化層的過(guò)程中,還使用了殘差鏈接(跳躍連接),因此我們把這一部分結(jié)構(gòu)整體叫做子層連接(代表子層及其鏈接結(jié)構(gòu)), 在每個(gè)編碼器層中,都有兩個(gè)子層,這兩個(gè)子層加上周圍的鏈接結(jié)構(gòu)就形成了兩個(gè)子層連接結(jié)構(gòu).
-
學(xué)習(xí)并實(shí)現(xiàn)了子層連接結(jié)構(gòu)的類: SublayerConnection
- 類的初始化函數(shù)輸入?yún)?shù)是size, dropout, 分別代表詞嵌入大小和置零比率.
- 它的實(shí)例化對(duì)象輸入?yún)?shù)是x, sublayer, 分別代表上一層輸出以及子層的函數(shù)表示.
- 它的輸出就是通過(guò)子層連接結(jié)構(gòu)處理的輸出.
🍔 編碼器層
5.1 編碼器層的作用
-
作為編碼器的組成單元, 每個(gè)編碼器層完成一次對(duì)輸入的特征提取過(guò)程, 即編碼過(guò)程.
-
編碼器層的構(gòu)成圖:
?
5.2 編碼器層的代碼分析
# 使用EncoderLayer類實(shí)現(xiàn)編碼器層
class EncoderLayer(nn.Module):def __init__(self, size, self_attn, feed_forward, dropout):"""它的初始化函數(shù)參數(shù)有四個(gè),分別是size,其實(shí)就是我們?cè)~嵌入維度的大小,它也將作為我們編碼器層的大小, 第二個(gè)self_attn,之后我們將傳入多頭自注意力子層實(shí)例化對(duì)象, 并且是自注意力機(jī)制, 第三個(gè)是feed_froward, 之后我們將傳入前饋全連接層實(shí)例化對(duì)象, 最后一個(gè)是置0比率dropout."""super(EncoderLayer, self).__init__()# 首先將self_attn和feed_forward傳入其中.self.self_attn = self_attnself.feed_forward = feed_forward# 如圖所示, 編碼器層中有兩個(gè)子層連接結(jié)構(gòu), 所以使用clones函數(shù)進(jìn)行克隆self.sublayer = clones(SublayerConnection(size, dropout), 2)# 把size傳入其中self.size = sizedef forward(self, x, mask):"""forward函數(shù)中有兩個(gè)輸入?yún)?shù),x和mask,分別代表上一層的輸出,和掩碼張量mask."""# 里面就是按照結(jié)構(gòu)圖左側(cè)的流程. 首先通過(guò)第一個(gè)子層連接結(jié)構(gòu),其中包含多頭自注意力子層,# 然后通過(guò)第二個(gè)子層連接結(jié)構(gòu),其中包含前饋全連接子層. 最后返回結(jié)果.x = self.sublayer[0](x, lambda x: self.self_attn(x, x, x, mask))return self.sublayer[1](x, self.feed_forward)
- 實(shí)例化參數(shù):
size = 512
head = 8
d_model = 512
d_ff = 64
x = pe_result
dropout = 0.2
self_attn = MultiHeadedAttention(head, d_model)
ff = PositionwiseFeedForward(d_model, d_ff, dropout)
mask = Variable(torch.zeros(8, 4, 4))
- 調(diào)用:
el = EncoderLayer(size, self_attn, ff, dropout)
el_result = el(x, mask)
print(el_result)
print(el_result.shape)
- 輸出效果:
tensor([[[ 33.6988, -30.7224, 20.9575, ..., 5.2968, -48.5658, 20.0734],[-18.1999, 34.2358, 40.3094, ..., 10.1102, 58.3381, 58.4962],[ 32.1243, 16.7921, -6.8024, ..., 23.0022, -18.1463, -17.1263],[ -9.3475, -3.3605, -55.3494, ..., 43.6333, -0.1900, 0.1625]],[[ 32.8937, -46.2808, 8.5047, ..., 29.1837, 22.5962, -14.4349],[ 21.3379, 20.0657, -31.7256, ..., -13.4079, -44.0706, -9.9504],[ 19.7478, -1.0848, 11.8884, ..., -9.5794, 0.0675, -4.7123],[ -6.8023, -16.1176, 20.9476, ..., -6.5469, 34.8391, -14.9798]]],grad_fn=<AddBackward0>)
torch.Size([2, 4, 512])
5.3 編碼器層總結(jié)
-
學(xué)習(xí)了編碼器層的作用:
- 作為編碼器的組成單元, 每個(gè)編碼器層完成一次對(duì)輸入的特征提取過(guò)程, 即編碼過(guò)程.
-
學(xué)習(xí)并實(shí)現(xiàn)了編碼器層的類: EncoderLayer
- 類的初始化函數(shù)共有4個(gè), 別是size,其實(shí)就是我們?cè)~嵌入維度的大小. 第二個(gè)self_attn,之后我們將傳入多頭自注意力子層實(shí)例化對(duì)象, 并且是自注意力機(jī)制. 第三個(gè)是feed_froward, 之后我們將傳入前饋全連接層實(shí)例化對(duì)象. 最后一個(gè)是置0比率dropout.
- 實(shí)例化對(duì)象的輸入?yún)?shù)有2個(gè),x代表來(lái)自上一層的輸出, mask代表掩碼張量.
- 它的輸出代表經(jīng)過(guò)整個(gè)編碼層的特征表示.
🍔 編碼器
6.1 編碼器的作用
-
編碼器用于對(duì)輸入進(jìn)行指定的特征提取過(guò)程, 也稱為編碼, 由N個(gè)編碼器層堆疊而成.
-
編碼器的結(jié)構(gòu)圖:
?
6.2 編碼器的代碼分析
# 使用Encoder類來(lái)實(shí)現(xiàn)編碼器
class Encoder(nn.Module):def __init__(self, layer, N):"""初始化函數(shù)的兩個(gè)參數(shù)分別代表編碼器層和編碼器層的個(gè)數(shù)"""super(Encoder, self).__init__()# 首先使用clones函數(shù)克隆N個(gè)編碼器層放在self.layers中self.layers = clones(layer, N)# 再初始化一個(gè)規(guī)范化層, 它將用在編碼器的最后面.self.norm = LayerNorm(layer.size)def forward(self, x, mask):"""forward函數(shù)的輸入和編碼器層相同, x代表上一層的輸出, mask代表掩碼張量"""# 首先就是對(duì)我們克隆的編碼器層進(jìn)行循環(huán),每次都會(huì)得到一個(gè)新的x,# 這個(gè)循環(huán)的過(guò)程,就相當(dāng)于輸出的x經(jīng)過(guò)了N個(gè)編碼器層的處理. # 最后再通過(guò)規(guī)范化層的對(duì)象self.norm進(jìn)行處理,最后返回結(jié)果. for layer in self.layers:x = layer(x, mask)return self.norm(x)
- 實(shí)例化參數(shù):
# 第一個(gè)實(shí)例化參數(shù)layer, 它是一個(gè)編碼器層的實(shí)例化對(duì)象, 因此需要傳入編碼器層的參數(shù)
# 又因?yàn)榫幋a器層中的子層是不共享的, 因此需要使用深度拷貝各個(gè)對(duì)象.
size = 512
head = 8
d_model = 512
d_ff = 64
c = copy.deepcopy
attn = MultiHeadedAttention(head, d_model)
ff = PositionwiseFeedForward(d_model, d_ff, dropout)
dropout = 0.2
layer = EncoderLayer(size, c(attn), c(ff), dropout)# 編碼器中編碼器層的個(gè)數(shù)N
N = 8
mask = Variable(torch.zeros(8, 4, 4))
- 調(diào)用:
en = Encoder(layer, N)
en_result = en(x, mask)
print(en_result)
print(en_result.shape)
- 輸出效果:
tensor([[[-0.2081, -0.3586, -0.2353, ..., 2.5646, -0.2851, 0.0238],[ 0.7957, -0.5481, 1.2443, ..., 0.7927, 0.6404, -0.0484],[-0.1212, 0.4320, -0.5644, ..., 1.3287, -0.0935, -0.6861],[-0.3937, -0.6150, 2.2394, ..., -1.5354, 0.7981, 1.7907]],[[-2.3005, 0.3757, 1.0360, ..., 1.4019, 0.6493, -0.1467],[ 0.5653, 0.1569, 0.4075, ..., -0.3205, 1.4774, -0.5856],[-1.0555, 0.0061, -1.8165, ..., -0.4339, -1.8780, 0.2467],[-2.1617, -1.5532, -1.4330, ..., -0.9433, -0.5304, -1.7022]]],grad_fn=<AddBackward0>)
torch.Size([2, 4, 512])
6.3 編碼器總結(jié)
-
學(xué)習(xí)了編碼器的作用:
- 編碼器用于對(duì)輸入進(jìn)行指定的特征提取過(guò)程, 也稱為編碼, 由N個(gè)編碼器層堆疊而成.
-
學(xué)習(xí)并實(shí)現(xiàn)了編碼器的類: Encoder
- 類的初始化函數(shù)參數(shù)有兩個(gè),分別是layer和N,代表編碼器層和編碼器層的個(gè)數(shù).
- forward函數(shù)的輸入?yún)?shù)也有兩個(gè), 和編碼器層的forward相同, x代表上一層的輸出, mask代碼掩碼張量.
- 編碼器類的輸出就是Transformer中編碼器的特征提取表示, 它將成為解碼器的輸入的一部分.
?