GPT2 teksti klassifitseerimiseks, kasutades kallistavaid näotransformereid

Allikasõlm: 809063

teksti klassifikatsioon

Seda sülearvutit kasutatakse GPT2 mudeli peenhäälestamiseks teksti klassifitseerimiseks Kallistav nägu trafod kohandatud andmestiku raamatukogu.

Hugging Face on meile väga tore, et hõlmame kõiki GPT2 jaoks vajalikke funktsioone klassifitseerimisülesannetes kasutamiseks. Aitäh kallistav nägu!

Ma ei leidnud palju teavet selle kohta, kuidas GPT2 klassifitseerimiseks kasutada, mistõttu otsustasin teha selle õpetuse sarnase struktuuriga teiste trafomudelitega.

Kui see põhjalik hariv sisu on teile kasulik, tellige meie AI-uuringute meililist hoiatada, kui avaldame uut materjali. 

Peamine idee: Kuna GPT2 on dekoodri transformaator, kasutatakse sisendjärjestuse viimast luba järgmise märgi kohta, mis peaks järgnema sisendile. See tähendab, et sisendjada viimane märk sisaldab kogu ennustuseks vajalikku teavet. Seda silmas pidades saame kasutada seda teavet genereerimisülesande asemel klassifitseerimisülesande ennustuste tegemiseks.

Teisisõnu, selle asemel, et kasutada ennustamiseks esimest märgi manustamist, nagu me Bertis, kasutame GPT2-ga ennustamiseks viimast märgi manustamist.

Kuna Bertis hoolisime ainult esimesest märgist, siis polsterdasime paremale. Nüüd kasutame GPT2-s ennustamiseks viimast märki, seega peame vasakul pool polsterdama. Tänu HuggingFace Transformersile tehtud kenale versiooniuuendusele saame GPT2 Tokenizeri konfigureerida just seda tegema.

Mida peaksin selle märkmiku kohta teadma?

Kuna ma kasutan PyTorchi meie trafode mudelite viimistlemiseks, on kõik PyTorchiga seotud teadmised väga kasulikud.

Teades natuke sellest trafod ka raamatukogu aitab.

Kuidas seda märkmikku kasutada?

Nagu iga projekti puhul, ehitasin selle sülearvuti taaskasutatavust silmas pidades.

Kõik muudatused toimuvad andmetöötluse osas, kus peate kohandama PyTorchi andmekomplekti, Data Collatorit ja DataLoaderit vastavalt oma andmevajadustele.

Kõik parameetrid, mida saab muuta, on all Import osa. Iga parameeter on kenasti kommenteeritud ja üles ehitatud nii, et see oleks võimalikult intuitiivne.

Andmebaas

See märkmik hõlmab kohandatud andmestiku trafode eeltreeningut. Kasutan tuntud filmide arvustusi positiivselt – negatiivse märgistusega Suur filmiarvustuse andmestik.

Stanfordi veebisaidil esitatud kirjeldus:

See on binaarse sentimentide klassifitseerimise andmestik, mis sisaldab oluliselt rohkem andmeid kui varasemad võrdlusandmed. Pakume 25,000 25,000 ülipolaarset filmiarvustust koolituse jaoks ja XNUMX XNUMX testimiseks. Kasutamiseks on ka täiendavaid märgistamata andmeid. Pakutakse toorteksti ja juba töödeldud sõnade kotti vorminguid. Lisateabe saamiseks vaadake väljaandes sisalduvat README-faili.

Miks see andmestik? Usun, et seda on klassifitseerimiseks lihtne mõista ja kasutada. Arvan, et sentimentandmetega on alati lõbus töötada.

Kodeerimine

Nüüd teeme natuke kodeerimist! Vaatame läbi sülearvuti kõik kodeerimislahtrid ja kirjeldame, mida see teeb, mis on kood ja millal see on asjakohane – näitame väljundit.

Tegin selle vormingu nii, et seda oleks lihtne jälgida, kui otsustate käivitada iga koodilahtri oma Pythoni märkmikus.

Kui ma õpin õpetusest, proovin alati tulemusi korrata. Usun, et seda on lihtne jälgida, kui selgituste kõrval on kood.

Allalaadimine

Lae alla Suur filmiarvustuse andmestik ja pakkige see kohapeal lahti.

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

Installi

  • trafod kogu Hugging Face'i suurepärase koodi kasutamiseks tuleb installida teek. Uusima versiooni saamiseks installin selle otse GitHubist.
  • ml_asjad raamatukogu, mida kasutatakse mitmesuguste masinõppega seotud ülesannete jaoks. Lõin selle teegi, et vähendada iga masinõppeprojekti jaoks kirjutatava koodi hulka.
# 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

Import

Importige selle märkmiku jaoks kõik vajalikud teegid.Deklareerige selle märkmiku jaoks kasutatavad parameetrid:

  • set_seed(123) – Reprodutseeritavuse tagamiseks on alati hea fikseerida seeme.
  • epochs – Treeninguperioodide arv (autorid soovitavad 2–4).
  • batch_size – Partiide arv – sõltuvalt järjestuse maksimaalsest pikkusest ja GPU mälust. 512 jada pikkuse puhul töötab TAVALISELT 10-ne partii cuda mäluprobleemideta. Väikese jada pikkuse jaoks võite proovida 32 või suuremat partiid. max_length – tekstijadade polsterdamine või kärpimine kindla pikkusega. Treenimise kiirendamiseks panen selle 60 peale.
  • device - Otsige kasutatavat GPU-d. Kui GPU-d ei leitud, kasutab see vaikimisi protsessorit.
  • model_name_or_path – Trafo mudeli nimi – kasutab juba eelkoolitatud mudelit. Trafo mudeli tee – laadib teie enda mudeli kohalikult kettalt. Selles õpetuses ma kasutan gpt2 mudel.
  • labels_ids – Siltide ja nende ID sõnastik – seda kasutatakse stringi siltide teisendamiseks numbriteks.
  • n_labels – Mitut silti me selles andmekogumis kasutame. Seda kasutatakse klassifitseerimispea suuruse määramiseks.
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)

Abifunktsioonid

Mulle meeldib hoida kõik selles märkmikus kasutatavad klassid ja funktsioonid selle jaotise all, et säilitada märkmiku puhas välimus:

Filmiarvustuste andmestik (andmekogum)

Kui olete varem PyTorchiga töötanud, on see üsna tavaline. Vajame seda klassi oma andmestiku lugemiseks, sõelumiseks ja tekstide tagastamiseks koos nendega seotud siltidega.

Selles klassis pean lugema ainult iga faili sisu, kasutama fix_texti, et parandada Unicode'i probleeme ning jälgida positiivseid ja negatiivseid tundeid.

Lisan kõik tekstid ja sildid nimekirjadesse.

Sellel PyTorchi andmestikuklassil on kolm põhiosa:

  • selles() kus me loeme andmekogumist ja teisendame teksti ja sildid numbriteks.
  • len () kus peame tagastama loetud näidete arvu. Seda kasutatakse len(MovieReviewsDataset()) kutsumisel.
  • getitem() kasutab alati sisendiks sisendväärtust, mis tähistab seda, millist näidet meie näidetest meie andmestikust tagastada. Kui väärtus 3 on läbitud, tagastame oma andmestiku näite positsioonil 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

Kasutan seda klassi andmekoguja loomiseks. Seda kasutatakse DataLoaderis mudelile edastatavate andmekogude loomiseks. Kasutan tekstide ja siltide numbriteks teisendamiseks igas järjestuses märgiseadistajat ja siltide kodeerijat.

Meile vedas, Hugging Face mõtles kõigele ja pani tokenisaatori tegema kõik rasked toimingud (teksti jagama märkideks, polsterdama, kärpima, kodeerima teksti numbriteks) ning seda on väga lihtne kasutada!

Sellel andmekoguja klassil on kaks põhiosa:

  • selles() kus initsialiseerime tokenisaatori, mida kavatseme kasutada, kuidas oma silte kodeerida ja kas peame määrama jada pikkuseks teistsuguse väärtuse.
  • helistama() kasutatakse funktsioonide kogujana, mis võtab sisendiks hulga andmenäiteid. See peab tagastama objekti vormingus, mida saab meie mudelile toita. Õnneks teeb meie tokenisaator seda meie eest ja tagastab muutujate sõnastiku, mis on valmis mudelile sisestamiseks järgmiselt: model(**inputs). Kuna me viimistleme mudelit, lisasin ka sildid.
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

rong(andmelugeja, optimeerija_, planeerija_, seade_)

Lõin selle funktsiooni DataLoaderi objekti täielikuks läbimiseks (objekt DataLoader luuakse meie Dataset* tüüpi objektist, kasutades klassi **MovieReviewsDataset). See on põhimõtteliselt üks epohhirong läbi kogu andmestiku.

Andmelaadur luuakse PyTorch DataLoaderist, mis võtab MovieReviewsDataset klassist loodud objekti ja paneb iga näite partiidena. Nii saame oma mudelite andmekoguseid toita!

Optimeerija_ ja planeerija_ on PyTorchis väga levinud. Nad peavad koolituse ajal värskendama meie mudeli parameetreid ja värskendama meie õppimiskiirust. Seal on palju enamat, kuid ma ei hakka detailidesse laskuma. See võib tegelikult olla tohutu jäneseauk, kuna nende funktsioonide taga toimub PALJU, mille pärast me ei pea muretsema. Aitäh PyTorch!

Selle käigus jälgime tegelikke ja prognoositavaid silte koos kadudega.

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

valideerimine (andmelugeja, seade_)

Rakendasin selle funktsiooni väga sarnaselt rongiga, kuid ilma parameetrite värskendamise, tagasikäigu ja gradiendi korraliku osata. Me ei pea tegema kõiki neid VÄGA arvutusmahukaid ülesandeid, sest me hoolime ainult oma mudeli ennustustest.

Kasutan DataLoaderit sarnaselt rongiga, et saada välja partiid, mida meie mudelile sööta.

Selle käigus jälgin tegelikke ja ennustatud silte koos kadudega.

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

Laadige mudel ja tokenisaator

Eelkoolitatud GPT2 trafo kolme olulise osa laadimine: konfiguratsioon, tokenisaator ja mudel.

Selle näite puhul kasutan gpt2 HuggingFace'i eelkoolitatud trafodest. Võite kasutada mis tahes soovitud GP2 variatsioone.

Luues model_config Mainin oma klassifitseerimisülesande jaoks vajalike siltide arvu. Kuna ma ennustan ainult kahte tunnet: positiivset ja negatiivset, on mul vaja ainult kahte silti num_labels.

Loomine tokenizer on Transformerite teegi kasutamisel üsna tavaline. Pärast tokenisaatori loomist on selle õpetuse jaoks ülioluline seada polsterdus vasakule tokenizer.padding_side = "left" ja lähtestage polsterdusmärk tokenizer.eos_token mis on GPT2 algne jada lõpu tunnus. See on selle õpetuse kõige olulisem osa, kuna GPT2 kasutab ennustamiseks viimast luba, nii et me peame vasakule polsterdama.

HuggingFace tegi juba suurema osa tööst meie eest ära ja lisas GPT2 mudelile klassifitseerimiskihi. Kasutatud mudeli loomisel GPT2ForSequenceClassification. Kuna meil on kohandatud polsterdusmärk, peame selle kasutatava mudeli jaoks lähtestama model.config.pad_token_id. Lõpuks peame mudeli teisaldama varem määratletud seadmesse.

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

Andmekogum ja koguja

Siin loon PyTorch Dataset ja Data Loader koos Data Collatori objektidega, mida kasutatakse andmete sisestamiseks meie mudelisse.

See on koht, kus ma kasutan MovieReviewsDataset klassis PyTorchi andmestiku loomiseks, mis tagastab tekste ja silte.

Kuna me peame oma mudelisse sisestama numbreid, peame teisendama tekstid ja sildid numbriteks. See on koguja eesmärk! Meie mudeli järjestuse väljastamiseks kulub PyTorchi andmestiku poolt väljastatud ja Data Collatori funktsiooni kaudu edastatavad andmed.

Hoian tokenisaatori PyTorchi andmekogust eemal, et muuta kood puhtamaks ja paremini struktureerituks. Ilmselgelt saate kasutada PyTorchi andmestiku sees olevat tokenisaatorit ja väljundjadasid, mida saab kasutada otse mudelis ilma andmekogujat kasutamata.

Soovitan tungivalt kasutada valideerimisteksti faili, et teha kindlaks, kui palju treeningut on vaja, et vältida ülepaigutamist. Kui olete välja selgitanud, millised parameetrid annavad parimaid tulemusi, saab valideerimisfaili lisada rongi ja käivitada lõpliku rongi kogu andmestikuga.

Andmekogujat kasutatakse PyTorchi andmekomplekti väljundite vormindamiseks, et need vastaksid GPT2 jaoks vajalikele sisenditele.

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

Rong

Lõin PyTorchi optimeerija ja planeerija kasutamise koolitusel. Kasutasin kõige tavalisemaid trafode mudelites kasutatavaid parameetreid.

Vaatasin määratletud ajastute arvu läbi ja helistasin rong ja kinnitamine funktsioone.

Üritan pärast iga epohhi väljastada sarnast teavet nagu Keras: rongi_kaotus: — val_kadu: — rongi_acc: — kehtiv_acc.

Pärast treeningut koostage treeningu ja valideerimise kaotuse ja täpsuse kõverad, et kontrollida, kuidas koolitus läks.

Märge: Treeninggraafikud võivad tunduda pisut veidrad: valideerimise täpsus algab treeningu täpsusest kõrgemal ja valideerimise kaotus algab treeningu kaotusest madalamal. Tavaliselt on see vastupidine. Eeldan, et andmete jagamine on lihtsalt valideerimisosa jaoks lihtsam või treeningosa või mõlema jaoks liiga raske. Kuna see õpetus käsitleb GPT2 kasutamist klassifitseerimiseks, ei muretse ma mudeli tulemuste pärast liiga palju.

# 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
Rongi ja valideerimise kaotus.
Treenimise ja kinnitamise täpsus.

Hinnake

Klassifitseerimisega tegelemisel on kasulik vaadata täpsust meenutamist ja F1 skoori.

Hea mõõdik mudeli hindamisel on segadusmaatriks.

# 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
Segadusmaatriks normaliseerunud.

Lõpetuseks

Kui olete nii kaugele jõudnud Õnnitlused! 🎊 ja Aitäh! 🙏 Huvi eest minu õpetuse vastu!

Olen seda koodi juba mõnda aega kasutanud ja tunnen, et see on jõudnud punkti, kus see on kenasti dokumenteeritud ja hõlpsasti jälgitav.

Muidugi on mul seda lihtne jälgida, sest ma ehitasin selle. Seetõttu on igasugune tagasiside teretulnud ja see aitab mul oma tulevasi õpetusi täiustada!

Kui näete midagi valesti, andke mulle sellest teada, avades minu lehel probleemi ml_things GitHubi hoidla!

Paljud õpetused on enamasti ühekordsed ja neid ei hooldata. Kavatsen hoida oma õpetusi nii palju kui võimalik.

See artikkel oli algselt avaldatud George Mihaila isiklik veebisait  ja avaldati autori loal uuesti TOPBOTSis.

Kas teile meeldib see artikkel? Registreeruge, et saada rohkem AI värskendusi.

Anname teile teada, kui avaldame rohkem tehnilist haridust.

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

Ajatempel:

Veel alates TOPBOOTID