Возвращаясь к трансферному обучению: тонкая настройка сети

искусственный интеллект

существует"Стоя на плечах гигантов: трансферное обучение«В статье мы говорили о методе трансферного обучения: используйте предварительно обученную сверточную нейронную сеть в качестве экстрактора признаков, а затем используйте стандартную модель классификации машинного обучения (например, логистическую регрессию) для обучения с извлеченными признаками и получите Classifier, этот процесс эквивалентен замене предыдущего поколения методов ручного извлечения признаков предварительно обученными сетями. Этот метод трансферного обучения также может обеспечить хорошую точность на небольших наборах данных (например, 17flowers).

В этой статье я также упомянул еще один вид трансферного обучения: тонкую настройку сетей, и в этой статье речь пойдет о тонкой настройке сетей.

Так называемая тонкая настройка сети эквивалентна «смене головы» предварительно обученной модели, то есть «отрезанию» последнего полносвязного слоя (который можно представить как «голову» сверточной нейронной сети). network), а затем подключаем новый полносвязный слой со случайно инициализируемыми параметрами, а затем обучаем на этой «хирургической» сверточной нейронной сети с нашим относительно небольшим набором данных.

При обучении на новой модели следует учитывать несколько моментов:

  1. При запуске обучения параметры слоев ниже «головы» (то есть слоев сети, которые не были заменены) нужно заморозить, то есть выполняется прямой расчет, но при обратном переносе параметры не обновляются, а процесс обучения обновляет только новые.Замените параметры на полносвязном слое.
  2. Тренируйтесь с очень маленькой скоростью обучения, скажем, 0,001
  3. Наконец, как вариант, когда параметры полносвязных слоев почти выучены, мы можем разморозить слои ниже «головы» и обучить всю сеть целиком.

Извлечение признаков и тонкая настройка сети

Сравнивая извлечение признаков в предыдущей статье, мы показываем разницу между ними с помощью интуитивно понятной графики:

Если мы выполним извлечение признаков на предварительно обученной модели VGG16, ее структура будет показана на следующем рисунке:

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

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

По сравнению с методом переноса обучения для извлечения признаков точная настройка сети обычно приводит к более высокой точности. Но помните, бесплатного обеда не бывает, а тонкая настройка сети требует больше работы:

Во-первых, время обучения очень велико.По сравнению с извлечением признаков, выполняется только прямая операция, а затем обучается простой алгоритм логистической регрессии.Скорость очень высокая.Поскольку сеть точной настройки обучается на модели глубокой сети, особенно на втором этапе комплексного Обратный перевод занимает больше времени. Используя набор данных 17flowers на моей видеокарте GTX 960, я тренировался несколько часов, и я еще не закончил тренировку, и в итоге я заснул :(, не знаю, сколько времени это заняло в итоге.

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

Сетевые слои и индексы

Перед "операцией" нужно понимать структуру модели, как минимум нужно знать название и индекс слоя, без этой информации как слепой берущийся за скальпель. В keras узнать информацию о слое очень просто:

print("[INFO] loading network ...")
model = VGG16(weights="imagenet", include_top=args["include_top"] > 0)

print("[INFO] showing layers ...")
for (i, layer) in enumerate(model.layers):
  print("[INFO] {}\t{}".format(i, layer.__class__.__name__))

Структура модели VGG16 выглядит следующим образом:

Можно видеть, что 20-й ~ 22-й уровни являются полносвязными слоями, которые также являются слоями, которые должны быть заменены сетью тонкой настройки.

Сетевой "смены головы"

Во-первых, мы определяем набор полносвязных слоев: INPUT => FC => RELU => DO => FC => SOFTMAX. По сравнению с полносвязным слоем в VGG16 он проще и имеет меньше параметров. Затем выходные данные базовой модели используются в качестве входных данных модели для завершения сшивания. Это соединение также довольно просто в keras.

class FCHeadNet:
  @staticmethod
  def build(base_model, classes, D):
    # initialize the head model that will be placed on top of
    # the base, then add a FC layer
    head_model = base_model.output
    head_model = Flatten(name="flatten")(head_model)
    head_model = Dense(D, activation="relu")(head_model)
    head_model = Dropout(0.5)(head_model)

    # add a softmax layer
    head_model = Dense(classes, activation="softmax")(head_model)

    return head_model

Поскольку в конструкторе VGG16 есть параметр include_top, который может решить, включать ли полностью подключенный слой головы, этот шаг «изменить голову» довольно прост:

base_model = VGG16(weights="imagenet", include_top=False, input_tensor=Input(shape=(224, 224, 3)))

# initialize the new head of the network, a set of FC layers followed by a softmax classifier
head_model = FCHeadNet.build(base_model, len(class_names), 256)

# place the head FC model on top of the base model -- this will become the actual model we will train
model = Model(inputs=base_model.input, outputs=head_model)

Модель, полученная в это время, представляет собой сетевую модель, подвергшуюся «замене головы».

тренироваться

Обучение сети точной настройки похоже на процесс обучения модели, упомянутый ранее, за исключением того, что есть дополнительное действие стоп-слоя, которое на самом деле представляет собой два процесса обучения. Как исправить параметры слоя? Это можно сделать одним предложением:

for layer in base_model.layers:
  layer.trainable = False

«Разморозить» аналогично, за исключением того, что значение layer.trainable установлено в True.

Для того, чтобы быстрее сойтись и как можно быстрее узнать параметры полносвязного слоя, рекомендуется на первом этапе использовать оптимизатор RMSprop. Но для скорости обучения необходимо выбрать относительно небольшое значение, например 0,001.

После довольно длительного периода обучения результаты новой модели на наборе данных 17flowers следующие:

[INFO] evaluating after fine-tuning ...
              precision    recall  f1-score   support

    bluebell       0.95      0.95      0.95        20
   buttercup       1.00      0.90      0.95        20
   coltsfoot       0.95      0.91      0.93        22
     cowslip       0.93      0.87      0.90        15
      crocus       1.00      1.00      1.00        23
    daffodil       0.92      1.00      0.96        23
       daisy       1.00      0.94      0.97        16
   dandelion       0.94      0.94      0.94        16
  fritillary       1.00      0.95      0.98        21
        iris       0.96      0.96      0.96        27
  lilyvalley       0.94      0.89      0.91        18
       pansy       0.90      0.95      0.92        19
    snowdrop       0.86      0.95      0.90        20
   sunflower       0.95      1.00      0.98        20
   tigerlily       0.96      0.96      0.96        23
       tulip       0.70      0.78      0.74        18
  windflower       1.00      0.95      0.97        19

   micro avg       0.94      0.94      0.94       340
   macro avg       0.94      0.93      0.94       340
weighted avg       0.94      0.94      0.94       340

По сравнению с трансферным обучением извлечению признаков точность значительно повысилась.

резюме

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

В приведенных выше примерах есть полные коды. Нажмите, чтобы прочитать исходный текст и перейти к примеру кода, который я создал на github.

Кроме того, я читаю книгу «Глубокое обучение компьютерному зрению с помощью Python», и, отвечая на ключевое слово «компьютерное зрение» в фоновом режиме публичного аккаунта WeChat, вы можете скачать электронную версию этой книги бесплатно.

прошлый обзор

  1. Стоя на плечах гигантов: трансферное обучение
  2. Поговорим о точности ранга 1 и ранга 5.
  3. Используйте методы увеличения данных, чтобы улучшить возможности обобщения модели.

image