Yüz Transformatörlerini Sararak Metin Sınıflandırması İçin GPT2

Kaynak Düğüm: 809063

metin sınıflandırması

Bu not defteri, GPT2 modelinde metin sınıflandırması için ince ayar yapmak için kullanılır. Sarılma Yüz transformatörler özel bir veri kümesindeki kitaplık.

Hugging Face, GPT2'nin sınıflandırma görevlerinde kullanılması için gereken tüm işlevleri içermesi bizim için çok güzel. Teşekkürler Hugging Face!

Sınıflandırma için GPT2'nin nasıl kullanılacağına dair fazla bilgi bulamadım, bu yüzden bu öğreticiyi diğer transformatör modelleriyle benzer yapıyı kullanarak yapmaya karar verdim.

Bu kapsamlı eğitim içeriği sizin için yararlıysa, AI araştırma e-posta listemize abone olun yeni materyal çıkardığımızda uyarılmak. 

Ana fikir: GPT2 bir kod çözücü transformatörü olduğundan, giriş sırasının son simgesi, girişi takip etmesi gereken bir sonraki simge hakkında tahminler yapmak için kullanılır. Bu, giriş dizisinin son belirtecinin tahminde ihtiyaç duyulan tüm bilgileri içerdiği anlamına gelir. Bunu aklımızda tutarak, bu bilgiyi üretim görevi yerine bir sınıflandırma görevinde bir tahmin yapmak için kullanabiliriz.

Başka bir deyişle, Bert'te yaptığımız gibi tahmin yapmak için ilk jeton yerleştirmeyi kullanmak yerine, GPT2 ile tahmin yapmak için son jeton yerleştirmeyi kullanacağız.

Bert'te sadece ilk jetonu önemsediğimiz için, sağ tarafa dolgu yapıyorduk. Şimdi GPT2'de tahmin için son jetonu kullanıyoruz, bu yüzden solda doldurmamız gerekecek. HuggingFace Transformers'a yapılan güzel bir yükseltme sayesinde, GPT2 Tokenizer'ı tam da bunu yapacak şekilde yapılandırabiliyoruz.

Bu defter için ne bilmeliyim?

Transformatör modellerimize ince ayar yapmak için PyTorch kullandığım için PyTorch hakkında herhangi bir bilgi çok faydalıdır.

Hakkında biraz bilgi sahibi olmak transformatörler kütüphane de yardımcı olur.

Bu defter nasıl kullanılır?

Her projede olduğu gibi, bu defteri yeniden kullanılabilirliği göz önünde bulundurarak yaptım.

Tüm değişiklikler, PyTorch Veri Kümesini, Veri Harmanlayıcısını ve Veri Yükleyiciyi kendi veri ihtiyaçlarınıza uyacak şekilde özelleştirmeniz gereken veri işleme bölümünde gerçekleşir.

Değiştirilebilecek tüm parametreler, Ithalat Bölüm. Her parametre güzel bir şekilde yorumlanmış ve olabildiğince sezgisel olacak şekilde yapılandırılmıştır.

Veri kümesi

Bu defter, özel bir veri kümesindeki ön eğitim transformatörlerini kapsayacaktır. İyi bilinen film incelemelerini olumlu - olumsuz etiketli kullanacağım Büyük Film İnceleme Veri Kümesi.

Stanford web sitesinde verilen açıklama:

Bu, önceki kıyaslama veri kümelerinden önemli ölçüde daha fazla veri içeren ikili duyarlılık sınıflandırması için bir veri kümesidir. Eğitim için 25,000 son derece kutupsal film incelemesi ve test için 25,000'lik bir dizi sunuyoruz. Kullanım için ek etiketlenmemiş veriler de var. Ham metin ve önceden işlenmiş kelime paketi biçimleri sağlanır. Daha fazla ayrıntı için sürümde bulunan BENİOKU dosyasına bakın.

Neden bu veri kümesi? Sınıflandırma için anlaması ve kullanması kolay bir veri seti olduğuna inanıyorum. Duygu verileriyle çalışmanın her zaman eğlenceli olduğunu düşünüyorum.

kodlama

Şimdi biraz kodlama yapalım! Defterdeki her bir kodlama hücresini gözden geçireceğiz ve ne yaptığını, kodun ne olduğunu ve ne zaman alakalı olduğunu açıklayacağız - çıktıyı göstereceğiz.

Her bir kod hücresini kendi python not defterinizde çalıştırmaya karar verirseniz, bu formatı takip etmesi kolay hale getirdim.

Bir öğreticiden öğrendiğimde, her zaman sonuçları kopyalamaya çalışırım. Açıklamaların yanında kodunuz varsa takip etmenin kolay olduğuna inanıyorum.

Dosya İndir

Atomic Cüzdanı indirin :  Büyük Film İnceleme Veri Kümesi ve yerel olarak açın.

Download the dataset.
!wget -q -nc http://ai.stanford.edu/~amaas/data/sentiment/aclImdb_v1.tar.gz
Unzip the dataset.
!tar -zxf /content/aclImdb_v1.tar.gz

Yükleme

  • transformatörler Hugging Face'in tüm harika kodlarını kullanmak için kitaplığın yüklenmesi gerekir. En son sürümü almak için onu doğrudan GitHub'dan kuracağım.
  • ml_şeyler çeşitli makine öğrenimi ile ilgili görevler için kullanılan kitaplık. Bu kitaplığı, her makine öğrenimi projesi için yazmam gereken kod miktarını azaltmak için oluşturdum.
# Install transformers library.
!pip install -q git+https://github.com/huggingface/transformers.git
# Install helper functions.
!pip install -q git+https://github.com/gmihaila/ml_things.git
Installing build dependencies ... done Getting requirements to build wheel ... done Preparing wheel metadata ... done |████████████████████████████████| 2.9MB 6.7MB/s |████████████████████████████████| 890kB 48.9MB/s |████████████████████████████████| 1.1MB 49.0MB/s Building wheelfor transformers (PEP 517) ... done Building wheel for sacremoses (setup.py) ... done |████████████████████████████████| 71kB 5.2MB/s Building wheel for ml-things (setup.py) ... done Building wheel for ftfy (setup.py) ... done

Ithalat

Bu not defteri için gerekli tüm kitaplıkları içe aktarın. Bu not defteri için kullanılan parametrelerin açıklanması:

  • set_seed(123) - Tekrarlanabilirlik için sabit bir tohum ayarlamak her zaman iyidir.
  • epochs - Eğitim dönemi sayısı (yazarlar 2 ile 4 arasında tavsiye ediyor).
  • batch_size - Parti sayısı - maksimum sıra uzunluğuna ve GPU belleğine bağlı olarak. 512 sıra uzunluğu için 10 USUALY içeren bir grup, cuda bellek sorunları olmadan çalışır. Küçük dizi uzunluğu için 32 veya daha yüksek partiyi deneyebilirsiniz. max_length - Metin dizilerini belirli bir uzunlukta doldurun veya kesin. Eğitimi hızlandırmak için 60'a ayarlayacağım.
  • device - Kullanılacak gpu arayın. Hiçbir gpu bulunmazsa varsayılan olarak cpu kullanır.
  • model_name_or_path - Transformatör modeli adı - önceden eğitilmiş modeli kullanacaktır. Transformatör modelinin yolu - kendi modelinizi yerel diskten yükleyecektir. Bu eğitimde kullanacağım gpt2 modeli.
  • labels_ids - Etiket ve kimlik sözlüğü - bu, dize etiketlerini sayılara dönüştürmek için kullanılacaktır.
  • n_labels - Bu veri kümesinde kaç etiket kullanıyoruz. Bu, sınıflandırma başlığının boyutuna karar vermek için kullanılır.
import io
import os
import torch
from tqdm.notebook import tqdm
from torch.utils.data import Dataset, DataLoader
from ml_things import plot_dict, plot_confusion_matrix, fix_text
from sklearn.metrics import classification_report, accuracy_score
from transformers import (set_seed, TrainingArguments, Trainer, GPT2Config, GPT2Tokenizer, AdamW, get_linear_schedule_with_warmup, GPT2ForSequenceClassification) # Set seed for reproducibility.
set_seed(123) # Number of training epochs (authors on fine-tuning Bert recommend between 2 and 4).
epochs = 4 # Number of batches - depending on the max sequence length and GPU memory.
# For 512 sequence length batch of 10 works without cuda memory issues.
# For small sequence length can try batch of 32 or higher.
batch_size = 32 # Pad or truncate text sequences to a specific length
# if `None` it will use maximum sequence of word piece tokens allowed by model.
max_length = 60 # Look for gpu to use. Will use `cpu` by default if no gpu found.
device = torch.device('cuda' if torch.cuda.is_available() else 'cpu') # Name of transformers model - will use already pretrained model.
# Path of transformer model - will load your own model from local disk.
model_name_or_path = 'gpt2' # Dictionary of labels and their id - this will be used to convert.
# String labels to number ids.
labels_ids = {'neg': 0, 'pos': 1} # How many labels are we using in training.
# This is used to decide size of classification head.
n_labels = len(labels_ids)

Yardımcı İşlevler

Dizüstü bilgisayarın temiz bir görünümünü korumaya yardımcı olmak için bu dizüstü bilgisayarda kullanılacak tüm Sınıfları ve işlevleri bu bölümde tutmayı seviyorum:

MovieReviewsDataset (Veri Kümesi)

Daha önce PyTorch ile çalıştıysanız, bu oldukça standarttır. Veri setimizi okumak, ayrıştırmak ve ilişkili etiketleriyle birlikte metinleri döndürmek için bu sınıfa ihtiyacımız var.

Bu sınıfta sadece her dosyanın içeriğini okumam, herhangi bir Unicode problemini düzeltmek için fix_text'i kullanmam ve olumlu ve olumsuz duyguları takip etmem gerekiyor.

Listelere tüm metinleri ve etiketleri ekleyeceğim.

Bu PyTorch Veri Kümesi sınıfının üç ana bölümü vardır:

  • içinde() veri setinde okuduğumuz ve metin ve etiketleri sayılara dönüştürdüğümüz yer.
  • len () burada okuduğumuz örneklerin sayısını döndürmemiz gerekir. Bu, len (MovieReviewsDataset ()) çağrılırken kullanılır.
  • getitem () her zaman girdi olarak, örneklerimizden hangi örneğin veri kümemizden döndürüleceğini temsil eden bir int değeri alır. 3 değeri geçilirse, 3. konumdaki veri kümemizden örnek formunu döndürürüz.
class MovieReviewsDataset(Dataset): r"""PyTorch Dataset class for loading data. This is where the data parsing happens. This class is built with reusability in mind: it can be used as is as. Arguments: path (:obj:`str`): Path to the data partition. """ def __init__(self, path, use_tokenizer): # Check if path exists. if not os.path.isdir(path): # Raise error if path is invalid. raise ValueError('Invalid `path` variable! Needs to be a directory') self.texts = [] self.labels = [] # Since the labels are defined by folders with data we loop # through each label. for label in ['pos', 'neg']: sentiment_path = os.path.join(path, label) # Get all files from path. files_names = os.listdir(sentiment_path)#[:10] # Sample for debugging. # Go through each file and read its content. for file_name in tqdm(files_names, desc=f'{label} files'): file_path = os.path.join(sentiment_path, file_name) # Read content. content = io.open(file_path, mode='r', encoding='utf-8').read() # Fix any unicode issues. content = fix_text(content) # Save content. self.texts.append(content) # Save encode labels. self.labels.append(label) # Number of exmaples. self.n_examples = len(self.labels) return def __len__(self): r"""When used `len` return the number of examples. """ return self.n_examples def __getitem__(self, item): r"""Given an index return an example from the position. Arguments: item (:obj:`int`): Index position to pick an example to return. Returns: :obj:`Dict[str, str]`: Dictionary of inputs that contain text and asociated labels. """ return {'text':self.texts[item], 'label':self.labels[item]}

Gpt2SınıflandırmaHarmanlayıcı

Veri Harmanlayıcısını oluşturmak için bu sınıfı kullanıyorum. Bu, modele beslenen veri banyolarını oluşturmak için DataLoader'da kullanılacaktır. Metinleri ve etiketleri sayıya dönüştürmek için her dizide jetonlaştırıcı ve etiket kodlayıcı kullanıyorum.

Bizim için şanslıyız, Hugging Face her şeyi düşündü ve tüm ağır kaldırıcıyı (metni jetonlara ayırma, doldurma, kısaltma, metni sayılara kodlama) yaptı ve kullanımı çok kolay!

Bu Veri Toplayıcı sınıfının iki ana bölümü vardır:

  • içinde() Kullanmayı planladığımız jetonlaştırıcıyı nerede başlatacağımızı, etiketlerimizi nasıl kodlayacağımızı ve sıra uzunluğunu farklı bir değere ayarlamamız gerekip gerekmediğini.
  • aramak() girdi olarak veri örneklerinden oluşan bir grup alan işlev harmanlayıcı olarak kullanılır. Modelimize beslenebilecek formatta bir nesne döndürmesi gerekiyor. Neyse ki, tokenleştiricimiz bunu bizim için yapıyor ve modele şu şekilde beslenmeye hazır bir değişkenler sözlüğü döndürüyor: model(**inputs). Modele ince ayar yaptığımız için etiketleri de ekledim.
class Gpt2ClassificationCollator(object): r""" Data Collator used for GPT2 in a classificaiton rask. It uses a given tokenizer and label encoder to convert any text and labels to numbers that can go straight into a GPT2 model. This class is built with reusability in mind: it can be used as is as long as the `dataloader` outputs a batch in dictionary format that can be passed straight into the model - `model(**batch)`. Arguments: use_tokenizer (:obj:`transformers.tokenization_?`): Transformer type tokenizer used to process raw text into numbers. labels_ids (:obj:`dict`): Dictionary to encode any labels names into numbers. Keys map to labels names and Values map to number associated to those labels. max_sequence_len (:obj:`int`, `optional`) Value to indicate the maximum desired sequence to truncate or pad text sequences. If no value is passed it will used maximum sequence size supported by the tokenizer and model. """ def __init__(self, use_tokenizer, labels_encoder, max_sequence_len=None): # Tokenizer to be used inside the class. self.use_tokenizer = use_tokenizer # Check max sequence length. self.max_sequence_len = use_tokenizer.model_max_length if max_sequence_len is None else max_sequence_len # Label encoder used inside the class. self.labels_encoder = labels_encoder return def __call__(self, sequences): r""" This function allowes the class objesct to be used as a function call. Sine the PyTorch DataLoader needs a collator function, I can use this class as a function. Arguments: item (:obj:`list`): List of texts and labels. Returns: :obj:`Dict[str, object]`: Dictionary of inputs that feed into the model. It holddes the statement `model(**Returned Dictionary)`. """ # Get all texts from sequences list. texts = [sequence['text'] for sequence in sequences] # Get all labels from sequences list. labels = [sequence['label'] for sequence in sequences] # Encode all labels using label encoder. labels = [self.labels_encoder[label] for label in labels] # Call tokenizer on all texts to convert into tensors of numbers with # appropriate padding. inputs = self.use_tokenizer(text=texts, return_tensors="pt", padding=True, truncation=True, max_length=self.max_sequence_len) # Update the inputs with the associated encoded labels as tensor. inputs.update({'labels':torch.tensor(labels)}) return inputs

tren (dataloader, optimizer_, scheduler_, device_)

DataLoader nesnesinde tam bir geçiş gerçekleştirmek için bu işlevi oluşturdum (DataLoader nesnesi, ** MovieReviewsDataset sınıfı kullanılarak Dataset * türü nesnemizden oluşturulur). Bu, temel olarak tüm veri kümesindeki bir çağ trenidir.

Veri yükleyici, MovieReviewsDataset sınıfından oluşturulan nesneyi alan ve her örneği toplu işlere koyan PyTorch DataLoader'dan oluşturulur. Bu şekilde, model veri yığınlarımızı besleyebiliriz!

Optimizer_ ve scheduler_ PyTorch'ta çok yaygındır. Modelimizin parametrelerini güncellemeleri ve eğitim sırasında öğrenme oranımızı güncellemeleri gerekir. Bundan çok daha fazlası var ama ayrıntılara girmeyeceğim. Endişelenmemize gerek olmayan bu işlevlerin arkasında ÇOK OLDUĞU için, bu aslında büyük bir tavşan deliği olabilir. PyTorch'a teşekkürler!

Süreçte, kayıpla birlikte gerçek etiketleri ve tahmin edilen etiketleri izliyoruz.

def train(dataloader, optimizer_, scheduler_, device_): r""" Train pytorch model on a single pass through the data loader. It will use the global variable `model` which is the transformer model loaded on `_device` that we want to train on. This function is built with reusability in mind: it can be used as is as long as the `dataloader` outputs a batch in dictionary format that can be passed straight into the model - `model(**batch)`. Arguments: dataloader (:obj:`torch.utils.data.dataloader.DataLoader`): Parsed data into batches of tensors. optimizer_ (:obj:`transformers.optimization.AdamW`): Optimizer used for training. scheduler_ (:obj:`torch.optim.lr_scheduler.LambdaLR`): PyTorch scheduler. device_ (:obj:`torch.device`): Device used to load tensors before feeding to model. Returns: :obj:`List[List[int], List[int], float]`: List of [True Labels, Predicted Labels, Train Average Loss]. """ # Use global variable for model. global model # Tracking variables. predictions_labels = [] true_labels = [] # Total loss for this epoch. total_loss = 0 # Put the model into training mode. model.train() # For each batch of training data... for batch in tqdm(dataloader, total=len(dataloader)): # Add original labels - use later for evaluation. true_labels += batch['labels'].numpy().flatten().tolist() # move batch to device batch = {k:v.type(torch.long).to(device_) for k,v in batch.items()} # Always clear any previously calculated gradients before performing a # backward pass. model.zero_grad() # Perform a forward pass (evaluate the model on this training batch). # This will return the loss (rather than the model output) because we # have provided the `labels`. # The documentation for this a bert model function is here: # https://huggingface.co/transformers/v2.2.0/model_doc/bert.html#transformers.BertForSequenceClassification outputs = model(**batch) # The call to `model` always returns a tuple, so we need to pull the # loss value out of the tuple along with the logits. We will use logits # later to calculate training accuracy. loss, logits = outputs[:2] # Accumulate the training loss over all of the batches so that we can # calculate the average loss at the end. `loss` is a Tensor containing a # single value; the `.item()` function just returns the Python value # from the tensor. total_loss += loss.item() # Perform a backward pass to calculate the gradients. loss.backward() # Clip the norm of the gradients to 1.0. # This is to help prevent the "exploding gradients" problem. torch.nn.utils.clip_grad_norm_(model.parameters(), 1.0) # Update parameters and take a step using the computed gradient. # The optimizer dictates the "update rule"--how the parameters are # modified based on their gradients, the learning rate, etc. optimizer.step() # Update the learning rate. scheduler.step() # Move logits and labels to CPU logits = logits.detach().cpu().numpy() # Convert these logits to list of predicted labels values. predictions_labels += logits.argmax(axis=-1).flatten().tolist() # Calculate the average loss over the training data. avg_epoch_loss = total_loss / len(dataloader) # Return all true labels and prediction for future evaluations. return true_labels, predictions_labels, avg_epoch_loss

doğrulama (dataloader, device_)

Bu işlevi trenle çok benzer bir şekilde uyguladım, ancak parametreler güncellemesi, geriye doğru geçiş ve gradyan uygun kısmı olmadan. Tüm bu ÇOK yoğun hesaplama gerektiren görevleri yapmamıza gerek yok çünkü sadece modelimizin tahminlerini önemsiyoruz.

DataLoader'ı, modelimizi beslemek için gruplar halinde çıkmak için trende olduğu gibi kullanıyorum.

Süreçte, kayıpla birlikte gerçek etiketleri ve tahmin edilen etiketleri izliyorum.

def validation(dataloader, device_): r"""Validation function to evaluate model performance on a separate set of data. This function will return the true and predicted labels so we can use later to evaluate the model's performance. This function is built with reusability in mind: it can be used as is as long as the `dataloader` outputs a batch in dictionary format that can be passed straight into the model - `model(**batch)`. Arguments: dataloader (:obj:`torch.utils.data.dataloader.DataLoader`): Parsed data into batches of tensors. device_ (:obj:`torch.device`): Device used to load tensors before feeding to model. Returns: :obj:`List[List[int], List[int], float]`: List of [True Labels, Predicted Labels, Train Average Loss] """ # Use global variable for model. global model # Tracking variables predictions_labels = [] true_labels = [] #total loss for this epoch. total_loss = 0 # Put the model in evaluation mode--the dropout layers behave differently # during evaluation. model.eval() # Evaluate data for one epoch for batch in tqdm(dataloader, total=len(dataloader)): # add original labels true_labels += batch['labels'].numpy().flatten().tolist() # move batch to device batch = {k:v.type(torch.long).to(device_) for k,v in batch.items()} # Telling the model not to compute or store gradients, saving memory and # speeding up validation with torch.no_grad(): # Forward pass, calculate logit predictions. # This will return the logits rather than the loss because we have # not provided labels. # token_type_ids is the same as the "segment ids", which # differentiates sentence 1 and 2 in 2-sentence tasks. # The documentation for this `model` function is here: # https://huggingface.co/transformers/v2.2.0/model_doc/bert.html#transformers.BertForSequenceClassification outputs = model(**batch) # The call to `model` always returns a tuple, so we need to pull the # loss value out of the tuple along with the logits. We will use logits # later to to calculate training accuracy. loss, logits = outputs[:2] # Move logits and labels to CPU logits = logits.detach().cpu().numpy() # Accumulate the training loss over all of the batches so that we can # calculate the average loss at the end. `loss` is a Tensor containing a # single value; the `.item()` function just returns the Python value # from the tensor. total_loss += loss.item() # get predicitons to list predict_content = logits.argmax(axis=-1).flatten().tolist() # update list predictions_labels += predict_content # Calculate the average loss over the training data. avg_epoch_loss = total_loss / len(dataloader) # Return all true labels and prediciton for future evaluations. return true_labels, predictions_labels, avg_epoch_loss

Yük Modeli ve Tokenizer

Önceden eğitilmiş GPT2 transformatörünün üç temel parçasını yükleme: konfigürasyon, belirteç ve model.

Bu örnek için kullanacağım gpt2 HuggingFace önceden eğitilmiş transformatörlerden. İstediğiniz herhangi bir GP2 varyasyonunu kullanabilirsiniz.

Yaratırken model_config Sınıflandırma görevim için ihtiyacım olan etiketlerin sayısına değineceğim. Yalnızca iki duyguyu tahmin ettiğim için: olumlu ve olumsuz, num_labels.

Tüm tedavilerimizde garanti sunuyoruz. Hastalarımıza ekstra maliyetler çıkartmadan uzun yıllar sağlıklı ve mutlu bir gülümseme için çalışıyoruz. tokenizer Transformers kitaplığını kullanırken oldukça standarttır. Simgeleştiriciyi oluşturduktan sonra, bu öğretici için solda dolguyu ayarlamak çok önemlidir. tokenizer.padding_side = "left" ve dolgu belirtecini başlatmak için tokenizer.eos_token GPT2'nin orijinal sıra sonu belirtecidir. GPT2 tahmin için son jetonu kullandığından, bu öğreticinin en önemli kısmı budur, bu yüzden sola kaydırmamız gerekir.

HuggingFace zaten bizim için işin çoğunu yaptı ve GPT2 modeline bir sınıflandırma katmanı ekledi. Kullandığım modeli oluştururken GPT2ForSequenceClassification. Özel bir padding jetonumuz olduğundan, bunu kullanarak model için onu başlatmamız gerekiyor. model.config.pad_token_id. Son olarak modeli daha önce tanımladığımız cihaza taşımamız gerekecek.

# Get model configuration.
print('Loading configuraiton...')
model_config = GPT2Config.from_pretrained(pretrained_model_name_or_path=model_name_or_path, num_labels=n_labels) # Get model's tokenizer.
print('Loading tokenizer...')
tokenizer = GPT2Tokenizer.from_pretrained(pretrained_model_name_or_path=model_name_or_path)
# default to left padding
tokenizer.padding_side = "left"
# Define PAD Token = EOS Token = 50256
tokenizer.pad_token = tokenizer.eos_token # Get the actual model.
print('Loading model...')
model = GPT2ForSequenceClassification.from_pretrained(pretrained_model_name_or_path=model_name_or_path, config=model_config) # resize model embedding to match new tokenizer
model.resize_token_embeddings(len(tokenizer)) # fix model padding token id
model.config.pad_token_id = model.config.eos_token_id # Load model to defined device.
model.to(device)
print('Model loaded to `%s`'%device)
Loading configuraiton... Loading tokenizer... Loading model... Some weights of GPT2ForSequenceClassification were not initialized from the model checkpoint at gpt2 and are newly initialized: ['score.weight'] You should probably TRAIN this model on a down-stream task to be able to use it for predictions and inference. Model loaded to `cuda`

Veri Kümesi ve Harmanlayıcı

Modelimize veri beslemek için kullanılacak Veri Harmanlayıcı nesneleriyle PyTorch Veri Kümesini ve Veri Yükleyiciyi oluşturduğum yer burasıdır.

Burası kullandığım yer Film İncelemeleriDataset metinleri ve etiketleri döndürecek PyTorch Veri Kümesini oluşturmak için sınıf.

Modelimize sayı girmemiz gerektiğinden, metinleri ve etiketleri sayılara dönüştürmemiz gerekir. Bir harmanlayıcının amacı budur! Modelimiz için sırayı çıkarmak için PyTorch Veri Kümesi tarafından çıkarılan verileri alır ve Veri Harmanlayıcı işlevinden geçer.

Kodu daha temiz ve daha iyi yapılandırılmış hale getirmek için jetonlaştırıcıyı PyTorch Veri Kümesinden uzak tutuyorum. Açıkça belirteç oluşturucuyu PyTorch Veri Kümesi içinde kullanabilir ve bir Veri Harmanlayıcı kullanmadan doğrudan modelde kullanılabilen çıktı dizileri kullanabilirsiniz.

Aşırı uyumu önlemek için ne kadar eğitim gerektiğini belirlemek için bir doğrulama metin dosyası kullanmanızı şiddetle tavsiye ederim. Hangi parametrelerin en iyi sonuçları verdiğini bulduktan sonra, doğrulama dosyası trene dahil edilebilir ve tüm veri kümesiyle son bir tren çalıştırılabilir.

Veri harmanlayıcı, PyTorch Veri Kümesi çıktılarını GPT2 için gereken girişlerle eşleşecek şekilde biçimlendirmek için kullanılır.

# Create data collator to encode text and labels into numbers.
gpt2_classificaiton_collator = Gpt2ClassificationCollator(use_tokenizer=tokenizer, labels_encoder=labels_ids, max_sequence_len=max_length) print('Dealing with Train...')
# Create pytorch dataset.
train_dataset = MovieReviewsDataset(path='/content/aclImdb/train', use_tokenizer=tokenizer)
print('Created `train_dataset` with %d examples!'%len(train_dataset)) # Move pytorch dataset into dataloader.
train_dataloader = DataLoader(train_dataset, batch_size=batch_size, shuffle=True, collate_fn=gpt2_classificaiton_collator)
print('Created `train_dataloader` with %d batches!'%len(train_dataloader)) print() print('Dealing with Validation...')
# Create pytorch dataset.
valid_dataset = MovieReviewsDataset(path='/content/aclImdb/test', use_tokenizer=tokenizer)
print('Created `valid_dataset` with %d examples!'%len(valid_dataset)) # Move pytorch dataset into dataloader.
valid_dataloader = DataLoader(valid_dataset, batch_size=batch_size, shuffle=False, collate_fn=gpt2_classificaiton_collator)
print('Created `eval_dataloader` with %d batches!'%len(valid_dataloader))
Dealing with Train... pos files: 100%|████████████████████████████████|12500/12500 [01:17<00:00, 161.19it/s] neg files: 100%|████████████████████████████████|12500/12500 [01:05<00:00, 190.72it/s] Created `train_dataset` with 25000 examples! Created `train_dataloader` with 782 batches! Reading pos files... pos files: 100%|████████████████████████████████|12500/12500 [00:54<00:00, 230.93it/s] neg files: 100%|████████████████████████████████|12500/12500 [00:42<00:00, 291.07it/s] Created `valid_dataset` with 25000 examples! Created `eval_dataloader` with 782 batches!

Tren

PyTorch tarafından eğitimde optimize edici ve zamanlayıcı kullanımı yarattım. Transformatör modelleri tarafından kullanılan en yaygın parametreleri kullandım.

Tanımlanmış dönemlerin sayısı boyunca döngü yaptım ve tren ve onaylama fonksiyonlar.

Her dönemden sonra Keras ile benzer bilgiler çıkarmaya çalışıyorum: train_loss: - val_loss: - train_acc: - valid_acc.

Eğitimden sonra, eğitimin nasıl gittiğini kontrol etmek için tren ve doğrulama kaybı ve doğruluk eğrilerini çizin.

Not: Eğitim grafikleri biraz garip görünebilir: Doğrulama doğruluğu eğitim doğruluğundan daha yüksek başlar ve doğrulama kaybı eğitim kaybından daha düşük başlar. Normalde bu tam tersi olacaktır. Veri bölüşümünün doğrulama kısmı için daha kolay veya eğitim kısmı veya her ikisi için çok zor olduğunu varsayıyorum. Bu eğitim, sınıflandırma için GPT2'yi kullanmakla ilgili olduğundan, modelin sonuçları hakkında çok fazla endişelenmeyeceğim.

# Note: AdamW is a class from the huggingface library (as opposed to pytorch) # I believe the 'W' stands for 'Weight Decay fix"
optimizer = AdamW(model.parameters(), lr = 2e-5, # default is 5e-5, our notebook had 2e-5 eps = 1e-8 # default is 1e-8. ) # Total number of training steps is number of batches * number of epochs.
# `train_dataloader` contains batched data so `len(train_dataloader)` gives # us the number of batches.
total_steps = len(train_dataloader) * epochs # Create the learning rate scheduler.
scheduler = get_linear_schedule_with_warmup(optimizer, num_warmup_steps = 0, # Default value in run_glue.py num_training_steps = total_steps) # Store the average loss after each epoch so we can plot them.
all_loss = {'train_loss':[], 'val_loss':[]}
all_acc = {'train_acc':[], 'val_acc':[]} # Loop through each epoch.
print('Epoch')
for epoch in tqdm(range(epochs)): print() print('Training on batches...') # Perform one full pass over the training set. train_labels, train_predict, train_loss = train(train_dataloader, optimizer, scheduler, device) train_acc = accuracy_score(train_labels, train_predict) # Get prediction form model on validation data. print('Validation on batches...') valid_labels, valid_predict, val_loss = validation(valid_dataloader, device) val_acc = accuracy_score(valid_labels, valid_predict) # Print loss and accuracy values to see how training evolves. print(" train_loss: %.5f - val_loss: %.5f - train_acc: %.5f - valid_acc: %.5f"%(train_loss, val_loss, train_acc, val_acc)) print() # Store the loss value for plotting the learning curve. all_loss['train_loss'].append(train_loss) all_loss['val_loss'].append(val_loss) all_acc['train_acc'].append(train_acc) all_acc['val_acc'].append(val_acc) # Plot loss curves.
plot_dict(all_loss, use_xlabel='Epochs', use_ylabel='Value', use_linestyles=['-', '--']) # Plot accuracy curves.
plot_dict(all_acc, use_xlabel='Epochs', use_ylabel='Value', use_linestyles=['-', '--'])
Epoch 100%|████████████████████████████████|4/4 [15:11<00:00, 227.96s/it] Training on batches... 100%|████████████████████████████████|782/782 [02:42<00:00, 4.82it/s] Validation on batches... 100%|████████████████████████████████|782/782 [02:07<00:00, 6.13it/s] train_loss: 0.54128 - val_loss: 0.38758 - train_acc: 0.75288 - valid_acc: 0.81904 Training on batches... 100%|████████████████████████████████|782/782 [02:36<00:00, 5.00it/s] Validation on batches... 100%|████████████████████████████████|782/782 [01:41<00:00, 7.68it/s] train_loss: 0.36716 - val_loss: 0.37620 - train_acc: 0.83288 -valid_acc: 0.82912 Training on batches... 100%|████████████████████████████████|782/782 [02:36<00:00, 5.00it/s] Validation on batches... 100%|████████████████████████████████|782/782 [01:24<00:00, 9.24it/s] train_loss: 0.31409 - val_loss: 0.39384 - train_acc: 0.86304 - valid_acc: 0.83044 Training on batches... 100%|████████████████████████████████|782/782 [02:36<00:00, 4.99it/s] Validation on batches... 100%|████████████████████████████████|782/782 [01:09<00:00, 11.29it/s] train_loss: 0.27358 - val_loss: 0.39798 - train_acc: 0.88432 - valid_acc: 0.83292
Eğitim ve doğrulama kaybı.
Eğitim ve doğrulama doğruluğu.

Değerlendirmek

Sınıflandırma ile uğraşırken hassas geri çağırma ve F1 puanına bakmak yararlıdır.

Bir modeli değerlendirirken sahip olunması gereken iyi bir ölçü, kafa karışıklığı matrisidir.

# Get prediction form model on validation data. This is where you should use
# your test data.
true_labels, predictions_labels, avg_epoch_loss = validation(valid_dataloader, device) # Create the evaluation report.
evaluation_report = classification_report(true_labels, predictions_labels, labels=list(labels_ids.values()), target_names=list(labels_ids.keys()))
# Show the evaluation report.
print(evaluation_report) # Plot confusion matrix.
plot_confusion_matrix(y_true=true_labels, y_pred=predictions_labels, classes=list(labels_ids.keys()), normalize=True, magnify=0.1, );
Training on batches... 100%|████████████████████████████████|782/782 [01:09<00:00, 11.24it/s] precision recall f1-score support neg 0.84 0.83 0.83 12500 pos 0.83 0.84 0.83 12500 accuracy 0.83 25000 macro avg 0.83 0.83 0.83 25000 weighted avg 0.83 0.83 0.83 25000
Karışıklık matrisi normale döndü.

Son Not

Bu kadar ileri gittiyseniz Tebrikler! 🎊 ve Teşekkür ederim! 🙏 eğitimime gösterdiğiniz ilgi için!

Bu kodu bir süredir kullanıyorum ve güzel bir şekilde belgelendiği ve takip edilmesi kolay bir noktaya geldiğini hissediyorum.

Elbette takip etmek benim için kolay çünkü onu ben yaptım. Bu nedenle herhangi bir geri bildirim memnuniyetle karşılanır ve gelecekteki eğitimlerimi geliştirmeme yardımcı olur!

Yanlış bir şey görürseniz, lütfen cihazımda bir sorun açarak bana bildirin. ml_things GitHub deposu!

Dışarıdaki birçok öğretici, çoğunlukla tek seferlik bir şeydir ve sürdürülmemektedir. Derslerimi elimden geldiğince güncel tutmayı planlıyorum.

Bu yazı orijinalinde George Mihaila'nın kişisel web sitesi  ve yazarın izniyle TOPBOTS'a yeniden yayınlandı.

Bu makaleyi beğendin mi? Daha fazla AI güncellemesi için kaydolun.

Daha fazla teknik eğitim verdiğimizde size haber vereceğiz.

Kaynak: https://www.topbots.com/gpt2-text-classification-using-hugging-face-transformers/

Zaman Damgası:

Den fazla TOPBOTLAR