Bert:从入门到实战 | 翻译征文 | 雷锋字幕组

 本文为雷锋字幕组“触摸世界前沿科技 | 翻译征文 ”活动收录稿件

1589881428272918.png
在本文中,我们将了解 Bert 是什么以及如何实现它,让我们开始吧。

BERT 是什么?

Bert 是 Transformers 的双向编码表示(Bidirectional Encoder Representations)。这是谷歌用于 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)表示感谢,他们帮助我们完成了这一旅程:)

有用的参考文献

原译文链接来自雷锋字幕组提供的选题

 本文为雷锋字幕组“触摸世界前沿科技 | 翻译征文 ”活动收录稿件