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

Настройка

Я использовал Paperspace для запуска машинного обучения в облаке, записные книжки Jupyter в качестве редактора и Python 3 в качестве языка программирования.

Настройка данных

Для обучения модели нам понадобятся три типа данных:

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

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

Обучение последнего слоя нейронной сети

Для обучения последнего уровня нейронной сети потребовалось всего 4 основные строки кода.

arch=resnet34
data = ImageClassifierData.from_paths(PATH, tfms=tfms_from_model(arch, sz))
learn = ConvLearner.pretrained(arch, data, precompute=True)
learn.fit(0.01, 2)

Первая строка определяет архитектуру модели. Мы будем использовать архитектуру ResNext-50 - одну из лучших моделей компьютерного зрения.

Во второй строке код указывает на конкретный ПУТЬ (/ data / dogscats) с определенной структурой папок - папка «поезд» и «действительная», каждая с папкой «собака» и «кошка», заполненными изображениями в формате .jpg.

Третья строка представляет модель, которую мы будем использовать для классификации. Модель Resnext, которую мы используем, будет предварительно обученной моделью в базе данных imagenet.

В первой строке первый параметр для learn.fit (), 0,01, относится к скорости обучения, применяемой к функции Gradient Decent. Чтобы понять скорость обучения, давайте сначала узнаем о Gradient Decent.

Понимание Gradient Decent

Gradient Decent используется для точной настройки вашего алгоритма путем нахождения коэффициентов функции, которая минимизирует вашу функцию затрат (сумму всех ошибок в вашем наборе обучающих данных). Представьте, что вы начинаете с любой точки на трехмерной плоскости, и ваша цель - продолжать спускаться по склону до тех пор, пока вы не сможете спускаться дальше. Ваша функция приличного градиента - это трехмерная плоскость с функцией потерь на оси Y, которая уменьшается по мере того, как вы спускаетесь по склону, как показано ниже:

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

Выбор подходящей скорости обучения

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

Самый простой способ эффективно выбрать подходящую скорость обучения - использовать lr_find (), которая отображает потери в зависимости от скорости обучения, чтобы найти наивысшую скорость обучения, при которой потери все еще явно улучшаются. В приведенном ниже примере оптимальная скорость обучения находится между 10 ^ -3 и 10 ^ -2.

Отжиг скорости обучения означает снижение скорости обучения во время тренировки. Fast.ai предлагает использовать косинусный отжиг для уменьшения скорости обучения - метод отжига, при котором скорость обучения замедляется по мере достижения локального минимума, а затем снова возвращается к более высокой скорости обучения, чтобы избежать более острые части и входят в более крупные чаши в трехмерной модели.

Использование увеличения данных для предотвращения переобучения

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

Кроме того, мы можем использовать Test Time Augmentation (TTA), чтобы делать прогнозы не только на изображениях в наборе проверок, но также и на ряде их случайно расширенных версий.

Интеграция последнего слоя в предварительно обученную нейронную сеть

Мы закончили обучение последнего слоя на основе 4 строк кода выше. В качестве последнего шага нам просто нужно вставить последний слой в другой предварительно обученный Imagenet CNN, разморозив остальные слои. Более ранние слои Imagenet имеют более общие функции, такие как градиенты, края и углы, поэтому мы ожидаем, что им потребуется меньше тонкой настройки для новых наборов данных. По этой причине мы собираемся использовать разные скорости обучения для разных уровней: первые несколько уровней будут на уровне 1e-4, средние уровни - на уровне 1e-3, а наш слой останется на уровне 1e-2. Это называется отжигом с разной скоростью обучения.

Вот и все, что нужно для создания классификатора изображений собак и кошек!

Обзор - шаги по обучению классификатора изображений

  1. Включите увеличение данных и precompute = True (что по существу замораживает все слои)
  2. Используйте lr_find (), чтобы найти наивысшую скорость обучения, при которой потери все еще явно улучшаются
  3. Обучите последний слой из предварительно вычисленных активаций на 1–2 эпохи.
  4. Обучите последний слой с увеличением данных (т.е. precompute = False) для 2–3 эпох с cycle_len = 1
  5. Разморозить все слои
  6. Установите для более ранних слоев скорость обучения в 3–10 раз ниже, чем для следующего более высокого уровня (отжиг с разной скоростью обучения)
  7. Снова используйте lr_find () (он распечатает скорость обучения только для последнего слоя)
  8. Обучите всю сеть с cycle_mult = 2 до переобучения

Советы по Jupyter

  • первая буква + табуляция = рекомендуемые функции
  • shift + tab = аргументы функции
  • shift + tab + ^ arrow = вызывает документацию
  • ?? learn.predict = вызывает исходный код
  • нажмите клавишу «h» = сочетания клавиш для ноутбука Jupyter

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