Hoşgeldin Misafir

BERT İnce Ayarı ve Uygulamaları

Mustafa73

20 Eyl 2023
423 Mesaj

Aktiflik

Seviye

Deneyim

TIM / GÖREV:
Merhaba ben Mustafa73 Lojistik Tim adına paylaşım yapıyorum. BERT İnce Ayarı ve Uygulamaları makalesinde sizi görmekten mutluyum.

Dizi ve Belirteç Düzeyinde BERT İnce Ayarı

BERT (Bidirectional Encoder Representations from Transformers), doğal dil işleme (NLP) görevlerinde sıklıkla kullanılan güçlü bir modeldir. BERT'in ince ayarı, belirli bir görevde daha iyi performans göstermesi için önceden eğitilmiş modelin yeniden eğitilmesini içerir. Bu işlemi, dizi düzeyinde ve belirteç düzeyinde uygulamalara göre yapabiliriz.

Dizi Düzeyinde Uygulamalar

Tek Metin Sınıflandırması
Tek metin sınıflandırması, bir metin dizisini girdi olarak alır ve bu metni belirli kategorilere ayırır. BERT modeline bir metin verildiğinde, bu metin özel bir "sınıflandırma belirteci" ([CLS]) ile başlatılır ve "[SEP]" belirteci ile sonlandırılır. "[CLS]" belirteci, tüm metnin temsilini kodlar ve bu belirtecin çıktısı sınıflandırma işlemi için kullanılır.

Metin Çifti Sınıflandırması
Metin çifti sınıflandırması, iki metin dizisini (örneğin iki cümleyi) girdi olarak alır ve bu metinlerin arasındaki ilişkiyi (benzerlik, bağlantı, vb.) değerlendirir. İki metin, [CLS] belirteci ile başlatılır, ilk metin "[SEP]" belirteci ile ayrılır ve ardından ikinci metin gelir. Bu tür bir uygulamada, BERT modelinin çıktısı iki metin arasındaki benzerliği veya ilişkiyi belirlemek için kullanılır.

Belirteç Düzeyinde Uygulamalar

Metin Etiketleme
Metin etiketleme, her kelimeye veya belirtece bir etiket atanmasını gerektirir. Örneğin, konuşma parçası etiketleme (POS tagging) her kelimeyi dil bilgisi kategorilerine (isim, sıfat, fiil, vb.) ayırır. BERT modeli, metindeki her kelimeyi ayrı ayrı temsil eder ve her kelimeye karşılık gelen etiketleri tahmin eder.

Soru Yanıtlama
Soru yanıtlama, bir pasaj ve bir soru verildiğinde, pasajın içerisinden doğru cevabı bulmayı amaçlar. BERT modeli, soruyu ve pasajı bir arada işler ve cevabın başladığı ve bittiği konumları tahmin eder. Model, metin aralığının başlangıcı ve sonu için ayrı ayrı skorlar hesaplar ve en yüksek skora sahip aralığı cevap olarak seçer.

Aşağıda, BERT modelini dizi ve belirteç düzeyinde ince ayarlamak için gerekli kodları sunuyorum. Bu kodlar, BERT modelini SNLI (Stanford Doğal Dil Çıkarımı) veri kümesi üzerinde ince ayarlayarak doğal dil çıkarımı görevini yerine getirir.

Gerekli Kütüphanelerin İndirilmesi ve Ayarlanması

Python:
import json
import os
import torch
from torch import nn
from torch.utils.data import Dataset, DataLoader
import d2l

# BERT Modeli ve Kelime Dağarcığının Yüklenmesi
def load_pretrained_model(pretrained_model, num_hiddens, ffn_num_hiddens, num_heads, num_layers, dropout, max_len, devices):
    data_dir = d2l.download_extract(pretrained_model)
    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, norm_shape=[256],
                         ffn_num_input=256, ffn_num_hiddens=ffn_num_hiddens,
                         num_heads=4, num_layers=2, dropout=dropout,
                         max_len=max_len, key_size=256, query_size=256,
                         value_size=256, hid_in_features=256,
                         mlm_in_features=256, nsp_in_features=256)
    bert.load_state_dict(torch.load(os.path.join(data_dir, 'pretrained.params')))
    return bert, vocab

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

Veri Kümesi Sınıfı

Python:
class SNLIBERTDataset(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)
    
    def _preprocess(self, all_premise_hypothesis_tokens):
        with multiprocessing.Pool(4) as pool:
            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):
        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)

Eğitim ve Test Verilerinin Yüklenmesi

Python:
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 = DataLoader(train_set, batch_size, shuffle=True, num_workers=num_workers)
test_iter = DataLoader(test_set, batch_size, num_workers=num_workers)

Model Tanımı

Python:
class BERTClassifier(nn.Module):
    def __init__(self, bert):
        super(BERTClassifier, self).__init__()
        self.encoder = bert.encoder
        self.hidden = bert.hidden
        self.output = nn.Linear(256, 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, :]))

net = BERTClassifier(bert)

Modelin Eğitilmesi

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

Bu kodlar, BERT modelinin SNLI veri kümesi üzerinde ince ayarlanmasını ve doğal dil çıkarımı görevinde kullanılmasını sağlar. Bu süreç, dizi ve belirteç düzeyinde çeşitli uygulamalar için modelin nasıl uyarlanabileceğini göstermektedir.

LOJİSTİK TİM SUNDU