Шаг 47.
Глубокое обучение на Python. Математические основы нейронных сетей. Механизм нейронных сетей: оптимизация на основе градиента (общие сведения)

    На этом шаге мы введем понятие градиента.

    Как было показано в предыдущих шагах, каждый слой нейронной сети из нашего первого примера преобразует данные следующим образом:

output = relu(dot(input, W) + b)

    В этом выражении W и b - тензоры, являющиеся атрибутами слоя. Они называются весами или обучаемыми параметрами слоя (атрибуты kernel и bias соответственно). Эти веса содержат информацию, извлеченную сетью из обучающих данных.

    Первоначально весовые матрицы заполняются небольшими случайными значениями (данный шаг называется случайной инициализацией). Конечно, бессмысленно было бы ожидать, что relu(dot(input, W) + b) вернет хоть сколько-нибудь полезное представление для случайных W и b. Начальные представления не несут никакого смысла, но они служат отправной точкой. Далее на основе сигнала обратной связи происходит постепенная корректировка весов, которая также называется обучением. Она и составляет суть машинного обучения.

    Ниже перечислены шаги, выполняемые в так называемом цикле обучения, который повторяется необходимое количество раз.

  1. Извлекается пакет обучающих экземпляров x и соответствующих целей y_true.

  2. Модель обрабатывает пакет x (этот шаг называется прямым проходом) и получает пакет предсказаний y_pred.

  3. Вычисляются потери модели на пакете, дающие оценку несовпадения между y_pred и y_true.

  4. Веса модели корректируются так, чтобы немного уменьшить потери на этом пакете.

    В конечном итоге получается модель, имеющая очень низкие потери на обучающем наборе данных: несовпадение предсказаний y_pred с ожидаемыми целями y_true малое. Модель "научилась" отображать входные данные в правильные конечные значения. Со стороны все это может походить на волшебство, однако, если разобрать процесс на мелкие шаги, он выглядит очень просто.

    Шаг 1 несложный - это просто операция ввода/вывода. Шаги 2 и 3 - всего лишь применение нескольких операций с тензорами, и вы сможете реализовать их, опираясь на полученные в предыдущих шагах знания. Наиболее запутанным выглядит шаг 4: корректировка весов сети. Как по отдельным весам в сети узнать, должен ли некоторый коэффициент увеличиваться или уменьшаться и насколько?

    Одно из простейших решений - заморозить все веса, кроме одного, и попробовать применить разные его значения. Допустим, первоначально вес имел значение 0,3. После прямого прохода потери сети составили 0,5. Теперь представьте, что после увеличения значения веса до 0,35 и повторения прямого прохода вы получили увеличение оценки потерь до 0,6, а после уменьшения веса до 0,25 - падение оценки потерь до 0,4. В данном случае похоже, что корректировка коэффициента на величину -0,05 вносит свой вклад в уменьшение потерь. Эту операцию можно было бы повторить для всех весов в сети.

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

    Градиентный спуск - метод оптимизации, широко применимый в современных нейронных сетях. Суть его заключается в следующем: все функции, используемые в наших моделях (например, dot или +), плавно и непрерывно преобразуют свои входные данные. Например, небольшое изменение у в операции z = x + у приведет к небольшому изменению z - и, зная направление изменения у, можно определить направление изменения z. Говоря математическим языком, данные функции дифференцируемы. Если объединить их в цепочку, получившаяся общая функция все равно будет дифференцируемой. Это утверждение, в частности, верно для функции, сопоставляющей веса модели с потерями в пакете данных. Небольшое изменение весов приводит к небольшому и предсказуемому изменению значения потерь, что позволяет использовать математический оператор, называемый градиентом, для описания изменения потерь при изменении весов модели в разных направлениях. Вычисленный градиент можно использовать для модификации весов (всех сразу в одном цикле, а не по одному) в направлении, уменьшающем потери.

    В следующих шагах мы попробуем разобраться в этих понятиях.

    На следующем шаге мы рассмотрим, что такое производная.




Предыдущий шаг Содержание Следующий шаг