GPT2 tekstiluokitukseen halkaisevien kasvomuuntajien avulla

Lähdesolmu: 809063

tekstin luokittelu

Tätä muistikirjaa käytetään GPT2-mallin hienosäätöön tekstiluokittelussa Halaaminen kasvot muuntajat kirjasto mukautetussa tietojoukossa.

Hugging Face on meille erittäin mukava sisällyttää kaikki GPT2: n edellyttämät toiminnot luokitustehtäviin. Kiitos halailevat kasvot!

En löytänyt paljon tietoa GPT2: n käytöstä luokittelussa, joten päätin tehdä tämän opetusohjelman käyttämällä samanlaista rakennetta muiden muuntajan mallien kanssa.

Jos tästä perusteellisesta opetussisällöstä on hyötyä sinulle, tilaa AI-tutkimuksen postituslista hälytys, kun julkaisemme uutta materiaalia. 

Pääidea: Koska GPT2 on dekooderimuuntaja, syötesekvenssin viimeistä tunnusta käytetään ennusteiden tekemiseen seuraavasta tunnuksesta, jonka tulisi seurata tuloa. Tämä tarkoittaa, että tulosekvenssin viimeinen tunnus sisältää kaikki ennustuksessa tarvittavat tiedot. Tässä mielessä voimme käyttää tätä tietoa ennustamiseen luokitustehtävässä sukupolvetehtävän sijaan.

Toisin sanoen sen sijaan, että käytettäisiin ensimmäistä tunnuksen upottamista ennustamiseen kuten Bertissä, käytämme viimeistä tunnuksen upotusta ennustamiseen GPT2: lla.

Koska välitimme vain Bertin ensimmäisestä tunnuksesta, tippaimme oikealle. Nyt GPT2: ssa käytämme viimeistä tunnusta ennustamiseen, joten meidän on täytettävä pad vasemmalla. Mukavan päivityksen ansiosta HuggingFace Transformers -sovellukseen voimme määrittää GPT2 Tokenizerin tekemään niin.

Mitä minun pitäisi tietää tästä muistikirjasta?

Koska käytän PyTorchia muunnosmalliemme hienosäätöön, kaikki tiedot PyTorchista ovat erittäin hyödyllisiä.

Tietäen hieman muuntajat myös kirjasto auttaa.

Kuinka käyttää tätä muistikirjaa?

Kuten jokaisessa projektissa, rakensin tämän muistikirjan uudelleenkäytettävyyttä ajatellen.

Kaikki muutokset tapahtuvat tietojenkäsittelyosassa, jossa sinun on mukautettava PyTorch-tietojoukko, Data Collator ja DataLoader vastaamaan omia datatarpeitasi.

Kaikki muutettavat parametrit ovat Tuonti -osiossa. Jokainen parametri on hienosti kommentoitu ja jäsennelty mahdollisimman intuitiiviseksi.

aineisto

Tämä muistikirja kattaa muuntajien esikäsittelyt mukautetussa tietojoukossa. Käytän tunnettuja elokuvakatselmuksia positiivisilla - negatiivisilla Suuri elokuvan tarkistusdata.

Stanfordin verkkosivustolla oleva kuvaus:

Tämä on binäärisen mielipiteen luokittelun tietojoukko, joka sisältää huomattavasti enemmän tietoa kuin edelliset vertailutietojoukot. Tarjoamme joukon 25,000 25,000 erittäin polaarista elokuvakatselmusta koulutusta varten ja XNUMX XNUMX testiä varten. Myös muita merkitsemättömiä tietoja on käytettävissä. Raakateksti ja jo käsitellyt pussi sanamuotoja tarjotaan. Katso lisätietoja julkaisun sisältämästä README-tiedostosta.

Miksi tämä tietojoukko? Uskon, että on helppo ymmärtää ja käyttää luokitusta varten. Mielestäni tunteiden tiedot ovat aina hauskoja työskennellä.

Koodaus

Tehdään nyt koodausta! Käymme läpi kunkin muistikirjan koodaussolun ja kuvailemme, mitä se tekee, mikä koodi on ja milloin on merkityksellistä - näytä tulos.

Tein tämän muodon olevan helppo seurata, jos päätät suorittaa jokaisen koodisolun omassa python-muistikirjassa.

Kun opetan opetusohjelmasta, yritän aina toistaa tulokset. Uskon, että sitä on helppo seurata, jos selitysten vieressä on koodi.

Lataukset

Lataa Suuri elokuvan tarkistusdata ja pura se paikallisesti.

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

asennuskerrat

  • muuntajat kirjasto on asennettava, jotta voit käyttää kaikkia Hugging Face -palvelun mahtavia koodeja. Saadaksesi uusimman version asennan sen suoraan GitHubista.
  • ml_things kirjasto, jota käytetään erilaisiin koneoppimiseen liittyviin tehtäviin. Loin tämän kirjaston vähentämään koodia, joka minun on kirjoitettava jokaiselle koneoppimisprojektille.
# 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

Tuonti

Tuo kaikki tarvittavat kirjastot tälle muistikirjalle Ilmoita tähän muistikirjaan käytetyt parametrit:

  • set_seed(123) - Aina hyvä asettaa kiinteä siemen uusittavuutta varten.
  • epochs - Harjoittelujaksojen lukumäärä (kirjoittajat suosittelevat välillä 2 ja 4).
  • batch_size - Erien määrä - riippuen sekvenssin maksimipituudesta ja GPU-muistista. 512 sekvenssin pituudelta 10 USUALY-erä toimii ilman cuda-muistiongelmia. Pienelle sekvenssipituudelle voi kokeilla 32 tai sitä suurempaa erää. max_length - Lisää tai katkaise tekstijaksoja tietylle pituudelle. Asetan sen 60: een nopeuttamaan harjoittelua.
  • device - Etsi käytettävää GPU: ta. Käyttää prosessoria oletusarvoisesti, jos prosessoria ei löydy.
  • model_name_or_path - Muuntajamallin nimi - käyttää jo esivalmistettua mallia. Muuntajamallin polku - lataa oman mallisi paikalliselta levyltä. Tässä opetusohjelmassa käytän gpt2 malli.
  • labels_ids - Tunnisteiden ja niiden tunnusten sanakirja - tätä käytetään merkkijonotunnusten muuntamiseen numeroiksi.
  • n_labels - Kuinka monta tarraa käytämme tässä tietojoukossa. Tätä käytetään luokituspään koon määrittämiseen.
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)

Helper-toiminnot

Haluan säilyttää kaikki tässä muistikirjassa käytettävät luokat ja toiminnot tämän osan alla, jotta muistikirja säilyy siistinä:

MovieReviewsDataset (tietojoukko)

Jos olet työskennellyt PyTorchin kanssa aiemmin, tämä on melko vakio. Tarvitsemme tämän luokan lukemaan tietojoukkomme, jäsentämään sen ja palauttamaan tekstit niihin liittyvillä tarroilla.

Tässä luokassa minun täytyy lukea vain jokaisen tiedoston sisältö, korjata kaikki Unicode-ongelmat käyttämällä fix_text-tiedostoa ja seurata positiivisia ja negatiivisia mielipiteitä.

Liitän kaikki tekstit ja tarrat luetteloihin.

Tässä PyTorch-tietojoukkoluokassa on kolme pääosaa:

  • sen sisällä() missä luemme tietojoukosta ja muunnamme tekstin ja tarrat numeroiksi.
  • len () mihin meidän on palautettava lukemiemme esimerkkien lukumäärä. Tätä käytetään soitettaessa len (MovieReviewsDataset ()).
  • getitem () ottaa aina syötteenä int-arvon, joka edustaa sitä, mikä esimerkki esimerkeistämme palaa tietojoukostamme. Jos arvo 3 välitetään, palautamme esimerkkilomakkeen datajoukostamme kohtaan 3.
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]}

Gpt2ClassificationCollator

Käytän tätä luokkaa Data Collatorin luomiseen. Tätä käytetään DataLoaderissa malliin syötettävien tietokylttien luomiseen. Muunnan tekstit ja tarrat numeroiksi kussakin sekvenssissä tokenisaattoria ja tunnisteenkooderia.

Onneksi meille, Hugging Face ajatteli kaiken ja sai tokenizerin tekemään kaiken raskaan nostamisen (jaa teksti rahakkeiksi, pehmuste, katkaisu, koodaa teksti numeroiksi) ja on erittäin helppokäyttöinen!

Tässä tiedonkerääjäluokassa on kaksi pääosaa:

  • sen sisällä() missä alustamme käyttämämme tokenizerin, miten koodataan tunnisteemme ja jos meidän on asetettava sekvenssin pituus eri arvoon.
  • puhelu() käytetään funktion kerääjänä, joka ottaa syötteenä erän datan esimerkkejä. Sen on palautettava objekti, jonka muoto on syötettävissä malliin. Onneksi tokenisaattorimme tekee sen puolestamme ja palauttaa muuttujien sanakirjan, joka on valmis syötettäväksi malliin tällä tavalla: model(**inputs). Koska hienosäätämme mallia, sisällytin myös tarrat.
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

juna (dataloader, optimizer_, Scheduler_, device_)

Loin tämän toiminnon suorittamaan täyden läpikulun DataLoader-objektin läpi (DataLoader-objekti luodaan Dataset * -tyyppisestä objektistamme käyttämällä luokkaa ** MovieReviewsDataset). Tämä on pohjimmiltaan yksi aikakausi koko tietojoukon läpi.

Dataloader luodaan PyTorch DataLoaderista, joka ottaa MovieReviewsDataset-luokassa luodun objektin ja laittaa kukin esimerkki eriin. Tällä tavalla voimme syöttää mallierädatamme!

Optimizer_ ja Scheduler_ ovat hyvin yleisiä PyTorchissa. Heidän on päivitettävä mallimme parametrit ja päivitettävä oppimisnopeutemme harjoittelun aikana. Siinä on paljon enemmän, mutta en aio mennä yksityiskohtiin. Tämä voi itse asiassa olla valtava kaninreikä, koska PALJON tapahtuu näiden toimintojen takana, joita meidän ei tarvitse huolehtia. Kiitos PyTorch!

Prosessissa seurataan todellisia tarroja ja ennustettuja tarroja sekä menetyksiä.

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

vahvistus (dataloader, device_)

Toteutin tämän toiminnon hyvin samalla tavalla kuin juna, mutta ilman parametrien päivitystä, taaksepäin kulkua ja kaltevaa kunnollista osaa. Meidän ei tarvitse tehdä kaikkia näitä ERITTÄIN laskennallisesti intensiivisiä tehtäviä, koska välitämme vain mallimme ennusteista.

Käytän DataLoaderia samalla tavalla kuin junassa erien saamiseksi mallimme syöttämiseksi.

Prosessissa seuraan todellisia tarroja ja ennustettuja tarroja sekä menetyksiä.

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

Lataa malli ja Tokenizer

Esitäytetyn GPT2-muuntajan kolmen olennaisen osan lataaminen: kokoonpano, tokenizer ja malli.

Tässä esimerkissä käytän gpt2 esijännitetyistä HuggingFace-muuntajista. Voit käyttää mitä tahansa GP2-muunnelmia.

Luomalla model_config Mainitsen luokittelutehtävässä tarvitsemani tarrojen määrän. Koska ennustan vain kaksi mielipidettä: positiivisen ja negatiivisen, tarvitsen vain kaksi tarraa num_labels.

Luominen tokenizer on melko vakio käytettäessä Transformers-kirjastoa. Tokenizerin luomisen jälkeen on tärkeää, että tämä opetusohjelma asettaa täytteen vasemmalle tokenizer.padding_side = "left" ja alusta täyttömerkki osoitteeseen tokenizer.eos_token mikä on GPT2: n alkuperäinen sekvenssitunnus. Tämä on tämän opetusohjelman tärkein osa, koska GPT2 käyttää viimeistä tunnusta ennustamiseen, joten meidän on täytettävä vasemmalle.

HuggingFace teki jo suurimman osan työstämme ja lisäsi luokittelutason GPT2-malliin. Luodessani mallia käytin GPT2ForSequenceClassification. Koska meillä on mukautettu pehmustemerkki, se on alustettava mallille model.config.pad_token_id. Lopuksi meidän on siirrettävä malli aiemmin määritettyyn laitteeseen.

# 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`

Aineisto ja kerääjä

Täällä luon PyTorch-tietojoukon ja Data Loaderin Data Collator -objekteilla, joita käytetään tietojen syöttämiseen mallissamme.

Tässä käytän ElokuvaArvostelutDataset luokassa luomaan PyTorch-tietojoukko, joka palauttaa tekstit ja tarrat.

Koska meidän on syötettävä numeroita malliin, tekstit ja tarrat on muunnettava numeroiksi. Tämä on keräilijän tarkoitus! Se vaatii PyTorch-tietojoukon tuottamat ja Data Collator -toiminnon kautta välitetyt tiedot mallin sekvenssin tuottamiseksi.

Pidän tokenisaattorin poissa PyTorch-tietojoukosta, jotta koodi olisi puhtaampi ja jäsennelty paremmin. Voit tietysti käyttää tokenisaattoria PyTorch-tietojoukon sisällä ja tulosekvenssejä, joita voidaan käyttää suoraan malliin käyttämättä Data Collatoria.

Suosittelen vahvasti käyttämään validointitekstitiedostoa sen määrittämiseksi, kuinka paljon koulutusta tarvitaan yliasennuksen välttämiseksi. Kun olet selvittänyt, mitkä parametrit tuottavat parhaat tulokset, validointitiedosto voidaan sisällyttää junaan ja ajaa viimeinen juna koko tietojoukon kanssa.

Tiedonkerääjää käytetään muotoilemaan PyTorch-tietojoukon lähdöt vastaamaan GPT2: lle tarvittavia tuloja.

# 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!

Juna

Loin PyTorchin optimoijan ja ajastimen käytön harjoittelussa. Käytin muuntajan mallien käyttämiä yleisimpiä parametreja.

Laskin läpi määriteltyjen aikakausien määrän ja soitin juna ja validointi toiminnot.

Yritän antaa samanlaisia ​​tietoja jokaisen aikakauden jälkeen kuin Keras: junahäviö: - val_häviö: - juna_acc: - voimassa oleva_acc.

Harjoituksen jälkeen piirrä juna- ja validointihäviöt ja tarkkuuskäyrät tarkistaaksesi, kuinka harjoittelu sujui.

Huomautus: Harjoittelutiedot saattavat näyttää hieman oudolta: Validointitarkkuus alkaa korkeammalla kuin harjoittelutarkkuus ja validointihäviö alkaa matalammalla kuin harjoitteluhäviö. Normaalisti tämä on päinvastaista. Oletan, että tietojen jakaminen on vain helpompaa validointiosalle tai liian vaikea harjoitusosalle tai molemmille. Koska tämä opetusohjelma koskee GPT2: n käyttöä luokittelussa, en välitä liikaa mallin tuloksista.

# 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
Junan ja validoinnin menetys.
Junan ja validoinnin tarkkuus.

Arvioida

Luokittelussa on hyödyllistä tarkastella tarkkuuden palautusta ja F1-pisteitä.

Hyvä mittari mallia arvioitaessa on sekaannusmatriisi.

# 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
Sekaannusmatriisi normalisoitui.

lopullinen Huomautus

Jos pääsisit niin pitkälle Onnea! 🎊 ja Kiitos! 🙏 kiinnostuksestasi opetusohjelmaani kohtaan!

Olen käyttänyt tätä koodia jonkin aikaa ja mielestäni se on tullut pisteeseen, jossa on hienosti dokumentoitu ja helppo seurata.

Minun on tietysti helppo seurata, koska rakensin sen. Siksi kaikki palautteet ovat tervetulleita, ja se auttaa minua parantamaan tulevia opetusohjelmiani!

Jos huomaat jotain vikaa, ilmoita siitä minulle avaamalla ongelma ml_things GitHub-arkisto!

Monet opetusohjelmat ovat enimmäkseen kertaluonteisia, eikä niitä ylläpidetä. Aion pitää opetusohjelmani ajan tasalla niin paljon kuin pystyn.

Tämä artikkeli julkaistiin alunperin George Mihailan henkilökohtainen verkkosivusto  ja julkaistu uudelleen TOPBOTS: lle tekijän luvalla.

Nauti tästä artikkelista? Tilaa lisää AI-päivityksiä.

Ilmoitamme sinulle, kun julkaisemme lisää teknistä koulutusta.

Lähde: https://www.topbots.com/gpt2-text-classification-using-hugging-face-transformers/

Aikaleima:

Lisää aiheesta TOPBOTIT