日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

pytorch元素相乘_bert_pytorch学习(1)

發布時間:2024/7/23 编程问答 29 豆豆
生活随笔 收集整理的這篇文章主要介紹了 pytorch元素相乘_bert_pytorch学习(1) 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

本文主要是記錄學習bert的pytorch實現代碼的一些心得

dataset

1. vocab

繼承關系:TorchVocab --> Vocab --> WordVocab

  • TorchVocab

該類主要是定義了一個詞典對象,包含如下三個屬性:

freqs:是一個collections.Counter對象,能夠記錄數據集中不同token所出現的次數

stoi:是一個collections.defaultdict對象,將數據集中的token映射到不同的index

itos:是一個列表,保存了從index到token的映射信息


代碼中sort與sorted的區別:

sort 是應用在 list 上的方法,sorted 可以對所有可迭代的對象進行排序操作。

list 的 sort 方法返回的是對已經存在的列表進行操作,而內建函數 sorted 方法返回的是一個新的 list,而不是在原來的基礎上進行的操作。

sorted的語法:

sorted(iterable, key=None, reverse=False)

iterable -- 可迭代對象。

key -- 主要是用來進行比較的元素,只有一個參數,具體的函數的參數就是取自于可迭代對象中,指定可迭代對象中的一個元素來進行排序。

reverse -- 排序規則,reverse = True 降序 , reverse = False 升序(默認)。

  • Vocab

Vocab繼承TorchVocab,該類主要定義了一些特殊token的表示

這里用到了一個裝飾器,簡單地說:裝飾器就是修改其他函數的功能的函數。這里包含了一個序列化的操作

  • WordVocab

WordVocab繼承自Vocab,里面包含了兩個方法to_seq和from_seq分別是將token轉換成index和將index轉換成token表示

2. dataset

主要實現了一個BERTDataset類,繼承自torch.utils.data.Dataset,里面一些操作都是根據論文中的兩種訓練模型構建的:masked words 和 next sentence predict

model

1. attention

這里首先定義了一個單注意力的類,然后通過該類疊加構造一個多頭注意力的類。

矩陣相乘有torch.mm和torch.matmul兩個函數。其中前一個是針對二維矩陣,后一個是高維。當torch.mm用于大于二維時將報錯。

masked_fill:a.masked_fill(mask == 0, value) mask必須是一個 ByteTensor 而且shape必須和 a一樣 并且元素只能是 0或者1 ,是將 mask中為1的 元素所在的索引,在a中相同的的索引處替換為 value ,mask value必須同為tensor

2. embedding

bert的embedding由三個部分組成:TokenEmbedding、PositionalEmbedding、SegmentEmbedding

pytorch中詞嵌入使用nn.Embedding,只需要調用 torch.nn.Embedding(m, n) 就可以了,m 表示單詞的總數目,n 表示詞嵌入的維度,其實詞嵌入就相當于是一個大矩陣,矩陣的每一行表示一個單詞,默認是隨機初始化的,不過也可以使用已經訓練好的詞向量。不理解的話可以自己用簡單的例子嘗試一下即可

這里的位置編碼是寫死的,不會隨著訓練進行更新,這是論文 attention is all you need 中的做法,而bert模型的官方TensorFlow源碼是將位置編碼position embedding直接初始化成可訓練的參數并通過訓練進行學習的,所以此處的實現和bert模型不同

import torch.nn as nn import torch import mathclass PositionalEmbedding(nn.Module):def __init__(self, d_model, max_len=512):super().__init__()# Compute the positional encodings once in log space.pe = torch.zeros(max_len, d_model).float()pe.require_grad = Falseposition = torch.arange(0, max_len).float().unsqueeze(1)div_term = (torch.arange(0, d_model, 2).float() * -(math.log(10000.0) / d_model)).exp()pe[:, 0::2] = torch.sin(position * div_term)pe[:, 1::2] = torch.cos(position * div_term)pe = pe.unsqueeze(0)self.register_buffer('pe', pe)def forward(self, x):return self.pe[:, :x.size(1)]

代碼中對positionembedding的實現一開始看有點懵,感覺和原文中的表達式不太一樣,后來查找資料發現是對原公式做了如下變換:

$$ 1/10000^{2i/d_{model}} = e^{log{10000^{-2i/d_{model}}}} = e^{-2i/d_{model}log{10000}} = e^{2i(-log^{10000}/d_{model})} $$

這樣一來便和代碼中的實現一致了,為什么要這么做,代碼注釋中說這樣可以使用log空間一次性計算position embedding,即能夠節省一定的內存開銷

3. utils

這部分主要是實現了模型中的一些組件:FNN,gelu激勵函數,layernorm正則化以及sublayer連接,理論部分論文中都介紹得很詳細,可以結合論文原文學習這部分的實現應該比較好理解

bert語言模型構建

接下來就是bert模型的具體實現了:

首先是構造transformer block。然后組成bert模型

這里要復習一下repeat()方法:torch.Tensor有兩個實例方法可以用來擴展某維的數據的尺寸,分別是repeat()和expand():

expand()方法返回當前張量在某維擴展更大后的張量。擴展(expand)張量不會分配新的內存,只是在存在的張量上創建一個新的視圖(view),一個大小(size)等于1的維度擴展到更大的尺寸。

repeat()方法沿著特定的維度重復這個張量,和expand()不同的是,這個函數拷貝張量的數據,而不是在原來的張量上修改。

trainer

主要設置了optim以及封裝了訓練迭代的操作

總結

以上是生活随笔為你收集整理的pytorch元素相乘_bert_pytorch学习(1)的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。