반응형
블로그 이미지
개발자로서 현장에서 일하면서 새로 접하는 기술들이나 알게된 정보 등을 정리하기 위한 블로그입니다. 운 좋게 미국에서 큰 회사들의 프로젝트에서 컬설턴트로 일하고 있어서 새로운 기술들을 접할 기회가 많이 있습니다. 미국의 IT 프로젝트에서 사용되는 툴들에 대해 많은 분들과 정보를 공유하고 싶습니다.
솔웅

최근에 올라온 글

최근에 달린 댓글

최근에 받은 트랙백

글 보관함

카테고리


반응형

16.7. Natural Language Inference: Fine-Tuning BERT — Dive into Deep Learning 1.0.3 documentation (d2l.ai)

 

16.7. Natural Language Inference: Fine-Tuning BERT — Dive into Deep Learning 1.0.3 documentation

 

d2l.ai

 

16.7. Natural Language Inference: Fine-Tuning BERT

 

In earlier sections of this chapter, we have designed an attention-based architecture (in Section 16.5) for the natural language inference task on the SNLI dataset (as described in Section 16.4). Now we revisit this task by fine-tuning BERT. As discussed in Section 16.6, natural language inference is a sequence-level text pair classification problem, and fine-tuning BERT only requires an additional MLP-based architecture, as illustrated in Fig. 16.7.1.

 

이 장의 이전 섹션에서 우리는 SNLI 데이터 세트(섹션 16.4에서 설명)에 대한 자연어 추론 작업을 위한 attention-based architecture(섹션 16.5)를 설계했습니다. 이제 BERT를 미세 조정하여 이 작업을 다시 살펴보겠습니다. 섹션 16.6에서 설명한 것처럼 자연어 추론은 시퀀스 수준 텍스트 쌍 분류 문제이며 BERT를 미세 조정하려면 그림 16.7.1에 설명된 것처럼 추가적인 MLP 기반 아키텍처만 필요합니다.

 

Fig. 16.7.1  This section feeds pretrained BERT to an MLP-based architecture for natural language inference.

 

In this section, we will download a pretrained small version of BERT, then fine-tune it for natural language inference on the SNLI dataset.

 

이 섹션에서는 사전 훈련된 BERT의 작은 버전을 다운로드한 다음 SNLI 데이터 세트에 대한 자연어 추론을 위해 미세 조정합니다.

 

import json
import multiprocessing
import os
import torch
from torch import nn
from d2l import torch as d2l

 

16.7.1. Loading Pretrained BERT

 

We have explained how to pretrain BERT on the WikiText-2 dataset in Section 15.9 and Section 15.10 (note that the original BERT model is pretrained on much bigger corpora). As discussed in Section 15.10, the original BERT model has hundreds of millions of parameters. In the following, we provide two versions of pretrained BERT: “bert.base” is about as big as the original BERT base model that requires a lot of computational resources to fine-tune, while “bert.small” is a small version to facilitate demonstration.

 

d2l.DATA_HUB['bert.base'] = (d2l.DATA_URL + 'bert.base.torch.zip',
                             '225d66f04cae318b841a13d32af3acc165f253ac')
d2l.DATA_HUB['bert.small'] = (d2l.DATA_URL + 'bert.small.torch.zip',
                              'c72329e68a732bef0452e4b96a1c341c8910f81f')

이 코드는 데이터 저장소(DATA_HUB)에 두 개의 BERT(Bidirectional Encoder Representations from Transformers) 모델에 대한 정보를 추가하는 역할을 합니다. BERT는 자연어 처리 작업에 사용되는 사전 훈련된 언어 모델 중 하나로, 큰 텍스트 코퍼스에서 학습된 후 다양한 NLP 작업에 전이 학습(transfer learning)을 적용할 수 있도록 훈련된 모델입니다.

  • 'bert.base': 이 키는 큰 규모의 BERT 모델에 대한 정보를 나타냅니다. 해당 모델의 체크포인트 파일은 bert.base.torch.zip로 저장되어 있으며, 해당 파일을 다운로드하여 모델을 로드할 수 있습니다. 이 모델은 큰 언어 모델이기 때문에 자연어 처리 작업에 높은 성능을 제공할 것으로 기대됩니다.
  • 'bert.small': 이 키는 작은 규모의 BERT 모델에 대한 정보를 나타냅니다. 작은 모델은 더 가벼우며 계산 비용이 적게 들지만, 큰 모델보다는 성능이 낮을 수 있습니다. 이 모델은 자연어 처리 작업에 적합한 자원이 제한된 환경에서 사용될 수 있습니다.

따라서 이 코드는 데이터 저장소에서 BERT 모델의 체크포인트 파일을 다운로드하고 이를 사용하여 BERT 모델을 로드할 수 있도록 필요한 정보를 설정합니다.

 

 

Either pretrained BERT model contains a “vocab.json” file that defines the vocabulary set and a “pretrained.params” file of the pretrained parameters. We implement the following load_pretrained_model function to load pretrained BERT parameters.

 

사전 훈련된 BERT 모델에는 어휘 세트를 정의하는 "vocab.json" 파일과 사전 훈련된 매개변수의 "pretrained.params" 파일이 포함되어 있습니다. 사전 훈련된 BERT 매개변수를 로드하기 위해 다음 load_pretrained_model 함수를 구현합니다.

 

def load_pretrained_model(pretrained_model, num_hiddens, ffn_num_hiddens,
                          num_heads, num_blks, dropout, max_len, devices):
    data_dir = d2l.download_extract(pretrained_model)
    # Define an empty vocabulary to load the predefined vocabulary
    vocab = d2l.Vocab()
    vocab.idx_to_token = json.load(open(os.path.join(data_dir, 'vocab.json')))
    vocab.token_to_idx = {token: idx for idx, token in enumerate(
        vocab.idx_to_token)}
    bert = d2l.BERTModel(
        len(vocab), num_hiddens, ffn_num_hiddens=ffn_num_hiddens, num_heads=4,
        num_blks=2, dropout=0.2, max_len=max_len)
    # Load pretrained BERT parameters
    bert.load_state_dict(torch.load(os.path.join(data_dir,
                                                 'pretrained.params')))
    return bert, vocab

이 함수는 다음과 같은 역할을 합니다:

  1. pretrained_model: 미리 학습된 BERT 모델의 이름 또는 경로를 나타냅니다.
  2. num_hiddens: BERT 모델의 은닉 상태 크기를 나타냅니다.
  3. ffn_num_hiddens: BERT 모델의 Feedforward 네트워크에서의 은닉 상태 크기를 나타냅니다.
  4. num_heads: BERT 모델의 어텐션 헤드 개수를 나타냅니다.
  5. num_blks: BERT 모델의 어텐션 블록 수를 나타냅니다.
  6. dropout: 드롭아웃 비율을 나타냅니다.
  7. max_len: 입력 시퀀스의 최대 길이를 나타냅니다.
  8. devices: 사용할 디바이스 목록입니다.

함수는 다음 단계로 수행됩니다:

  • pretrained_model을 통해 지정된 미리 학습된 BERT 모델을 다운로드하고 압축을 해제합니다.
  • 빈 어휘 사전(vocab)을 정의하고, 미리 정의된 어휘 파일을 로드하여 이 어휘 사전을 채웁니다.
  • BERT 모델을 지정된 구성 및 어휘 사전을 사용하여 초기화합니다.
  • 미리 학습된 BERT 모델의 파라미터를 로드하여 BERT 모델을 미리 학습된 상태로 설정합니다.
  • 초기화된 BERT 모델과 어휘 사전을 반환합니다.

이 함수를 호출하면 미리 학습된 BERT 모델과 해당 어휘 사전이 반환됩니다. 이 모델을 사용하여 다양한 자연어 처리 작업을 수행할 수 있습니다.

 

 

To facilitate demonstration on most of machines, we will load and fine-tune the small version (“bert.small”) of the pretrained BERT in this section. In the exercise, we will show how to fine-tune the much larger “bert.base” to significantly improve the testing accuracy.

 

대부분의 머신에서 시연을 용이하게 하기 위해 이 섹션에서는 사전 훈련된 BERT의 작은 버전("bert.small")을 로드하고 미세 조정합니다. 이 연습에서는 훨씬 더 큰 "bert.base"를 미세 조정하여 테스트 정확도를 크게 향상시키는 방법을 보여줍니다.

 

devices = d2l.try_all_gpus()
bert, vocab = load_pretrained_model(
    'bert.small', num_hiddens=256, ffn_num_hiddens=512, num_heads=4,
    num_blks=2, dropout=0.1, max_len=512, devices=devices)

위의 코드는 BERT 모델을 불러오고 설정하는 작업을 수행합니다. 

  1. devices = d2l.try_all_gpus(): 이 코드는 가능한 모든 GPU 디바이스를 사용 가능한 경우 가져옵니다. 이것은 여러 GPU에서 BERT 모델을 병렬로 학습하거나 추론할 때 사용됩니다.
  2. load_pretrained_model(...): 이 함수는 앞서 정의한 load_pretrained_model 함수를 호출하여 미리 학습된 BERT 모델을 로드하고 설정합니다.
    • 'bert.small': 불러올 미리 학습된 BERT 모델의 이름 또는 경로를 나타냅니다.
    • num_hiddens=256: BERT 모델의 은닉 상태 크기를 설정합니다.
    • ffn_num_hiddens=512: BERT 모델의 Feedforward 네트워크에서의 은닉 상태 크기를 설정합니다.
    • num_heads=4: BERT 모델의 어텐션 헤드 개수를 설정합니다.
    • num_blks=2: BERT 모델의 어텐션 블록 수를 설정합니다.
    • dropout=0.1: 드롭아웃 비율을 설정합니다.
    • max_len=512: 입력 시퀀스의 최대 길이를 설정합니다.
    • devices=devices: 사용할 GPU 디바이스 목록을 전달합니다.

이 코드를 실행하면 bert 변수에는 설정된 BERT 모델이 로드되며, vocab 변수에는 어휘 사전이 로드됩니다. 이제 bert 모델을 사용하여 다양한 자연어 처리 작업을 수행할 수 있습니다.

Downloading ../data/bert.small.torch.zip from http://d2l-data.s3-accelerate.amazonaws.com/bert.small.torch.zip...

 

16.7.2. The Dataset for Fine-Tuning BERT

 

For the downstream task natural language inference on the SNLI dataset, we define a customized dataset class SNLIBERTDataset. In each example, the premise and hypothesis form a pair of text sequence and is packed into one BERT input sequence as depicted in Fig. 16.6.2. Recall Section 15.8.4 that segment IDs are used to distinguish the premise and the hypothesis in a BERT input sequence. With the predefined maximum length of a BERT input sequence (max_len), the last token of the longer of the input text pair keeps getting removed until max_len is met. To accelerate generation of the SNLI dataset for fine-tuning BERT, we use 4 worker processes to generate training or testing examples in parallel.

 

SNLI 데이터 세트에 대한 다운스트림 작업 자연어 추론을 위해 맞춤형 데이터 세트 클래스 SNLIBERTDataset를 정의합니다. 각 예에서 전제와 가설은 한 쌍의 텍스트 시퀀스를 형성하고 그림 16.6.2에 설명된 대로 하나의 BERT 입력 시퀀스로 압축됩니다. BERT 입력 시퀀스에서 전제와 가설을 구별하기 위해 세그먼트 ID가 사용된다는 섹션 15.8.4를 상기하세요. BERT 입력 시퀀스의 사전 정의된 최대 길이(max_len)를 사용하면 max_len이 충족될 때까지 더 긴 입력 텍스트 쌍의 마지막 토큰이 계속 제거됩니다. BERT 미세 조정을 위한 SNLI 데이터 세트 생성을 가속화하기 위해 4개의 작업자 프로세스를 사용하여 훈련 또는 테스트 예제를 병렬로 생성합니다.

 

class SNLIBERTDataset(torch.utils.data.Dataset):
    def __init__(self, dataset, max_len, vocab=None):
        all_premise_hypothesis_tokens = [[
            p_tokens, h_tokens] for p_tokens, h_tokens in zip(
            *[d2l.tokenize([s.lower() for s in sentences])
              for sentences in dataset[:2]])]

        self.labels = torch.tensor(dataset[2])
        self.vocab = vocab
        self.max_len = max_len
        (self.all_token_ids, self.all_segments,
         self.valid_lens) = self._preprocess(all_premise_hypothesis_tokens)
        print('read ' + str(len(self.all_token_ids)) + ' examples')

    def _preprocess(self, all_premise_hypothesis_tokens):
        pool = multiprocessing.Pool(4)  # Use 4 worker processes
        out = pool.map(self._mp_worker, all_premise_hypothesis_tokens)
        all_token_ids = [
            token_ids for token_ids, segments, valid_len in out]
        all_segments = [segments for token_ids, segments, valid_len in out]
        valid_lens = [valid_len for token_ids, segments, valid_len in out]
        return (torch.tensor(all_token_ids, dtype=torch.long),
                torch.tensor(all_segments, dtype=torch.long),
                torch.tensor(valid_lens))

    def _mp_worker(self, premise_hypothesis_tokens):
        p_tokens, h_tokens = premise_hypothesis_tokens
        self._truncate_pair_of_tokens(p_tokens, h_tokens)
        tokens, segments = d2l.get_tokens_and_segments(p_tokens, h_tokens)
        token_ids = self.vocab[tokens] + [self.vocab['<pad>']] \
                             * (self.max_len - len(tokens))
        segments = segments + [0] * (self.max_len - len(segments))
        valid_len = len(tokens)
        return token_ids, segments, valid_len

    def _truncate_pair_of_tokens(self, p_tokens, h_tokens):
        # Reserve slots for '<CLS>', '<SEP>', and '<SEP>' tokens for the BERT
        # input
        while len(p_tokens) + len(h_tokens) > self.max_len - 3:
            if len(p_tokens) > len(h_tokens):
                p_tokens.pop()
            else:
                h_tokens.pop()

    def __getitem__(self, idx):
        return (self.all_token_ids[idx], self.all_segments[idx],
                self.valid_lens[idx]), self.labels[idx]

    def __len__(self):
        return len(self.all_token_ids)

이 코드는 SNLI 데이터셋을 BERT 모델의 입력 형식에 맞게 전처리하는 데 사용되는 SNLIBERTDataset 클래스를 정의합니다. 이 클래스는 PyTorch의 torch.utils.data.Dataset 클래스를 상속하며, 데이터를 로드하고 전처리하는 역할을 합니다. 

 

  1. __init__(self, dataset, max_len, vocab=None): 이 클래스의 생성자는 다음과 같은 매개변수를 받습니다.
    • dataset: SNLI 데이터셋.
    • max_len: BERT 입력 시퀀스의 최대 길이.
    • vocab: 어휘 사전 (생략 가능).
  2. _preprocess(self, all_premise_hypothesis_tokens): 이 메서드는 데이터셋을 전처리하고 BERT 모델 입력에 맞게 변환합니다. 멀티프로세스를 사용하여 병렬로 처리하며, BERT 모델에 입력으로 들어갈 토큰 ID, 세그먼트 ID, 유효한 길이를 반환합니다.
  3. _mp_worker(self, premise_hypothesis_tokens): 이 메서드는 멀티프로세스 작업을 위해 호출되며, 입력으로 주어진 전제와 가설 문장의 토큰을 BERT 입력 형식에 맞게 전처리합니다.
  4. _truncate_pair_of_tokens(self, p_tokens, h_tokens): 이 메서드는 전제와 가설 문장의 토큰 길이가 max_len을 초과하지 않도록 자르는 역할을 합니다.
  5. __getitem__(self, idx): 이 메서드는 데이터셋에서 특정 인덱스 idx에 해당하는 데이터를 반환합니다. 이 데이터는 BERT 모델의 입력과 레이블을 포함합니다.
  6. __len__(self): 이 메서드는 데이터셋의 총 데이터 수를 반환합니다.

이 클래스를 사용하면 SNLI 데이터를 BERT 모델에 입력으로 제공하기 위한 데이터셋을 쉽게 생성할 수 있습니다.

 

After downloading the SNLI dataset, we generate training and testing examples by instantiating the SNLIBERTDataset class. Such examples will be read in minibatches during training and testing of natural language inference.

 

SNLI 데이터 세트를 다운로드한 후 SNLIBERTDataset 클래스를 인스턴스화하여 훈련 및 테스트 예제를 생성합니다. 이러한 예제는 자연어 추론을 훈련하고 테스트하는 동안 미니배치로 읽혀집니다.

 

# Reduce `batch_size` if there is an out of memory error. In the original BERT
# model, `max_len` = 512
batch_size, max_len, num_workers = 512, 128, d2l.get_dataloader_workers()
data_dir = d2l.download_extract('SNLI')
train_set = SNLIBERTDataset(d2l.read_snli(data_dir, True), max_len, vocab)
test_set = SNLIBERTDataset(d2l.read_snli(data_dir, False), max_len, vocab)
train_iter = torch.utils.data.DataLoader(train_set, batch_size, shuffle=True,
                                   num_workers=num_workers)
test_iter = torch.utils.data.DataLoader(test_set, batch_size,
                                  num_workers=num_workers)

이 코드는 BERT 모델을 사용하여 SNLI 데이터셋을 학습하기 위한 데이터 로딩 및 전처리 부분을 담당합니다.

  1. batch_size, max_len, num_workers 설정: 이 부분에서는 배치 크기(batch_size), 최대 시퀀스 길이(max_len), 그리고 데이터 로더에 사용할 워커 수(num_workers)를 설정합니다. 원래 BERT 모델에서는 max_len을 512로 사용하나, 메모리 부족 문제가 발생할 경우 이 값을 낮출 수 있습니다.
  2. 데이터 다운로드 및 전처리: data_dir 변수에 SNLI 데이터셋을 다운로드하고 압축을 해제합니다. 그 후, train_set과 test_set을 각각 SNLIBERTDataset 클래스로 초기화합니다. 이 때, max_len은 지정한 값으로 설정하고, vocab은 미리 로드한 어휘 사전을 사용합니다.
  3. 데이터 로더 생성: train_set과 test_set을 기반으로 데이터 로더(train_iter와 test_iter)를 생성합니다. 데이터 로더는 미니배치를 생성하고 데이터를 셔플하며, 병렬로 데이터를 로드하기 위해 num_workers를 사용합니다.

이렇게 설정된 데이터 로더를 사용하여 BERT 모델을 학습하고 평가할 수 있습니다.

read 549367 examples
read 9824 examples

 

16.7.3. Fine-Tuning BERT

As Fig. 16.6.2 indicates, fine-tuning BERT for natural language inference requires only an extra MLP consisting of two fully connected layers (see self.hidden and self.output in the following BERTClassifier class). This MLP transforms the BERT representation of the special “<cls>” token, which encodes the information of both the premise and the hypothesis, into three outputs of natural language inference: entailment, contradiction, and neutral.

 

그림 16.6.2에서 알 수 있듯이 자연어 추론을 위해 BERT를 미세 조정하려면 두 개의 완전히 연결된 레이어로 구성된 추가 MLP만 필요합니다(다음 BERTClassifier 클래스의 self.hidden 및 self.output 참조). 이 MLP는 전제와 가설 모두의 정보를 인코딩하는 특수 "<cls>" 토큰의 BERT 표현을 수반, 모순 및 중립의 세 가지 자연어 추론 출력으로 변환합니다.

 

class BERTClassifier(nn.Module):
    def __init__(self, bert):
        super(BERTClassifier, self).__init__()
        self.encoder = bert.encoder
        self.hidden = bert.hidden
        self.output = nn.LazyLinear(3)

    def forward(self, inputs):
        tokens_X, segments_X, valid_lens_x = inputs
        encoded_X = self.encoder(tokens_X, segments_X, valid_lens_x)
        return self.output(self.hidden(encoded_X[:, 0, :]))

이 모델은 다음과 같은 구조를 가집니다:

  1. self.encoder: BERT 모델의 인코더 부분을 가져와서 저장합니다. 이는 입력 데이터에 대한 특성 추출을 담당합니다.
  2. self.hidden: BERT 모델의 은닉 상태 부분을 가져와서 저장합니다. 이 부분은 모델의 내부 표현을 다룹니다.
  3. self.output: 감정 분류를 위한 출력 레이어로, 3개의 클래스로 분류하기 위한 선형 레이어입니다.

forward 메서드에서는 다음과 같은 과정을 거칩니다:

  1. 입력 데이터(inputs)를 받습니다. 이 입력 데이터는 토큰, 세그먼트, 유효한 길이로 이루어져 있습니다.
  2. 입력 데이터를 BERT 인코더(self.encoder)를 통해 처리하여 인코딩된 데이터(encoded_X)를 얻습니다.
  3. 인코딩된 데이터 중 첫 번째 토큰(encoded_X[:, 0, :])의 표현을 가져와서 이를 출력 레이어(self.output)에 입력합니다.
  4. 출력 레이어는 입력 표현을 활용하여 감정 분류를 수행하고 결과를 반환합니다.

이렇게 정의된 BERTClassifier 모델은 BERT를 기반으로 하여 텍스트 감정 분류를 수행하는 모델입니다.

 

In the following, the pretrained BERT model bert is fed into the BERTClassifier instance net for the downstream application. In common implementations of BERT fine-tuning, only the parameters of the output layer of the additional MLP (net.output) will be learned from scratch. All the parameters of the pretrained BERT encoder (net.encoder) and the hidden layer of the additional MLP (net.hidden) will be fine-tuned.

 

다음에서는 사전 훈련된 BERT 모델 bert가 다운스트림 애플리케이션을 위한 BERTClassifier 인스턴스 net에 공급됩니다. BERT 미세 조정의 일반적인 구현에서는 추가 MLP(net.output)의 출력 레이어 매개변수만 처음부터 학습됩니다. 사전 훈련된 BERT 인코더(net.encoder)의 모든 매개변수와 추가 MLP(net.hidden)의 숨겨진 계층이 미세 조정됩니다.

 

net = BERTClassifier(bert)

이 코드는 앞서 정의한 BERTClassifier 클래스를 사용하여 실제 BERT 모델을 텍스트 감정 분류를 위한 모델로 초기화하는 부분입니다.

여기서 net은 BERTClassifier 클래스의 인스턴스로, bert는 미리 학습된 BERT 모델을 의미합니다. 이 코드를 실행하면 net은 텍스트 감정 분류를 위한 모델로 설정되며, 이 모델은 BERT의 인코더와 은닉 상태를 활용하여 입력된 텍스트 데이터를 분류합니다.

즉, net을 사용하면 미리 학습된 BERT 모델을 감정 분류 작업에 활용할 수 있게 됩니다.

 

Recall that in Section 15.8 both the MaskLM class and the NextSentencePred class have parameters in their employed MLPs. These parameters are part of those in the pretrained BERT model bert, and thus part of parameters in net. However, such parameters are only for computing the masked language modeling loss and the next sentence prediction loss during pretraining. These two loss functions are irrelevant to fine-tuning downstream applications, thus the parameters of the employed MLPs in MaskLM and NextSentencePred are not updated (staled) when BERT is fine-tuned.

 

섹션 15.8에서 MaskLM 클래스와 NextSentencePred 클래스 모두 사용된 MLP에 매개변수를 가지고 있다는 점을 기억하세요. 이러한 매개변수는 사전 훈련된 BERT 모델 bert의 매개변수의 일부이므로 net의 매개변수의 일부입니다. 그러나 이러한 매개변수는 사전 훈련 중 마스크된 언어 모델링 손실과 다음 문장 예측 손실을 계산하는 데만 사용됩니다. 이 두 가지 손실 함수는 다운스트림 애플리케이션을 미세 조정하는 것과 관련이 없으므로 BERT가 미세 조정될 때 MaskLM 및 NextSentencePred에 사용된 MLP의 매개변수가 업데이트(정지)되지 않습니다.

 

To allow parameters with stale gradients, the flag ignore_stale_grad=True is set in the step function of d2l.train_batch_ch13. We use this function to train and evaluate the model net using the training set (train_iter) and the testing set (test_iter) of SNLI. Due to the limited computational resources, the training and testing accuracy can be further improved: we leave its discussions in the exercises.

 

오래된 그래디언트가 있는 매개변수를 허용하려면 d2l.train_batch_ch13의 단계 함수에ignore_stale_grad=True 플래그가 설정됩니다. 우리는 이 함수를 사용하여 SNLI의 훈련 세트(train_iter)와 테스트 세트(test_iter)를 사용하여 모델 네트워크를 훈련하고 평가합니다. 제한된 계산 리소스로 인해 훈련 및 테스트 정확도가 더욱 향상될 수 있습니다. 이에 대한 논의는 연습에 남겨두겠습니다.

 

lr, num_epochs = 1e-4, 5
trainer = torch.optim.Adam(net.parameters(), lr=lr)
loss = nn.CrossEntropyLoss(reduction='none')
net(next(iter(train_iter))[0])
d2l.train_ch13(net, train_iter, test_iter, loss, trainer, num_epochs, devices)

이 코드는 BERT 모델을 텍스트 감정 분류 작업에 학습시키는 부분입니다.

  1. lr, num_epochs 변수는 학습률 (lr)과 학습 에포크 수 (num_epochs)를 설정합니다. lr은 0.0001로 설정되어 있으며, 학습률은 모델 가중치 업데이트에 사용되는 값입니다. num_epochs는 5로 설정되어 있으며, 데이터셋을 5번 반복하여 학습합니다.
  2. trainer 변수는 torch.optim.Adam 옵티마이저를 초기화합니다. 이 옵티마이저는 모델의 파라미터를 업데이트하는 데 사용됩니다.
  3. loss 변수는 nn.CrossEntropyLoss를 초기화합니다. 이 손실 함수는 다중 클래스 분류 작업에서 사용되며, 모델의 출력과 실제 레이블 간의 크로스 엔트로피 손실을 계산합니다. reduction='none'으로 설정되어 있으므로 손실을 각 샘플에 대한 개별 손실로 계산합니다.
  4. net(next(iter(train_iter))[0]) 코드는 학습 데이터의 첫 번째 미니배치를 사용하여 모델을 실행하고 출력을 확인하는 용도로 사용됩니다.
  5. d2l.train_ch13 함수를 호출하여 모델을 학습합니다. 이 함수는 모델, 학습 데이터 반복자, 테스트 데이터 반복자, 손실 함수, 옵티마이저, 학습 에포크 수, 그리고 디바이스를 입력으로 받아 모델을 학습하고 학습 결과를 시각화합니다. 이를 통해 BERT 모델이 텍스트 감정 분류 작업을 수행하도록 학습됩니다.

이러한 단계를 통해 BERT 모델이 주어진 데이터에 대해 감정 분류 작업을 수행하도록 학습됩니다.

loss 0.520, train acc 0.791, test acc 0.786
10588.8 examples/sec on [device(type='cuda', index=0), device(type='cuda', index=1)]

 

16.7.4. Summary

  • We can fine-tune the pretrained BERT model for downstream applications, such as natural language inference on the SNLI dataset.
  • SNLI 데이터세트에 대한 자연어 추론과 같은 다운스트림 애플리케이션을 위해 사전 훈련된 BERT 모델을 미세 조정할 수 있습니다.
  • During fine-tuning, the BERT model becomes part of the model for the downstream application. Parameters that are only related to pretraining loss will not be updated during fine-tuning.
  • 미세 조정 중에 BERT 모델은 다운스트림 애플리케이션을 위한 모델의 일부가 됩니다. 사전 훈련 손실에만 관련된 매개변수는 미세 조정 중에 업데이트되지 않습니다.

 

16.7.5. Exercises

  1. Fine-tune a much larger pretrained BERT model that is about as big as the original BERT base model if your computational resource allows. Set arguments in the load_pretrained_model function as: replacing ‘bert.small’ with ‘bert.base’, increasing values of num_hiddens=256, ffn_num_hiddens=512, num_heads=4, and num_blks=2 to 768, 3072, 12, and 12, respectively. By increasing fine-tuning epochs (and possibly tuning other hyperparameters), can you get a testing accuracy higher than 0.86?
  2. How to truncate a pair of sequences according to their ratio of length? Compare this pair truncation method and the one used in the SNLIBERTDataset class. What are their pros and cons?

 

 

 

 

 

 

 

반응형


반응형

16.6. Fine-Tuning BERT for Sequence-Level and Token-Level Applications — Dive into Deep Learning 1.0.3 documentation (d2l.ai)

 

16.6. Fine-Tuning BERT for Sequence-Level and Token-Level Applications — Dive into Deep Learning 1.0.3 documentation

 

d2l.ai

 

In the previous sections of this chapter, we have designed different models for natural language processing applications, such as based on RNNs, CNNs, attention, and MLPs. These models are helpful when there is space or time constraint, however, crafting a specific model for every natural language processing task is practically infeasible. In Section 15.8, we introduced a pretraining model, BERT, that requires minimal architecture changes for a wide range of natural language processing tasks. On the one hand, at the time of its proposal, BERT improved the state of the art on various natural language processing tasks. On the other hand, as noted in Section 15.10, the two versions of the original BERT model come with 110 million and 340 million parameters. Thus, when there are sufficient computational resources, we may consider fine-tuning BERT for downstream natural language processing applications.

 

이 장의 이전 섹션에서는 RNN, CNN, Attention 및 MLP를 기반으로 하는 자연어 처리 애플리케이션을 위한 다양한 모델을 설계했습니다. 이러한 모델은 공간이나 시간 제약이 있을 때 유용하지만 모든 자연어 처리 작업에 대한 특정 모델을 만드는 것은 사실상 불가능합니다. 섹션 15.8에서는 광범위한 자연어 처리 작업에 대해 최소한의 아키텍처 변경이 필요한 사전 훈련 모델인 BERT를 소개했습니다. 한편, BERT는 제안 당시 다양한 자연어 처리 작업에 대한 최신 기술을 개선했습니다. 반면에 섹션 15.10에서 언급했듯이 원래 BERT 모델의 두 가지 버전에는 1억 1천만 개와 3억 4천만 개의 매개 변수가 있습니다. 따라서 계산 리소스가 충분할 경우 다운스트림 자연어 처리 애플리케이션을 위해 BERT를 미세 조정하는 것을 고려할 수 있습니다.

 

In the following, we generalize a subset of natural language processing applications as sequence-level and token-level. On the sequence level, we introduce how to transform the BERT representation of the text input to the output label in single text classification and text pair classification or regression. On the token level, we will briefly introduce new applications such as text tagging and question answering and shed light on how BERT can represent their inputs and get transformed into output labels. During fine-tuning, the “minimal architecture changes” required by BERT across different applications are the extra fully connected layers. During supervised learning of a downstream application, parameters of the extra layers are learned from scratch while all the parameters in the pretrained BERT model are fine-tuned.

 

다음에서는 자연어 처리 애플리케이션의 하위 집합을 시퀀스 수준 및 토큰 수준으로 일반화합니다. 시퀀스 수준에서는 단일 텍스트 분류 및 텍스트 쌍 분류 또는 회귀에서 텍스트 입력의 BERT 표현을 출력 레이블로 변환하는 방법을 소개합니다. 토큰 수준에서는 텍스트 태깅 및 질문 답변과 같은 새로운 애플리케이션을 간략하게 소개하고 BERT가 입력을 표현하고 출력 레이블로 변환하는 방법을 조명합니다. 미세 조정 중에 다양한 애플리케이션 전반에 걸쳐 BERT에 필요한 "최소 아키텍처 변경"은 추가로 완전히 연결된 레이어입니다. 다운스트림 애플리케이션의 지도 학습 중에 추가 레이어의 매개변수는 사전 학습된 BERT 모델의 모든 매개변수가 미세 조정되는 동안 처음부터 학습됩니다.

 

16.6.1. Single Text Classification

Single text classification takes a single text sequence as input and outputs its classification result. Besides sentiment analysis that we have studied in this chapter, the Corpus of Linguistic Acceptability (CoLA) is also a dataset for single text classification, judging whether a given sentence is grammatically acceptable or not (Warstadt et al., 2019). For instance, “I should study.” is acceptable but “I should studying.” is not.

 

단일 텍스트 분류는 단일 텍스트 시퀀스를 입력으로 사용하고 해당 분류 결과를 출력합니다. 이 장에서 연구한 감정 분석 외에도 CoLA(언어적 수용성 코퍼스)는 주어진 문장이 문법적으로 수용 가능한지 여부를 판단하는 단일 텍스트 분류를 위한 데이터 세트이기도 합니다(Warstadt et al., 2019). 예를 들어, “I should study.” 는 괜찮지만 “I should studying” 문법적으로 틀리다.

 

Fig. 16.6.1&nbsp; Fine-tuning BERT for single text classification applications, such as sentiment analysis and testing linguistic acceptability. Suppose that the input single text has six tokens.&nbsp;그림 16.6.1&nbsp; 감정 분석 및 언어 수용성 테스트와 같은 단일 텍스트 분류 애플리케이션을 위해 BERT를 미세 조정합니다. 입력 단일 텍스트에 6개의 토큰이 있다고 가정합니다.

Section 15.8 describes the input representation of BERT. The BERT input sequence unambiguously represents both single text and text pairs, where the special classification token “<cls>” is used for sequence classification and the special classification token “<sep>” marks the end of single text or separates a pair of text. As shown in Fig. 16.6.1, in single text classification applications, the BERT representation of the special classification token “<cls>” encodes the information of the entire input text sequence. As the representation of the input single text, it will be fed into a small MLP consisting of fully connected (dense) layers to output the distribution of all the discrete label values.

 

16.6. Fine-Tuning BERT for Sequence-Level and Token-Level Applications — Dive into Deep Learning 1.0.3 documentation

 

d2l.ai

섹션 15.8에서는 BERT의 입력 표현을 설명합니다. BERT 입력 시퀀스는 단일 텍스트와 텍스트 쌍을 모두 명확하게 나타냅니다. 여기서 특수 분류 토큰 "<cls>"는 시퀀스 분류에 사용되고 특수 분류 토큰 "<sep>"은 단일 텍스트의 끝을 표시하거나 텍스트 쌍을 구분합니다. . 그림 16.6.1에서 볼 수 있듯이 단일 텍스트 분류 응용 프로그램에서 특수 분류 토큰 "<cls>"의 BERT 표현은 전체 입력 텍스트 시퀀스의 정보를 인코딩합니다. 입력된 단일 텍스트의 표현으로서 완전히 연결된(조밀한) 레이어로 구성된 작은 MLP에 공급되어 모든 개별 레이블 값의 분포를 출력합니다.

 

16.6.2. Text Pair Classification or Regression

We have also examined natural language inference in this chapter. It belongs to text pair classification, a type of application classifying a pair of text.

 

우리는 또한 이 장에서 자연어 추론을 조사했습니다. 텍스트 쌍 분류(text pair classification)는 텍스트 쌍을 분류하는 애플리케이션 유형에 속합니다.

 

Taking a pair of text as input but outputting a continuous value, semantic textual similarity is a popular text pair regression task. This task measures semantic similarity of sentences. For instance, in the Semantic Textual Similarity Benchmark dataset, the similarity score of a pair of sentences is an ordinal scale ranging from 0 (no meaning overlap) to 5 (meaning equivalence) (Cer et al., 2017). The goal is to predict these scores. Examples from the Semantic Textual Similarity Benchmark dataset include (sentence 1, sentence 2, similarity score):

 

한 쌍의 텍스트를 입력으로 사용하지만 연속 값을 출력하는 의미론적 텍스트 유사성은 널리 사용되는 텍스트 쌍 회귀 작업입니다. 이 작업은 문장의 의미적 유사성을 측정합니다. 예를 들어 의미론적 텍스트 유사성 벤치마크 데이터세트에서 한 쌍의 문장의 유사성 점수는 0(의미 중첩 없음)에서 5(동등성을 의미) 범위의 순서 척도입니다(Cer et al., 2017). 목표는 이러한 점수를 예측하는 것입니다. 의미론적 텍스트 유사성 벤치마크 데이터 세트의 예는 다음과 같습니다(문장 1, 문장 2, 유사성 점수).

 

  • “A plane is taking off.”, “An air plane is taking off.”, 5.000;
  • “비행기가 이륙하고 있습니다.”, “비행기가 이륙하고 있습니다.”, 5.000;
  • “A woman is eating something.”, “A woman is eating meat.”, 3.000;
  • “여자가 뭔가를 먹고 있어요.”, “여자가 고기를 먹고 있어요.”, 3.000;
  • “A woman is dancing.”, “A man is talking.”, 0.000.
  • “여자가 춤을 추고 있다.”, “남자가 말하고 있다.”, 0.000.

Fig. 16.6.2&nbsp; Fine-tuning BERT for text pair classification or regression applications, such as natural language inference and semantic textual similarity. Suppose that the input text pair has two and three tokens.

 

Comparing with single text classification in Fig. 16.6.1, fine-tuning BERT for text pair classification in Fig. 16.6.2 is different in the input representation. For text pair regression tasks such as semantic textual similarity, trivial changes can be applied such as outputting a continuous label value and using the mean squared loss: they are common for regression.

 

그림 16.6.1의 단일 텍스트 분류와 비교하면 그림 16.6.2의 텍스트 쌍 분류를 위한 BERT 미세 조정은 입력 표현이 다릅니다. 의미론적 텍스트 유사성과 같은 텍스트 쌍 회귀 작업의 경우 연속 레이블 값을 출력하고 평균 제곱 손실을 사용하는 등 사소한 변경 사항을 적용할 수 있습니다. 이는 회귀에서 일반적입니다.

 

16.6.3. Text Tagging

 

Now let’s consider token-level tasks, such as text tagging, where each token is assigned a label. Among text tagging tasks, part-of-speech tagging assigns each word a part-of-speech tag (e.g., adjective and determiner) according to the role of the word in the sentence. For example, according to the Penn Treebank II tag set, the sentence “John Smith ’s car is new” should be tagged as “NNP (noun, proper singular) NNP POS (possessive ending) NN (noun, singular or mass) VB (verb, base form) JJ (adjective)”.

 

이제 각 토큰에 레이블이 할당되는 텍스트 태그 지정과 같은 토큰 수준 작업을 고려해 보겠습니다. 텍스트 태깅 작업 중에서 품사 태깅은 문장에서 단어의 역할에 따라 각 단어에 품사 태그(예: 형용사 및 한정사)를 할당합니다. 예를 들어 Penn Treebank II 태그 세트에 따르면 "John Smith's car is new"라는 문장은 "NNP(명사, 고유 단수) NNP POS(소유 어미) NN(명사, 단수 또는 대량) VB로 태그되어야 합니다. (동사, 기본형) JJ (형용사)”.

 

Fig. 16.6.3&nbsp; Fine-tuning BERT for text tagging applications, such as part-of-speech tagging. Suppose that the input single text has six tokens.

Fine-tuning BERT for text tagging applications is illustrated in Fig. 16.6.3. Comparing with Fig. 16.6.1, the only distinction lies in that in text tagging, the BERT representation of every token of the input text is fed into the same extra fully connected layers to output the label of the token, such as a part-of-speech tag.

 

텍스트 태깅 애플리케이션을 위한 BERT 미세 조정은 그림 16.6.3에 설명되어 있습니다. 그림 16.6.1과 비교하면 유일한 차이점은 텍스트 태깅에 있다는 것입니다. 입력 텍스트의 모든 토큰에 대한 BERT 표현은 품사 태그와 같은 토큰의 레이블을 출력하기 위해 동일한 추가 완전히 연결된 레이어에 공급됩니다.

 

16.6.4. Question Answering

As another token-level application, question answering reflects capabilities of reading comprehension. For example, the Stanford Question Answering Dataset (SQuAD v1.1) consists of reading passages and questions, where the answer to every question is just a segment of text (text span) from the passage that the question is about (Rajpurkar et al., 2016). To explain, consider a passage “Some experts report that a mask’s efficacy is inconclusive. However, mask makers insist that their products, such as N95 respirator masks, can guard against the virus.” and a question “Who say that N95 respirator masks can guard against the virus?”. The answer should be the text span “mask makers” in the passage. Thus, the goal in SQuAD v1.1 is to predict the start and end of the text span in the passage given a pair of question and passage.

 

또 다른 토큰 수준 응용 프로그램인 질문 답변은 독해 능력을 반영합니다. 예를 들어, Stanford 질문 응답 데이터 세트(SQuAD v1.1)는 읽기 구절과 질문으로 구성되며, 모든 질문에 대한 대답은 질문에 관한 구절의 텍스트 세그먼트(텍스트 범위)입니다(Rajpurkar et al. , 2016). 설명하려면 “일부 전문가들은 마스크의 효능이 확실하지 않다고 보고합니다. 그러나 마스크 제조업체들은 N95 마스크와 같은 자사 제품이 바이러스를 예방할 수 있다고 주장합니다.” 그리고 “N95 마스크가 바이러스를 예방할 수 있다고 누가 말합니까?”라는 질문. 대답은 해당 구절의 "마스크 제작자"라는 텍스트 범위여야 합니다. 따라서 SQuAD v1.1의 목표는 한 쌍의 질문과 지문이 주어진 지문에서 텍스트 범위의 시작과 끝을 예측하는 것입니다.

 

Fig. 16.6.4&nbsp; Fine-tuning BERT for question answering. Suppose that the input text pair has two and three tokens.

 

To fine-tune BERT for question answering, the question and passage are packed as the first and second text sequence, respectively, in the input of BERT. To predict the position of the start of the text span, the same additional fully connected layer will transform the BERT representation of any token from the passage of position i into a scalar score si. Such scores of all the passage tokens are further transformed by the softmax operation into a probability distribution, so that each token position i in the passage is assigned a probability pi of being the start of the text span. Predicting the end of the text span is the same as above, except that parameters in its additional fully connected layer are independent from those for predicting the start. When predicting the end, any passage token of position i is transformed by the same fully connected layer into a scalar score ei. Fig. 16.6.4 depicts fine-tuning BERT for question answering.

 

질문 답변을 위해 BERT를 미세 조정하기 위해 질문과 구절은 BERT 입력에서 각각 첫 번째 및 두 번째 텍스트 시퀀스로 패킹됩니다. 텍스트 범위의 시작 위치를 예측하기 위해 동일한 추가 완전 연결 레이어는 위치 i의 통과에서 모든 토큰의 BERT 표현을 스칼라 점수 si로 변환합니다. 모든 구절 토큰의 이러한 점수는 소프트맥스 연산에 의해 확률 분포로 추가로 변환되어 구절의 각 토큰 위치 i에 텍스트 범위의 시작이 될 확률 pi가 할당됩니다. 텍스트 범위의 끝을 예측하는 것은 추가 완전 연결 레이어의 매개 변수가 시작 예측을 위한 매개 변수와 독립적이라는 점을 제외하면 위와 동일합니다. 끝을 예측할 때 위치 i의 모든 통과 토큰은 동일한 완전 연결 레이어에 의해 스칼라 점수 ei로 변환됩니다. 그림 16.6.4는 질문 응답을 위한 BERT의 미세 조정을 보여줍니다.

 

 

For question answering, the supervised learning’s training objective is as straightforward as maximizing the log-likelihoods of the ground-truth start and end positions. When predicting the span, we can compute the score si+ej for a valid span from position i to position j (i≤j), and output the span with the highest score.

 

질문 답변의 경우 지도 학습의 훈련 목표는 실제 시작 및 끝 위치의 로그 가능성을 최대화하는 것만큼 간단합니다. 스팬을 예측할 때 i 위치에서 j 위치(i≤j)까지 유효한 스팬에 대해 점수 si+ej를 계산하고 점수가 가장 높은 스팬을 출력할 수 있습니다.

 

16.6.5. Summary

  • BERT requires minimal architecture changes (extra fully connected layers) for sequence-level and token-level natural language processing applications, such as single text classification (e.g., sentiment analysis and testing linguistic acceptability), text pair classification or regression (e.g., natural language inference and semantic textual similarity), text tagging (e.g., part-of-speech tagging), and question answering.

    BERT는 single text classification, text pair classification or regression, text tagging, question answering 같은 sequence-level과 token level natural language processing applications에 대해 최소한의 아키텍쳐 변경만으로 task 를 수행할 수 있도록 함.

  • During supervised learning of a downstream application, parameters of the extra layers are learned from scratch while all the parameters in the pretrained BERT model are fine-tuned.

    다운스트림 애플리케이션의 지도 학습 중에 추가 레이어의 매개변수는 사전 학습된 BERT 모델의 모든 매개변수가 미세 조정되는 동안 처음부터 학습됩니다.

 

16.6.6. Exercises

  1. Let’s design a search engine algorithm for news articles. When the system receives an query (e.g., “oil industry during the coronavirus outbreak”), it should return a ranked list of news articles that are most relevant to the query. Suppose that we have a huge pool of news articles and a large number of queries. To simplify the problem, suppose that the most relevant article has been labeled for each query. How can we apply negative sampling (see Section 15.2.1) and BERT in the algorithm design?
  2. How can we leverage BERT in training language models?
  3. Can we leverage BERT in machine translation?

 

반응형


반응형

16.4. Natural Language Inference and the Dataset — Dive into Deep Learning 1.0.3 documentation (d2l.ai)

 

16.4. Natural Language Inference and the Dataset — Dive into Deep Learning 1.0.3 documentation

 

d2l.ai

 

16.5. Natural Language Inference: Using Attention

We introduced the natural language inference task and the SNLI dataset in Section 16.4. In view of many models that are based on complex and deep architectures, Parikh et al. (2016) proposed to address natural language inference with attention mechanisms and called it a “decomposable attention model”. This res