# Эволюция архитектур CNN: путеводитель Стэнфорда по глубокому обучению

Источник: https://www.youtube.com/watch?v=aVJy4O5TOk8
Канал: Stanford Online
Опубликовано: 02.09.2025

---

В Стэнфордском университете в рамках знаменитого курса CS231N прошла лекция, посвященная эволюции архитектур сверточных нейросетей (CNN) и тонкостям их обучения. Сопреподаватель курса Зейн Данте подробно разобрал, как из простых кирпичиков создаются сложнейшие современные модели и с какими подводными камнями сталкиваются инженеры на практике. Этот материал представляет собой подробный путеводитель по миру глубокого обучения компьютерного зрения на основе лекционных материалов весеннего семестра 2025 года.

## 🛠️ Анатомия сверточных нейросетей: от базовых блоков к новым слоям
[[JUMP:0:59]]

Построение современной архитектуры CNN — это искусство правильной комбинации базовых блоков, которые ИТ-сообщество изучало на протяжении последних лет. Процесс начинается со сверточных слоев (Convolutional Layers), где набор предопределенных фильтров скользит по изображению. Например, для стандартного RGB-изображения размером 32x32 пикселя глубина входных данных равна трем. Каждый фильтр вычисляет скалярное произведение своих весов с пикселями изображения, добавляет параметр смещения (bias) и формирует карту активаций (activation map). Если на первом слое применяется 6 фильтров, то выходная глубина станет равной 6, и фильтры следующего сверточного слоя обязаны иметь аналогичную глубину для корректной обработки данных. Как напомнил Зейн Данте, обычно за сверткой следует функция нелинейности, например, ReLU.

Вторым классическим компонентом выступает слой пулинга (Pooling Layer). Он устроен гораздо проще свертки: скользящее окно (типичный размер 2x2 со страйдом 2) сокращает пространственные размеры (высоту и ширину). На практике одинаково часто применяются как Max Pooling (выбор максимального значения), так и Average Pooling (вычисление среднего). Лектор рекомендует разработчикам новых архитектур тестировать оба варианта, чтобы эмпирически определить наилучший для конкретной задачи.

Помимо сверток, пулинга и полносвязных (Fully Connected) слоев, современный стек CNN включает еще несколько критически важных элементов, без которых обучение глубоких моделей было бы невозможным:

* Слои нормализации (Normalization Layers)
* Слои дропаута (Dropout)
* Усовершенствованные функции нелинейности

## ⚖️ Борьба за стабильность: слои нормализации и триумф LayerNorm
[[JUMP:3:52]]

Основная идея любого слоя нормализации заключается в вычислении статистик — среднего значения и стандартного отклонения — для входящих данных с целью их последующего масштабирования. По словам Зейна Данте, этот процесс всегда состоит из двух шагов: сначала данные приводятся к единичному гауссову распределению (среднее 0, дисперсия 1), а затем масштабируются и сдвигаются с помощью обучаемых параметров ($\gamma$ и $\beta$), которые модель настраивает через градиентный спуск. Различие между существующими типами нормализации кроется исключительно в том, по какому именно подмножеству данных рассчитываются эти статистики.



Сегодня в глубоком обучении доминирует Layer Normalization (LayerNorm), особенно за счет своей незаменимости в архитектурах трансформеров. В простом векторном случае LayerNorm вычисляет среднее и стандартное отклонение для каждого входящего образца (семпла) отдельно по всему вектору признаков. В контексте сверточных сетей, где тензор данных имеет размерности батча ($N$), каналов ($C$), высоты ($H$) и ширины ($W$), LayerNorm считает одну пару статистик для каждого изображения индивидуально, усредняя значения по всем каналам и пространственным координатам.

Отвечая на вопросы студентов, лектор провел четкую границу с другими методами:

* **Batch Normalization (BatchNorm):** вычисляет статистики для каждого канала отдельно, но усредняет их по всему мини-батчу данных во время градиентного спуска.
* **Instance Normalization:** действует еще более гранулярно, вычисляя статистики отдельно для каждого канала и каждого конкретного изображения.
* **Group Normalization:** разбивает каналы на группы и считает статистики внутри этих групп для каждого семпла.

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

## 🎲 Дропаут: контролируемый хаос ради генерализации
[[JUMP:9:38]]

Дропаут (Dropout) представляет собой слой регуляризации, который вносит элемент случайности на этапе обучения и полностью отключается при тестировании модели. Цель метода — усложнить для сети запоминание обучающей выборки, заставив ее обобщать скрытые закономерности. Количественно это выражается в том, что в каждом прямом проходе (forward pass) слой случайно зануляет определенный процент выходов (активаций) предыдущего слоя. Величина этого процента задается гиперпараметром $p$, где наиболее популярными значениями выступают 0.5 или 0.25. С технической точки зрения, современные библиотеки используют маскирование, что позволяет даже не обсчитывать зануленные узлы, экономя ресурсы.

Почему этот подход, кажущийся деструктивным, работает? Зейн Данте признает, что теоретически дропаут изучен не до конца и его успех скорее эмпирический, однако предлагает наглядную ментальную модель. Представьте, что сеть учится классифицировать кошек на основе набора признаков: «уши», «хвост», «пушистость», «когти». Без регуляризации модель может намертво привязаться к жесткой корреляции пары признаков (например, «уши» + «пушистость»). Дропаут, случайно выбивая часть признаков в процессе обучения, лишает сеть возможности полагаться на одни и те же пары. Ей приходится выстраивать избыточные репрезентации и искать более широкие взаимосвязи, что резко повышает качество работы на новых данных.



Важный нюанс заключается во поведении дропаута на этапе тестирования (test time):

1.  Никакие активации больше не маскируются и не зануляются.
2.  Поскольку при тесте сеть задействует на 100% больше узлов, чем в среднем при обучении (при $p=0.5$), масштаб входящих сигналов резко возрастает.
3.  Чтобы компенсировать этот сдвиг и сохранить дисперсию, выходы умножаются на вероятность сохранения активаций $p$.

Что касается обратного распространения ошибки (backprop), то для зануленных элементов градиент становится равен нулю (аналогично поведению ReLU). Это означает, что веса, связанные с отключенными в данном проходе нейронами, никак не обновляются.

## 📈 Эволюция функций активации: почему Sigmoid уступил место ReLU и GELU
[[JUMP:15:57]]

Функции активации привносят в нейросети нелинейность, без которой каскад сверток и полносвязных слоев превратился бы в одно гигантское линейное уравнение. Исторически популярный сигмоид (Sigmoid) сегодня практически ликвидирован из промежуточных слоев из-за фундаментальной проблемы — затухания градиентов (vanishing gradients). На графике сигмоида отчетливо видно, что в областях очень больших или очень малых значений функция становится чрезвычайно пологой. Ее производная в этих экстремумах стремится к нулю. В результате при обратном проходе через множество слоев градиент прогрессивно уменьшается, и ранние слои сети практически перестают обучаться.

Решением проблемы в свое время стал ReLU (Rectified Linear Unit), который предлагает чистую единичную производную в положительной области и нулевую в отрицательной. Помимо борьбы с затуханием градиентов, ReLU невероятно дешев в вычислениях: операция `max(0, x)` выполняется на порядки быстрее сигмоида. Однако у ReLU есть свой изъян — «мертвая» зона для любых отрицательных входов, где градиент равен нулю.

В современную эпоху глубокого обучения (особенно с приходом трансформеров) на передовую вышла функция GELU (Gaussian Error Linear Unit). Она сглаживает резкий перелом производной в нуле, свойственный ReLU, используя функцию распределения стандартного нормального распределения. На экстремумах GELU сходится к поведению ReLU, но в окрестностях нуля обеспечивает плавность и оставляет ненулевые градиенты для небольших отрицательных значений.

Также лектор упомянул функцию SiLU/Swish (в материалах лекции обозначенную как Celu), описываемую формулой $x \times \text{sigmoid}(x)$. Она обладает схожим графиком и свойствами плавности. Место всех этих активаций в структуре CNN неизменно — они ставятся сразу после линейных операторов (матричного умножения или свертки).

## 🏛️ Великие архитектуры: как VGG переосмыслил размер фильтров
[[JUMP:21:41]]

История соревнования на датасете ImageNet показывает, что преодоление человеческого уровня точности распознавания напрямую совпало с экспоненциальным ростом глубины сетей. Историческим прорывом была AlexNet, доказавшая мощь вычислений на GPU, но истинным эталоном проектирования 2010-х годов стала архитектура VGG.



Если сопоставить AlexNet и VGG на блочных диаграммах, VGG выделяется своей строгой мономерной структурой. Ее авторы внедрили революционный стандарт:

* Использование исключительно компактных сверточных фильтров размером 3x3.
* Шаг свертки (stride) всегда равен 1.
* Добавление дополнения (padding) в 1 пиксель по краям, что позволяет сохранять пространственные размеры изображения при прохождении через свертку.
* Группировка нескольких сверточных слоев подряд перед каждым слоем макс-пулинга.

Финальный аккорд VGG традиционен для классических классификаторов: два полносвязных слоя размерностью 4096 и выходной слой на 1000 узлов, что продиктовано количеством классов в ImageNet.

Главная теоретическая ценность VGG заключается в понимании концепции эффективного рецептивного поля (effective receptive field). Зейн Данте наглядно продемонстрировал это аудитории: если мы возьмем стек из трех последовательных слоев со свертками 3x3 (при страйде 1), то один пиксель на выходе третьего слоя будет иметь область видимости (рецептивное поле) на исходном изображении размером 7x7 пикселей. При этом стек из трех слоев 3x3 имеет колоссальные преимущества перед одним слоем 7x7:

1.  **Меньше параметров:** для $C$ каналов один слой 7x7 требует $7 \times 7 \times C \times C = 49C^2$ весов. Три слоя 3x3 требуют лишь $3 \times (3 \times 3 \times C \times C) = 27C^2$ параметров.
2.  **Выше выразительная способность:** вместо одной нелинейности в слое 7x7 мы получаем три последовательные функции активации, что позволяет моделировать значительно более сложные, нелинейные зависимости в данных.

## 🚡 Революция ResNet: как «сквозные каналы» победили деградацию глубоких сетей
[[JUMP:28:56]]

Долгое время простое наращивание слоев в CNN упиралось в стену. Эмпирические исследования выявили парадокс: при попытке построить обычную («прямую») сеть из 56 слоев, её ошибка как на тестовой, так и на обучающей выборке оказывалась *выше*, чем у аналогичной сети из 20 слоев. Поскольку ошибка росла и на этапе обучения, это явно не было оверфиттингом (переобучением). Причина крылась в проблеме оптимизации (degradation problem) — экстремально глубокие сети становилось невероятно тяжело обучать из-за сложного ландшафта потерь.

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

Решением, предложенным исследователем Каймингом Хе, стали остаточные связи (residual connections или skip connections). Вместо того чтобы заставлять слои напрямую искать целевое отображение $H(x)$, архитектура ResNet заставляет их искать разницу — остаточное отображение $F(x) = H(x) - x$. Мы просто берем исходный входной сигнал $x$, копируем его в обход двух сверточных слоев и прибавляем к их выходу.



Это архитектурное решение в корне изменило процесс оптимизации:

* Если слою не нужно ничего учить, его веса могут просто устремиться к нулю, и блок за счет прибавления $x$ превратится в идеальную функцию идентичности.
* Модели больше не застревают в плохих локальных минимумах, которые парализовали «прямые» глубокие сети.
* Поскольку операция сложения требует идентичных размеров тензоров, внутри остаточного блока строго выдерживается размер фильтров 3x3 со страйдом 1 и паддингом 1. На стыках блоков, где пространственное разрешение уменьшается, ResNet применяет свертку со страйдом 2 или пулинг для коррекции размерностей.

Благодаря остаточным связям авторам удалось успешно обучить сети глубиной более 100 слоев. В семействе ResNet были представлены модели на 18, 34, 50, 101 и 152 слоя. При переходе от 101 к 152 слоям прирост точности составил всего около 1%, что говорит о насыщении емкости модели на ImageNet, однако сам факт стабильного обучения такой махины стал триумфом индустрии. Ограничением на еще больший рост сейчас выступает лишь физический объем памяти GPU.

## 🪄 Магия правильной инициализации: формула Кайминга Хе против взрыва градиентов
[[JUMP:41:59]]

Даже самая совершенная архитектура CNN обречена на провал, если веса ее слоев инициализированы некорректно. Зейн Данте продемонстрировал это на примере 6-слойной полносвязной сети с активацией ReLU:

1.  **Слишком малая инициализация (умножение случайного Гауссиана на 0.01):** с каждым последующим слоем среднее значение и стандартное отклонение активаций стремительно сжимаются, коллапсируя в ноль. Модель «затухает».
2.  **Слишком большая инициализация (умножение на 0.05):** происходит лавинообразный взрыв — значения средних и дисперсий на глубоких слоях улетают в бесконечность. Поскольку ReLU не имеет верхнего лимита, операция умножения весов друг на друга на каждом шаге экспоненциально раздувает масштабы сигналов.

Универсальным спасением является метод инициализации Кайминга (Kaiming Initialization / He Initialization). Ее создатель, Кайминг Хе (по мнению лектора — возможно, самый цитируемый компьютерный ученый за последние 15 лет), вывел математическую формулу для весов:

$$\text{Standard Deviation} = \sqrt{\frac{2}{D_{\text{in}}}}$$

где $D_{\text{in}}$ — размерность входных данных слоя. Для сверточного слоя $D_{\text{in}}$ рассчитывается как произведение площади ядра фильтра на количество входных каналов (например, $3 \times 3 \times C$). Данная формула математически гарантирует, что при использовании нелинейности ReLU дисперсия и среднее значение активаций будут оставаться стабильными и константными на протяжении любого количества слоев сети.

## 🖼️ Подготовка данных и аугментация: как сделать модель устойчивой к реальности
[[JUMP:48:58]]

Первичная подготовка (preprocessing) изображений перед подачей в модель в современном ИТ-мире стандартизирована: вычисляются средние значения и стандартные отклонения отдельно по каналам R, G и B для всего датасета. Затем из каждого пикселя каждого входящего изображения вычитается среднее, и результат делится на стандартное отклонение. Из-за трудоемкости этого процесса разработчики часто используют готовые константы, рассчитанные на ImageNet, даже если обучают сеть на совершенно других данных, и этот перенос отлично работает.

Гораздо более творческим этапом выступает аугментация данных (Data Augmentation). Она подчиняется общему правилу регуляризации: искусственный шум и случайность добавляются только во время обучения, а на этапе тестирования они отключаются или усредняются. Аугментация критически важна, поскольку она виртуально расширяет датасет и не дает сети тупо зазубрить пиксели тренировочных примеров. Обучающий лосс при этом становится выше, но способность модели к обобщению на тесте драматически растет.

Лектор выделил основные техники аугментации:

* **Горизонтальный флип (Horizontal Flipping):** зеркальное отражение. Прекрасно подходит для повседневных объектов (кошек, машин), но категорически противопоказано для задач распознавания текста (OCR).
* **Вертикальный флип (Vertical Flipping):** специфический инструмент, уместный для снимков с микроскопов или аэрофотосъемки, но вредный для обычных фото (кошка вверх ногами в реальности почти не встречается).
* **Random Resized Crop (Случайное кадрирование с изменением размера):** золотой стандарт индустрии. Алгоритм берет изображение, выбирает случайный масштаб по короткой стороне ($L$), масштабирует его, сохраняя пропорции, а затем вырезает случайный патч фиксированного размера (например, 224x224 пикселя).
* **Цветовой джиттер (Color Jitter):** случайное варьирование яркости и контрастности изображения. Границы джиттера Зейн Данте рекомендует подбирать на глаз: измененная картинка должна оставаться легко распознаваемой для человека.
* **Cutout / Random Erasing:** закрашивание случайного прямоугольного куска изображения черным или серым цветом. Метод незаменим, если в реальных условиях эксплуатации камера может быть частично перекрыта посторонними предметами (окклюзия).

Отдельно стоит отметить Test Time Augmentation (TTA) — аугментацию во время тестирования. В этом режиме одно и то же тестовое изображение прогоняется через модель в нескольких вариациях (разные кропы, флипы), а финальные предсказания усредняются. Этот нехитрый трюк позволяет без переобучения модели стабильно выжимать дополнительные 1–2% точности в промышленных задачах.

## 🧠 Тонкая настройка (Transfer Learning): что делать, если у вас мало данных
[[JUMP:58:05]]

В реальности у инженеров почти никогда нет миллиона изображений для обучения с нуля. Спасением является тот факт, что сверточные нейросети формируют строгую иерархию признаков: первые слои ищут банальные грани и текстуры, а глубокие слои собирают их в высокоуровневые концепты объектов. Если извлечь вектор признаков из предпоследнего слоя обученной сети (размерностью 4096 или 2048) и измерить L2-расстояние между разными картинками в этом пространстве, окажется, что похожие по смыслу объекты группируются поразительно кучно.

На основе этого лектор выделил три главные стратегии трансферного обучения, выбор которых зависит от объема вашей выборки и сходства доменов:

1.  **Мало данных + похожий домен (например, лица людей):** мы берем модель, предобученную на ImageNet, полностью «замораживаем» все ее слои (запрещаем обновление весов при backprop), срезаем финальный слой классификатора на 1000 классов и ставим вместо него слой со своим числом классов. Обучается *только* этот новый финальный линейный классификатор. Модель выступает в роли фиксированного экстрактора признаков.
2.  **Много данных + похожий домен:** в этом сценарии (который сам Зейн Данте использует чаще всего для своих проектов с объемом от 1 до 10 млн изображений) имеет смысл разморозить и обучить *всю* сеть целиком, но обязательно инициализировать её веса не случайно, а именно предобученными весами ImageNet.
3.  **Абсолютно другой домен (например, снимки поверхности Марса):** здесь модель, обученная на земных кошках и собаках, может демонстрировать сильное смещение (bias). Если данных много, лучше учить сеть с нуля. Если данных мало, ситуация становится экстремально тяжелой и требует применения специализированных методов генерализации (Out-of-domain generalization), что сейчас является полем активных академических исследований.

В качестве продвинутого метода лектор упомянул технологию LoRA (Low-Rank Adaptation). Вместо изменения колоссального массива исходных весов при fine-tuning, LoRA позволяет заморозить базовую модель и обучать лишь низкоранговые матрицы дельт (различий) к весам слоев, обходясь мизерным числом настраиваемых параметров.

## 🕹️ Стратегия отладки и поиска гиперпараметров: почему случайный поиск лучше сетки
[[JUMP:1:07:20]]

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

Золотым правилом отладки (debugging) в глубоком обучении лектор назвал контролируемый оверфиттинг на микро-выборке. Возьмите всего один-два тренировочных примера и запустите обучение. Проверить корректность кода очень просто: лосс модели должен гарантированно и стремительно упасть в абсолютный нуль, а точность — сойтись к 100%. Сеть обязана легко «зазубрить» один пример. Если этого не происходит — в коде или в выборе архитектуры гарантированно закрался критический баг. Этот тест также позволяет нащупать первоначальные грубые границы жизнеспособного шага обучения (learning rate).

После этого запускается грубый поиск (coarse search) параметров в рамках одной эпохи обучения для оценки динамики падения лосса. На этом этапе критически важно непрерывно мониторить графики точности:

* Если графики обучения и валидации идут рука об руку вверх — модель недообучена, можно смело продолжать процесс.
* Если график точности обучения продолжает расти, а валидационная кривая пошла вниз — вы столкнулись с оверфиттингом. Необходимо немедленно усиливать регуляризацию (добавлять дропаут, аугментации) или искать больше данных.

Напоследок Зейн Данте развенчал популярный миф о поиске гиперпараметров по сетке (Grid Search). В реальных задачах случайный поиск (Random Search) работает в разы эффективнее. Причина кроется в геометрии пространства параметров: как правило, среди набора гиперпараметров есть те, которые критически влияют на результат (например, learning rate), и те, к изменению которых модель почти нечувствительна. 

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