Машинное обучение

Автоэнкодеры и VAE

Что если нейросеть могла бы сжимать изображения лучше, чем JPEG? Обычный алгоритм сжатия использует одни и те же правила для всех картинок - фотографий, рисунков, схем. Автоэнкодер подходит к задаче иначе: он смотрит на тысячи примеров и сам учится находить самое компактное представление, сохраняя только то, что действительно важно, и отбрасывая все остальное. Из 784 пикселей цифры он оставляет 32 числа - и по ним восстанавливает изображение почти без потерь. Как ему это удается?

  • **Обнаружение мошенничества** - автоэнкодер обучается на нормальных банковских транзакциях, а когда на вход попадает мошенническая операция, ошибка реконструкции резко возрастает: модель не умеет восстанавливать то, чего никогда не видела, и это становится сигналом тревоги
  • **Генерация лиц и изображений** - VAE обучается на миллионах фотографий и создаёт непрерывное латентное пространство, в котором можно плавно менять возраст, выражение лица, поворот головы, двигая всего несколько чисел в векторе z
  • **Шумоподавление в медицинских снимках** - Denoising Autoencoder убирает шум из рентгеновских снимков и МРТ, сохраняя диагностически важные детали, что позволяет врачам видеть патологии, скрытые за артефактами

Предварительные знания

  • Transformers and the Attention Mechanism

От глубоких автоэнкодеров к вариационному скачку

В 2006 году Джеффри Хинтон и Руслан Салахутдинов опубликовали в Science статью, показавшую, что глубокий автоэнкодер, аккуратно предобученный слой за слоем, сжимает данные в низкоразмерный код намного лучше, чем метод главных компонент. Это был один из результатов, помогших возродить интерес к глубоким сетям. Следующий крупный шаг произошёл в 2013 году, когда Дидерик Кингма и Макс Веллинг предложили вариационный автоэнкодер, который трактует латентный код как распределение вероятностей, а не как фиксированную точку. Это превратило автоэнкодер из инструмента сжатия в настоящую генеративную модель, из которой можно семплировать, и он до сих пор остаётся краеугольным камнем генеративного моделирования.

Архитектура Encoder-Decoder

Автоэнкодер - это нейросеть, которая обучается **воспроизводить свой собственный вход на выходе**. Звучит бессмысленно? Секрет в том, что между входом и выходом стоит узкое место - **bottleneck**. Сеть состоит из двух частей: **encoder** сжимает вход в маленькое представление z, а **decoder** пытается восстановить исходные данные из этого сжатого кода. Если восстановление удалось - значит, сеть научилась находить компактное представление, сохраняющее суть данных.

Почему это полезно? Encoder учится **извлекать самые важные признаки** из данных. Если изображение 28x28 (784 пикселя) можно закодировать в 32 числа и потом восстановить - значит, эти 32 числа содержат суть изображения. Это **обученное сжатие**: в отличие от JPEG, который использует фиксированные правила, автоэнкодер адаптируется к конкретному типу данных и находит специфичные для него паттерны.

**Зачем нужен bottleneck:** Без узкого места (если latent size >= input size) сеть просто скопирует вход на выход через identity mapping. Никакого полезного обучения не произойдёт. **Bottleneck заставляет сеть:** - Отбрасывать шум и несущественные детали - Находить закономерности и корреляции между признаками - Создавать компактное, информативное представление **Аналогия:** представьте, что вам нужно описать фотографию всего 10 словами. Вы выберете самое важное: "мужчина в красной куртке на фоне гор". Bottleneck заставляет сеть делать то же самое - выбирать суть.

Функция потерь автоэнкодера - это **ошибка реконструкции**: насколько выход X' отличается от входа X. Чаще всего используется **MSE** (Mean Squared Error): среднее от (xi - xi')^2 для каждого элемента. Для бинарных данных (черно-белые изображения) лучше подходит **Binary Cross-Entropy**. Обучение идёт обычным backpropagation через обе части сети одновременно.

Применения encoder-decoder архитектуры выходят далеко за рамки сжатия. Encoder можно использовать отдельно как **feature extractor**: обученные на больших данных представления часто лучше ручных признаков. Это особенно ценно для задач с малым количеством размеченных данных - сначала обучаем автоэнкодер на неразмеченных данных (unsupervised pretraining), затем используем encoder как начальную точку для классификатора.

Что произойдёт, если размер латентного слоя (bottleneck) автоэнкодера будет равен или больше размера входа?

Латентное пространство

Bottleneck автоэнкодера создаёт **латентное пространство** (latent space) - скрытое пространство низкой размерности, в котором данные представлены в сжатом виде. Каждая точка в этом пространстве - вектор z - кодирует один пример из обучающей выборки. Удивительное свойство: **похожие входы оказываются рядом** в латентном пространстве. Все пятёрки из MNIST кластеризуются в одной области, все тройки - в другой. Сеть сама открывает структуру данных, без учителя.

Латентное пространство автоэнкодера - это **нелинейное снижение размерности**. Классический PCA тоже сжимает данные, но находит только линейные зависимости. Автоэнкодер с нелинейными активациями (ReLU, Sigmoid) может обнаружить **сложные нелинейные структуры** в данных. Если использовать автоэнкодер только с линейными слоями и MSE loss, результат будет математически эквивалентен PCA - но с нелинейностями автоэнкодер значительно выразительнее.

**Размерность латентного пространства - ключевой компромисс:** - **Слишком маленькое** (2-5 для MNIST): сеть не может запомнить все детали, реконструкции размытые. Но пространство хорошо структурировано и поддаётся визуализации. - **Оптимальное** (16-64 для MNIST): хороший баланс между качеством реконструкции и сжатием. Сеть выучивает содержательные признаки. - **Слишком большое** (200+ для MNIST): отличная реконструкция, но latent space хаотичный, много избыточности. Сеть не вынуждена находить компактное представление. Правило: начинайте с latent_dim примерно в 10-50 раз меньше входа и подбирайте по качеству реконструкции.

Одно из самых интересных свойств латентного пространства - **интерполяция**. Если взять два изображения, закодировать их в точки z1 и z2, а потом равномерно двигаться от z1 к z2 в латентном пространстве, декодируя промежуточные точки - получатся плавные переходы между изображениями. Тройка постепенно превращается в восьмёрку, улыбка - в серьёзное лицо. Это работает, потому что латентное пространство непрерывно: рядом расположенные точки декодируются в похожие изображения.

Латентные представления полезны не только для визуализации. Вектор z можно использовать как **входной признак для downstream задач**: классификации, кластеризации, поиска похожих объектов. Autoencoder обучается на неразмеченных данных (unsupervised) и извлекает признаки, которые затем помогают решать задачи с малым количеством меток. Этот подход называется **representation learning** - обучение представлений.

Чем латентное пространство автоэнкодера принципиально отличается от PCA как метода снижения размерности?

Вариационный автоэнкодер (VAE)

Обычный автоэнкодер хорошо сжимает данные, но у его латентного пространства есть серьёзная проблема: оно **неоднородное и с пустотами**. Между кластерами цифр в latent space могут быть «мёртвые зоны», где ни одна реальная точка не попадала при обучении. Если декодировать случайную точку из такой зоны - получится мусор, не похожий ни на что. Это значит, что обычный автоэнкодер **не может генерировать новые данные** - он только сжимает и восстанавливает существующие.

**VAE (Variational Autoencoder)** решает эту проблему: вместо кодирования входа в точку z, encoder выдаёт **параметры распределения** - среднее (mu) и дисперсию (sigma). Каждый вход описывается не одной точкой, а «облаком» возможных кодов. Это заставляет облака разных примеров перекрываться, заполняя пустоты в латентном пространстве.

**Reparameterization trick - ключ к обучению VAE:** Проблема: если z - случайная величина, как пропустить через неё градиент? Решение - перепараметризация: `z = mu + sigma * epsilon`, где `epsilon ~ N(0, 1)` - `mu` и `sigma` - выходы encoder (обучаемые) - `epsilon` - случайный шум из стандартного нормального распределения - Градиент по `mu` и `sigma` вычисляется нормально - Стохастичность изолирована в `epsilon` (не зависит от параметров) Этот трюк позволяет обучать VAE обычным backpropagation, несмотря на случайное сэмплирование.

Loss функция VAE состоит из двух частей: **reconstruction loss** (как хорошо восстановлены данные) и **KL-divergence** (насколько латентное распределение отклоняется от стандартного нормального N(0,1)). KL-loss работает как **регуляризатор**: он подталкивает все кодировки к центру (0,0) и стандартной дисперсии, предотвращая появление пустот и изолированных кластеров. Баланс между двумя loss определяет качество: слишком сильный KL - размытые реконструкции, слишком слабый - пустоты в latent space.

Главное преимущество VAE - **возможность генерации**. Поскольку KL-loss подталкивает латентное пространство к стандартному нормальному распределению, можно просто сэмплировать z из N(0,1) и декодировать - получится новое, ранее не существовавшее, но реалистичное изображение. Можно также управлять генерацией: менять отдельные координаты z и наблюдать, как меняется выход. Одна координата может отвечать за наклон цифры, другая - за толщину штриха, третья - за стиль написания.

Какую роль играет KL-divergence в функции потерь VAE?

Denoising и практические применения

**Denoising Autoencoder (DAE)** - вариант, который решает конкретную проблему: обычный автоэнкодер может выучить «ленивое» отображение, просто копируя вход. DAE борется с этим так: на вход подаётся **зашумлённая версия данных**, а на выходе ожидается **чистый оригинал**. Сеть вынуждена учиться не копировать пиксели, а **понимать структуру данных**, чтобы отличать сигнал от шума.

Почему DAE учится лучше обычного автоэнкодера? Добавление шума - это форма **регуляризации**. Сеть не может просто запомнить вход, потому что каждый раз шум разный. Она вынуждена выучивать **устойчивые (robust) признаки** - те, которые сохраняются несмотря на шум. Эти признаки отражают настоящую структуру данных. Поэтому DAE часто используют для **предобучения** (pretraining): признаки, устойчивые к шуму, оказываются полезными для любых downstream задач.

**Другие варианты автоэнкодеров:** **Sparse Autoencoder:** добавляет L1-регуляризацию на активации латентного слоя. Большинство нейронов в z вынуждены быть нулями - каждый вход активирует только малое подмножество. Результат: каждый нейрон специализируется на конкретном признаке. **Contractive Autoencoder (CAE):** штрафует чувствительность латентного представления к малым изменениям входа. В loss добавляется норма якобиана encoder. Результат: z меняется мало при небольшом шуме во входе - модель выучивает устойчивые признаки. **Convolutional Autoencoder:** использует свёрточные слои вместо полносвязных. Encoder: Conv + Pooling (сжатие). Decoder: ConvTranspose + Upsampling (расширение). Стандарт для работы с изображениями.

Практические применения автоэнкодеров выходят далеко за рамки генерации картинок. **Обнаружение аномалий:** обучаем автоэнкодер на нормальных данных, а потом измеряем ошибку реконструкции для новых. Если ошибка большая - входные данные аномальны, модель не умеет их восстанавливать. Этот подход используется для поиска мошеннических транзакций, дефектов на производстве и сетевых вторжений. **Сжатие данных:** encoder уменьшает размер, decoder восстанавливает. **Предобучение:** encoder извлекает признаки из неразмеченных данных, а потом дообучается на размеченных.

Автоэнкодеры стали фундаментом для целого семейства моделей. VAE открыли путь к генеративному моделированию, которое развилось в GAN и диффузионные модели. Denoising autoencoder лёг в основу **Denoising Diffusion Models** (DDPM) - архитектуры, стоящей за Stable Diffusion и DALL-E. Идея та же: обучить сеть убирать шум, а потом итеративно превращать чистый шум в изображение.

Автоэнкодеры - это только для генерации картинок

Автоэнкодеры - универсальный инструмент для сжатия данных, обнаружения аномалий, предобучения и шумоподавления в любых типах данных

Генерация изображений - лишь одно из применений (и в основном это VAE). Обычные автоэнкодеры широко используются для обнаружения мошенничества (аномальные транзакции имеют высокую ошибку реконструкции), сжатия данных (encoder как компрессор), предобучения нейросетей на неразмеченных данных и шумоподавления (denoising autoencoder). Они работают с таблицами, временными рядами, текстом, аудио - не только с картинками.

Итоги

  • **Encoder-Decoder архитектура:** автоэнкодер сжимает вход через bottleneck и восстанавливает его на выходе - узкое место заставляет сеть выучивать самые важные признаки, отбрасывая шум и несущественные детали
  • **Латентное пространство:** bottleneck создаёт низкоразмерное представление данных, где похожие входы кластеризуются рядом - это нелинейный аналог PCA, позволяющий визуализировать и интерполировать между примерами
  • **VAE для генерации:** вариационный автоэнкодер кодирует данные в распределения (mu + sigma) вместо точек, а KL-divergence выравнивает латентное пространство к N(0,1) - результат: непрерывное пространство без пустот, из которого можно генерировать новые данные
  • **Denoising и варианты:** добавление шума при обучении заставляет сеть выучивать устойчивые признаки, sparse регуляризация даёт интерпретируемость, а contractive штраф - стабильность представлений
  • **От сжатия к генерации:** автоэнкодеры начинались как инструмент сжатия - из 784 пикселей в 32 числа - но выросли в фундамент генеративного AI, от VAE до диффузионных моделей, стоящих за Stable Diffusion и DALL-E

Связанные темы

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

  • GAN (генеративно-состязательные сети) — Альтернативный подход к генерации данных: если VAE учится через реконструкцию и KL-divergence, то GAN использует состязание генератора и дискриминатора. GAN часто даёт более чёткие изображения, но VAE обеспечивает более структурированное латентное пространство
  • PCA (метод главных компонент) — Линейный предшественник автоэнкодера: PCA находит оптимальные линейные проекции данных, а линейный автоэнкодер с MSE loss математически эквивалентен PCA. Нелинейные автоэнкодеры расширяют эту идею на сложные нелинейные структуры

Вопросы для размышления

  • Почему VAE генерирует более размытые изображения, чем GAN? Как связаны reconstruction loss, KL-divergence и качество генерации - и что можно было бы изменить в архитектуре для улучшения чёткости?
  • Если обучить автоэнкодер на фотографиях кошек и подать на вход фотографию собаки, что произойдёт с ошибкой реконструкции и почему? Как это свойство используется на практике?
  • Denoising autoencoder и Denoising Diffusion Model (DDPM) используют одну идею - обучение на удалении шума. Чем принципиально отличается подход DDPM, который позволяет ему генерировать изображения фотографического качества?

Связанные уроки

  • ml-31-transformers — Опирается на глубокие сети и энкодеры
  • ml-33-gan — Оба генеративные, разный сигнал обучения
  • ml-19-pca — Линейный автоэнкодер даёт подпространство PCA
  • la-15-svd — Узкое место PCA связано с SVD
  • ml-20-anomaly-detection — Ошибка реконструкции выявляет аномалии
  • stat-14-pca
Автоэнкодеры и VAE

0

1

Войти

Как автоэнкодер может обнаруживать аномалии, если он обучался только на нормальных данных?