Bert:從入門到實戰 | 翻譯徵文 | 雷鋒字幕組
本文為雷鋒字幕組「觸摸世界前沿科技 | 翻譯徵文 」活動收錄稿件
在本文中,我們將了解 Bert 是什麼以及如何實現它,讓我們開始吧。
BERT 是什麼?
Bert 是 Transformers 的雙向編碼表示(Bidirectional Encoder Representations)。這是Google用於 NLP 與訓練語言表示的新技術。Bert 已經在大量的單詞上進行了訓練(一些研究人員說,Bert 模型在英文維基百科的 25 億個單詞上進行了訓練)。這意味著,現在機器學習社區可以使用 Bert 模型執行各種各樣的 NLP 任務,例如問答任務、命名實體識別(NER)和情感分析等分類問題。
在 Bert 論文中,他們提出了兩種 Bert 模型,一種是 Best Base,一種是 Bert Large。兩種模型都有大量的編碼器層,base 模型有 12 層,large 模型有 24 層。如果你了解 transformers 的概念,你就會明白,Bert 還在 transformers 的編碼器堆棧上進行了訓練,以使用相同的注意力機制。但是為什麼稱之為「雙向」呢?
雙向是什麼意思?
因為 transformers 編碼器一次性讀取單詞的整個序列,這與定向模型相反,定向模型從左到右或從右到左順序讀取收入。雙向方法根據單詞周圍的環境,來幫助模型學習和理解單詞的含義和意圖。因為我們將其用於惡意分類,在此我們僅解釋在分類任務中使用 Bert 模型的步驟。
Bert 的輸入是什麼?
Bert 的輸入很特殊, 它以[CSL]標記開頭,表示分類任務。像在 Transformers 中一樣,Bert 模型將採用一系列單詞(向量)作為輸入,以保持在堆棧中從第一個編碼層到最後一層的傳遞。堆棧中的每一層將在序列上採用自注意方法,然後將其傳遞到前饋網路上,以傳遞下一編碼層。
Bert 的輸出是什麼?
Bert 模型的輸出包括大小(隱藏大小)向量,且輸出的首位為[CLS]標記。現在,此輸出可以用作我們神經網路分類器的輸入,對單詞的惡性進行分類。在 Bert 論文中,他們僅使用單層的神經網路作為分類器就取得了很棒的效果。
現在我們了解了 Bert 的概念,接下來我們要深入到實施階段了。
數據:
我們的數據來自 Kaggle 競賽 Jigsaw Multilingual Toxic Comment Classification 。在訓練數據中,我們僅使用英語,而在驗證和測試數據中,我們使用多種語言。
我們使用的文件:
-
jigsaw-toxic-comment-train.csv
-
validation.csv
-
test.csv
下面我們進入到最有趣的部分……Bert 實現
-
導入庫
-
在 TPU 上運行 Bert 模型 針對 Kaggle 用戶
-
函數 3.1 注釋編碼函數 3.2 建立 Keras 模型函數
-
預處理和配置 4.1 配置 4.2 導入數據集 4.3 標記解析器 4.4 編碼注釋 4.5 準備 TensorFlow 數據集以進行建模
-
建模 5.1 建模 5.2 訓練模型,調整超參數 5.3 測試模型
-
預測和存儲結果
1.輸入庫
import os import numpy as np import pandas as pd import tensorflow as tf from tensorflow.keras.layers import Dense, Input from tensorflow.keras.optimizers import Adam from tensorflow.keras.models import Model from tensorflow.keras.callbacks import ModelCheckpoint from kaggle_datasets import KaggleDatasets import transformers from transformers import TFAutoModel, AutoTokenizer from tqdm.notebook import tqdm from tokenizers import Tokenizer, models, pre_tokenizers, decoders, processors
2. 在 TPU 上運行 Bert 模型針對 Kaggle 用戶
try: tpu = tf.distribute.cluster_resolver.TPUClusterResolver() print('Running on TPU ', tpu.master()) except ValueError: tpu = None if tpu: tf.config.experimental_connect_to_cluster(tpu) tf.tpu.experimental.initialize_tpu_system(tpu) strategy = tf.distribute.experimental.TPUStrategy(tpu) else: strategy = tf.distribute.get_strategy() print("REPLICAS: ", strategy.num_replicas_in_sync)
3.函數
3.1 注釋編碼函數
編碼工作是為了將單詞轉換為向量,封裝單詞的含義,相似的詞的數字更接近。
def regular_encode(texts, tokenizer, maxlen=512): """ Function to encode the word """ # encode the word to vector of integer enc_di = tokenizer.batch_encode_plus( texts, return_attention_masks=False, return_token_type_ids=False, pad_to_max_length=True, max_length=maxlen ) return np.array(enc_di['input_ids'])
3.2 建立 Keras 模型函數
def build_model(transformer, max_len=512): """ This function to build and compile Keras model """ #Input: for define input layer #shape is vector with 512-dimensional vectors input_word_ids = Input(shape=(max_len,), dtype=tf.int32, name="input_word_ids") # name is optional sequence_output = transformer(input_word_ids)[0] # to get the vector cls_token = sequence_output[:, 0, :] # define output layer out = Dense(1, activation='sigmoid')(cls_token) # initiate the model with inputs and outputs model = Model(inputs=input_word_ids, outputs=out) model.compile(Adam(lr=1e-5), loss='binary_crossentropy',metrics=[tf.keras.metrics.AUC()]) return model
4.預處理
4.1 配置
# input pipeline that delivers data for the next step before the current step has finished. # The tf.data API helps to build flexible and efficient input pipelines. # This document demonstrates how to use the tf.data # API to build highly performant TensorFlow input pipelines. AUTO = tf.data.experimental.AUTOTUNE# upload data into google cloud storage GCS_DS_PATH = KaggleDatasets().get_gcs_path()# Configuration EPOCHS = 2 BATCH_SIZE = 16 * strategy.num_replicas_in_sync MAX_LEN = 192 MODEL = 'bert-base-multilingual-cased'
4.2 導入數據集
train1 = pd.read_csv("/kaggle/input/jigsaw-multilingual-toxic-comment-classification/jigsaw-toxic-comment-train.csv") valid = pd.read_csv('/kaggle/input/jigsaw-multilingual-toxic-comment-classification/validation.csv') test = pd.read_csv('/kaggle/input/jigsaw-multilingual-toxic-comment-classification/test.csv') sub = pd.read_csv('/kaggle/input/jigsaw-multilingual-toxic-comment-classification/sample_submission.csv')
4.3 標記解析器
tokenizer = AutoTokenizer.from_pretrained(MODEL)
4.4 編碼注釋
%%time x_train = regular_encode(train1.comment_text.values, tokenizer, maxlen=MAX_LEN) x_valid = regular_encode(valid.comment_text.values, tokenizer, maxlen=MAX_LEN) x_test = regular_encode(test.content.values, tokenizer, maxlen=MAX_LEN) y_train = train1.toxic.values y_valid = valid.toxic.values
4.5 準備 TensorFlow 數據集以進行建模
# Create a source dataset from your input data. # Apply dataset transformations to preprocess the data. # Iterate over the dataset and process the elements.train_dataset = ( tf.data.Dataset # create dataset .from_tensor_slices((x_train, y_train)) # Once you have a dataset, you can apply transformations .repeat() .shuffle(2048) .batch(BATCH_SIZE)# Combines consecutive elements of this dataset into batches. .prefetch(AUTO) #This allows later elements to be prepared while the current element is being processed. )valid_dataset = ( tf.data.Dataset # create dataset .from_tensor_slices((x_valid, y_valid)) # Once you have a dataset, you can apply transformations .batch(BATCH_SIZE) #Combines consecutive elements of this dataset into batches. .cache() .prefetch(AUTO)#This allows later elements to be prepared while the current element is being processed. )test_dataset = ( tf.data.Dataset# create dataset .from_tensor_slices(x_test) # Once you have a dataset, you can apply transformations .batch(BATCH_SIZE) )
5.建模
5.1 建模
%%time with strategy.scope(): transformer_layer = TFAutoModel.from_pretrained(MODEL) model = build_model(transformer_layer, max_len=MAX_LEN) model.summary()
5.2 訓練模型,調整超參數
n_steps = x_train.shape[0] // BATCH_SIZE train_history = model.fit(train_dataset, steps_per_epoch=n_steps, validation_data=valid_dataset, epochs=EPOCHS)
5.3 測試模型
n_steps = x_valid.shape[0] // BATCH_SIZE train_history_2 = model.fit(valid_dataset.repeat(), steps_per_epoch=n_steps,epochs=EPOCHS*2)
6.預測和存儲結果
sub['toxic'] = model.predict(test_dataset, verbose=1) sub.to_csv('submission.csv', index=False)
結論
Bert 是一個功能強大的預訓練模型,對當今的 NLP 世界產生了巨大影響。你可以在很多不同的任務中使用 Bert,例如語言翻譯,問答,以及在文本分類之外預測下一個單詞。
致謝
我必須對我的隊友(Sarah和North)以及 DS17 的講師(Irfan, Husain, Yazied, and Amjad)表示感謝,他們幫助我們完成了這一旅程:)
有用的參考文獻
本文為雷鋒字幕組「觸摸世界前沿科技 | 翻譯徵文 」活動收錄稿件