GPT2 для класифікації тексту за допомогою обіймаючих трансформаторів обличчя

Вихідний вузол: 809063

класифікація тексту

Цей блокнот використовується для точного налаштування моделі GPT2 для використання класифікації тексту Обіймати обличчя Трансформатори бібліотеку на спеціальному наборі даних.

Hugging Face дуже приємно для нас, оскільки включає всі функції, необхідні для використання GPT2 у завданнях класифікації. Дякую Hugging Face!

Мені не вдалося знайти багато інформації про те, як використовувати GPT2 для класифікації, тому я вирішив створити цей підручник, використовуючи подібну структуру з іншими моделями трансформаторів.

Якщо цей поглиблений навчальний зміст вам корисний, підпишіться на наш список розсилки досліджень ШІ щоб отримати попередження, коли ми випускаємо новий матеріал. 

Головна думка: Оскільки GPT2 є трансформатором декодера, останній маркер вхідної послідовності використовується для прогнозування наступного маркера, який має слідувати за введенням. Це означає, що останній маркер вхідної послідовності містить всю інформацію, необхідну для передбачення. Маючи це на увазі, ми можемо використовувати цю інформацію, щоб зробити прогноз у завданні класифікації замість завдання генерації.

Іншими словами, замість використання першого вбудовування токена для прогнозування, як ми робимо в Bert, ми будемо використовувати останнє вбудовування токена для прогнозування за допомогою GPT2.

Оскільки ми дбали лише про перший жетон у Bert, ми відступали праворуч. Тепер у GPT2 ми використовуємо останній маркер для передбачення, тому нам потрібно буде прокладати ліворуч. Завдяки чудовому оновленню HuggingFace Transformers ми можемо налаштувати GPT2 Tokenizer саме для цього.

Що я повинен знати про цей блокнот?

Оскільки я використовую PyTorch для точного налаштування наших моделей трансформаторів, будь-які знання PyTorch дуже корисні.

Знаючи трохи про Трансформатори бібліотека також допомагає.

Як користуватися цим зошитом?

Як і в будь-якому іншому проекті, я створив цей блокнот з думкою про багаторазове використання.

Усі зміни відбудуться в частині обробки даних, де вам потрібно буде налаштувати PyTorch Dataset, Data Collator і DataLoader відповідно до ваших потреб у даних.

Усі параметри, які можна змінити, знаходяться під Імпорт розділ. Кожен параметр добре прокоментований і структурований, щоб бути максимально інтуїтивно зрозумілим.

Набір даних

У цьому блокноті розглядатимуться трансформатори перед навчанням на спеціальному наборі даних. Я буду використовувати рецензії на відомі фільми позитивно — негативно Великий набір даних огляду фільмів.

Опис на веб-сайті Стенфордського університету:

Це набір даних для двійкової класифікації настрою, який містить значно більше даних, ніж попередні набори даних. Ми пропонуємо набір із 25,000 25,000 дуже полярних оглядів фільмів для навчання та XNUMX XNUMX для тестування. Також є додаткові немарковані дані для використання. Надаються формати необробленого тексту та вже обробленого пакета слів. Для отримання додаткової інформації перегляньте файл README, який міститься у випуску.

Чому цей набір даних? Я вважаю, що це простий для розуміння та використання набір даних для класифікації. Я думаю, що з даними про настрої завжди цікаво працювати.

Кодування

Тепер давайте трохи кодуємо! Ми пройдемося по кожній комірці кодування в зошиті та опишемо, що вона робить, що це за код і коли це актуально — покажемо результат.

Я створив цей формат, щоб його було легко використовувати, якщо ви вирішите запускати кожну клітинку коду у своєму власному блокноті Python.

Коли я вчуся з підручника, я завжди намагаюся відтворити результати. Я вважаю, що це легко, якщо у вас є код поруч із поясненнями.

Завантаження

Завантажити Великий набір даних огляду фільмів і розпакуйте його локально.

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

Встановлюється

  • Трансформатори потрібно встановити бібліотеку, щоб використовувати весь чудовий код із Hugging Face. Щоб отримати останню версію, я встановлю її прямо з GitHub.
  • ml_things бібліотека, яка використовується для різних завдань, пов’язаних з машинним навчанням. Я створив цю бібліотеку, щоб зменшити кількість коду, який мені потрібно писати для кожного проекту машинного навчання.
# 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

Імпорт

Імпортуйте всі необхідні бібліотеки для цього блокнота. Оголошіть параметри, які використовуються для цього блокнота:

  • set_seed(123) – Завжди добре встановити фіксоване насіння для відтворюваності.
  • epochs – Кількість епох навчання (автори рекомендують від 2 до 4).
  • batch_size – Кількість пакетів – залежно від максимальної довжини послідовності та пам’яті GPU. Для послідовності довжиною 512 пакет із 10 ЗАВИЧАЙНО працює без проблем з пам’яттю cuda. Для невеликої довжини послідовності можна спробувати партію з 32 або більше. max_length – доповнювати або обрізати текстові послідовності до певної довжини. Я встановлю його на 60, щоб прискорити тренування.
  • device – Шукайте GPU для використання. Використовуватиме процесор за замовчуванням, якщо графічний процесор не знайдено.
  • model_name_or_path – Назва моделі трансформатора – використовуватиме вже попередньо навчену модель. Шлях моделі трансформатора – завантажить вашу власну модель з локального диска. У цьому підручнику я буду використовувати gpt2 модель.
  • labels_ids – Словник міток та їхні ідентифікатори – це буде використано для перетворення міток рядків у числа.
  • n_labels – Скільки міток ми використовуємо в цьому наборі даних. Це використовується для визначення розміру головки класифікації.
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)

Допоміжні функції

Мені подобається зберігати всі класи та функції, які використовуватимуться в цьому блокноті, у цьому розділі, щоб підтримувати чистий вигляд блокнота:

MovieReviewsDataset(Dataset)

Якщо ви раніше працювали з PyTorch, це досить стандартно. Нам потрібен цей клас, щоб читати наш набір даних, аналізувати його та повертати тексти з відповідними мітками.

У цьому класі мені потрібно лише читати вміст кожного файлу, використовувати fix_text, щоб виправити будь-які проблеми з Юнікодом і відстежувати позитивні та негативні настрої.

Усі тексти та мітки додам у списки.

Цей клас набору даних PyTorch складається з трьох основних частин:

  • у цьому() де ми зчитуємо набір даних і перетворюємо текст і мітки на числа.
  • len () де нам потрібно повернути кількість прикладів, які ми прочитали. Це використовується під час виклику len(MovieReviewsDataset()).
  • getitem() завжди приймає як вхідне значення int, яке представляє, який приклад із наших прикладів повертати з нашого набору даних. Якщо передано значення 3, ми повернемо приклад із нашого набору даних у позицію 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

Я використовую цей клас для створення Data Collator. Це буде використано в DataLoader для створення пакетів даних, які надходять у модель. Я використовую токенізатор і кодувальник міток для кожної послідовності, щоб перетворювати тексти та мітки на числа.

На щастя для нас, Hugging Face подумав про все і змусив токенізатор виконувати всю важку роботу (розбивати текст на маркери, доповнювати, усікати, кодувати текст у числа) і дуже простий у використанні!

Цей клас Data Collator складається з двох основних частин:

  • у цьому() де ми ініціалізуємо токенізер, який плануємо використовувати, як кодувати наші мітки та чи потрібно нам встановити інше значення довжини послідовності.
  • виклик () використовується як функція сортування, яка приймає як вхідні дані пакет прикладів даних. Він повинен повернути об’єкт із форматом, який можна передати нашій моделі. На щастя, наш токенізатор робить це за нас і повертає словник змінних, готових для передачі в модель таким чином: model(**inputs). Оскільки ми вдосконалюємо модель, я також включив мітки.
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

train(завантажувач даних, оптимізатор_, планувальник_, пристрій_)

Я створив цю функцію для виконання повного проходу через об’єкт DataLoader (об’єкт DataLoader створюється з нашого об’єкта типу Dataset* за допомогою класу **MovieReviewsDataset). По суті, це одна епоха по всьому набору даних.

Завантажувач даних створюється з PyTorch DataLoader, який бере об’єкт, створений з класу MovieReviewsDataset, і розміщує кожен приклад у пакетах. Таким чином ми можемо надавати наші моделі пакети даних!

Оптимізатор_ і планувальник_ дуже поширені в PyTorch. Вони повинні оновлювати параметри нашої моделі та оновлювати швидкість навчання під час навчання. Це набагато більше, але я не буду вдаватися в подробиці. Це насправді може бути величезна кроляча нора, оскільки за цими функціями відбувається БАГАТО, про що нам не потрібно хвилюватися. Дякую, PyTorch!

У процесі ми відстежуємо фактичні мітки та прогнозовані мітки разом із втратою.

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

перевірка (завантажувач даних, пристрій_)

Я реалізував цю функцію дуже подібним чином, як поїзд, але без параметрів update, backward pass і gradient decent part. Нам не потрібно виконувати всі ці ДУЖЕ інтенсивні обчислювальні завдання, тому що ми дбаємо лише про прогнози нашої моделі.

Я використовую DataLoader подібним чином, як і в поїзді, щоб отримувати партії для передачі в нашу модель.

У процесі я відстежую фактичні мітки та прогнозовані мітки разом із втратою.

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

Завантажити модель і токенізер

Завантаження трьох важливих частин попередньо підготовленого трансформатора GPT2: конфігурація, токенізатор і модель.

Для цього прикладу я буду використовувати gpt2 від попередньо навчених трансформерів HuggingFace. Ви можете використовувати будь-які варіанти GP2.

При створенні model_config Я згадаю кількість міток, які мені знадобляться для мого класифікаційного завдання. Оскільки я передбачаю лише два настрої: позитивний і негативний, мені знадобляться лише дві мітки num_labels.

Створення tokenizer є досить стандартним при використанні бібліотеки Transformers. Після створення токенізера для цього посібника важливо встановити відступ ліворуч tokenizer.padding_side = "left" і ініціалізуйте маркер заповнення tokenizer.eos_token який є оригінальним маркером кінця послідовності GPT2. Це найважливіша частина цього підручника, оскільки GPT2 використовує останній маркер для передбачення, тому нам потрібно пройти ліворуч.

HuggingFace вже виконав більшу частину роботи за нас і додав класифікаційний рівень до моделі GPT2. При створенні використовуваної моделі GPT2ForSequenceClassification. Оскільки у нас є спеціальний маркер заповнення, нам потрібно ініціалізувати його для моделі, що використовує model.config.pad_token_id. Нарешті нам потрібно буде перемістити модель на пристрій, який ми визначили раніше.

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

Набір даних і сортувальник

Тут я створюю об’єкти PyTorch Dataset і Data Loader з Data Collator, які використовуватимуться для введення даних у нашу модель.

Тут я використовую Набір даних MovieReviews для створення набору даних PyTorch, який повертатиме тексти та мітки.

Оскільки нам потрібно ввести числа в нашу модель, нам потрібно перетворити тексти та підписи на числа. Це мета коллатора! Він приймає дані, виведені з набору даних PyTorch, і пропускає їх через функцію Data Collator, щоб вивести послідовність для нашої моделі.

Я тримаю токенізер подалі від набору даних PyTorch, щоб зробити код чистішим і краще структурованим. Ви, очевидно, можете використовувати токенизатор всередині набору даних PyTorch і вихідні послідовності, які можна використовувати безпосередньо в моделі без використання Data Collator.

Я наполегливо рекомендую використовувати текстовий файл перевірки, щоб визначити, скільки навчання потрібно, щоб уникнути переобладнання. Після того, як ви з’ясуєте, які параметри дають найкращі результати, файл перевірки можна включити в потяг і запустити остаточний потяг із усім набором даних.

Колатор даних використовується для форматування вихідних даних PyTorch Dataset відповідно до вхідних даних, необхідних для GPT2.

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

поїзд

Я створив оптимізатор і планувальник для використання PyTorch під час навчання. Я використовував найбільш поширені параметри, які використовуються моделями трансформаторів.

Я прокрутив кількість визначених епох і викликав поїзд та  перевірка достовірності функції.

Я намагаюся виводити подібну інформацію після кожної епохи, як Keras: train_loss: — val_loss: — train_acc: — valid_acc.

Після навчання побудуйте криві втрат і точності підтвердження та перевірки, щоб перевірити, як пройшло навчання.

Примітка: Навчальні графіки можуть виглядати трохи дивно: точність перевірки починається вище, ніж точність навчання, а втрати підтвердження починаються нижче, ніж втрати навчання. Зазвичай це буде навпаки. Я припускаю, що розділення даних просто простіше для частини перевірки або занадто складно для частини навчання, або обох. Оскільки цей підручник присвячений використанню GPT2 для класифікації, я не буду надто турбуватися про результати моделі.

# 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
Поїзд і втрата перевірки.
Навчання та перевірка точності.

Оцінювати

При роботі з класифікацією корисно дивитися на точність запам’ятовування та оцінку F1.

Хорошим показником для оцінки моделі є матриця плутанини.

# 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
Матриця плутанини нормалізована.

Заключна примітка

Якщо ви дійшли так далеко Вітаю! 🎊 і Дякую! 🙏 за ваш інтерес до мого підручника!

Я використовую цей код уже деякий час, і я відчуваю, що він дійшов до точки, коли він добре задокументований і простий у дотриманні.

Звичайно, мені це легко зрозуміти, тому що я створив це. Ось чому будь-який відгук вітається, і він допоможе мені покращити мої майбутні підручники!

Якщо ви бачите щось не так, повідомте мене, відкривши питання на моєму сайті ml_things репозиторій GitHub!

Багато навчальних посібників є здебільшого одноразовими і не підтримуються. Я планую постійно оновлювати свої навчальні посібники.

Ця стаття була спочатку опублікована на Персональний сайт Георгія Михайла  та повторно опубліковано в TOPBOTS з дозволу автора.

Вам подобається ця стаття? Підпишіться на отримання нових оновлень AI.

Ми повідомимо вас, коли випустимо більше технічної освіти.

Джерело: https://www.topbots.com/gpt2-text-classification-using-hugging-face-transformers/

Часова мітка:

Більше від ТОПБОТИ