[深度學習] 自然語言處理 --- Bert 開發實戰 (huggingface-transformers)

本文主要介紹如果使用huggingface的transformers 2.0 進行NLP的模型訓練

除了transformers,其它兼容tf2.0的bert項目還有:

我的博客裏有介紹使用方法  [深度學習] 自然語言處理--- 基於Keras Bert使用(上)

  1. keras-bert(Star:1.4k) 支持tf2,但它只支持bert一種預訓練模型
  2. bert4keras (Star:692)支持tf2,bert/roberta/albert的預訓練權重進行finetune

  3. bert-for-tf2(Star:329)只給了tf2.0 pipeline示例

huggingface的transformers也發佈了transformers2.0,開始支持tf.2.0的各個預訓練模型,雖然沒有對pytorch支持的那麼全面但在我們的場景已經足夠適用了。

 

一 加載google原始預訓練Bert模型

1、先將原始google預訓練的模型文件轉換成pytorch格式

這個命令在安裝transformers時會回到環境變量中。

python convert_bert_original_tf_checkpoint_to_pytorch.py -h

python convert_bert_original_tf_checkpoint_to_pytorch.py \
--tf_checkpoint_path Models/chinese_L-12_H-768_A-12/bert_model.ckpt.index \
--bert_config_file Models/chinese_L-12_H-768_A-12/bert_config.json  \
--pytorch_dump_path  Models/chinese_L-12_H-768_A-12/pytorch_model.bin

output:

INFO:transformers.modeling_bert:Converting TensorFlow checkpoint from /home/work/Bert/Models/chinese_L-12_H-768_A-12/bert_model.ckpt.index
Save PyTorch model to Models/chinese_L-12_H-768_A-12/pytorch_model.bin

在開源代碼庫下面有好多有關轉換的py文件

 

2、加載轉換後的模型

import logging
logging.basicConfig(level=logging.INFO)
import tensorflow as tf
print("Tensorflow Version:", tf.__version__)
import torch
print("Pytorch Version:", torch.__version__)

from transformers import *

import os
pretrained_path = 'Models/chinese_L-12_H-768_A-12'
config_path = os.path.join(pretrained_path, 'bert_config.json')
vocab_path = os.path.join(pretrained_path, 'vocab.txt')

# 加載config
config = BertConfig.from_json_file(config_path)
# 加載torch原始模型
bert_model = BertModel.from_pretrained(pretrained_path, config=config)

# 加載tf原始模型
tfbert_model = TFBertModel.from_pretrained(pretrained_path,from_pt=True, config=config)

發現問題:如果加載爲TF2的模型,參數會變少 (請使用 pytorch版本加載轉換後的模型)

 

3、token編碼inputs

tokenizer = BertTokenizer.from_pretrained(vocab_path)

 

 

 

二  使用Bert模型

構建模型

class BertNerModel(TFBertPreTrainedModel):
    def __init__(self, config, *inputs, **kwargs):
      super(BERT_NER, self).__init__(config, *inputs, **kwargs)
      self.bert_layer = TFBertMainLayer(config, name='bert')
      self.bert_layer.trainable = False
      self.concat_layer = tf.keras.layers.Concatenate(name='concat_bert')
    
    def call(self, inputs):
      outputs = self.bert_layer(inputs)
      #將後n層的結果相連
      tensor = self.concat_layer(list(outputs[2][-4:]))

這裏給出的是簡要的代碼,可以自行根據任務在bert_layer之後加入RNN

自定義模型的寫法可以參考官方源碼裏的TFBertForSequenceClassification, 繼承TFBertPreTrainedModel

self.bert_layer(inputs)的返回值爲tuple類型:

  1. 最後1層隱藏層的輸出值,shape=(batch_size, max_length, hidden_dimention)
  2. [CLS] 對應的輸出值,shape=(batch_size, hidden_dimention)
  3. 只有設置了config.output_hidden_states = True,纔有該值,所有隱藏層的輸出值,返回值類型是list 每個list裏的值的shape(batch_size, max_length, hidden_dimention)`

模型的初始化

bert_ner_model = BertNerModel.from_pretrained("bert-base-chinese", output_hidden_states=True)

因爲是模型繼承的TFBertPreTrainedModel因此這裏初始化使用的父類的方式。第一個參數是要加載預訓練好的模型參數

注意事項

  1. 通過設置:self.bert.trainable = False, 模型可以更快收斂,減少訓練時間
  2. 預測的時候,輸出的數據一定要與max_length一致,否則效果完全不可用,猜測可能是我們只給了, 沒有給input_mask,有看到transformers的源碼,如果不給attention_mask,默認全是1的
  3. 通過設置 output_hidden_states=True, 可以得到隱藏層的結果

 

 

 

http://www.writinglite.com/post/shen-du-xue-xi/2019-12-12-tensorflow2.0-ji-yu-bertde-kai-fa-shi-zhan-huggingface-transformers

發佈了173 篇原創文章 · 獲贊 226 · 訪問量 33萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章