您好,登錄后才能下訂單哦!
本篇內容主要講解“Pytorch怎么實現Transformer”,感興趣的朋友不妨來看看。本文介紹的方法操作簡單快捷,實用性強。下面就讓小編來帶大家學習“Pytorch怎么實現Transformer”吧!
# 關于word embedding,以序列建模為例 # 輸入句子有兩個,第一個長度為2,第二個長度為4 src_len = torch.tensor([2, 4]).to(torch.int32) # 目標句子有兩個。第一個長度為4, 第二個長度為3 tgt_len = torch.tensor([4, 3]).to(torch.int32) print(src_len) print(tgt_len)
輸入句子(src_len)有兩個,第一個長度為2,第二個長度為4
目標句子(tgt_len)有兩個。第一個長度為4, 第二個長度為3
用隨機數生成句子,用0填充空白位置,保持所有句子長度一致
src_seq = torch.cat([torch.unsqueeze(F.pad(torch.randint(1, max_num_src_words, (L, )), (0, max(src_len)-L)), 0) for L in src_len]) tgt_seq = torch.cat([torch.unsqueeze(F.pad(torch.randint(1, max_num_tgt_words, (L, )), (0, max(tgt_len)-L)), 0) for L in tgt_len]) print(src_seq) print(tgt_seq)
src_seq為輸入的兩個句子,tgt_seq為輸出的兩個句子。
為什么句子是數字?在做中英文翻譯時,每個中文或英文對應的也是一個數字,只有這樣才便于處理。
在該字典中,總共有8個字(行),每個字對應8維向量(做了簡化了的)。注意在實際應用中,應當有幾十萬個字,每個字可能有512個維度。
# 構造word embedding src_embedding_table = nn.Embedding(9, model_dim) tgt_embedding_table = nn.Embedding(9, model_dim) # 輸入單詞的字典 print(src_embedding_table) # 目標單詞的字典 print(tgt_embedding_table)
字典中,需要留一個維度給class token,故是9行。
通過字典取出1.2
中得到的句子
# 得到向量化的句子 src_embedding = src_embedding_table(src_seq) tgt_embedding = tgt_embedding_table(tgt_seq) print(src_embedding) print(tgt_embedding)
該階段總程序
import torch # 句子長度 src_len = torch.tensor([2, 4]).to(torch.int32) tgt_len = torch.tensor([4, 3]).to(torch.int32) # 構造句子,用0填充空白處 src_seq = torch.cat([torch.unsqueeze(F.pad(torch.randint(1, 8, (L, )), (0, max(src_len)-L)), 0) for L in src_len]) tgt_seq = torch.cat([torch.unsqueeze(F.pad(torch.randint(1, 8, (L, )), (0, max(tgt_len)-L)), 0) for L in tgt_len]) # 構造字典 src_embedding_table = nn.Embedding(9, 8) tgt_embedding_table = nn.Embedding(9, 8) # 得到向量化的句子 src_embedding = src_embedding_table(src_seq) tgt_embedding = tgt_embedding_table(tgt_seq) print(src_embedding) print(tgt_embedding)
位置編碼是transformer的一個重點,通過加入transformer位置編碼,代替了傳統RNN的時序信息,增強了模型的并發度。位置編碼的公式如下:(其中pos代表行,i代表列)
# 得到分子pos的值 pos_mat = torch.arange(4).reshape((-1, 1)) # 得到分母值 i_mat = torch.pow(10000, torch.arange(0, 8, 2).reshape((1, -1))/8) print(pos_mat) print(i_mat)
# 初始化位置編碼矩陣 pe_embedding_table = torch.zeros(4, 8) # 得到偶數行位置編碼 pe_embedding_table[:, 0::2] =torch.sin(pos_mat / i_mat) # 得到奇數行位置編碼 pe_embedding_table[:, 1::2] =torch.cos(pos_mat / i_mat) pe_embedding = nn.Embedding(4, 8) # 設置位置編碼不可更新參數 pe_embedding.weight = nn.Parameter(pe_embedding_table, requires_grad=False) print(pe_embedding.weight)
有些位置是空白用0填充的,訓練時不希望被這些位置所影響,那么就需要用到self mask。self mask的原理是令這些位置的值為無窮小,經過softmax后,這些值會變為0,不會再影響結果。
3.1.1 得到有效位置矩陣
# 得到有效位置矩陣 vaild_encoder_pos = torch.unsqueeze(torch.cat([torch.unsqueeze(F.pad(torch.ones(L), (0, max(src_len) - L)), 0)for L in src_len]), 2) valid_encoder_pos_matrix = torch.bmm(vaild_encoder_pos, vaild_encoder_pos.transpose(1, 2)) print(valid_encoder_pos_matrix)
3.1.2 得到無效位置矩陣
invalid_encoder_pos_matrix = 1-valid_encoder_pos_matrix mask_encoder_self_attention = invalid_encoder_pos_matrix.to(torch.bool) print(mask_encoder_self_attention)
True
代表需要對該位置mask
3.1.3 得到mask矩陣
用極小數填充需要被mask的位置
# 初始化mask矩陣 score = torch.randn(2, max(src_len), max(src_len)) # 用極小數填充 mask_score = score.masked_fill(mask_encoder_self_attention, -1e9) print(mask_score)
算其softmat
mask_score_softmax = F.softmax(mask_score) print(mask_score_softmax)
可以看到,已經達到預期效果
到此,相信大家對“Pytorch怎么實現Transformer”有了更深的了解,不妨來實際操作一番吧!這里是億速云網站,更多相關內容可以進入相關頻道進行查詢,關注我們,繼續學習!
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。