03-BERT源碼分析

BERT的源碼文件主要包括下面幾個部分


顧名思義,模型的描述主要就是在modeling.py這個文件中

pre_training.py,create_pretraining_data.py,extract_feature.py, tokenization.py是預(yù)訓(xùn)練相關(guān)的主要主要描述部分

下面,主要是對BERT模型構(gòu)建的部分進行解析。

其中BERT 模型包括配置和模型兩個部分,下面是配置的主要參數(shù)

 vocab\_size,\\               hidden\_size=768,\\               num\_hidden\_layers=12,\\               num\_attention\_heads=12,\\               intermediate\_size=3072,\\               hidden\_act="gelu",\\               hidden\_dropout\_prob=0.1,\\               attention\_probs\_dropout\_prob=0.1,\\               max\_position\_embeddings=512,\\               type\_vocab\_size=16,\\               initializer\_range=0.02

模型的輸入包括下面三個部分:

input_ids, ? ? ? ? ? ? #padding過后的token id 序列

input_mask, ?????#輸入的mask

token_type_ids,#token的類型,可能會有一些type類型

下面是主要的模型流程:

1.上面三個的shape都是 ? [batch_size, seq_length]

2.創(chuàng)建embedding_table(embedding_lookup)以及加上position_embedding和token_type_embedding(embedding_postprocessor)

3.創(chuàng)建attention mask :attention_mask ?[batch_size, seq_length, seq_length]

4.transformer_model: -> self.all_encoder_layers?? list of [batch_size, seq_length, hidden_size] #transformer層,輸出結(jié)果到一個列表

5.self.sequence_output =self.all_encoder_layers[-1] ?[batch_size, seq_length, hidden_size] #最后一層作為輸出

6.self.pooled_output ??[batch_size, hidden_size] #奇怪的pool操作,只取第一個位置變量

可以看到,主要部分是tranformer_model這個函數(shù)

這里,trasformer使用了residual的設(shè)計,所以每層輸入和輸出的hidden_size要一樣,這里都是768.

這里先設(shè)置了幾個維度的縮寫

# B = batch size (number of sequences)

#? F = `from_tensor` sequence length

#? T = `to_tensor` sequence length

#? N = `num_attention_heads`

#? H = `size_per_head`

下面是attention的過程

1. attention_head_size =int(hidden_size / num_attention_heads)#設(shè)置每個head里面權(quán)重的維度

2. 每層的transformer 包含三個主要操作,self-attention,intermediate,output

2.1 self-attention : ??from_tensor [B, F,N*H], ? to_tensor[B, T, N*H]是兩個輸入變量,這里兩個變量是一樣的,所以叫做self-attention

? ? query_layer = [B*F, N*H] ?#單獨的權(quán)重轉(zhuǎn)換為多head的一個矩陣

? ? key_layer?= [B*T, N*H] ? ? ?#單獨的權(quán)重轉(zhuǎn)換為多head的一個矩陣

? ? value_layer?= [B*T, N*H] ? #單獨的權(quán)重轉(zhuǎn)換為多head的一個矩陣

????attention_scores?= [B, N, F, T] ? #scaled,這個挺有意思的,先scale

? ??attention_scores ?+= adder (1-mask)*-10000 ?#在softmax之前轉(zhuǎn)化mask表示方式

? ? attention_probs = softmax 操作<-attention_scores #pad部分的attention值很?。ń咏?) ??

? ? drop attention_probs #dropout 操作

? ? context_layer =?tf.matmul(attention_probs, value_layer) ?#? [B, F, N, H]

? ? dropout + layer_norm(context_layer?+ layer_input #residual 操作)

2.2 intermediate 就是一個全連接層

? ? ? ? 輸出[B, N, intermediate_size]

2.3?output 也是一個全連接層,

????????輸出[B, F, N*H]

? ???????dropout + layer_norm(context_layer?+ layer_input #residual 操作)

3.輸出最后一層transformer的輸出[B,F,N*H] 進行pooler操作(取第一個位置的輸出)

然后再進行全連接層+tanh激活作為輸出,也就是[B,N*H]

綜上,其實BERT主要這么深(12層)也是靠的sum residual的設(shè)計。muli-head attention確實有意思,其中的trick很多,比如pool操作,比如scale操作,layer norm操作等。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容