Notice: This page requires JavaScript to function properly.
Please enable JavaScript in your browser settings or update your browser.
Вивчайте Тренування Моделі | Секція
Practice
Projects
Quizzes & Challenges
Вікторини
Challenges
/
PyTorch: Основи для ML-Інженера

bookТренування Моделі

Підготовка до навчання

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

  1. Функція втрат: для класифікації можна використовувати CrossEntropyLoss, яка очікує на вхід необроблені безперервні значення (логіти) та автоматично застосовує softmax;
  2. Оптимізатор: для ефективного оновлення градієнтів можна використовувати оптимізатор Adam.
import torch.nn as nn
import torch.optim as optim
# Define the loss function (cross-entropy for multi-class classification)
criterion = nn.CrossEntropyLoss()
# Define the optimizer (Adam with a learning rate of 0.01)
optimizer = optim.Adam(model.parameters(), lr=0.01)

У PyTorch функція крос-ентропії поєднує log-softmax та negative log-likelihood (NLL) втрату в одну функцію втрат:

L=log(ezyj=1Cezj)\mathcal{L} = - \log{\left( \frac{e^{z_y}}{\sum^C_{j=1}e^{z_j}} \right)}

де:

  • zy — логіт, що відповідає правильному класу;
  • C — загальна кількість класів.

Також важливо розділити дані на навчальну та валідаційну вибірки (ідеально, якщо також існує окрема тестова вибірка). Оскільки набір даних відносно невеликий (1143 рядки), використовується розподіл 80% на 20%. У цьому випадку валідаційна вибірка також буде виконувати роль тестової.

Note
Додатково

80% для навчання та 20% для тестування часто підходить для багатьох сценаріїв. Однак для великих наборів даних, наприклад, з мільйонами записів, навіть менший відсоток, виділений на тестову вибірку (10% або менше), може бути достатнім для надійної оцінки ефективності. Навпаки, при дуже малих наборах даних (наприклад, менше тисячі записів) важливо забезпечити, щоб тестова вибірка була достатньо великою (25-30%), щоб надати змістовну оцінку якості моделі.

Крім того, отримані масиви NumPy слід перетворити на тензори, оскільки моделі PyTorch вимагають тензорні вхідні дані для обчислень.

from sklearn.model_selection import train_test_split

X_train, X_test, y_train, y_test =  train_test_split(X, y, test_size=0.2, random_state=42)
X_train = torch.tensor(X_train, dtype=torch.float32)
X_test = torch.tensor(X_test, dtype=torch.float32)
y_train = torch.tensor(y_train, dtype=torch.long)
y_test = torch.tensor(y_test, dtype=torch.long)

Цикл навчання

Цикл навчання включає такі етапи для кожної епохи:

  1. Прямий прохід: пропуск вхідних ознак через модель для отримання прогнозів;
  2. Обчислення втрат: порівняння прогнозів із реальними значеннями за допомогою функції втрат;
  3. Зворотний прохід: обчислення градієнтів відносно параметрів моделі за допомогою зворотного поширення помилки;
  4. Оновлення параметрів: коригування параметрів моделі за допомогою оптимізатора;
  5. Моніторинг прогресу: періодичний вивід значення втрат для спостереження за збіжністю.

Як видно, процес навчання подібний до процесу лінійної регресії.

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849
import torch.nn as nn import torch import torch.optim as optim import matplotlib.pyplot as plt import os os.system('wget https://staging-content-media-cdn.codefinity.com/courses/1dd2b0f6-6ec0-40e6-a570-ed0ac2209666/section_3/model_definition.py 2>/dev/null') from model_definition import model, X, y from sklearn.model_selection import train_test_split # Set manual seed for reproducibility torch.manual_seed(42) # Reinitialize model after setting seed model.apply(lambda m: m.reset_parameters() if hasattr(m, "reset_parameters") else None) X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2, random_state=42) X_train = torch.tensor(X_train, dtype=torch.float32) X_test = torch.tensor(X_test, dtype=torch.float32) y_train = torch.tensor(y_train, dtype=torch.long) y_test = torch.tensor(y_test, dtype=torch.long) # Define the loss function (Cross-Entropy for multi-class classification) criterion = nn.CrossEntropyLoss() # Define the optimizer (Adam with a learning rate of 0.01) optimizer = optim.Adam(model.parameters(), lr=0.01) # Number of epochs epochs = 100 # Store losses for plotting training_losses = [] # Training loop for epoch in range(epochs): # Zero out gradients from the previous step optimizer.zero_grad() # Compute predictions predictions = model(X_train) # Compute the loss loss = criterion(predictions, y_train) # Compute gradients loss.backward() # Update parameters optimizer.step() # Store the loss training_losses.append(loss.item()) # Plot the training loss plt.plot(range(epochs), training_losses, label="Training Loss") plt.xlabel("Epoch") plt.ylabel("Loss") plt.title("Training Loss over Epochs") plt.legend() plt.show()
copy
Note
Примітка

Виклик model(input) автоматично викликає метод forward() моделі. Це відбувається тому, що nn.Module перевизначає метод __call__, який внутрішньо викликає forward(). Рекомендується використовувати model(input) замість model.forward(input), оскільки перший варіант гарантує, що всі хуки або додаткові функціональні можливості (наприклад, model.train() чи model.eval()) будуть коректно застосовані.

Спостереження за збіжністю

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

question mark

Яка з наведених послідовностей кроків є правильною для циклу навчання в PyTorch?

Select the correct answer

Все було зрозуміло?

Як ми можемо покращити це?

Дякуємо за ваш відгук!

Секція 1. Розділ 18

Запитати АІ

expand

Запитати АІ

ChatGPT

Запитайте про що завгодно або спробуйте одне із запропонованих запитань, щоб почати наш чат

bookТренування Моделі

Свайпніть щоб показати меню

Підготовка до навчання

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

  1. Функція втрат: для класифікації можна використовувати CrossEntropyLoss, яка очікує на вхід необроблені безперервні значення (логіти) та автоматично застосовує softmax;
  2. Оптимізатор: для ефективного оновлення градієнтів можна використовувати оптимізатор Adam.
import torch.nn as nn
import torch.optim as optim
# Define the loss function (cross-entropy for multi-class classification)
criterion = nn.CrossEntropyLoss()
# Define the optimizer (Adam with a learning rate of 0.01)
optimizer = optim.Adam(model.parameters(), lr=0.01)

У PyTorch функція крос-ентропії поєднує log-softmax та negative log-likelihood (NLL) втрату в одну функцію втрат:

L=log(ezyj=1Cezj)\mathcal{L} = - \log{\left( \frac{e^{z_y}}{\sum^C_{j=1}e^{z_j}} \right)}

де:

  • zy — логіт, що відповідає правильному класу;
  • C — загальна кількість класів.

Також важливо розділити дані на навчальну та валідаційну вибірки (ідеально, якщо також існує окрема тестова вибірка). Оскільки набір даних відносно невеликий (1143 рядки), використовується розподіл 80% на 20%. У цьому випадку валідаційна вибірка також буде виконувати роль тестової.

Note
Додатково

80% для навчання та 20% для тестування часто підходить для багатьох сценаріїв. Однак для великих наборів даних, наприклад, з мільйонами записів, навіть менший відсоток, виділений на тестову вибірку (10% або менше), може бути достатнім для надійної оцінки ефективності. Навпаки, при дуже малих наборах даних (наприклад, менше тисячі записів) важливо забезпечити, щоб тестова вибірка була достатньо великою (25-30%), щоб надати змістовну оцінку якості моделі.

Крім того, отримані масиви NumPy слід перетворити на тензори, оскільки моделі PyTorch вимагають тензорні вхідні дані для обчислень.

from sklearn.model_selection import train_test_split

X_train, X_test, y_train, y_test =  train_test_split(X, y, test_size=0.2, random_state=42)
X_train = torch.tensor(X_train, dtype=torch.float32)
X_test = torch.tensor(X_test, dtype=torch.float32)
y_train = torch.tensor(y_train, dtype=torch.long)
y_test = torch.tensor(y_test, dtype=torch.long)

Цикл навчання

Цикл навчання включає такі етапи для кожної епохи:

  1. Прямий прохід: пропуск вхідних ознак через модель для отримання прогнозів;
  2. Обчислення втрат: порівняння прогнозів із реальними значеннями за допомогою функції втрат;
  3. Зворотний прохід: обчислення градієнтів відносно параметрів моделі за допомогою зворотного поширення помилки;
  4. Оновлення параметрів: коригування параметрів моделі за допомогою оптимізатора;
  5. Моніторинг прогресу: періодичний вивід значення втрат для спостереження за збіжністю.

Як видно, процес навчання подібний до процесу лінійної регресії.

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849
import torch.nn as nn import torch import torch.optim as optim import matplotlib.pyplot as plt import os os.system('wget https://staging-content-media-cdn.codefinity.com/courses/1dd2b0f6-6ec0-40e6-a570-ed0ac2209666/section_3/model_definition.py 2>/dev/null') from model_definition import model, X, y from sklearn.model_selection import train_test_split # Set manual seed for reproducibility torch.manual_seed(42) # Reinitialize model after setting seed model.apply(lambda m: m.reset_parameters() if hasattr(m, "reset_parameters") else None) X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2, random_state=42) X_train = torch.tensor(X_train, dtype=torch.float32) X_test = torch.tensor(X_test, dtype=torch.float32) y_train = torch.tensor(y_train, dtype=torch.long) y_test = torch.tensor(y_test, dtype=torch.long) # Define the loss function (Cross-Entropy for multi-class classification) criterion = nn.CrossEntropyLoss() # Define the optimizer (Adam with a learning rate of 0.01) optimizer = optim.Adam(model.parameters(), lr=0.01) # Number of epochs epochs = 100 # Store losses for plotting training_losses = [] # Training loop for epoch in range(epochs): # Zero out gradients from the previous step optimizer.zero_grad() # Compute predictions predictions = model(X_train) # Compute the loss loss = criterion(predictions, y_train) # Compute gradients loss.backward() # Update parameters optimizer.step() # Store the loss training_losses.append(loss.item()) # Plot the training loss plt.plot(range(epochs), training_losses, label="Training Loss") plt.xlabel("Epoch") plt.ylabel("Loss") plt.title("Training Loss over Epochs") plt.legend() plt.show()
copy
Note
Примітка

Виклик model(input) автоматично викликає метод forward() моделі. Це відбувається тому, що nn.Module перевизначає метод __call__, який внутрішньо викликає forward(). Рекомендується використовувати model(input) замість model.forward(input), оскільки перший варіант гарантує, що всі хуки або додаткові функціональні можливості (наприклад, model.train() чи model.eval()) будуть коректно застосовані.

Спостереження за збіжністю

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

question mark

Яка з наведених послідовностей кроків є правильною для циклу навчання в PyTorch?

Select the correct answer

Все було зрозуміло?

Як ми можемо покращити це?

Дякуємо за ваш відгук!

Секція 1. Розділ 18
some-alt