GPT2 Szövegosztályozáshoz átölelő arctranszformátorok használatával

Forrás csomópont: 809063

szöveges besorolás

Ez a jegyzetfüzet a GPT2 modell finomhangolására szolgál szövegosztályozáshoz Átölelő arc transzformerek könyvtár egy egyéni adatkészleten.

A Hugging Face nagyon kedves számunkra, mert minden olyan funkciót tartalmaz, amely a GPT2 osztályozási feladatokhoz szükséges. Köszönöm Hugging Face!

Nem találtam sok információt a GPT2 osztályozáshoz való használatáról, ezért úgy döntöttem, hogy ezt az oktatóanyagot hasonló szerkezettel készítem el más transzformátormodellekhez.

Ha ez a mélyreható oktatási tartalom hasznos az Ön számára, iratkozzon fel AI kutatási levelezőlistánkra figyelmeztetni kell, ha új anyagot adunk ki. 

Fő gondolat: Mivel a GPT2 egy dekódoló transzformátor, a bemeneti szekvencia utolsó tokenje a bemenetet követő következő token előrejelzésére szolgál. Ez azt jelenti, hogy a bemeneti sorozat utolsó tokenje tartalmazza az előrejelzéshez szükséges összes információt. Ezt szem előtt tartva felhasználhatjuk ezt az információt arra, hogy előrejelzést készítsünk egy osztályozási feladatban a generálási feladat helyett.

Más szavakkal, ahelyett, hogy az első token beágyazást használnánk az előrejelzéshez, mint ahogyan azt Bertben tesszük, az utolsó token beágyazást használjuk a GPT2 jóslására.

Mivel Bertben csak az első token érdekelt, jobbra papoltunk. Most a GPT2-ben az utolsó tokent használjuk az előrejelzéshez, így a bal oldalon kell majd betennünk. A HuggingFace Transformers szép frissítésének köszönhetően a GPT2 Tokenizert pontosan erre konfigurálhatjuk.

Mit kell tudni erről a notebookról?

Mivel PyTorch-ot használok a transzformátormodelleink finomhangolására, a PyTorch-ról szerzett ismeretek nagyon hasznosak.

Tudva egy kicsit a transzformerek a könyvtár is segít.

Hogyan kell használni ezt a notebookot?

Mint minden projektnél, ezt a notebookot is az újrafelhasználhatóság szem előtt tartásával készítettem.

Minden változás az adatfeldolgozási részben fog megtörténni, ahol a PyTorch Dataset, Data Collator és DataLoader testreszabására van szükség a saját adatigényeinek megfelelően.

Az összes megváltoztatható paraméter a alatt található Behozatal szakasz. Minden paraméter szépen kommentálva van, és a lehető legintuitívabb szerkezetű.

adatbázisba

Ez a jegyzetfüzet a transzformátorok előtanítását fedi le egyéni adatkészleten. A jól ismert, pozitív – negatív címkével ellátott filmkritikákat fogom használni Nagy filmismertető adatkészlet.

A Stanford honlapján található leírás:

Ez egy adatkészlet a bináris hangulatosztályozáshoz, amely lényegesen több adatot tartalmaz, mint a korábbi benchmark adatkészletek. 25,000 25,000 erősen poláris filmkritikát biztosítunk edzésekhez és XNUMX XNUMX teszteléshez. További címkézetlen adatok is használhatók. A nyers szöveg és a már feldolgozott szavak formátuma biztosított. További részletekért tekintse meg a kiadásban található README fájlt.

Miért ez az adathalmaz? Szerintem egy könnyen érthető és használható adatkészlet az osztályozáshoz. Szerintem a hangulatadatokkal mindig szórakoztató dolgozni.

Kódolás

Most csináljunk egy kis kódolást! Végigmegyünk a jegyzetfüzet minden kódoló celláján, és leírjuk, mit csinál, mi a kód, és mikor releváns – mutasd meg a kimenetet.

Ezt a formátumot úgy alakítottam ki, hogy könnyen követhető legyen, ha úgy dönt, hogy minden kódcellát a saját python notebookjában futtat.

Amikor egy oktatóanyagból tanulok, mindig megpróbálom megismételni az eredményeket. Úgy gondolom, hogy könnyen követhető, ha a magyarázatok mellett ott van a kód.

Letöltések

Töltse le a Nagy filmismertető adatkészlet és helyben bontsa ki.

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

Telepítések

  • transzformerek A könyvtárat telepíteni kell a Hugging Face fantasztikus kódjának használatához. A legújabb verzió beszerzéséhez közvetlenül a GitHubról telepítem.
  • ml_dolgok különböző gépi tanulással kapcsolatos feladatokhoz használt könyvtár. Azért hoztam létre ezt a könyvtárat, hogy csökkentsem az egyes gépi tanulási projektekhez írandó kód mennyiségét.
# 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

Behozatal

Importálja az összes szükséges könyvtárat ehhez a jegyzetfüzethez. A jegyzetfüzethez használt paraméterek deklarálása:

  • set_seed(123) – Mindig jó fix vetőmagot beállítani a reprodukálhatóság érdekében.
  • epochs – A képzési időszakok száma (a szerzők 2 és 4 között javasolják).
  • batch_size – A kötegek száma – a sorozat maximális hosszától és a GPU memóriájától függően. 512 sorozathosszúság esetén egy 10-es köteg általában cuda memóriaproblémák nélkül működik. Kis sorozathosszúság esetén próbálja ki a 32-es vagy nagyobb tételt. max_length – Szövegsorozatok beillesztése vagy csonkítása meghatározott hosszúságúra. 60-ra állítom, hogy felgyorsítsam az edzést.
  • device – Keresse meg a használni kívánt gpu-t. Alapértelmezés szerint CPU-t használ, ha nem található gpu.
  • model_name_or_path – A transzformátormodell neve – a már előképzett modellt fogja használni. Transzformátormodell útvonala – a saját modelljét betölti a helyi lemezről. Ebben az oktatóanyagban fogom használni gpt2 modell.
  • labels_ids – Címkék és azonosítóik szótár – ez a karakterlánccímkék számokká alakítására szolgál.
  • n_labels – Hány címkét használunk ebben az adatkészletben. Ez az osztályozási fej méretének meghatározására szolgál.
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)

Segítő funkciók

Szeretnék a jegyzetfüzetben használt összes osztályt és funkciót ebben a részben megtartani, hogy segítsenek fenntartani a jegyzetfüzet tiszta megjelenését:

MovieReviewsDataset (adatkészlet)

Ha korábban PyTorch-al dolgozott, ez meglehetősen szabványos. Szükségünk van erre az osztályra, hogy beolvassuk az adatkészletünket, elemezze azt, és visszaadja a szövegeket a hozzájuk tartozó címkékkel.

Ebben az osztályban csak be kell olvasnom az egyes fájlok tartalmát, a fix_textet kell használnom az esetleges Unicode-problémák kijavításához, és nyomon kell követnem a pozitív és negatív érzéseket.

Minden szöveget és címkét a listákhoz csatolok.

Ennek a PyTorch Dataset osztálynak három fő része van:

  • benne () ahol az adathalmazban olvasunk, és a szöveget és a címkéket számokká alakítjuk.
  • len () ahol a beolvasott példák számát kell visszaadnunk. Ezt a len(MovieReviewsDataset()) meghívásakor használjuk.
  • getitem() mindig egy input értéket vesz fel, amely azt jelzi, hogy a példáink közül melyik példát kell visszaadni az adatkészletünkből. Ha 3-as értéket adunk át, akkor a példát az adatkészletünkből a 3. pozícióban adjuk vissza.
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

Ezt az osztályt használom az adatgyűjtő létrehozásához. Ezt fogja használni a DataLoader a modellbe betáplált adatok fürdőinek létrehozásához. A tokenizátort és a címkekódolót minden sorozatnál használom a szövegek és címkék számmá alakításához.

Szerencsére Hugging Face mindenre gondolt, és rávette a tokenizátort az összes nehéz feladatra (szöveg felosztása tokenekre, kitöltés, csonkítás, szöveg számokká kódolása), és nagyon könnyen használható!

Ennek az adatgyűjtő osztálynak két fő része van:

  • benne () hol inicializáljuk a használni kívánt tokenizert, hogyan kódoljuk a címkéinket, és ha más értékre kell állítanunk a sorozat hosszát.
  • hívás() függvénygyűjtőként használják, amely bemeneti adathalmazt vesz fel. Olyan formátumú objektumot kell visszaadnia, amely a modellünkbe betáplálható. Szerencsére a tokenizátorunk ezt megteszi helyettünk, és visszaadja a változók szótárát, amely készen áll a modellbe való betáplálásra, így: model(**inputs). Mivel finomhangoljuk a modellt, mellékeltem a címkéket is.
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

vonat(adatkezelő, optimalizáló_, ütemező_, eszköz_)

Ezt a függvényt a DataLoader objektum teljes áthaladására hoztam létre (a DataLoader objektum a Dataset* típusú objektumunkból jön létre a **MovieReviewsDataset osztály használatával). Ez alapvetően egy korszakfolyamat a teljes adatkészleten keresztül.

Az adatbetöltő a PyTorch DataLoaderből jön létre, amely átveszi a MovieReviewsDataset osztályból létrehozott objektumot, és minden példát kötegekbe helyez. Így tudjuk betáplálni a modell adatkötegeinket!

Az optimalizáló_ és az ütemező_ nagyon gyakori a PyTorch-ben. A képzés során frissíteniük kell modellünk paramétereit, és frissíteniük kell a tanulási sebességünket. Sokkal több van ennél, de nem megyek bele a részletekbe. Ez valójában egy hatalmas nyúllyuk lehet, mivel SOK minden történik e funkciók mögött, ami miatt nem kell aggódnunk. Köszönjük PyTorch!

A folyamat során nyomon követjük a tényleges címkéket és a várható címkéket, valamint a veszteséget.

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

érvényesítés(adatkezelő, eszköz_)

Ezt a funkciót nagyon hasonló módon valósítottam meg, mint a vonat, de a paraméterfrissítés, a hátramenet és a gradiens tisztességes rész nélkül. Nem kell elvégeznünk ezeket a NAGYON számításigényes feladatokat, mert csak a modellünk előrejelzései érdekelnek minket.

A DataLoader-t hasonló módon használom, mint a vonatban, hogy kiadjak a modellünkbe betáplálandó tételeket.

A folyamat során nyomon követem a tényleges címkéket és a várható címkéket, valamint a veszteséget.

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

Modell és tokenizátor betöltése

Az előképzett GPT2 transzformátor három lényeges részének betöltése: konfiguráció, tokenizátor és modell.

Ehhez a példához fogom használni gpt2 HuggingFace előképzett transzformátorokból. A GP2 tetszőleges változatát használhatja.

model_config Megemlítem az osztályozási feladatomhoz szükséges címkék számát. Mivel csak két érzést jósolok: pozitív és negatív, csak két címkére lesz szükségem num_labels.

tokenizer elég szabványos a Transformers könyvtár használatakor. A tokenizátor létrehozása után kritikus fontosságú, hogy ez az oktatóanyag a bal oldali kitöltést állítsa be tokenizer.padding_side = "left" és inicializálja a padding tokent tokenizer.eos_token amely a GPT2 eredeti sorozatvége tokenje. Ez az oktatóanyag leglényegesebb része, mivel a GPT2 az utolsó tokent használja az előrejelzéshez, ezért balra kell lépnünk.

A HuggingFace már elvégezte helyettünk a munka nagy részét, és besorolási réteget adott a GPT2 modellhez. Az általam használt modell elkészítésekor GPT2ForSequenceClassification. Mivel van egy egyéni padding tokenünk, inicializálnunk kell a használt modellhez model.config.pad_token_id. Végül át kell helyeznünk a modellt a korábban meghatározott eszközre.

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

Adatkészlet és gyűjtő

Itt hozom létre a PyTorch Dataset és Data Loader with Data Collator objektumokat, amelyeket a modellünkbe való adatok betáplálására használunk.

Itt használom a MovieReviewsDataset osztályt a PyTorch Dataset létrehozásához, amely szövegeket és címkéket ad vissza.

Mivel a modellünkbe számokat kell bevinnünk, a szövegeket és a címkéket számokká kell alakítanunk. Ez a gyűjtő célja! A PyTorch Dataset által kiadott és a Data Collator függvényen áthaladó adatokra van szükség ahhoz, hogy kiadja a modellünk sorozatát.

A tokenizert távol tartom a PyTorch Datasettől, hogy a kód tisztább és strukturáltabb legyen. Nyilvánvalóan használhatja a PyTorch Dataset-en belüli tokenizert és kimeneti szekvenciákat, amelyeket közvetlenül a modellben használhatunk Data Collator használata nélkül.

Erősen javaslom egy érvényesítő szövegfájl használatát annak meghatározására, hogy mennyi edzésre van szükség a túlillesztés elkerülése érdekében. Miután kitalálta, hogy mely paraméterek adják a legjobb eredményeket, az érvényesítő fájl beépíthető a vonatba, és lefuttatható egy végső vonat a teljes adatkészlettel.

Az adatgyűjtő a PyTorch Dataset kimenetek formázására szolgál, hogy megfeleljenek a GPT2-hez szükséges bemeneteknek.

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

Vonat

A PyTorch által edzés közbeni optimalizálót és ütemezőt készítettem. A transzformátormodellek által használt leggyakoribb paramétereket használtam.

Végigfutottam a meghatározott korszakok számát, és meghívtam a vonat és a érvényesítés funkciókat.

Hasonló információkat próbálok kiadni minden korszak után, mint a Keras: vonat_veszteség: — veszteség érték: — vonat_acc: — érvényes_acc.

Az edzés után ábrázolja a vonatozást és az érvényesítési veszteség- és pontossági görbéket, hogy ellenőrizze, hogyan zajlott a képzés.

Jegyzet: A képzési diagramok kissé furcsának tűnhetnek: Az érvényesítési pontosság magasabban kezdődik, mint a képzési pontosság, és az érvényesítési veszteség alacsonyabb, mint a képzési veszteség. Általában ennek az ellenkezője lesz. Feltételezem, hogy az adatok felosztása egyszerűbb az érvényesítési résznél, vagy túl nehéz a betanítási részhez, vagy mindkettőhöz. Mivel ez az oktatóanyag a GPT2 osztályozási használatáról szól, nem fogok túl sokat aggódni a modell eredményei miatt.

# 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
Vonat és érvényesítés elvesztése.
A vonatozás és az érvényesítés pontossága.

értékelje

Amikor az osztályozással foglalkozunk, érdemes a precíziós visszahívást és az F1 pontszámot megvizsgálni.

Egy jó mérőeszköz a modell értékeléséhez a zavaros mátrix.

# 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
A zavart mátrix normalizálódott.

végső megjegyzés

Ha idáig eljutottál Gratula! 🎊 és Köszönöm! 🙏 a bemutatóm iránti érdeklődésért!

Már egy ideje használom ezt a kódot, és úgy érzem, eljutott egy olyan pontra, ahol szépen dokumentált és könnyen követhető.

Persze könnyen követhető, mert én építettem. Ezért szívesen fogadunk minden visszajelzést, és ez segít javítani a jövőbeni oktatóanyagaimat!

Ha valami hibát lát, kérem, jelezze nekem egy probléma megnyitásával ml_things GitHub adattár!

Sok oktatóanyag többnyire egyszeri, és nincs karbantartva. Azt tervezem, hogy amennyire csak tudom, naprakészen tartom az oktatóanyagaimat.

Ezt a cikket eredetileg közzétették George Mihaila személyes weboldala  és a szerző engedélyével újra közzétesszük a TOPBOTS-nál.

Tetszett ez a cikk? Iratkozzon fel további AI-frissítésekért.

Értesíteni fogunk, ha további műszaki oktatást adunk ki.

Forrás: https://www.topbots.com/gpt2-text-classification-using-hugging-face-transformers/

Időbélyeg:

Még több TOPBOTOK