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

Получение существующей модели

Вы можете получить существующую модель AlexNet во многих местах. Я собираюсь использовать тот, что отсюда.

С сайта нам нужно скачать все файлы и поместить их в папку. Вы можете сделать это вручную, используя curl / wget, или просто запустить этот скрипт, который создает папку pretrained/, и скачать все необходимые файлы. В остальной части руководства предполагается, что вы использовали сценарий.

Чтобы убедиться, что все работает правильно, вы можете cd в pretrained/ и запустить python3 myalexnet_forward_newtf.py.

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

Единственное изменение, которое я внесу, - это строка 9, в которой указано, что vlc_alexnet.npy находится в папке pretrained/, а не в корневом каталоге. Я также изменил размер изображения на (224, 224).

Изменение размера изображений

Предварительно обученный AlexNet был обучен на изображениях ImageNet размером (224, 224), но данные CIFAR-10 - (32, 32). Есть несколько способов решить эту проблему: добавить отступ или изменить размер изображения. Поскольку разница между размером ImageNet и размером Cifar-10 настолько велика, если мы добавим отступ, он займет большую часть изображения.

Вместо этого мы увеличим размер изображения. Для этого мы добавим методы к существующим cifar.py и helper.py с помощью scikit-image. Сначала мы устанавливаем пакет с помощью

pip3 install --user scikit-image

Функция reshape служит основой только для использования skimage.transform.resize, которое используется transform_to_input_output_and_pad и reshape_batch. Первый преобразует набор в измененный ввод и однократный вывод. Последний делает то же самое с партией.

Затем мы обновляем cifar.py, чтобы использовать эти вспомогательные функции.

Мы добавляем create_resized_test_set и create_resized_batches, которые создают партии и набор тестов с измененным размером.

Добавление к существующей модели

Часть ConvNet в AlexNet была предварительно обучена, поэтому она уже хороша в извлечении функций. Однако полностью связанный слой обслуживается набором данных ImageNet. Мы заменим предварительно обученный полностью связанный слой нашим собственным для набора данных CIFAR-10.

Мы создадим новый файл с именем transfer_training.py, который будет содержать код, загружающий предварительно обученную модель, а также обучающие данные CIFAR-10. Сначала мы импортируем pretrained.py и берем maxpool5, который является слоем непосредственно перед полностью связанным слоем. Мы настраиваем один слой FC, который выводит 10 классов для CIFAR-10. Мы снижаем скорость обучения до 0.00001, потому что, если мы оставим ее такой же, как и раньше, модель фактически не будет обучаться. Все остальное настраиваем так же, как и раньше.

Затем мы запускаем только что созданный cifar.create_resized_test_set. Вы можете запустить create_resized_batches, но это займет много памяти, которой у меня нет.

Далее мы добавляем все тренировочные процессы, которые мы сделали ранее. Я решил дополнять изображения пакетом за пакетом, поскольку он занимает меньше памяти, хотя и требует больше времени на обучение. Поэтому в строках 38 и 39 ниже я получаю каждую партию и меняю ее форму, изменяя размер изображений до (224, 224). Затем я просто запускаю оптимизатор, как обычно.

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

При запуске python3 transfer_training.py в течение ~ 20 периодов точность теста составляет ~ 80%, что значительно больше, чем ~ 60% от нашего собственного обучения. Это потому, что инструктор AlexNet очень хорошо проделал большую часть работы по обучению слоев ConvNet, и мы просто немного адаптируем его к нашему набору данных.

Добавление к существующей модели (с использованием VGG19)

На практике есть и другие модели, в которых мы можем использовать трансферное обучение, которые дают лучшие результаты, чем AlexNet. VGG19 очень популярен, поэтому мы собираемся использовать его для обнаружения изображений CIFAR-10. Механизм для него можно передавать, так что вы можете использовать другие модели, если захотите.

Во-первых, нам нужно скачать тензорнет, в котором есть много предварительно обученных моделей для Tensorflow. Для этого запускаем pip3 install --user tensornets. Затем мы создаем новый файл с именем vgg_transfer_learning.py, в котором используем переносное обучение на VGG19. Настройка VGG19 довольно проста, а все остальное такое же, как и раньше.

Для VGG19 результаты лучше при использовании tf.losess.softmax_cross_entropy, который используется в строке 13. Различия между различными функциями потерь объясняются здесь. Мы также используем tf.identity по причинам, которые можно найти здесь. Как только мы узнаем, как его настроить, все остальное станет идентичным.

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

Заключение

Хотя создание и обучение самостоятельно - важное упражнение, использование трансферного обучения более полезно, поскольку дает лучшие результаты. Использование предварительно обученного AlexNet дает точность ~ 0,80, в то время как использование VGG19 дает точность ~ 0,9, что намного лучше, чем точность ~ 0,6 из нашего собственного обучения.