Эта статья является шестой в серии руководств по созданию моделей глубокого обучения с помощью Pytorch. Ниже представлена ​​полная серия:

  1. Учебник по Pytorch для начинающих
  2. Понять тензорные размерности в моделях DL
  3. CNN и художественные визуализации
  4. Гиперпараметрическая настройка с Optuna
  5. Перекрестная проверка K-сгиба
  6. Сверточный автоэнкодер (этот пост)
  7. Автоэнкодер с шумоподавлением
  8. Вариационный автоэнкодер

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

Автоэнкодер

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

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

Реализация в Pytorch

Будут показаны следующие шаги:

  1. Импортировать библиотеки и набор данных MNIST
  2. Определить сверточный автоэнкодер
  3. Инициализировать функцию потерь и оптимизатор
  4. Обучить модель и оценить модель
  5. Сгенерируйте новые образцы из скрытого кода
  6. Визуализируйте скрытое пространство с t-SNE

1. Импортируйте библиотеки и набор данных MNIST.

Мы можем импортировать набор данных с помощью библиотеки torchvision. Мы загружаем обучающие и тестовые наборы данных и преобразуем наборы данных изображений в Tensor. Нормализовать изображения не нужно, потому что наборы данных содержат цветные изображения. После того, как мы разделим обучающий набор данных на обучающий и проверочный наборы, random_split предоставит случайное разделение для этих двух наборов. DataLoader используется для создания загрузчиков данных для наборов для обучения, проверки и тестирования, которые разделены на мини-пакеты. batchsize - это количество образцов, использованных в одной итерации во время обучения модели.

2. Определите сверточный автоэнкодер.

Здесь мы определяем автоэнкодер со сверточными слоями. Он будет состоять из двух классов: один для кодировщика и один для декодера. Кодер будет содержать три сверточных слоя и два полностью связанных слоя. Некоторые слои пакетных норм добавляются как регуляризаторы. Декодер будет иметь ту же архитектуру, но в обратном порядке.

3. Инициализировать функцию потерь и оптимизатор.

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

  • torch.device для обучения модели с помощью аппаратного ускорителя, такого как графический процессор
  • сети Encoder и Decoder, которые будут перемещены на устройство
  • nn.MSEloss и torch.optim.Adam

4. Обучите и оцените модель.

Мы определяем функцию для обучения модели AE. Сначала мы передаем входные изображения в кодировщик. Позже закодированные данные передаются в кодировщик, и затем мы вычисляем потерю восстановления с помощью loss_fn(x_hat,x). После того, как мы очищаем градиент, чтобы не накапливать другие значения, мы выполняем обратное распространение и в конце вычисляем градиент, вызывая opt.step().

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

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

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

  • test_dataset[i][0].unsqueeze(0) используется для извлечения i-го изображения из тестового набора данных, а затем оно будет увеличено на 1 измерение по оси 0. Этот шаг необходим для передачи изображения автоэнкодеру.
  • decoder(encoder(img)) используется для получения реконструированного изображения
  • plt.imshow(img.cpu().squeeze().numpy()) используется для печати исходного изображения. squeeze() удаляет добавленное ранее измерение и имеет важное значение для визуализации изображения. numpy() преобразует тензор в ndarray, который является единственным типом объекта, принимаемым функцией plt.imshow. numpy() возвращает копию тензорного объекта в память ЦП.

Теперь мы можем, наконец, начать обучать модель на обучающем наборе и оценивать ее на проверочном наборе.

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

Мы также можем наблюдать, как потери реконструкции уменьшаются по эпохам:

5. Сгенерируйте новые образцы из скрытого кода.

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

Чтобы построить эти реконструкции, нам нужно знать диапазон скрытого пространства, который вы можете увидеть в разделе ниже с визуализацией скрытого пространства. Мы можем заметить, что в нижнем левом углу графика цифры не имеют смысла. Действительно, скрытое пространство пусто в точке (-1, -1).

6. Визуализируйте скрытое пространство с помощью t-SNE.

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

Давайте изобразим представление скрытого пространства с помощью библиотеки plotly express:

Из этого графика мы видим, что похожие цифры сгруппированы вместе. Например, «4» перекрываются с «9» и «5».

Чтобы представление было легче читать, мы можем применить уменьшение размерности, называемое t-SNE, для визуализации скрытого кода в 2-мерном пространстве. По этой причине мы зафиксируем количество компонентов равным 2.

Вы можете видеть, что он четко отличает одну цифру от другой. Есть некоторые исключения с точками, которые попадают в другие категории, но t-SNE по-прежнему остается улучшением по сравнению с предыдущим представлением.

Последние мысли:

Поздравляю! Вы научились реализовывать сверточный автокодировщик. Существует не так много руководств, в которых рассказывается об автоэнкодерах со сверточными слоями с Pytorch, поэтому я хотел внести какой-то вклад. Автоэнкодер позволяет сжимать изображения и извлекать наиболее важную информацию. Есть также много расширений этой модели для повышения производительности, некоторые из них - это автоэнкодер с шумоподавлением, вариационный автоэнкодер и генеративные состязательные сети. Код Github находится здесь. Спасибо за прочтение. Хорошего дня.

Вам понравилась статья? Станьте участником и получайте неограниченный доступ к новым сообщениям о данных каждый день!