Трансферное обучение — это метод машинного обучения, при котором предварительно обученная модель адаптируется для новой, но похожей задачи. Одним из ключевых шагов в трансферном обучении является возможность заморозить слои предварительно обученной модели, чтобы во время обучения обновлялись только некоторые части сети. Замораживание имеет решающее значение, если вы хотите сохранить функции, которые уже изучена предварительно обученной моделью.

В этом уроке мы рассмотрим процесс замораживания весов в PyTorch для переноса обучения на простом примере.

Предварительные условия

Если у вас не установлены библиотеки torch и torchvision, вот как мы можем сделать это в терминале:

pip install torch torchvision

Импортировать библиотеки

Начнем с кода Python. Сначала мы импортируем библиотеки для этого урока:

import torch
import torch.nn as nn
import torchvision.models as models

Загрузите предварительно обученную модель

Для этого примера мы будем использовать предварительно обученную модель ResNet-18:

# Load the pre-trained model
resnet18 = models.resnet18(pretrained=True)

Замораживание слоев

Чтобы заморозить слои, мы установили атрибут requires_grad на False. Это не позволяет PyTorch вычислять градиенты для этих слоев во время обратного распространения ошибки.

# Freeze all layers
for param in resnet18.parameters():
    param.requires_grad = False

Разморозка некоторых слоев

Обычно для достижения наилучших результатов мы настраиваем некоторые более поздние уровни сети. Мы можем сделать это следующим образом:

# Unfreeze last layer
for param in resnet18.fc.parameters():
    param.requires_grad = True

Изменение сетевой архитектуры

Мы заменим последний полносвязный слой, чтобы адаптировать модель к новой задаче, с другим количеством выходных классов (скажем, 10 классов). Кроме того, это позволяет нам использовать эту предварительно обученную сеть для других приложений, помимо классификации, например для сегментации. Вместо этого для сегментации мы заменяем последний слой сверточным слоем. В этом примере мы продолжим задачу классификации с 10 классами.

# Replace last layer
num_ftrs = resnet18.fc.in_features
resnet18.fc = nn.Linear(num_ftrs, 10)

Обучение модифицированной модели

Давайте определим простой цикл обучения. В демонстрационных целях мы будем использовать случайные данные.

# Create random data
inputs = torch.randn(5, 3, 224, 224)
labels = torch.randint(0, 10, (5,))

# Loss and optimizer
criterion = nn.CrossEntropyLoss()
optimizer = torch.optim.SGD(resnet18.fc.parameters(), lr=0.001, momentum=0.9)

# Training loop
for epoch in range(5):
    optimizer.zero_grad()
    outputs = resnet18(inputs)
    loss = criterion(outputs, labels)
    loss.backward()
    optimizer.step()
    print(f'Epoch {epoch+1}/5, Loss: {loss.item()}')

В этом примере во время обучения будут обновляться только веса последнего слоя.

Заключение

Заморозить слои в PyTorch просто и понятно. Установив для атрибута requires_grad значение False, вы предотвращаете обновление определенных слоев во время обучения, позволяя эффективно использовать возможности предварительно обученных моделей.

Понимание того, как заморозить и разморозить слои в PyTorch, имеет решающее значение для эффективного трансферного обучения, поскольку позволяет использовать предварительно обученные модели для аналогичных, но разных задач. С помощью этого простого, но мощного метода вы сможете сэкономить время и вычислительные ресурсы при обучении глубоких нейронных сетей.

Спасибо за чтение! Если вы находите мои блоги интересными или хотите со мной связаться, обратитесь сюда, Github или LinkedIn.

На простом английском языке

Спасибо, что вы являетесь частью нашего сообщества! Прежде чем уйти: