1.導(dǎo)入Bert庫
我在寫代碼的時候看到很多代碼有的使用以下這種方式導(dǎo)入
from pytorch_pretrained_bert import BertTokenizer,BertModel
有的使用transformer的方式導(dǎo)入的,所有我就有的時候有點郁悶究竟使用那種方式導(dǎo)入.
from transformers import BertTokenizer,BertConfig,BertModel
根據(jù)這個博主的博文,https://blog.csdn.net/qq_43391414/article/details/118252012
知道transerformers包包又名pytorch-transformers或者pytorch-pretrained-bert”
但是根據(jù)一些了解,實際上transformers庫是最新的版本(以前稱為pytorch-transformers和pytorch-pretrained-bert)
所以它在前兩者的基礎(chǔ)上對一些函數(shù)與方法進行了改進,包括一些函數(shù)可能只有在transformers庫里才能使用,所以使用transformers庫比較方便。
它提供了一系列的STOA(最先進)模型的實現(xiàn),包括(Bert、XLNet、RoBERTa等)。
所以導(dǎo)入bert模型的時候推薦使用以下方式比較好
from transformers import BertTokenizer,BertModel
2.bert模型中究竟要輸入什么樣的格式的數(shù)據(jù)
我在寫代碼的時候遇到的情況是,有的人的代碼直接把句子分詞,處理成id的格式輸入到bert模型中,有的人要把數(shù)據(jù)處理成input_ids,mask_attention,token....各種各樣的格式,五花八門的,作為一個小白進入干進入深度學(xué)習(xí)領(lǐng)域,感覺不是很友好.數(shù)據(jù)預(yù)處理這塊,一個人的代碼就有一千種寫法,真的不知道相信誰.
所以我就看到了bert模型的源碼,看到了他的foward函數(shù):
def forward(
self,
input_ids: Optional[torch.Tensor] = None,
attention_mask: Optional[torch.Tensor] = None,
token_type_ids: Optional[torch.Tensor] = None,
position_ids: Optional[torch.Tensor] = None,
head_mask: Optional[torch.Tensor] = None,
inputs_embeds: Optional[torch.Tensor] = None,
encoder_hidden_states: Optional[torch.Tensor] = None,
encoder_attention_mask: Optional[torch.Tensor] = None,
past_key_values: Optional[List[torch.FloatTensor]] = None,
use_cache: Optional[bool] = None,
output_attentions: Optional[bool] = None,
output_hidden_states: Optional[bool] = None,
return_dict: Optional[bool] = None,
) -> Union[Tuple[torch.Tensor], BaseModelOutputWithPoolingAndCrossAttentions]:
這些就是我們要使用bert模型的輸入數(shù)據(jù)格式:
-
1.input_ids:
- 數(shù)據(jù)類型:torch.Tensor
- 表示的內(nèi)容:經(jīng)過 tokenizer 分詞后的 subword 對應(yīng)的下標(biāo)列表
-
2.attention_mask
- 數(shù)據(jù)類型:torch.Tensor
- 表示的內(nèi)容:在 self-attention 過程中,這一塊 mask 用于標(biāo)記 subword 所處句子和 padding 的區(qū)別,將有用的信息用1表示,將 padding 部分填充為 0;
-
3.token_type_ids:
- 數(shù)據(jù)類型:torch.Tensor
- 表示的內(nèi)容:標(biāo)記 subword 當(dāng)前所處句子(第一句/第二句/ padding),如果只有一句話使用0填充
-
4.position_ids:
- 數(shù)據(jù)類型:torch.Tensor
- 表示的內(nèi)容:標(biāo)記當(dāng)前詞所在句子的位置下標(biāo);用1表示padding出來的值
-
5.head_mask:
- 數(shù)據(jù)類型:torch.Tensor
- 表示的內(nèi)容:用于將某些層的某些注意力計算無效化;
-
6.inputs_embeds:
- 數(shù)據(jù)類型:torch.Tensor
- 表示的內(nèi)容:如果提供了,那就不需要input_ids,跨過 embedding lookup 過程直接作為 Embedding 進入 Encoder 計算;
-
7.encoder_hidden_states:
- 數(shù)據(jù)類型:torch.Tensor
- 表示的內(nèi)容:這一部分在 BertModel 配置為 decoder 時起作用,將執(zhí)行 cross-attention 而不是 self-attention;
-
8.encoder_attention_mask:
- 數(shù)據(jù)類型:torch.Tensor
- 表示的內(nèi)容:這個參數(shù)貌似是把預(yù)先計算好的 K-V 乘積傳入,以降低 cross-attention 的開銷(因為原本這部分是重復(fù)計算);
-
9.past_key_values:
- 數(shù)據(jù)類型:List[torch.FloatTensor]
- 表示的內(nèi)容:這個參數(shù)貌似是把預(yù)先計算好的 K-V 乘積傳入,以降低 cross-attention 的開銷(因為原本這部分是重復(fù)計算);
-
10.use_cache:
- 數(shù)據(jù)類型:bool
- 表示的內(nèi)容:將保存上一個參數(shù)并傳回,加速 decoding;
-
11.output_attentions:
- 數(shù)據(jù)類型:bool
- 表示的內(nèi)容:是否返回中間每層的 attention 輸出;
-
12.output_hidden_states:
- 數(shù)據(jù)類型:bool
- 表示的內(nèi)容:是否返回中間每層的輸出;
-
13.return_dict:
- 數(shù)據(jù)類型:bool
- 表示的內(nèi)容:是否按鍵值對的形式(ModelOutput 類,也可以當(dāng)作 tuple 用)返回輸出,默認(rèn)為真。
====================================================
在這里可以使用Dataset先將數(shù)據(jù)處理好,放到這里面,然后將Dataset放到DataLoader中,設(shè)置好批次,一個批次一個批次的加載數(shù)據(jù).
詳細(xì)的寫法可以看我寫的筆記,Dataset和DataLoader的使用方法.
3.Bert模型的輸出
輸入Bert模型中只要輸入,input_ids,attention_mask,token_type_ids就可以了,下面只是我的部分代碼.
out = self.bert(x['input_ids'], x['attention_mask'], x['token_type_ids'])
輸入之后的輸出out包括以下四個數(shù)據(jù)
- last_hidden_state:
torch.FloatTensor類型的,最后一個隱藏層的序列的輸出。大小是(batch_size, sequence_length, hidden_size) sequence_length是我們截取的句子的長度,hidden_size是768. - pooler_output:
torch.FloatTensor類型的,[CLS]的這個token的輸出,輸出的大小是(batch_size, hidden_size) - hidden_states :
tuple(torch.FloatTensor)這是輸出的一個可選項,如果輸出,需要指定config.output_hidden_states=True,它也是一個元組,它的第一個元素是embedding,其余元素是各層的輸出,每個元素的形狀是(batch_size, sequence_length, hidden_size) - attentions:
這也是輸出的一個可選項,如果輸出,需要指定config.output_attentions=True,它也是一個元組,它的元素是每一層的注意力權(quán)重,用于計算self-attention heads的加權(quán)平均值