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

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

В этом посте мы стремимся дать пошаговое руководство по выполнению трансферного обучения при распознавании изображений. Мы покажем, как использовать сверточную нейронную сеть (CNN) вместе с графическим процессором и процессором для построения модели классификации изображений и как ускорить обучение с помощью OPU (Optical Processing Unit), разработанного LightOn.

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

Перенос обучения

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

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

  1. Загрузите набор данных и выбранную модель.
  2. Извлеките сверточные особенности набора поездов.
  3. Выполните случайную проекцию объектов в k-мерное пространство. Мы объясним, как выполнить этот шаг с графическим процессором, а также с OPU LightOn.
  4. Установите линейный классификатор на случайные характеристики набора тестов, например логистический классификатор.

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

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

Загрузка данных и моделей

Начнем с загрузки данных для нашей целевой задачи. Мы используем набор данных STL10, доступный в пакете torchvision, который состоит из 5000 изображений поездов и 8000 тестовых изображений 10 различных классов. Обзор представлен на рисунке 3.

Начнем с установки следующих параметров:

- root: путь к каталогу данных. Если набора данных нет, он будет загружен здесь;

- transforms применять к каждому образцу. Мы используем простую нормализацию и изменяем размер изображений до (224, 224);

- batch_size: размер пакета для количества выборок, обрабатываемых одновременно;

- num_workers: количество ядер ЦП, используемых загрузчиками данных.

Мы используем DenseNet169 [2], предварительно обученный в ImageNet, доступный в библиотеке torchvision.

Мы также настраиваем устройство для любых будущих вычислений: мы можем выбрать cpu, если мы хотим выполнять все вычисления на ЦП, или cuda:x, если мы работаем на машине с одним или несколькими графическими процессорами. В последнем случае используемым графическим процессором будет номер x, обычно начиная с 0. Например, мы используем номер графического процессора 0 в нашем коде, записывая cuda:0.

Поскольку нам не нужен линейный участок в конце, мы выбираем только сверточную часть CNN с .features. Более того, чтобы оптимизировать объем памяти, выделенной на GPU для задачи, мы передаем фиктивный ввод через сеть, чтобы получить размер сверточных функций. Для DenseNet169, обученного на (224, 224) изображениях, выходной размер будет 81536.

Извлечение сверточных функций

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

Это делается с помощью следующего вызова функции:

Мы выделяем матрицу conv_features размера (num_images, out_shape) для сверточных характеристик поезда или тестового набора и вектор labels длины num_images для меток. Мы просматриваем все изображения в загрузчике и сохраняем сверточные функции и соответствующие метки в этих двух матрицах.

Наконец, мы используем кодирование на основе знаков для сверточных функций, где положительные числа сопоставляются с 1, а остальные с 0. Мы также синхронизируем извлечение признаков и кодирование с библиотекой time в python. Всем вызовам time предшествует torch.synchronize(), чтобы гарантировать правильное вычисление времени, если используется графический процессор, поскольку операции на графическом процессоре выполняются асинхронно.

Теперь мы можем просто вызвать нашу функцию в наборе для обучения и тестирования:

Выполнение случайного проецирования

Случайная проекция: просто умножение

Мы можем выполнить случайное проецирование либо на GPU, либо на OPU. Напоминаем, что случайная проекция состоит в умножении на фиксированную матрицу R, элементы которой взяты из нормального распределения, как в следующей формуле:

Y = |XR|²

Матрица X размера (n * m), содержащая сверточные признаки, проецируется в k-мерное пространство. Если k ›m, объекты будут проецироваться в пространство более высоких измерений, где они могут быть линейно отделимы. Это свойство характерно только для нелинейных случайных проекций. Если k ‹m, размер признаков будет уменьшен, что ускоряет последующее обучение линейного классификатора за счет конечной точности.

Далее мы исследуем первую ситуацию, установив k = 120000.

С графическим процессором

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

Мы выбираем 120000 как количество случайных признаков и генерируем случайную матрицу:

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

Чтобы получить матрицу случайных характеристик для набора поездов / тестов и времени проекции, мы вызываем:

С OPU

Давайте теперь проделаем ту же операцию с OPU.

Для выполнения случайного проецирования с помощью OPU мы используем библиотеку lightonml , которая предоставляет простой API Python для выполнения случайных проекций с помощью OPU LightOn.

Прежде всего, мы импортируем объект OPUMap из библиотеки lightonml и создаем экземпляр класса, передавая количество случайных проекций n_components в качестве аргумента.

Простой вызов opu.transform(X) выполняет случайную проекцию входной матрицы X, содержащей сверточные характеристики набора поездов / тестов. Мы сохраняем выходную матрицу в переменной random_features .

Мы также синхронизируем продолжительность проекции с библиотекой time, доступной в python.

Поскольку вызов является синхронным, нет необходимости вызывать torch.synchronize() перед операторами времени, как мы это делали для сверточных функций.

После проецирования функции, создаваемые OPU, имеют формат uint8 format. Хотя это не является строго необходимым, их удобно преобразовать в float32, потому что многие алгоритмы в Python, такие как внутренняя часть функции соответствия некоторых классификаторов scikit-learn, оптимизированы для этого типа данных.

Последний вызов функции для получения обучающих / тестовых случайных функций с OPU LightOn следующий:

Подбор классификатора

Теперь мы можем просто подогнать линейный классификатор к функциям обучения и оценить его эффективность на тестовой выборке. Мы выбрали RidgeClassifier, доступный в scikit-learn, из-за его быстрой реализации по сравнению с другими классификаторами, такими как логистическая регрессия.

Мы создаем объект RidgeClassifier и передаем в качестве аргумента коэффициент регуляризации alpha. Мы могли бы установить его с помощью перекрестной проверки, но обычно значения, близкие к 1e6 , дают довольно хорошие результаты с OPU LightOn. Если используется графический процессор, это значение необходимо уменьшить до 1e3.

Результаты

В этом прогоне мы получили точность 96,50% на тестовом наборе, выполнив случайное проецирование с помощью OPU LightOn, по сравнению с 96,9% с использованием графического процессора. Поскольку набор данных STL10 содержит 8000 тестовых изображений, разница между точностью теста 96,5% и 96,9% состоит только из еще 32 ошибочных классификаций.

Здесь мы ясно видим, что результаты, полученные с OPU и GPU, довольно близки, если мы сравним одну модель. Однако когда дело доходит до времени, сравнения нет. Чтобы выполнить проекцию на GPU, нам нужно сначала сгенерировать случайную матрицу и разбить ее на блоки, что занимает 430 с для матрицы размера (81536, 120000), используемой в этом эксперименте. Фактическое случайное проецирование занимает 30,3 с на сверточных характеристиках тестового набора, тогда как OPU выполняет такое же проецирование за 8,5 с для ускорения в 3,5 раза. Более того, OPU не нуждается в генерации случайной матрицы, а это означает, что мы достигаем ускорения в 54 раза, если мы принимаем во внимание процесс генерации.

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

Заключение

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

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

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

Если вы хотите проверить код и запустить его, вот ссылка на блокнот Jupyter.

О нас

LightOn - компания, занимающаяся аппаратным обеспечением, которая разрабатывает новые оптические процессоры, которые значительно ускоряют вычисления с помощью машинного обучения. Процессоры LightOn открывают новые горизонты в вычислительной и инженерной областях, которые сталкиваются с вычислительными ограничениями. Заинтересованы в ускорении вычислений? Попробуйте наше решение на LightOn Cloud! 🌈

Пожалуйста, подпишитесь на нас в Твиттере на @LightOnIO, подпишитесь на нашу рассылку новостей и / или зарегистрируйтесь в нашей серии семинаров. Мы ведем прямую трансляцию, так что вы можете присоединиться откуда угодно. 🌍

Автор

Лука Томмасоне, инженер по машинному обучению в LightOn AI Research.

Благодарности

Мы благодарим Игоря Каррона, Виктуар Луи, Якопо Поли и Франсуа Бонифаса за просмотр этого сообщения в блоге.

использованная литература

[1] Ольга Русаковская *, Цзя Дэн *, Хао Су, Джонатан Краузе, Санджив Сатиш, Шон Ма, Чжихенг Хуанг, Андрей Карпати, Адитья Хосла, Майкл Бернштейн, Александр К. Берг и Ли Фэй -Fei. (* = равный вклад) ImageNet Large Scale Visual Recognition Challenge. Международный журнал компьютерного зрения, 2015 г.

[2] Хуанг Г. и др. «Плотно связанные сверточные сети. arXiv 2017. » Препринт arXiv arXiv: 1608.06993