Автоэнкодер (autoencoder): как сеть сжимает данные

Автоэнкодер (autoencoder) - это нейросеть, которая учится восстанавливать собственный вход. Звучит как бессмысленная затея: зачем сети предсказывать то, что ей уже подали? Весь смысл в узком месте посередине. Сеть вынуждена пропустить данные через слой меньшей размерности, и чтобы потом восстановить картинку или сигнал, ей приходится выучить компактное представление - то самое «сжатие смысла», ради которого автоэнкодеры и применяют. Ниже разберём архитектуру по частям, функцию потерь, основные виды и где это работает на практике. Если нужно решить конкретную задачу по теме, соберите запрос в форме ниже.
Что такое автоэнкодер
Автоэнкодер - это модель обучения без учителя, которая отображает вход в самого себя через сжатое промежуточное представление. Формально она состоит из двух функций: энкодера , который переводит вход в код , и декодера , восстанавливающего вход из кода: . Цель обучения - добиться, чтобы был как можно ближе к .
Ключевая деталь в том, что размерность кода меньше размерности входа. Если бы был такой же или больше, сеть могла бы просто скопировать вход «один в один» и ничему полезному не научиться. Узкое горлышко (bottleneck) заставляет модель отбрасывать шум и хранить только важное. По сути автоэнкодер - это обучаемое нелинейное обобщение метода главных компонент: PCA ищет лучшее линейное подпространство, автоэнкодер - произвольно изогнутое многообразие.

Энкодер, латентное пространство и декодер
Разберём три части по отдельности.
Энкодер - это нисходящая часть сети. Слои постепенно уменьшают число нейронов: например, изображение пикселя проходит через слои 512, 128, 32 и сжимается до кода из десятков чисел. Каждый слой выделяет всё более абстрактные признаки.
Латентное пространство (latent space) - это пространство кодов . Его размерность называют размерностью латента или bottleneck-размерностью. Точки, близкие в этом пространстве, соответствуют похожим объектам: цифры одного класса собираются в один кластер, лица с похожими чертами оказываются рядом. Именно поэтому латент удобен для поиска похожих объектов и для визуализации данных.
Декодер - зеркальная восходящая часть. Слои наращивают размерность обратно: 32, 128, 512, 784, и на выходе получается реконструкция . Энкодер и декодер обучаются совместно: невозможно настроить сжатие, не зная, как потом восстанавливать.
Размерность латента - главный гиперпараметр. Слишком маленький латент теряет детали, реконструкция размывается. Слишком большой - сеть почти копирует вход и перестаёт обобщать. Подбирают по качеству реконструкции на валидации.
Функция потерь: реконструкция
Автоэнкодер учат минимизировать ошибку реконструкции - расхождение между входом и его восстановлением. Для вещественных данных (например, яркостей пикселей) берут среднеквадратичную ошибку:
Здесь - размерность входа. Для бинарных данных (чёрно-белые пиксели как вероятности) чаще используют бинарную кросс-энтропию:
Параметры энкодера и декодера обновляют обратным распространением ошибки и градиентным спуском. Никаких меток не нужно - цель формируется из самого входа, поэтому автоэнкодер относят к обучению без учителя (точнее, к самообучению).
Выбор потери - не формальность. Среднеквадратичная ошибка штрафует крупные расхождения сильнее мелких и хорошо подходит для непрерывных величин с примерно гауссовым шумом. Кросс-энтропия естественна, когда выход интерпретируется как вероятность и проходит через сигмоиду на последнем слое. Если перепутать одно с другим, сеть либо сходится медленно, либо систематически смещает реконструкцию (например, делает все пиксели сероватыми). Поэтому функцию потерь подбирают под распределение данных так же тщательно, как и архитектуру.
Виды автоэнкодеров
Базовая схема порождает целое семейство.
Недополный (undercomplete) - классический случай: латент меньше входа, узкое горлышко само по себе является регуляризатором. Это то, с чего начинают.
Разреженный (sparse) - латент может быть большим, но на активации накладывают штраф ( или KL-расхождение), чтобы в коде «горело» мало нейронов. Сеть учит словарь признаков, как в разреженном кодировании.
Шумоподавляющий (denoising) - на вход подают испорченный шумом объект , а восстанавливать требуют чистый . Сеть вынуждена выучить устойчивую структуру данных, а не запоминать пиксели. Это один из самых практичных вариантов.

Сжимающий (contractive) - добавляет штраф на норму якобиана энкодера, делая код устойчивым к малым возмущениям входа.
Вариационный (VAE) - принципиально иной зверь: энкодер выдаёт не точку, а параметры распределения (среднее и дисперсию), из которого латент сэмплируется. К потере реконструкции добавляется KL-расхождение с нормальным распределением. VAE - порождающая модель: из латента можно генерировать новые правдоподобные объекты, а не только восстанавливать имеющиеся.
Чем автоэнкодер отличается от PCA
PCA - линейный метод: он ищет ортогональные оси максимальной дисперсии и проецирует данные на подпространство. Автоэнкодер с линейными слоями и MSE-потерей выучивает ровно то же подпространство, что и PCA. Но как только в сеть добавляют нелинейные функции активации, автоэнкодер начинает находить искривлённые многообразия, недоступные PCA.
Грубо говоря, PCA умеет «разрезать» данные плоскостью, а нелинейный автоэнкодер - изогнутой поверхностью. На данных вроде закрученной спирали или цифр MNIST это даёт куда более компактное и осмысленное представление. Расплата - нужна обучающая выборка, время на градиентный спуск и риск переобучения.
Есть и практическое следствие этого родства. Если инициализировать линейный автоэнкодер и обучить его с MSE, веса энкодера сойдутся к главным компонентам с точностью до поворота внутри подпространства. Поэтому линейный автоэнкодер иногда используют как «PCA на больших данных», которые не помещаются в память целиком: его учат мини-батчами, тогда как классический PCA требует разложения всей ковариационной матрицы. А нелинейная версия - это уже инструмент для данных, где линейного приближения заведомо мало.
Где применяют автоэнкодеры
Сжатый латент - универсальный инструмент.
- Снижение размерности и визуализация. Латент из 2-3 чисел можно нарисовать на плоскости; кластеры объектов видно глазом. Часто латент потом подают в t-SNE или UMAP.
- Поиск аномалий. Сеть учат на нормальных данных. Аномальный объект она восстанавливает плохо - большая ошибка реконструкции служит сигналом тревоги. Так ловят мошеннические транзакции, дефекты на производстве, сбои в сетевом трафике.
- Шумоподавление. Denoising-автоэнкодер чистит зашумлённые изображения, аудио, сигналы датчиков.
- Предобучение и инициализация. Энкодер, обученный без меток, даёт хорошие начальные веса для последующей классификации с малым числом размеченных примеров.
- Генерация (VAE). Сэмплируя латент, получают новые лица, шрифты, молекулы - основа многих порождающих пайплайнов.
Частые ошибки
- Латент равен или больше входа без регуляризации. Сеть выучивает тождественное отображение, реконструкция идеальна, пользы ноль. Либо сужайте латент, либо добавляйте штраф (sparse) или шум (denoising).
- Ожидание чёткой генерации от обычного автоэнкодера. Простой автоэнкодер восстанавливает, но не порождает: латент не обязан быть гладким. Для генерации нужен VAE с регуляризацией латента.
- Реконструкция как самоцель. Идеальная реконструкция на трейне часто означает переобучение. Смотрите на валидацию и на полезность латента в нижестоящей задаче.
- Неверная функция потерь. MSE для бинарных пикселей или кросс-энтропия для произвольных вещественных значений дают плохую сходимость. Тип потери выбирают под распределение данных.
- Слишком глубокая сеть на малых данных. Энкодер с десятком слоёв на тысяче примеров переобучается мгновенно. Глубину наращивают вместе с размером выборки.
FAQ
Автоэнкодер - это обучение с учителем или без? Без учителя (точнее, самообучение). Метки не нужны: целью реконструкции служит сам вход . Поэтому автоэнкодеры применяют там, где разметки мало или нет.
Можно ли автоэнкодером генерировать новые данные? Обычным автоэнкодером - плохо: латентное пространство «дырявое», случайная точка часто декодируется в мусор. Для генерации берут вариационный автоэнкодер (VAE), который заставляет латент быть гладким и близким к нормальному распределению.
Чем автоэнкодер лучше PCA? Он нелинейный и потому ловит искривлённые зависимости в данных, которых PCA не видит. Но он сложнее, требует обучения и обучающей выборки. Если связи в данных в основном линейные - PCA проще и быстрее.
Коротко
Автоэнкодер - нейросеть, которая сжимает вход в латентный код энкодером и восстанавливает его декодером, минимизируя ошибку реконструкции. Узкое горлышко заставляет модель выучить компактное нелинейное представление данных - обобщение PCA. Семейство включает недополный, разреженный, шумоподавляющий, сжимающий и вариационный (VAE, порождающий) варианты. На практике автоэнкодеры снижают размерность, ищут аномалии по ошибке реконструкции, чистят шум и предобучают сети без меток.
Читайте также

Алгоритм t-SNE: визуализация многомерных данных на плоскости
Алгоритм t-SNE для визуализации: как метод снижает размерность, что такое перплексия, чем t-распределение лучше нормального и как читать карту кластеров без ложных выводов.

Алгоритм UMAP: как работает снижение размерности
Алгоритм UMAP простыми словами: как метод строит граф ближайших соседей, оптимизирует низкоразмерное вложение, чем отличается от t-SNE и как подобрать n_neighbors и min_dist для визуализации данных.

Вариационный автоэнкодер (VAE): как сеть учится генерировать
Вариационный автоэнкодер (VAE) понятно: вероятностный энкодер, репараметризация, ELBO и KL-расхождение, отличие от обычного автоэнкодера и где VAE применяют для генерации.