Введение

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

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

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

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

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

Какие модели можно применять?

Список моделей для Transfer Learning мы можем посмотреть в GitHub-репозитории TorchVision.

Вот список моделей (наиболее популярных), которые доступны на момент написания этой статьи:

  • АлексНет
  • ConvNeXt
  • Плотная сеть
  • Эффективная сеть (v1, v2)
  • GoogleNet
  • Зарождение
  • МаксВиТ
  • Мобильная сеть
  • Реснет
  • Регнет
  • Свин
  • ВГГ

Реализация

Во-первых, вам нужно импортировать некоторые библиотеки

import torch
import torchvision
import torch.nn as nn
import torch.optim as optim
import torch.nn.functional as F
from torch.utils.data import Dataset, DataLoader, ConcatDataset
import torchvision.transforms as transforms

После того, как вы импортировали библиотеки, вам необходимо подготовить набор данных, как это было во время обучения модели переноса. Вы можете проверить параметры в репозитории GitHub модели. Давайте попробуем это на примере модели EfficientNet_V2_M.

class EfficientNet_V2_M_Weights(WeightsEnum):
    IMAGENET1K_V1 = Weights(
        url="https://download.pytorch.org/models/efficientnet_v2_m-dc08266a.pth",
        transforms=partial(
            ImageClassification,
            crop_size=480,
            resize_size=480,
            interpolation=InterpolationMode.BILINEAR,
        ),

Там мы видим, что будет лучше, если размер наших изображений будет 480*480 пикселей. Также стоит нормализовать хотя бы по классическим параметрам (mean=[0,485, 0,456, 0,406], std=[0,229, 0,224, 0,225]).

img_tform = torch.nn.Sequential(
    transforms.Resize((480, 480)),    # Resize image for model, because model input is 480 * 480 pixels image 
    transforms.Normalize(mean=[0.485, 0.456, 0.406], std=[0.229, 0.224, 0.225])    # Normalize image like ImageNet
)

Итак, как мы можем реализовать предварительно обученную модель?

Чаще всего модель состоит из двух основных частей: экстрактора признаков и классификатора. Средство извлечения признаков было построено из некоторых слоев, таких как свертки, активации и т. д. Классификатор — это конец модели.

Нам нужно заморозить некоторые слои, но как выбрать замораживающие слои?

Существуют 4 наиболее распространенные ситуации:

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

Итак, нам нужно удалить предыдущий блок Classifier и создать новый с выходным размером, равным количеству классов, которые мы пытаемся предсказать.

# importing our model
model = torchvision.models.efficientnet_v2_m(weights='IMAGENET1K_V1')
layers_freeze = 8  # freezing feature extractor

model.classifier = nn.Sequential(
    nn.Dropout(0.2, inplace=True),
    nn.Linear(1280, num_classes)  # creating a new classifier
)

# train some layers and leave other frozen
for i in range(layers_freeze):
    for param in model.features[i].parameters():
        param.requires_grad = False

model.to(device);  # move model to the our device(cpu or cuda)

После всего этого мы можем начать наш поезд.

Пожалуйста, обратите внимание и давайте вашему оптимизатору только те параметры, которые вы не заморозили:

optim.AdamW(filter(lambda x: x.requires_grad, model.parameters()), lr=learning_rate)

Тест

Я реализовал этот EfficientNet_V2_M в классической задаче «Цветок102».

Есть мои результаты:

Итак, мы видим, что модель очень быстро научилась и уже в первой эпохе показала отличную точность.

Заключение

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