Transfer learning: дообучение готовых моделей
Главный практический приём индустрии: не учить с нуля, а дообучать готовое.
Transfer learning — использование сети, уже обученной на большом наборе данных, как основы для своей задачи с малым числом примеров.
Почему не учить с нуля
Обучить большую сеть с нуля нужны миллионы картинок и дни на мощных GPU — у вас этого обычно нет. Но есть готовые модели (например ResNet), уже обученные на миллионах изображений ImageNet. Они выучили универсальные признаки: первые слои узнают края и текстуры, средние — формы и части объектов. Эти знания полезны почти для любой картиночной задачи. Идея transfer learning: взять эти готовые признаки и приставить к ним свой маленький «классификатор» под вашу задачу.
Как это работает: заморозка и замена головы
План в три шага. Берём предобученную сеть. Замораживаем её веса (запрещаем им обучаться — они уже хороши). Заменяем последний слой («голову») на новый под наше число классов и учим только его. Поскольку учится лишь крошечная голова, хватает сотни примеров и пары минут.
import torch
import torch.nn as nn
import torchvision.models as models
# 1. берём предобученную ResNet18
model = models.resnet18(weights="IMAGENET1K_V1")
# 2. замораживаем все веса — градиенты по ним не считаем
for param in model.parameters():
param.requires_grad = False
# 3. заменяем голову под свои 3 класса
# (у нового слоя requires_grad=True по умолчанию)
model.fc = nn.Linear(model.fc.in_features, 3)
Разберём ключевую механику. Установка requires_grad = False всем параметрам — это та самая заморозка из раздела про autograd: по таким весам градиенты не считаются и оптимизатор их не трогает. А новый model.fc создан только что, у него requires_grad=True — значит, учиться будет только он.
Оптимизатор учит только голову
Поскольку у замороженных слоёв градиентов нет, оптимизатору можно отдать вообще все параметры — он обновит только те, у кого requires_grad=True. Но чище отдать явно лишь параметры новой головы:
# учим только новый слой
optimizer = torch.optim.Adam(model.fc.parameters(), lr=0.001)
Дальше — обычный цикл обучения из пяти шагов. Ничего нового: forward → loss → zero_grad → backward → step. Просто backprop дойдёт только до незамороженной головы.
Заморозить или дообучить всё (fine-tuning)
| Подход | Когда |
| заморозить тело, учить голову | мало данных, задача близка к исходной — быстро и безопасно |
| дообучить всю сеть (fine-tuning) | данных побольше, нужно адаптировать признаки — с маленьким lr |
При полном fine-tuning размораживают всю сеть, но берут очень маленький lr, чтобы не разрушить уже выученные признаки. Начинают обычно с заморозки — это проще и часто достаточно.
Почему это так важно
Transfer learning — причина, по которой современный ИИ доступен не только гигантам. Дообучить готовую модель под свою задачу можно на ноутбуке за минуты. Та же идея лежит в основе дообучения языковых моделей: берут предобученную на терабайтах текста сеть и адаптируют под конкретную задачу малым числом примеров.
Итог
- Transfer learning = взять предобученную сеть и дообучить под свою задачу.
- Признаки первых слоёв (края, текстуры) универсальны — их незачем учить заново.
- Базовый рецепт: заморозить тело (
requires_grad=False), заменить голову, учить только её. - Полный fine-tuning размораживает всё, но с маленьким
lr; обычно начинают с заморозки.