🧠 Основы нейронных сетей и глубокого обучения в Stanford CS221 0:06
Лекция №4 курса Stanford CS221, прочитанная в Стэнфордском университете (Stanford University) осенью 2025 года, посвящена переходу от линейных моделей к глубокому обучению (deep learning). Основная цель занятия — научить студентов строить нелинейные модели классификации и регрессии, используя для этого мощные инструменты автоматического дифференцирования. Автор лекции Stanford Online объясняет, как концептуально устроены современные нейронные сети и какие технические приемы позволяют успешно их обучать.
🛠 Переход на PyTorch: от «ручной» работы к стандартам индустрии 0:36
Ранее студенты строили собственные библиотеки для вычислительных графов, чтобы понять процесс обратного распространения ошибки (backpropagation) изнутри. Однако на практике для реальных задач разработчики используют PyTorch или Jax.
Ключевые концепции работы с PyTorch:
- Тензоры как узлы: В PyTorch тензор (
torch.tensor) следует воспринимать как узел вычислительного графа, а не просто как массив данных. - Вычисления: Операции в PyTorch выполняются «на лету» (eager execution), в отличие от ручной реализации, где вычисления можно было откладывать до этапа обратного прохода.
- Градиенты: Параметр
requires_grad=Trueотмечает узлы, для которых нужно вычислить градиенты. По общему правилу, это должны быть параметры модели, а не входные данные. - Изоляция вычислений: Функция
detachпозволяет «отрезать» узел от графа вычислений, чтобы градиенты не распространялись дальше. Это критически важно при использовании режимаtorch.no_grad, который минимизирует накладные расходы при инференсе модели.
📉 Цикл обучения: от данных до оптимизации 18:02
Классический пайплайн обучения в PyTorch состоит из четырех повторяющихся шагов:
- Прямой проход (forward pass): Получение предсказаний (логитов) и расчет функции потерь (например,
cross_entropy_loss). - Зануление градиентов: В PyTorch градиенты накапливаются, поэтому их нужно принудительно обнулять перед каждым шагом.
- Обратный проход (backward pass): Вызов
loss.backward()для вычисления градиентов по параметрам модели. - Шаг оптимизатора: Метод
optimizer.step()обновляет веса модели на основе накопленных градиентов.
🌀 Нелинейность: путь к выразительным моделям 26:39
Линейные модели ограничены прямыми границами принятия решений. Чтобы выйти за эти рамки, не обязательно сразу строить сложную нейросеть: иногда достаточно использовать нелинейные карты признаков (feature maps).
Однако главная цель глубокого обучения — позволить самой сети «выучить» эти признаки.
- Многослойный перцептрон (MLP): При объединении двух линейных слоев без функции активации, сеть остается линейной из-за ассоциативности матричного умножения.
- Функции активации: Для создания истинной нелинейности добавляются функции активации, например ReLU (Rectified Linear Unit).
- Проблема «мертвых нейронов»: ReLU выдает нулевой градиент для всех отрицательных входных значений. Если нейрон «застрял» в этой области, он перестает обучаться. В качестве решений используются Leaky ReLU, GeLU или Swish.
🏗 Стабилизация глубоких сетей 51:33
С увеличением глубины сети возникают проблемы взрывающихся или исчезающих градиентов.
- Residual Connections (Skip Connections): Добавление входа к выходу слоя (
x + f(x)) создает «путь отступления» для градиентов, даже если сам слойf(x)выдает почти нулевые значения. - Layer Normalization: Нормализация активаций (вычитание среднего и деление на стандартное отклонение) удерживает их значения от ухода в бесконечность или ноль.
- Инициализация весов: Важно правильно инициализировать веса (например, через Xavier-инициализацию), учитывая размер входного измерения, чтобы избежать изначально огромных значений.
- Стохастическая оптимизация: Использование мини-батчей (mini-batch SGD) вместо полного градиентного спуска ускоряет обучение и позволяет работать с огромными датасетами, предоставляя несмещенную оценку градиента.