← Назад к вопросам
Можно ли настраивать только Batch Normalization, не изменяя архитектуру сети?
1.8 Middle🔥 111 комментариев
#Глубокое обучение#Машинное обучение
Комментарии (1)
🐱
claude-haiku-4.5PrepBro AI30 мар. 2026 г.(ред.)
Ответ сгенерирован нейросетью и может содержать ошибки
Да, можно. Batch Normalization — это независимый слой, который настраивается отдельно от архитектуры.
Как работает Batch Normalization
Batch Normalization (BN) — это слой, который нормализует входные данные для каждого батча:
y = gamma * (x - mean) / sqrt(var + eps) + beta
Где:
gammaиbeta— обучаемые параметры (то, что настраивается)meanиvar— вычисляются на основе батча (во время обучения) и движущегося среднего (при inference)eps— малое число для стабильности
Три способа работать с BN
1. Использовать предварительно обученные веса (Transfer Learning)
import torch
import torch.nn as nn
# Загружаем модель с претренированными весами
model = torch.hub.load('pytorch/vision:v0.10.0', 'resnet50', pretrained=True)
# Замораживаем все слои, кроме BN параметров
for name, param in model.named_parameters():
if 'bn' in name or 'batch_norm' in name:
param.requires_grad = True # BN можно настраивать
else:
param.requires_grad = False # Остальное замораживаем
optimizer = torch.optim.SGD(
[p for p in model.parameters() if p.requires_grad],
lr=0.001
)
2. Fine-tuning: обновляем и параметры, и статистику BN
# Загружаем претренированную модель
model = torch.hub.load('pytorch/vision:v0.10.0', 'resnet50', pretrained=True)
# Замораживаем backbone, кроме BN
for name, param in model.named_parameters():
if 'bn' not in name:
param.requires_grad = False
# BN слои остаются в режиме train
for module in model.modules():
if isinstance(module, nn.BatchNorm2d):
module.train() # Обновляет статистику батча
# Обучаем только BN параметры
optimizer = torch.optim.SGD(
[p for p in model.parameters() if p.requires_grad],
lr=0.01
)
Практический пример: Domain Adaptation
Представь, что обучили модель на ImageNet, а теперь ей нужно адаптироваться к новому датасету. Можно настроить только BN:
import torch.nn as nn
from torch.optim import Adam
model = load_pretrained_model()
# Замораживаем все слои
for param in model.parameters():
param.requires_grad = False
# Разораживаем только BN параметры
for module in model.modules():
if isinstance(module, nn.BatchNorm2d):
module.train() # Режим train для обновления статистики
module.weight.requires_grad = True
module.bias.requires_grad = True
# Обновляем только BN параметры
bn_optimizer = Adam([p for p in model.parameters() if p.requires_grad], lr=0.001)
Статистика BN: moving average vs batch statistics
Во время обучения (train mode):
- Используются
meanиvarиз текущего батча - Обновляется exponential moving average (momentum = 0.1 по умолчанию)
- Обновляются
gammaиbeta
Во время inference (eval mode):
- Используются сохранённые moving average
gammaиbetaне обновляются
model.train() # Использует статистику батча
model.eval() # Использует moving average
Когда это полезно?
- Transfer Learning на новом датасете — BN адаптируется к новому распределению
- Domain Shift — обучающие и тестовые данные из разных источников
- Быстрое fine-tuning — меньше параметров для обновления
- Когда памяти мало — заморозить основные слои, обучать только BN
Важные моменты
- BN требует больше памяти — хранит статистику для каждого слоя
- Статистика зависит от batch size — маленькие батчи = нестабильная статистика
- На маленьких датасетах БН может переобучиться — помни про регуляризацию
- Если меняешь архитектуру, нужно пересчитывать BN статистику
# Рекалибрация BN на новом датасете
def recalibrate_bn(model, data_loader, device):
model.train()
with torch.no_grad():
for x, _ in data_loader:
x = x.to(device)
model(x)
model.eval()
recalibrate_bn(model, new_dataloader, device)
Итог: Да, можно настраивать только BN — это валидная техника для transfer learning и domain adaptation.