Я написал этот блог, чтобы завершить свой первый публичный доклад на PyCon Thailand 2018 и добавить некоторые подробности. Скачать все материалы.

Чтобы запустить ноутбук на бесплатном графическом процессоре Google Colab, прочтите здесь

Ad Tech

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

Глубокое обучение

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

Одноуровневая нейронная сеть

Это фундаментальная сеть. Есть один слой с одной нейронной единицей или нейроном. Нейрон выполняет скалярное произведение с вводом и его весом и применяет к нему функцию активации. Сегодня очень популярной активацией является ReLU, Rectified Linear Unit, которая выполняет функцию max (0, x).

Полностью подключенная сеть

Это многоуровневая сеть с несколькими нейронами. Все нейроны между слоями связаны. Вы можете иметь любое количество скрытых слоев и нейронов.

Сверточная нейронная сеть (CNN)

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

Максимальное объединение

Максимальное объединение выбирает максимальное значение, которое оно покрывает. Как показано на рисунке, это максимальное объединение 2 x 2 пикселя с шагом = 2 (шаг, который он перемещает за раз).

Создать сеть

Мы можем создать сеть, используя то, что мы упоминали ранее для классификации изображений. Например, LeNet-5 на этом рисунке представляет собой сеть, используемую для классификации рукописных цифр 0–9. Он состоит из CNN, пула и полностью подключенной сети.

Функции потерь

Функция потерь - это функция для измерения разницы между выходом сети и целью. Для классификации изображений мы применяем функцию softmax и используем потерю кросс-энтропии как функцию потерь. Например, если целью y_i является класс 2 (одно горячее встраивание - [0, 0, 1]), потеря будет 0,532.

Достойные градиенты

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

Мы можем обновить каждый вес, используя это уравнение. Скорость обучения - это гиперпараметр, который мы должны определить. Если оно слишком велико, потери будут превышены и никогда не достигнут минимума (см. Верхний правый рисунок).

Update weight : w += - learning_rate * gradient

Цикл обучения сети

Теперь делаем цикл обучения. Вычислить выходные данные, потери, градиенты и параметры обновления (веса и смещения). Повторяем процесс до тех пор, пока не получим минимальный убыток.

PyTorch

Как видите, глубокое обучение требует большого количества работы и вычислений. Эффективный способ - использовать фреймворк глубокого обучения.
PyTorch - фреймворк глубокого обучения для Python. Он поставляется с Autograd-a, автоматически вычисляющим градиенты. Он оснащен инструментами для простого и эффективного создания и обучения глубокому обучению. Он также поддерживает графический процессор (GPU). Он поддерживает Linux, Mac и Windows и прост в установке (см. Pytorch.org).

Тензор

Тензор - это фундаментальная структура данных PyTorch. Это многомерная матрица, похожая на ndarrays numpy, но способная работать на графическом процессоре для ускорения вычислений.

Проектные трубопроводы

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

1. Получите данные

Мы используем набор данных Flickrlogos-32 из https://www.uni-augsburg.de/en/fakultaet/fai/informatik/prof/mmc/research/datensatze/flickrlogos кад/ (см. Раздел« Скачать )

  • 32 бренда + без логотипа
  • Adidas, Aldi, Apple, Becks, BMW, Carlsberg, Chimay, Coca-Cola, Corona, DHL, Erdinger, Esso, Fedex, Ferrari, Ford, Foster's, Google, Guiness, Heineken, HP, Milka, Nvidia, Paulaner, Pepsi, Ritter Sport, Shell, Singha, Starbucks, Stella Artois, Texaco, Tsingtao и UPS.
  • Есть 320 изображений логотипов для обучения, 960 изображений для проверки, 3960 изображений для тестирования и 3000 изображений без логотипов.

  • Импортируйте необходимую библиотеку.
  • Определите каталоги.
  • Создайте служебную функцию load_datasets, чтобы загрузить набор данных из FLICLLOGOS_URL и распаковать его в SOURCE_DIR.

2. Подготовьте данные для сети

  • Создайте служебную функцию list_image_paths для чтения относительных путей к файлам изображений из текстового файла в переменные списка.
  • Добавьте train_logo_relpaths и половину val_logo_relpaths в train_relpaths.
  • Добавьте train_logo_relpaths и вторую половину val_logo_relpaths в val_relpaths.

  • Мы собираемся использовать datasets.ImageFolder (), который предпочитает структуру каталогов как dataset / classes / img.jpg.
  • Создайте служебную функцию prepare_datasets для копирования файлов изображений в соответствии со списками относительных путей к предпочтительной структуре каталогов.

  • Импорт библиотек torch и torchvision
  • Определите data_transforms, который изменяет размер, преобразует в тензор и нормализует входные данные по среднему значению и стандартному отклонению набора обучающих данных.
  • Создайте наборы данных с помощью torchvision.datasets.ImageFolder с каталогами наборов аргументов и data_transform.
  • Создайте загрузчики данных с помощью DataLoader с размером пакета = 32 для каждого набора данных.

  • Мы создаем служебную функцию imshow для отображения изображения.

3. Создать сеть

  • Мы создадим сеть лайков LeNet-5 для нашей классификации изображений.

  • Создайте нашу сеть с помощью подкласса nn.Module
  • Определите метод __init__, создав слой conv1 с использованием nn.Conv2d с аргументами-3 внутренних канала, 6 исходящих каналов, 5 x 5 пикселей фильтр с шагом = 1 по умолчанию, слой conv2 с аргументами - 6 входящих каналов, 16 исходящих каналов и фильтр того же размера.
  • Создайте слой pool, используя nn.MaxPool2d с фильтром arguments-2 x 2-пиксель, stride = 2.
  • Создайте полностью связанный слой fc1, используя nn.Linear с аргументами- (16 * 53 * 53) входящие элементы, 120 выходных элементов, fc2 с аргументами-120 встроенными функциями, 84 исходными функциями и fc3 с аргументами-84 встроенными функциями, 33 исходящими функциями.

  • Определите метод forward для входных данных.
  • Перенаправить входные данные через слой conv1, применить nn.functional.relu и перенаправить через слой pool.
  • Перенаправить входные данные через слой conv2, применить nn.functional.relu и перенаправить через слой pool.
  • Сведите x в двумерный тензор- [количество экземпляров, 16 * 53 * 53] с помощью метода view.
  • Вперед через fc1, применить relu, вперед через fc2, применить relu и вперед через fc3 без relu, потому что вместо этого мы будем использовать softmax.
  • Прежде чем создать экземпляр нашей сети, используйте torch.device для обнаружения графического процессора, если он доступен, в противном случае используйте центральный процессор.
  • Затем установите нашу сеть на устройство

4. Обучите сеть

  • Импортировать torch.optim
  • Определите критерий или функцию потерь, используя nn.CrossEntropyLoss, который уже включает функцию softmax с потерей энтропии.
  • Используйте optim.SGD или Stochastic Gradient Decent в качестве оптимизатора с lr (скорость обучения) = 0,001.

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

  • Установите входы и метки для устройства.
  • Установите нулевые начальные градиенты с помощью optimizer.zero_grad, чтобы предотвратить добавление градиентов для каждой итерации.
  • Установите для torch.set_grad_enabled значение True, если это тренировка.
  • Вычислить выходы.
  • Вычислите потерю.
  • Если это обучение, вычислите градиенты с помощью loss.backward и обновите параметры с помощью optimizer.step.

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

  • Обучите и проверьте сеть.
  • На один графический процессор потребовалось около 11 минут с лучшей точностью 61,87%, что совсем не лучшим образом.

5. Оценить

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

Мы можем многое сделать, чтобы улучшить нашу собственную сеть. Но есть одна практика глубокого обучения, которая очень полезна и эффективна. Это называется трансферным обучением.

Трансферное обучение

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

Источник: https://machinelearningmastery.com/transfer-learning-for-deep-learning/

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

Как?

  1. Выберите предварительно обученную сеть.
  2. Сопоставьте наши данные с форматом входных сетевых данных.
  3. Замените выходной слой.
  4. Переобучить сеть.

ResNet18

Это ResNet18. Вы можете видеть, насколько сложна сеть. Чтобы обучить его с нуля, может потребоваться много дней и много вычислительной мощности.

Соответствовать формату сетевого входа

Мы нормализуем наши наборы данных со средним значением и стандартным отклонением обучающего набора данных ResNet18.

Загрузить предварительно обученную сеть

  • Загрузите ResNet18 с помощью torchvision.models.resnet18.
  • Выходной слой fc - это слой, который мы собираемся заменить.

Заменить выходной слой

  • Замените fc новым fc- 512 встроенными и 33 выходными функциями.

Переобучить сеть

  • Обучите сеть с помощью train_val ().
  • Точность набора данных проверки намного лучше.

Оценить на тестовом наборе данных

  • Оцените сеть на тестовом наборе данных с помощью test ().

Как средство извлечения фиксированных функций

Предыдущее обучение передачи называется точной настройкой. Мы можем использовать переносное обучение как средство извлечения фиксированных функций, заморозив всю сеть, кроме последнего слоя. Нам нужно установить requires_grad == False, чтобы заморозить параметры, чтобы градиенты не вычислялись в backward ().

Вот и все. Надеюсь, вы видите, насколько мощным является трансферное обучение.

Вопросов?

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

Рекомендовать ресурсы