Как учится машина. Революция в области нейронных сетей и глубокого обучения - Ян Лекун
Рис. 4.2. Функция стоимости обучения
Функцию стоимости можно сравнить с горным ландшафтом (слева), линии высот которого представлены справа. Обучение машины включает в себя поиск дна долины, то есть значения обучаемых параметров, которое дает наименьшее значение стоимости. В этом примере долгота и широта – это два обучаемых параметра w[0] и w[1], а минимум находится на координатах (3, 2). Когда мы начинаем обучать систему, мы не знаем ни формы этого ландшафта, ни положения его минимума. Но при заданном значении параметров, можно вычислить его высоту, т. е. значение стоимости. Мы также можем вычислить вектор градиента g, который указывает вверх в направлении наибольшего наклона. Градиент, представленный стрелками, отличается в каждой точке ландшафта.
Изменяя параметры в направлении, противоположном градиенту (–g), мы делаем шаг в сторону дна долины. Эта операция заключается в замене вектора w его значением, из которого мы вычитаем вектор градиента и умножаем на константу e, определяющую размер шага. Цель – найти точку в самом низу долины, протестировав минимум конфигураций.
Представьте: мы заблудились. Ничего не видно: кромешная тьма и ужасная погода. Чтобы вернуться в деревню, лежащую в глубине долины, если нет ни дороги ни тропы, мы пойдем в сторону максимального уклона. Мы наблюдаем, куда он ведет, делаем шаг в эту сторону и шаг за шагом попадаем в долину. Направление наибольшего наклона называется градиентом функции стоимости. Дно долины – это минимум функции стоимости, а его координаты – это значения параметров, минимизирующие стоимость.
Наша цель – быстро найти эту самую низкую точку долины. Тестирование требует значительных затрат времени и вычислительных ресурсов, особенно если в обучающей базе есть миллионы примеров. Поэтому мы прибегаем к методу «минимизации функции градиентным спуском». Сейчас он повсеместно используется в области ИИ в качестве обучающего механизма.
Начнем с понимания принципа. Чтобы найти линию с наибольшим уклоном, вычисляем градиент. Чтобы найти его, мы представляем себе изменение параметра, относительно небольшое, чтобы увидеть, как стоимость уменьшается или увеличивается. Используя снова метафору горы, мы делаем небольшой шаг в заданном направлении, чтобы выяснить, ведет ли этот шаг вниз или вверх. Чтобы это сработало, незначительные изменения параметров должны соответствовать незначительным изменениям функции стоимости. Это свойство функции математики называют «непрерывностью». Функции, график которых представляет собой лестницы или вершину скалы[48], свойством непрерывности не обладают.
Мы изменяем два параметра один за другим. Сначала мы поворачиваем в направлении w[0] (то есть на восток). Мы можем оценить наклон g[0], сделав небольшой шаг, измерив соответствующее изменение высоты и разделив эту разницу на размер шага. Если высота уменьшается, мы делаем шаг в этом направлении. Размер этого шага пропорционален уклону. Чем круче уклон, тем легче сделать большой шаг, поскольку вы идете в правильном направлении. Если уклон менее значителен, то мы сделаем вниз лишь небольшой шаг. Но если высота вместе с шагом увеличивается, когда параметр изменяется, то чтобы спуститься, нам придется сделать шаг в противоположном направлении.
Затем мы поворачиваем на 90°, чтобы шагнуть в направлении w[1] (то есть на север), и повторяем операцию: мы оцениваем уклон g[1] и, в зависимости от результата, делаем шаг, размер которого пропорционален наклону вперед или назад. Комбинация этих двух шагов приближает нас ко дну долины. Повторяя операцию столько раз, сколько необходимо, в конечном итоге мы достигнем этой самой низкой точки (откуда уже невозможно спуститься ниже).
Вектор g, компонентами которого являются наклоны [g[0], g[1]], называется градиентом. Рис. 4.2 представляет собой вектор градиента. Согласно этому определению, вектор указывает вверх вдоль линии наибольшего наклона, а его длина – это наклон в этом направлении. Сделав шаг в направлении, противоположном этому градиенту, мы движемся ко дну долины. Направление, противоположное вектору g, – это вектор – g, компоненты которого имеют противоположные знаки [– g[0], –g[1]].
В более общем плане градиентный спуск выполняется следующим образом:
1. Рассчитываем стоимость обучения для текущего значения вектора параметров (в текущей точке).
2. Измеряем наклоны по каждой из осей и собираем наклоны в векторе градиента g.
3. Модифицируем вектор параметров в направлении, противоположном градиенту. Для этого мы инвертируем знаки компонентов градиента, а затем умножаем их на константу e, которая определяет размер шага.
4. Наконец, добавляем полученный вектор к вектору параметров. Другими словами, заменяем каждый компонент вектора параметров его текущим значением за вычетом соответствующего компонента вектора градиента, умноженного на размер шага e.
5. Размер шага градиента очень важен: если он слишком мал, то хотя в конечном итоге минимум найдется, это отнимет много времени, потому что с каждым шагом расстояние сокращается незначительно. Если шаг слишком большой, то рискуем превысить минимум и перебраться на другую сторону. Следовательно, постоянная e должна быть такой, чтобы изменение параметров не привело нас со склона горы, где мы сейчас стоим, на противоположный, перебросив через гребень.
6. Повторяем операции, пока не окажемся на дне долины. Другими словами, до тех пор, пока стоимость обучения не перестанет уменьшаться.
Рис. 4.3. Путь, предназначенный для метода градиентного спуска
Процедура градиентного спуска состоит в том, чтобы выполнить ряд шагов в направлении наибольшего нисходящего наклона, противоположного градиенту, пока вы не достигнете дна долины. Размер шага пропорционален шагу градиента e. Справа e немного больше и вызывает колебания траектории. Слишком большой шаг градиента может привести к ошибке.
Пример
Мы находимся в координатах [w[0], w[1]]. В этот момент высота (стоимость обучения) равна h = L (X, Y, w). Опишем процедуру градиентного спуска через помехи. Процедура простая, но не самая эффективная. Начнем с создания дополнительного вектора параметров wa, полученного путем небольшого изменения значения w[0] (назовем его dw) следующим образом:
wa[0] = w[0] + dw
wa[1] = w[1]
Затем мы вычисляем высоту в новой позиции a = L (X, Y, wa). Изменение высоты из-за помехи составляет a – h. Наклон в направлении помехи – это отношение (a – h) / dw. Почему нужен этот отчет? Потому что нас интересует наклон горы, то есть величина, на которую мы должны умножить размер нашего шага, чтобы получить изменение высоты.
Аналогично, изменяя w в направлении w[1] следующим образом:
wb[0] = w[0]
wb[1] = w[1] + dw
мы можем вычислить высоту b = L (X, Y, wb). Наклон