Bert預訓練源碼
主要代碼
地址:https://github.com/google-research/bert
- create_pretraning_data.py:原始文件轉換為訓練數據格式
- tokenization.py:漢字,單詞切分,復合詞處理,create_pretraning_data中調用
- modeling.py: 模型結構
- run_pretraing.py: 運行預訓練
tokenization.py
作用:句子切分,特殊符號處理。
主要類:BasicTokenizer, WordpieceTokenizer, FullTokenizer
- BasicTokenizer.tokenize: 文本轉為unicode, 去除特殊符號,漢字前后加空格,按空格切分單詞,去掉文本重音,按標點符號切割單詞。最后生成一個list
- WordpieceTokenizer.tokenize: 長度過長的單詞標記為UNK,復合詞切分,找不到的詞標記為UNK
- FullTokenizer:先后調用BasicTokenizer和WordpieceTokenizer
create_pretraning_data.py
輸入:詞典, 原始文本(空行分割不同文章,一行一句)
輸出:訓練數據
作用:生成訓練數據,句子對組合,單詞mask等
入口函數main
-
加載詞典,加載原始文本
-
create_training_instances
讀取原始文本文件,做unicode轉換,中文,標點,特殊符號處理,空格切分,復合詞切分。轉換為[[[first doc first sentence],[first doc second sentence],[first doc third sentence]],[[second doc first sentence],[]],....] 這樣的結構
去除空文章,文章順序打亂
輸入的原始文本會重復使用dupe_factor次 -
對每一篇文章生成訓練數據create_instances_from_document
訓練語句長度限制max_seq_length,0.1的概率生成長度較小的訓練語句,增加魯棒性
句子對(A,B)隨機組合
對於一篇文章,按順序獲取n行句子,其長度總和限制為target_seq_length,
隨機選取n行中的前m行作為A
0.5的概率,B是n行中后面剩余的部分;其他情況,B是隨機選取的其他文章內容,開始位置是隨機的
文章中沒有使用的部分繼續組合(A, B)
添加CLS,SEP分隔符,生成句子向量
對句子對中的單詞做隨機mask (create_masked_lm_predictions), 隨機取num_to_predict個單詞做mask,0.8的概率標記為MASK,0.1的概率標記為原始單詞,0.1的概率標記為隨機單詞
封裝,句子對,句子id,是否為隨機下一句,mask的下標位置,mask對應的原始單詞 -
訓練數據序列化,存入文件。單詞轉為id,句子長度不足的后面補0。
modeling.py
BertConfig: 配置
BertModel: 模型主體
建模主體過程:
- 獲取詞向量 [batch_size, seq_length, embedding_size]
- 添加句向量,添加位置向量,在最后一個維度上做歸一化,整體做dropout
- transformer
全連接映射 [B*F, embedding_size]->[B*F, N*H]
\(dropout(softmax(QK^T))V\), 其中mask了原本沒有數據的部分
全連接,dropout,殘差處理,歸一化,全連接,dropout,殘差處理,歸一化
上述循環多層
取最終[CLS]對應的向量做句向量
run_pretraining.py
作用:生成目標函數,加載已有參數,迭代訓練
主要函數:model_fn_builder
- 評估mask單詞的預測准確性,整體loss為mask處預測對的分數的平均值
- 評估next_sentence預測准確性,loss為預測對的概率值
- 總損失為上面兩個損失相加