Батчінг і міні-батчі: як зробити ваш модель глибокого навчання ефективною

Техніки обробки даних: Batch (повне тренування) та Mini-Batch (міні-батч) у навчанні моделей машинного навчання та глибокого навчання часто виникають у контексті того, як ми ділимо набір даних на менші частини для включення їх у процес навчання. Давайте пояснимо ці два поняття з простими визначеннями та прикладами.

1. Що таке Batch (Повне тренування)?

Метод Batch, також відомий як «повне тренування», означає подачу всіх навчальних даних до моделі одночасно (в одному «батчі») і виконання оновлення параметрів (наприклад, оновлення ваг) на основі всього набору даних.

Приклад: Уявіть, що у вас є 1,000 навчальних прикладів. За методом Batch ви одночасно подаєте всі 1,000 прикладів до моделі. Модель обчислює втрати на основі всіх 1,000 прикладів і оновлює свої ваги за один крок.

Переваги:

  • Оскільки використовуються всі дані, обчислюється найточніший градієнт.
  • Навчання відбувається «великою кроком», а не через маленькі інкрементальні кроки.

Недоліки:

  • Використання пам'яті (RAM) може бути дуже високим (оскільки всі дані обробляються одночасно).
  • Це може бути повільно з точки зору обчислень у випадку дуже великих наборів даних.
  • Оскільки параметри оновлюються лише після обробки всього набору даних, модель не отримує частіше відгуки (повільний зворотний зв'язок).

2. Що таке Mini-Batch тренування?

Метод Mini-Batch полягає в поділі даних на менші частини (наприклад, 32, 64 або 128 прикладів) і по черзі обробляти кожну частину в моделі, оновлюючи параметри поступово.

Приклад: Припустимо, у вас є 1,000 навчальних прикладів. Ви ділимо їх на 10 частин з розміром батча 100 (1,000 / 100 = 10 частин). Кожна частина з 100 прикладів (мікробатч) подається в модель. Модель обчислює втрати для цих 100 прикладів і оновлює свої ваги. Потім вона переходить до наступних 100 прикладів і повторює процес.

Переваги:

  • Більш ефективне використання пам'яті, оскільки не потрібно завантажувати весь набір даних одночасно.
  • Дозволяє отримувати більш часті відгуки (оновлення) для моделі, оскільки параметри оновлюються з кожним мікробатчем.
  • Прискорює обчислення для великих наборів даних. Поки один батч обробляється, дані можуть бути завантажені в пам'ять GPU паралельно.

Недоліки:

  • У порівнянні з методом повного батча, оцінка градієнта може бути більш «шумною», оскільки кожен мікробатч обчислює різні значення помилки.
  • Якщо розмір батча занадто малий (наприклад, 10 або 20), навчання може стати незбалансованим, що призведе до повільного або нестабільного прогресу навчання.

3. Порівняння з простим прикладом

Припустимо, ви володієте піцерією і отримали 1,000 замовлень піци.

Метод Batch (повний батч): Ви намагаєтесь поставити всі піци (1,000 штук) в піч одночасно та випікати їх одночасно.

  • Перевага: Ви можете сказати: «Я все зробив за один раз».
  • Недолік: Піч має бути дуже великою (уявіть, що це потребує багато RAM). Крім того, ви не можете перевірити смак жодної піци, поки всі не будуть готові, тому помітите проблеми занадто пізно.

Метод Mini-Batch: Ви ділимо піци на менші групи, наприклад, групи по 10 (1,000 / 10 = 100 груп).

  • Ви випікаєте перші 10 піц, перевіряєте їх смак (оцінюєте помилку під час навчання моделі), і коригуєте соус чи час випікання, якщо потрібно (оновлюєте ваги). Потім переходите до наступної групи з 10.
  • Таким чином, ємність печі більш розумна (менше RAM потрібно), і ви можете перевіряти смак кожних 10 піц, роблячи маленькі корективи під час процесу (більш частий зворотний зв'язок та оновлення).

4. Висновок

Метод Batch (повне тренування) передбачає оновлення моделі за допомогою всього набору даних одночасно. Хоча він дає більш стабільні результати, оскільки обчислює градієнти по всіх даних, він може бути дуже дорогим (з точки зору обчислень та пам'яті) для великих наборів даних.

Метод Mini-Batch ділить дані на менші частини і оновлює модель після обробки кожної частини. Цей метод заощаджує пам'ять і робить навчання швидшим і практичнішим.
Міні-батч — це найбільш використовуваний підхід.

Щоб простіше пояснити:

  • Batch (повне тренування): Всі дані -> Оновлення за один крок.
  • Mini-Batch (мікробатч): Розділення даних -> Оновлення після кожної частини.

Більшість бібліотек для глибокого навчання (наприклад, PyTorch, TensorFlow) використовують підхід міні-батчів у своїх циклах навчання, керуючи параметром «batch size» (розмір батча). Це дозволяє вказати, скільки даних обробляти за один раз під час навчання. Зазвичай використовувані розміри батчів — це степені числа 2, такі як 32, 64 і 128.

НА ПРАКТИЦІ

У наступних прикладах я продемонструю процеси «batch» і «mini-batch» тренувань, використовуючи PyTorch та TensorFlow (Keras). Ви побачите фрагменти коду, подібні до тих, які реальний розробник міг би використовувати у своїй щоденній практиці.

1. Приклад тренування з Mini-Batch за допомогою PyTorch

Код нижче можна вважати рішенням для простої задачі регресії (10 вхідних ознак, 1 вихід). Ключовою частиною тут є те, як ми визначаємо batch_size, використовуючи DataLoader, і тренуємо на міні-батчах.

import torch  
import torch.nn as nn  
import torch.optim as optim  
from torch.utils.data import DataLoader, TensorDataset  

# 1) Створення синтетичного набору даних (X: 1000 прикладів, кожен з 10 ознаками, y: 1000 прикладів, одне значення)  
X = torch.randn(1000, 10) # 1000 x 10  
y = torch.randn(1000, 1) # 1000 x 1  

# 2) Огортаємо набір даних у TensorDataset та DataLoader PyTorch  
dataset = TensorDataset(X, y)  

# 3) Визначаємо розмір міні-батча (наприклад, 32)  
batch_size = 32  

# 4) Використовуємо DataLoader для розподілу даних на батчі і перемішування їх (shuffle=True) для підготовки до ітерації  
data_loader = DataLoader(dataset, batch_size=batch_size, shuffle=True)  

# 5) Визначаємо просту нейронну мережу  
model = nn.Sequential(  
 nn.Linear(10, 20), # Вхідний розмір 10, вихідний розмір 20  
 nn.ReLU(), # Активаційна функція ReLU  
 nn.Linear(20, 1) # Останній шар (20 -> 1)  
)  

# 6) Налаштовуємо оптимізатор і функцію втрат  
optimizer = optim.SGD(model.parameters(), lr=0.01)  
criterion = nn.MSELoss() # Функція втрат MSE (середнє квадратичне відхилення)  

# 7) Цикл навчання (епохи = 5 для демонстрації)  
num_epochs = 5  
for epoch in range(num_epochs):  
 # Проходимо через всі батчі в DataLoader  
 for batch_X, batch_y in data_loader:  
 # 7.1) Прогноз моделі (прямий прохід)  
 predictions = model(batch_X)  

 # 7.2) Обчислюємо втрати  
 loss = criterion(predictions, batch_y)  

 # 7.3) Кроки зворотного поширення та оптимізації  
 optimizer.zero_grad() # Скидаємо градієнти  
 loss.backward() # Зворотне поширення  
 optimizer.step() # Оновлюємо параметри  

 # Виводимо приклад результату в кінці кожної епохи  
 print(f"Epoch [{epoch+1}/{num_epochs}], Loss: {loss.item():.4f}")

Пояснення

  • batch_size=32: Розділяє набір даних з 1000 прикладів на частини по 32, що означає, що модель тренується на 32 приклади за один крок.
  • shuffle=True: Забезпечує випадковий порядок батчів під час кожної епохи для кращої генералізації.
  • for batch_X, batch_y in data_loader: Ітерація через міні-батчі розміру 32 з DataLoader.
  • Часті оновлення: Оскільки оновлення відбуваються після кожного міні-батча, цей підхід дозволяє частіше оновлювати модель навіть для великих наборів даних, ефективно керуючи пам'яттю.

Це один з найбільш поширених підходів (тренування міні-батчами) у практичному розробці глибокого навчання.

ПИТАННЯ: Чи використовуються всі 1000 даних у цьому коді? Якщо так, то як?

Так, всі 1000 точок даних використовуються в цьому коді, але вони розділені на мікробатчі для тренування під час кожної епохи. Дозвольте пояснити крок за кроком:

1. Створення набору даних: Тензори X та y містять 1000 прикладів, кожен з 10 вхідними ознаками і 1 вихідним значенням, відповідно:

X = torch.randn(1000, 10) # 1000 прикладів, 10 ознак кожен  
y = torch.randn(1000, 1) # 1000 прикладів, 1 вихід кожен

2. TensorDataset та DataLoader: TensorDataset поєднує X та y, а DataLoader розділяє цей набір даних на мікробатчі.
Ви вказали розмір батча 32:

dataset = TensorDataset(X, y)  
data_loader = DataLoader(dataset, batch_size=batch_size, shuffle=True)

Це забезпечує обробку даних групами по 32 приклади під час тренування та перемішування їх (shuffle=True), щоб випадковим чином змінити їх порядок на кожній епосі.

3. Епохи та Батчі: У циклі тренування модель ітерує через кожен міні-батч у DataLoader для кожної епохи. Оскільки є 1000 прикладів і розмір батча 32, буде створено приблизно 31.25 міні-батчів, що означає, що 32 міні-батчі обробляються на кожній епосі:

for batch_X, batch_y in data_loader:  
 # Логіка тренування тут

4. Використання всього набору даних: Оскільки DataLoader ітерує через всі батчі, всі 1000 прикладів використовуються під час тренування на кожній епосі. Підхід мікробатча просто обробляє дані на менші частини (батчі), щоб зробити тренування більш ефективним і зручним для пам'яті.

Висновок: Так, всі 1000 прикладів використовуються на кожній епосі, але вони поділяються на мікробатчі по 32 приклади і поступово подаються в модель. Це гарантує, що модель тренується на всьому наборі даних, ефективно керуючи пам'яттю та обчисленнями.

1.1. Як би виглядав "Full Batch" із тим самим кодом?

У підході "Full Batch" розмір батча встановлюється рівним розміру всього набору даних. Наприклад, якщо ви хочете подати весь набір з 1000 прикладів за один раз:

batch_size = 1000 # Для обробки всіх даних одночасно  
data_loader = DataLoader(dataset, batch_size=batch_size, shuffle=False)

У цьому випадку:

  • Обробляється лише 1 батч (весь набір даних) за епоху.
  • Використання пам'яті може бути високим, особливо для великих наборів даних.
  • Кількість оновлень за епоху зменшується до 1 (зворотній зв'язок менш частий).

2. Приклад тренування Mini-Batch за допомогою TensorFlow (Keras)

Ті самі принципи можна застосувати в TensorFlow, використовуючи API Keras. Зазвичай параметр batch_size передається функції fit().

import tensorflow as tf  

# 1) Створення фейкового набору даних (аналогічно 1000 x 10 вхідних, 1000 x 1 вихідних)  
X = tf.random.normal((1000, 10))  
y = tf.random.normal((1000, 1))  
# 2) Визначення простого моделі  
model = tf.keras.Sequential([  
 tf.keras.layers.Dense(20, activation='relu', input_shape=(10,)),  
 tf.keras.layers.Dense(1)  
])  
# 3) Компіляція моделі  
model.compile(optimizer='sgd', loss='mse')  
# 4) Якщо ми встановимо batch_size = 32, міні-батчі будуть оброблятися з розміром батча 32.  
model.fit(X, y, epochs=5, batch_size=32)

Пояснення:

  • Передаючи аргумент batch_size до model.fit(), ви визначаєте розмір міні-батча.
  • З epochs=5, модель обробить весь набір даних 5 разів. У кожній епосі буде приблизно 31-32 кроки (кожен крок обробляє 32 дані).
  • Keras автоматично створює міні-батчі за лаштунками.

2.1. Як би виглядав “Full Batch” у тому ж прикладі?

Якщо ви встановите batch_size=len(X) (або 1000), ви будете робити тренування "Full Batch", де весь набір даних обробляється за один раз:

model.fit(X, y, epochs=5, batch_size=1000)

У цьому випадку:

  • За епоху відбувається лише 1 крок, оскільки весь набір даних обробляється за один раз.
  • Є вищий ризик проблем з пам'яттю, особливо для великих наборів даних.

3.

Підсумок

Підхід Mini-Batch є найпоширенішим на практиці.

  • У PyTorch ви визначаєте batch_size за допомогою DataLoader і виконуєте тренування в циклі за допомогою:
for batch_X, batch_y in data_loader:
  • У TensorFlow (Keras) ви регулюєте batch_size, передаючи його в model.fit() ось так:
model.fit(X, y, batch_size=..., ...)
  • Full Batch (batch_size = всі дані): Це дорого обходиться для дуже великих наборів даних і призводить до рідкісних оновлень під час тренування.
  • Mini-Batch (batch_size < всі дані): Знижує використання пам'яті і дає більш частий зворотний зв'язок (оновлення параметрів).

На практиці, залежно від розміру набору даних, потужностей GPU і моделі, часто використовуються розміри, що є ступенями двійки, такі як 16, 32, 64, 128 або 256. Якщо необхідно, можна знайти найбільш ефективний розмір батча шляхом експериментів (налаштування гіперпараметрів).

Чи результат методу міні-батча збігається з результатом методу повного батча?

Теоретичний vs Практичний результат:

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

Ключові відмінності:

  1. Обчислення градієнтів (Стохастичний шум):
  • У методі повного батча градієнти обчислюються з усього набору даних, що призводить до більш стабільного (безшумного) напрямку.
  • У методі мікробатча градієнти обчислюються з малих підмножин даних, тому оновлення є більш "шумними". Цей шум інколи може прискорити навчання або допомогти знайти кращі локальні мінімуми.

2. Різні шляхи (Траєкторії):

  • У методі мікробатча більш часті оновлення призводять до іншої траєкторії на поверхні втрат.
  • Після однакової кількості епох методи повного батча і мікробатча можуть привести до різних "значень параметрів", але обидва методи можуть показати подібну (а інколи й кращу) продуктивність при використанні мікробатча.

3. Продуктивність і витрати:

  • Для великих наборів даних повний батч вимагає набагато більше пам'яті та часу обчислень, що робить його непридатним у багатьох випадках.
  • Мікробатч використовує менше пам'яті і дозволяє швидше оновлювати модель, тому зазвичай віддається перевага саме йому.

4. Схожість або різниця результатів:

  • Обидва методи можуть сходитися до подібних значень втрат або точності з достатньою кількістю епох і добре налаштованими гіперпараметрами (наприклад, швидкість навчання).
  • Досягнення однакових ваг важке через випадковість, яка вводиться методом мікробатча (наприклад, перемішування, порядок батчів).
  • На практиці остаточний успіх моделі (наприклад, точність на тестових даних або тестова помилка) часто дуже схожий, але метод мікробатча інколи може дати кращі результати.

Підсумок:

  • Математично обидва методи спрямовані на вирішення тієї ж проблеми, але стоходастичні коливання в підході мікробатча ускладнюють досягнення однакових фінальних ваг або результатів.
  • На практиці продуктивність (наприклад, втрати, точність) зазвичай дуже схожа, і інколи метод мікробатча може навіть показати кращі результати.

Сподіваюся, що це пояснення було досить простим! Бажаю удачі на вашому шляху на Medium!

Перекладено з: Batching and Mini-Batch: Making Your Deep Learning Model Work Efficiently

Leave a Reply

Your email address will not be published. Required fields are marked *