# Эндрю Нг о TensorFlow: «Вам больше не нужно реализовывать backprop вручную»

Источник: https://www.youtube.com/watch?v=S9ElPZupUsE
Канал: DeepLearning.AI
Опубликовано: 25.08.2017

---

В новом обучающем видео от DeepLearning.AI основатель платформы Эндрю Нг знакомит слушателей с основами TensorFlow — одного из ведущих фреймворков для глубокого обучения. На примере минимизации простой квадратичной функции автор демонстрирует, как структура программы позволяет автоматизировать сложные математические вычисления и оптимизировать параметры нейронных сетей.

## 🧠 Основы минимизации функций в TensorFlow
[[JUMP:00:00]]

Эндрю Нг начинает демонстрацию с постановки классической задачи оптимизации. Вместо того чтобы сразу переходить к сложным нейронным сетям, он предлагает рассмотреть простую функцию стоимости $J(w) = w^2 - 10w + 25$ [00:39]. Лектор поясняет, что эта функция эквивалентна выражению $(w - 5)^2$, а значит, её минимальное значение достигается при $w = 5$ [00:54].

Основная идея использования TensorFlow заключается в том, что разработчику достаточно описать саму функцию, а фреймворк самостоятельно найдет способ её минимизации. По словам Эндрю Нг, такой подход масштабируется на любые сложные нейросети, где функция стоимости зависит от сотен тысяч или миллионов параметров (весов $W$ и смещений $b$) [01:19].

Для начала работы в среде Python (используется Jupyter Notebook) необходимо импортировать ключевые библиотеки:

*   **NumPy** (традиционно как `np`) для работы с массивами [01:44].
*   **TensorFlow** (как `tf`) — основной инструмент разработки [01:44].

## 🛠 Структура программы и определение параметров
[[JUMP:01:44]]

Первым шагом в TensorFlow является определение параметров, которые алгоритм будет изменять в процессе обучения. Для этого используется конструкция `tf.Variable`. В примере Нг определяет переменную `w` как число с плавающей точкой (`tf.float32`) и инициализирует её значением 0 [02:03].

Далее описывается сама функция стоимости. Лектор показывает два способа записи:

1.  **Функциональный стиль:** Использование встроенных функций `tf.add`, `tf.multiply` и возведения в степень [02:15]. Это выглядит как громоздкая цепочка вложенных операций.
2.  **Перегрузка операторов:** Эндрю Нг подчеркивает, что TensorFlow поддерживает стандартные математические символы (`+`, `-`, `*`, `**`), что делает код более читаемым и компактным [05:56].

Ключевым элементом программы является выбор оптимизатора. В данном примере используется `tf.train.GradientDescentOptimizer` с заданной скоростью обучения (learning rate) 0.01 [02:46]. Инструкция `optimizer.minimize(cost)` сообщает фреймворку, какую именно величину нужно уменьшать [03:01].

## 🚀 Запуск вычислений и сессии
[[JUMP:03:14]]

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

*   **Инициализация:** Необходимо создать специальную операцию `tf.global_variables_initializer()`, чтобы подготовить все переменные к работе [03:14].
*   **Сессия:** Для выполнения любых действий требуется запустить `tf.Session` [03:14].
*   **Метод `session.run()`:** Это «сердце» программы, которое фактически запускает вычисления [03:27].

Эндрю Нг демонстрирует процесс обучения в динамике:

*   После инициализации значение $w$ равно 0 [03:56].
*   После одного шага градиентного спуска значение $w$ становится равным 0.1 [04:22].
*   После 1000 итераций значение достигает 4.9999, что практически идеально совпадает с теоретическим минимумом в точке 5.0 [04:37].

## 📊 Работа с данными: Placeholder и Feed Dict
[[JUMP:06:23]]

В реальных задачах машинного обучения данные (обучающая выборка) постоянно меняются, в отличие от фиксированных коэффициентов в уравнении. Для решения этой проблемы в TensorFlow используется механизм **плейсхолдеров** (`tf.placeholder`) [07:03].

Эндрю Нг модифицирует пример, превращая коэффициенты квадратичной функции в переменные данные:

1.  Создается плейсхолдер `x` для массива из трех чисел [07:03].
2.  Функция стоимости теперь зависит от `x`: $x[0] \cdot w^2 + x[1] \cdot w + x[2]$ [07:27].
3.  При запуске `session.run()` данные передаются через аргумент `feed_dict` [08:43].

Этот механизм крайне важен для реализации **mini-batch gradient descent** (мини-пакетного градиентного спуска), где на каждой итерации в граф «скармливаются» новые порции данных [10:19]. Эндрю Нг демонстрирует гибкость подхода: просто сменив входные данные в `feed_dict` (например, на коэффициенты 1, -20, 100), он заставляет алгоритм мгновенно перенастроиться на поиск минимума новой функции (в данном случае $w=10$) [09:25].

## 🏗 Граф вычислений и автоматическое дифференцирование
[[JUMP:11:15]]

Основная мощь TensorFlow, по мнению Эндрю Нг, заключается в автоматическом построении **графа вычислений** [12:05]. Когда разработчик описывает формулу, фреймворк создает структуру узлов, где каждый узел — это либо переменная, либо математическая операция (сложение, умножение, возведение в квадрат) [14:09].

Главные преимущества такого подхода:

*   **Автоматический Backprop:** Разработчику нужно реализовать только прямой проход (forward propagation) — описание того, как из входов получается стоимость [13:18]. TensorFlow автоматически знает, как вычислить производные для обратного прохода (back propagation), так как в каждую операцию (add, multiply) уже встроена функция вычисления её градиента [13:43].
*   **Легкая смена алгоритмов:** Чтобы заменить обычный градиентный спуск на более эффективный алгоритм **Adam**, достаточно изменить всего одну строку кода [15:05].

В завершение лекции Эндрю Нг отмечает, что современная документация TensorFlow может использовать разные нотации для графов — где-то узлы обозначают значения, а где-то — сами операции, но суть вычислений остается прежней [14:51].