Bert:從入門到實戰 | 翻譯徵文 | 雷鋒字幕組

 本文為雷鋒字幕組「觸摸世界前沿科技 | 翻譯徵文 」活動收錄稿件

1589881428272918.png
在本文中,我們將了解 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 實現

  1. 導入庫

  2. 在 TPU 上運行 Bert 模型 針對 Kaggle 用戶

  3. 函數 3.1 注釋編碼函數 3.2 建立 Keras 模型函數

  4. 預處理和配置 4.1 配置 4.2 導入數據集 4.3 標記解析器 4.4 編碼注釋 4.5 準備 TensorFlow 數據集以進行建模

  5. 建模 5.1 建模 5.2 訓練模型,調整超參數 5.3 測試模型

  6. 預測和存儲結果

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,例如語言翻譯,問答,以及在文本分類之外預測下一個單詞。

致謝

我必須對我的隊友(SarahNorth)以及 DS17 的講師(Irfan, Husain, Yazied, and Amjad)表示感謝,他們幫助我們完成了這一旅程:)

有用的參考文獻

原譯文鏈接來自雷鋒字幕組提供的選題

 本文為雷鋒字幕組「觸摸世界前沿科技 | 翻譯徵文 」活動收錄稿件