Конспект лекций FAU по глубокому обучению
Сети прямого распространения — часть 3
Алгоритм обратного распространения
Это конспект лекций FAU YouTube Lecture Deep Learning. Это полная стенограмма видео лекции и соответствующие слайды. Мы надеемся, вам понравится это так же, как видео. Конечно, эта стенограмма была создана с использованием методов глубокого обучения в основном автоматически, и вручную были внесены лишь незначительные изменения. Если вы заметили ошибки, сообщите нам об этом!
Навигация
Предыдущая лекция / Посмотреть это видео / Высший уровень / Следующая лекция
Добро пожаловать всем на глубокое обучение! Спасибо за внимание. Сегодняшней темой будет алгоритм обратного распространения ошибки. Итак, вас может заинтересовать, как мы на самом деле вычисляем эти производные в сложных нейронных сетях. Давайте рассмотрим простой пример. Наша истинная функция равна 2 x₁ плюс 3 x₂ в степени 2 плюс 3. Теперь нам нужно вычислить частную производную f(x) в позиции (1 3)ᵀ по отношению к x₁. Есть два алгоритма, которые могут сделать это достаточно эффективно. Первыми будут конечные разности. Вторая — аналитическая производная. Итак, мы рассмотрим оба примера здесь.
Для конечных разностей идея состоит в том, что вы вычисляете значение функции в некоторой позиции x. Затем вы добавляете очень маленькое приращение h к x и вычисляете функцию. Вы также вычисляете функцию at f(x) и берете разницу между ними. Затем вы делите на значение h. Так что на самом деле это определение производной: это предел разницы между f(x+h) и f(x), деленный на h, в котором мы приближаем h к 0. Теперь проблема в том, что это не симметрично. Итак, иногда вы хотите предпочесть симметричное определение. Вместо того, чтобы вычислять это точно в x, мы идем h/2 назад и h/2 вперед. Это позволяет нам вычислить производную точно в позиции x. Затем нам все еще нужно разделить на h. Это симметричное определение.
Мы можем сделать это для нашего примера. Попробуем это оценить. Берем исходное определение (2x₁+ 3x₂)² + 3. Мы хотели посмотреть на позицию (1 3)ᵀ. Давайте воспользуемся приведенным выше определением +h/2. Здесь мы устанавливаем h на небольшое значение, скажем, 2 ⋅ 10⁻². Мы подключаем его, и вы можете видеть это здесь, в этом ряду. Таким образом, это будет ((2(1+10⁻²+9)² + 3), и, конечно же, мы также должны вычесть наше небольшое значение во втором члене. Затем мы также разделим на меньшее значение. Таким образом, мы получим примерно 124,4404 минус 123,5604. Это будет примерно 43,9999. Таким образом, мы можем вычислить это для любой функции, даже если мы не знаем определения функции, например, если в качестве программного обеспечения модуль, к которому мы не можем получить доступ В этом случае мы можем использовать конечные разности для аппроксимации частной производной.
На практике мы используем h в диапазоне 1⋅ 10⁻⁵, что подходит для точности с плавающей запятой. В зависимости от точности вашей вычислительной системы вы также можете определить, каким будет подходящее значение для h. Вы можете проверить это в ссылке номер семь. Мы видим, что это действительно легко использовать. Мы можем вычислить это для любой функции, формальное определение которой нам не нужно, но, конечно, это неэффективно с вычислительной точки зрения. Представьте, что вы хотите определить градиент, который является набором всех частных производных функции, имеющей размерность 100. Это означает, что вам нужно вычислить функцию 101 раз, чтобы вычислить весь этот градиент. Таким образом, это может быть не такой уж хороший выбор для общей оптимизации, потому что это может стать неэффективным. Но, конечно, это очень классный способ проверить свою реализацию. Представьте, что вы реализовали аналитическую версию и иногда допускаете ошибки. Затем вы можете использовать это как трюк, чтобы проверить, правильно ли реализована ваша аналитическая производная. Это также то, чему вы подробно научитесь в упражнениях здесь. Это действительно полезно, если вы хотите отладить свою реализацию.
Итак, давайте поговорим об аналитических градиентах. Теперь аналитический градиент мы можем получить, используя набор правил аналитического дифференцирования. Итак, первое правило будет заключаться в том, что производная константы будет равна 0. Тогда наш оператор является линейным оператором, что означает, что мы можем переставить его, если у нас есть, например, суммы различных компонентов. Далее, мы также знаем производные одночленов. Если у вас есть xⁿ, производная будет n ⋅ xⁿ⁻¹. Цепное правило применяется, если у вас есть вложенные функции. По сути, это ключевая идея, которая нам также нужна для алгоритма обратного распространения ошибки. Вы видите, что производная по x некоторой вложенной функции будет производной функции по g, умноженной на производную функции g относительно x.
Хорошо, давайте поместим их в самый верхний правый угол. Они понадобятся нам в следующих нескольких слайдах. Давайте попробуем вычислить это, чтобы здесь вы увидели частную производную по x₁ от f(x) в (1 3)ᵀ. Затем мы можем просто подключить определение. Итак, это будет частная производная от (2x₁+9)². Итак, мы уже можем написать 9, потому что мы уже можем подставить 3 и умножить его на 3, чтобы получить 9. На следующем шаге мы можем вычислить частную производную относительно внешней функции. В настоящее время. есть применение цепного правила, и мы вводим эту новую переменную z. На следующем шаге мы можем вычислить частную производную z в степени 2, где мы должны уменьшить показатель степени на 1, а затем умножить на этот показатель степени. Таким образом, это будет 2(2x₁+9), умноженное на частную производную 2x₁+9. Итак, мы можем еще немного упростить это. Вы можете видеть, что если мы применим частную производную к 2x₁+9, x₁ исчезнет. Остается только 2, так как минус константа 9 тоже обращается в нуль. Таким образом, в итоге мы получаем 2(2x₁+9) умножить на 2. Теперь, если вы подставите x₁ = 1, вы увидите, что наша производная равно 44. В нашей числовой реализации, которую мы оценили ранее, вы можете видеть, что у нас было 43,9999. Итак, мы были довольно близки. Но, конечно, аналитический градиент более точен.
Теперь вопрос: «Можем ли мы сделать это автоматически?» и, конечно же, ответ «да». Мы используем эти правила, цепное правило, линейность и два других, чтобы разложить сложные функции нейронных сетей. Мы не делаем этого вручную, а делаем это полностью автоматически в алгоритме обратного распространения ошибки. Это будет более эффективно в вычислительном отношении, чем конечные разности.
Таким образом, вы можете вкратце описать алгоритм обратного распространения ошибки здесь: для каждого нейрона вам нужны входные данные x₁, x₂ и, конечно же, выходные данные, это y шляпа. Затем вы можете вычислить — зеленым цветом — прямой проход. Вы где-то оцениваете функцию потерь и получаете производную по y, которая приходит при обратном проходе. Затем для каждого элемента вашего сетевого графа вам нужно знать производные по отношению к входным данным, здесь x₁ и x₂. Чего нам не хватает на этом рисунке, так это, конечно, тренируемых весов. Для обучаемых весов нам также потребуется вычислить производные по ним, чтобы вычислить обновления параметров. Итак, для каждого модуля или узла вам нужно знать производную по входам и производную по весам. Если у вас есть это для каждого модуля, вы можете составить график, и с помощью этого графика вы можете вычислять произвольные производные очень сложных функций.
Вернемся к нашему примеру и применим к нему обратное распространение. Так что же нам делать? Итак, сначала мы вычисляем прямой проход. Чтобы иметь возможность вычислить прямой проход, мы подключаем промежуточные определения. Итак, мы разложим это теперь на некоторые a, которые в 2 раза больше x₁, и b, что в 3 раза больше x₂ . Затем мы можем их вычислить: мы получаем значения 2 и 9 для a и b. Это позволяет нам вычислить c, то есть сумму двух значений. Это равно 11. Затем мы можем вычислить e из того, что является не чем иным, как степенью двойки c. Это дает нам 121, и теперь мы, наконец, вычисляем g, то есть e плюс 3. Итак, мы получаем 124.
Хорошо, теперь нам нужно выполнить обратное распространение. Итак, нам нужно вычислить частные производные. Здесь частные производные g по e будут равны 1. Затем мы вычисляем частную производную e по c и вы увидите, что это 2c. Поскольку c равно 11, это оценивается как 22. Затем нам нужна частная производная от c по отношению к a, которая снова равна 1. Теперь, нам нужна частная производная a по x₁. Если вы посмотрите на этот блок, то увидите, что эта частная производная будет равна 2. Таким образом, мы должны умножить все частные производные справа налево, чтобы получить результат: 1 умножить на 22, умножить на 1, умножить на 2, и это будет 44. Итак, это был алгоритм обратного распространения, примененный к нашему примеру.
Теперь у нас есть своего рода проблема со стабильностью. Мы довольно часто умножаем на потенциально высокие и низкие числа в рамках алгоритма обратного распространения ошибки. Это затем дает нам проблему положительной обратной связи, и это может привести к катастрофе. Пример положительной обратной связи и того, как она может привести к катастрофе, показан в небольшом видео здесь.
Теперь, что мы можем с этим поделать? По сути, это обратная связь. У нас есть этот контроллер и выход, где мы вычисляем градиент. Вы видите, что существует это значение η. Итак, если у нас слишком высокое η, это создаст положительную обратную связь. Это приведет к очень высоким значениям наших обновлений, и тогда наши потери могут вырасти или действительно резко увеличиться. Поэтому, если он слишком велик, у нас даже может быть увеличение функции потерь, хотя мы стремимся минимизировать его. Что также может случиться, так это то, что если вы выберете η слишком маленьким, вы получите синюю кривую. Это называется исчезающим градиентом, когда у нас просто слишком маленькие шаги, и мы не достигаем хорошей сходимости. Так что потери не уменьшаются. Это также проблема, называемая «исчезающими градиентами». Таким образом, только если вы правильно выберете η, вы получите хорошую скорость обучения. При хорошей скорости обучения потери должны начать очень быстро уменьшаться в течение многих итераций, следующих за этой зеленой кривой. Затем мы должны перейти к какой-то конвергенции, и когда у нас больше не будет изменений, мы, по сути, находимся в точке конвергенции набора обучающих данных. Затем мы можем перестать обновлять наши веса. Итак, мы видим, что выбор ЭДА имеет решающее значение для нашего обучения, и только если вы сказали это правильно, вы получите хороший тренировочный процесс.
Итак, давайте подытожим обратное распространение: оно построено на цепном правиле. Он использует прямой проход. Как только мы подойдем к концу и оценим функцию потерь — по сути, разницу с нашей целью обучения — тогда мы сможем выполнить обратное распространение. Эти вычисления очень эффективны при использовании подхода динамического программирования. Обратное распространение не является обучающим алгоритмом. Это просто способ вычисления градиента. Актуальные программы обучения вы увидите, когда мы будем обсуждать потери и оптимизацию в одной из следующих лекций. Некоторые очень важные следствия: У нас есть произведение частичных чисел, что означает умножение числовой ошибки. Это может быть очень проблематично. Кроме того, из-за произведения парциалов мы получаем либо исчезновение, либо взрыв решеток. Таким образом, когда у вас есть очень низкие значения, близкие к нулевым значениям, и вы начинаете умножать их друг на друга, вы получаете экспоненциальное затухание, вызывающее исчезновение градиентов. Конечно, если у вас очень высокие числа, вы также можете очень быстро оказаться в экспоненциальном росте — взрывающихся градиентах.
Мы видим, что градиенты имеют решающее значение для нашего обучения. Итак, давайте немного поговорим о функциях активации и их производных. Одной из классических является знаковая функция. У нас уже было это в персептроне. Теперь вы можете видеть, что он симметричен и нормализован между 1 и -1. Но помните, мы говорим о частных производных для вычисления обновлений веса. Таким образом, производная этой функции немного проблематична, потому что она равна 0 везде, кроме точки 0, и там вы, по сути, имеете бесконечность как значение. Так что не очень хорошо использовать это в сочетании с градиентным спуском.
Итак, чем занимались люди? Они переключились на другие функции, и одной из популярных является сигмовидная функция. Итак, это s-образная функция, которая масштабирует все от 0 до 1, используя отрицательную экспоненциальную функцию в знаменателе. Приятно то, что если вы вычислите производную от этого, то это, по существу, f(x) умножить на 1 — f(x). Так что, по крайней мере, производная может быть вычислена довольно эффективно. В прямом проходе вам всегда приходится иметь дело с экспоненциальными функциями, которые также являются проблематичными. Кроме того, если вы посмотрите на эту функцию, скажем, между -3 и 3, вы получите градиенты, которые могут подходить для обратного распространения. Как только вы уйдете дальше от -3 или 3, вы увидите, что производная этой функции будет очень близка к нулю. Итак, у нас есть насыщение, и опять же, если вы ожидаете, что у вас есть пара этих сигмовидных функций друг за другом, то вполне вероятно, что они будут давать очень низкие значения. Это также может привести к исчезновению градиентов.
Так что же люди сделали, чтобы победить это? Ну, они ввели кусочно-линейную функцию активации, называемую «выпрямленной линейной единицей» (ReLU), которая является максимумом нуля и x. Таким образом, все, что ниже нуля, обрезается до нуля, а все остальное просто сохраняется. Теперь это хорошо, потому что мы можем вычислить это очень эффективно. Экспоненциальная функция здесь не задействована, и производная просто равна 1, если x больше нуля и равен нулю во всех остальных случаях. Таким образом, исчезающий градиент гораздо меньше, поскольку практически все положительное полупространство можно использовать для градиентного спуска. Есть также некоторые проблемы с ReLU, которые мы рассмотрим более подробно, когда будем говорить о функциях активации.
Хорошо, теперь вы поняли многие основные концепции алгоритма обратного распространения ошибки. Но нам еще предстоит поговорить о более сложных ситуациях и отдельных слоях. Итак, прямо сейчас мы сделали все на уровне нейронных узлов. Если вы хотите выполнить все обратное распространение на уровне нейронов, это очень сложно, и вы очень быстро потеряете контроль. Итак, в следующей лекции мы представим абстракцию слоев и посмотрим, как мы можем вычислить эти градиенты для целых слоев. Так что оставайтесь с нами и продолжайте смотреть! Надеюсь вам понравилось это видео и увидимся в следующем. Спасибо!
Если вам понравился этот пост, вы можете найти больше эссе здесь, больше учебных материалов по машинному обучению здесь или посмотреть нашу Глубокое обучение Лекцию. Я также был бы признателен за аплодисменты или подписку на YouTube, Twitter, Facebook или LinkedIn, если вы хотите получать информацию о новых эссе, видео и исследованиях в будущем. Эта статья выпущена на условиях Creative Commons 4.0 Attribution License и может быть перепечатана и изменена при ссылке.
использованная литература
[1] Р. О. Дуда, П. Э. Харт и Д. Г. Сторк. Классификация узоров. John Wiley and Sons, Inc., 2000.
[2] Кристофер М. Бишоп. Распознавание образов и машинное обучение (информатика и статистика). Секокус, Нью-Джерси, США: Springer-Verlag New York, Inc., 2006.
[3] Ф. Розенблатт. «Персептрон: вероятностная модель хранения и организации информации в мозгу». В: Psychological Review 65.6 (1958), стр. 386–408.
[4] WS. Маккалок и У. Питтс. «Логическое исчисление идей, имманентных нервной деятельности». В: Бюллетень математической биофизики 5 (1943), стр. 99–115.
[5] Д. Э. Румельхарт, Г. Э. Хинтон и Р. Дж. Уильямс. «Изучение представлений путем обратного распространения ошибок». В: Nature 323 (1986), стр. 533–536.
[6] Ксавье Глорот, Антуан Бордес и Йошуа Бенжио. «Глубокие разреженные нейронные сети выпрямителя». В: Труды четырнадцатой Международной конференции по искусственному интеллекту Vol. 15. 2011, стр. 315–323.
[7] William H. Press, Saul A. Teukolsky, William T. Vetterling, et al. Числовые рецепты 3-е издание: Искусство научных вычислений. 3-е изд. Нью-Йорк, штат Нью-Йорк, США: Издательство Кембриджского университета, 2007.