Основы глубокого обучения Будума Нихиль

Предисловие

С оживлением нейросетей в 2000-е годы глубокое обучение стало очень активно развивающейся областью исследований, основой передачи знаний с помощью машин. В этой книге приведены примеры и объяснения, которые помогут понять основные идеи этой сложной отрасли. Такие крупные компании, как Google, Microsoft и Facebook, уделяют внимание глубокому обучению и расширяют свои подразделения в этой области. Для всех прочих глубокое обучение остается сложным, многогранным и малопонятным предметом. В работах по этой теме много неясного жаргона, а разнообразные учебники, выложенные в сети, не дают четкого представления о том, как решаются задачи в данной области. Наша цель – восполнить этот пробел.

Требования и цели

Это книга для аудитории, на базовом уровне владеющей математическим анализом, матричным исчислением и программированием на Python. Понять материал без этих знаний можно, но, скорее всего, очень сложно. Для некоторых разделов пригодится эрудиция в области линейной алгебры. К концу книги, надеемся, читатели уже будут понимать принципы решения задач в глубоком обучении, исторический контекст современных подходов к нему и узнают, как внедрить его алгоритмы при помощи открытой библиотеки TensorFlow.

Условные обозначения

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

Курсив

Новые термины, ссылки, названия и расширения файлов.

Моноширинный шрифт

Им оформлены программные элементы – названия переменных или свойств, базы данных, переменные среды, операторы и ключевые слова.

Моноширинный шрифт, полужирный

Команды или иной текст, вводимые пользователем.

Моноширинный шрифт, курсив

То, что нужно заменить пользовательскими значениями или такими, которые определяются контекстом (например, переменные в формулах).

Образцы кода

Дополнительный материал (образцы кода, примеры и т. д.) вы найдете по адресу https://github.com/darksigma/Fundamentals-of-Deep-Learning-Book.

Эта книга поможет вам в работе. Если приведен пример кода, его можно использовать в программах и документах. Не нужно получать у нас разрешение, если только вы не воспроизводите значительную часть кода. Например, написание программы, где использовано несколько кусков кода из этой книги, согласования не требует. Но необходимо разрешение на продажу или распространение CD-ROM с примерами из книг O’Reilly. Цитирование текста и кода из этой книги при ответах на вопросы разрешения не требует. На включение крупных фрагментов образца кода из этой книги в документацию вашего продукта необходимо разрешение.

Мы не требуем ссылок, но будем благодарны за них. Ссылка обычно включает название, автора и издательство. Например: Fundamentals of Deep Learning by Nikhil Buduma and Nicholas Locascio (O’Reilly). Copyright 2017 Nikhil Buduma and Nicholas Locascio.

Если вам кажется, что использование вами образцов кода выходит за установленные выше рамки, свяжитесь с нами по электронной почте [email protected].

Глава 1. Нейросеть

Создание умных машин

Мозг – самый невероятный орган. Именно он определяет, как мы воспринимаем всё, что видим, слышим, обоняем, пробуем на вкус и осязаем. Он позволяет хранить воспоминания, испытывать эмоции и даже мечтать. Без мозга мы были бы примитивными организмами, способными лишь на простейшие рефлексы. В целом он делает человека разумным.

Мозг ребенка весит меньше полукилограмма, но как-то решает задачи, пока недоступные даже самым большим и мощным компьютерам. Всего через несколько месяцев после рождения дети способны распознавать лица родителей, отделять объекты от фона и даже различать голоса. За первый год у них развивается интуитивное понимание естественной физики, они учатся видеть, где находятся частично или полностью скрытые от них объекты, и ассоциировать звуки с их значениями. Уже в раннем возрасте они на высоком уровне овладевают грамматикой, а в их словаре появляются тысячи слов[1].

Десятилетиями мы мечтаем о создании разумных машин с таким же мозгом, как у нас: роботов-помощников для уборки в доме; машин, которые управляют собой сами; микроскопов, автоматически выявляющих болезни. Но создание машин с искусственным интеллектом требует решения сложнейших вычислительных задач в истории, которые, однако, наш мозг способен раскусить в доли секунды. Для этого нужно разработать иной способ программирования компьютеров при помощи методов, которые появились в основном в последние десять лет. Это очень активная отрасль в исследованиях искусственного интеллекта, которая получила название глубокого обучения.

Ограничения традиционных компьютерных программ

Почему некоторые задачи компьютерам решать тяжело? Стандартные программы доказали свою состоятельность в двух областях: 1) они очень быстро ведут вычисления; 2) они неукоснительно следуют инструкциям. Если вы финансист и вам нужно провести сложные математические подсчеты, вам повезло. Типовые программы вам в помощь. Но представьте себе, что нам нужно сделать кое-что поинтереснее: например, написать программу для автоматического распознавания почерка. Возьмем за основу рис. 1.1.

Рис. 1.1. Изображение из массива рукописных данных MNIST[2]

Хотя каждая цифра на рисунке слегка отличается от предыдущей, мы легко опознаем в первом ряде нули, во втором – единицы и т. д. Теперь напишем компьютерную программу, которая решит ту же задачу. Какие правила нужно задать, чтобы различать цифры?

Начнем с простого. Например, укажем, что нулю соответствует изображение округлого замкнутого контура. Все примеры с рис. 1.1, кажется, удовлетворяют этому определению, но таких признаков недостаточно. Что, если у кого-то ноль – не всегда замкнутая фигура? И как отличить такой ноль (см. рис. 1.2) от шестерки?

Рис.1 Основы глубокого обучения

Рис. 1.2. Ноль, алгоритмически трудноотличимый от шестерки

Можно задать рамки расстояния между началом и концом петли, но не очень понятно какие. И это только начало проблем. Как различить тройки и пятерки? Четверки и девятки? Можно добавлять правила, или признаки, после тщательных наблюдений и месяцев проб и ошибок, но понятно одно: процесс будет нелегок.

Многие другие классы задач попадают в ту же категорию: распознавание объектов и речи, автоматический перевод и т. д. Мы не знаем, какие программы писать для них, потому что не понимаем, как с этим справляется наш мозг. А если бы и знали, такая программа была бы невероятно сложной.

Механика машинного обучения

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

Например, в двухлетнем возрасте родители не учат нас узнавать собаку, измеряя форму ее носа или контуры тела. Мы можем отличать ее от других существ, потому что нам показали много примеров собак и несколько раз исправили наши ошибки. Уже при рождении мозг дал нам модель, описывающую наше мировосприятие. С возрастом благодаря ей мы стали на основе получаемой сенсорной информации строить предположения о том, с чем сталкиваемся. Если предположение подтверждалось родителями, это способствовало укреплению модели. Если же они говорили, что мы ошиблись, мы меняли модель, дополняя ее новой информацией. С опытом она становится все точнее, поскольку включает больше примеров. И так происходит на подсознательном уровне, мы этого даже не понимаем, но можем с выгодой использовать.

Глубокое обучение – отрасль более широкой области исследований искусственного интеллекта: машинного обучения, подразумевающего получение знаний из примеров. Мы не задаем компьютеру огромный список правил решения задачи, а предоставляем модель, с помощью которой он может сравнивать примеры, и краткий набор инструкций для ее модификации в случае ошибки. Со временем она должна улучшиться настолько, чтобы решать поставленные задачи очень точно.

Перейдем к более строгому изложению и сформулируем идею математически. Пусть наша модель – функция h(x, ). Входное значение x – пример в векторной форме. Допустим, если x – изображение в оттенках серого, компоненты вектора – интенсивность пикселей в каждой позиции, как показано на рис. 1.3.

Рис. 1.3. Векторизация изображения для алгоритма машинного обучения

Входное значение  – вектор параметров, используемых в нашей модели. Программа пытается усовершенствовать их значения на основе растущего числа примеров. Подробнее мы рассмотрим этот вопрос в главе 2.

Чтобы интуитивно понимать модели машинного обучения, рассмотрим пример. Допустим, мы решили узнать, как предсказывать результаты экзаменов, если известно количество часов сна и учебы в день перед испытанием. Мы собираем массив данных и при каждом замере х = [x1 x2]T записываем количество часов сна (x1), учебы (x2) и отмечаем, выше или ниже они средних по классу. Наша цель – создать модель h(х,) с вектором параметров  = [0 1 2]T, чтобы:

Рис.3 Основы глубокого обучения

По нашему предположению, проект модели h(х,) будет таким, как описано выше (с геометрической точки зрения он описывает линейный классификатор, делящий плоскость координат надвое). Теперь мы хотим узнать вектор параметров , чтобы научить модель делать верные предсказания (1, если результаты ниже среднего уровня, и 1 – если выше) на основании примерного входного значения x. Такая модель называется линейным персептроном и используется с 1950-х[3]. Предположим, наши данные соответствуют тому, что показано на рис. 1.4.

Рис. 1.4. Образец данных для алгоритма предсказания экзаменов и потенциального классификатора

Оказывается, при  = [24 3 4]T модель машинного обучения способна сделать верное предсказание для каждого замера:

Рис.5 Основы глубокого обучения

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

Звучит разумно, но есть много очень серьезных вопросов. Во-первых, откуда берется оптимальное значение вектора параметров ? Решение этой задачи требует применения метода оптимизации. Оптимизаторы стремятся повысить производительность модели машинного обучения, последовательно изменяя ее параметры, пока погрешность не станет минимальной.

Мы подробнее расскажем об обучении векторов параметров в главе 2, описывая процесс градиентного спуска[4]. Позже мы постараемся найти способы еще больше увеличить эффективность этого процесса.

Во-вторых, очевидно, что эта модель (линейного персептрона) имеет ограниченный потенциал обучения. Например, случаи распределения данных на рис. 1.5 нельзя удобно описать с помощью линейного персептрона.

Рис.6 Основы глубокого обучения

Рис. 1.5. По мере того как данные принимают более комплексные формы, нам становятся необходимы более сложные модели для их описания

Но эти ситуации – верхушка айсберга. Когда мы переходим к более комплексным проблемам – распознаванию объектов или анализу текста, – данные приобретают очень много измерений, а отношения, которые мы хотим описать, становятся крайне нелинейными. Чтобы отразить это, в последнее время специалисты по машинному обучению стали строить модели, напоминающие структуры нашего мозга. Именно в этой области, обычно называемой глубоким обучением, ученые добились впечатляющих успехов в решении проблем компьютерного зрения и обработки естественного языка. Их алгоритмы не только значительно превосходят все остальные, но даже соперничают по точности с достижениями человека, а то и превосходят их.

Нейрон

Нейрон – основная единица мозга. Небольшой его фрагмент, размером примерно с рисовое зернышко, содержит более 10 тысяч нейронов, каждый из которых в среднем формирует около 6000 связей с другими такими клетками[5]. Именно эта громоздкая биологическая сеть позволяет нам воспринимать мир вокруг. В этом разделе наша задача – воспользоваться естественной структурой для создания моделей машинного обучения, которые решают задачи аналогично. По сути, нейрон оптимизирован для получения информации от «коллег», ее уникальной обработки и пересылки результатов в другие клетки. Процесс отражен на рис. 1.6. Нейрон получает входную информацию по дендритам – структурам, напоминающим антенны. Каждая из входящих связей динамически усиливается или ослабляется на основании частоты использования (так мы учимся новому!), и сила соединений определяет вклад входящего элемента информации в то, что нейрон выдаст на выходе. Входные данные оцениваются на основе этой силы и объединяются в клеточном теле. Результат трансформируется в новый сигнал, который распространяется по клеточному аксону к другим нейронам.

Рис.7 Основы глубокого обучения

Рис. 1.6. Функциональное описание биологической структуры нейрона

Мы можем преобразовать функциональное понимание работы нейронов в нашем мозге в искусственную модель на компьютере. Последняя описана на рис. 1.7, где применен подход, впервые введенный в 1943 году Уорреном Маккаллоу и Уолтером Питтсом[6]. Как и биологические нейроны, искусственный получает некоторый объем входных данных – x1x2, …, xn, каждый элемент которых умножается на определенное значение веса – w1w2, …, wn. Эти значения, как и раньше, суммируются, давая логит нейрона:

Рис.8 Основы глубокого обучения
. Часто он включает также смещение (константа, здесь не показана). Логит проходит через функцию активации f, образуя выходное значение y = f(z). Это значение может быть передано в другие нейроны.

Рис.9 Основы глубокого обучения

Рис. 1.7. Схема работы нейрона в искусственной нейросети

Математическое обсуждение искусственного нейрона мы закончим, выразив его функции в векторной форме. Представим входные данные нейрона как вектор x = [x1 x2xn], а веса нейрона как w = [w1 w2wn]. Теперь выходные данные нейрона можно выразить как y = f (x w + b), где b – смещение. Мы способны вычислить выходные данные из скалярного произведения входного вектора на вектор весов, добавив смещение и получив логит, а затем применив функцию активации. Это кажется тривиальным, но представление нейронов в виде ряда векторных операций очень важно: только в таком формате их используют в программировании.

Выражение линейных персептронов в виде нейронов

Выше мы говорили об использовании моделей машинного обучения для определения зависимости между результатом на экзаменах и временем, потраченным на обучение и сон. Для решения задачи мы создали линейный классификатор-персептрон, который делит плоскость декартовых координат надвое:

Рис.10 Основы глубокого обучения

Как показано на рис. 1.4, это оптимальный вариант для : он позволяет корректно классифицировать все примеры в нашем наборе данных. Здесь мы видим, что наша модель h работает по образцу нейрона. Посмотрите на нейрон на рис. 1.8. У него два входных значения, смещение, и он использует функцию:

Рис.11 Основы глубокого обучения
Рис.12 Основы глубокого обучения

Рис. 1.8. Выражение результатов экзамена в виде нейрона

Легко показать, что линейный персептрон и нейронная модель полностью эквивалентны. И просто продемонстрировать, что одиночные нейроны более выразительны, чем линейные персептроны. Каждый из них может быть выражен в виде одиночного нейрона, но последние могут также отражать модели, которые нельзя выразить с помощью линейного персептрона.

Нейросети с прямым распространением сигнала

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

Нейроны в человеческом мозге расположены слоями. Его кора, по большей части отвечающая за интеллект, состоит из шести слоев. Информация перетекает по ним, пока сенсорные данные не преобразуются в концептуальное понимание[7]. Например, самый нижний слой визуальной зоны коры получает необработанные визуальные данные от глаз. Эта информация преобразуется в каждом следующем слое и передается далее, пока на шестом слое мы не заключаем, что видим кошку, банку газировки или самолет. На рис. 1.9 показан упрощенный вариант этих слоев.

Рис.13 Основы глубокого обучения

Рис. 1.9. Простой пример нейросети с прямым распространением сигнала с тремя слоями (входной, скрытый, выходной) и тремя нейронами на каждый слой

На основе этих идей мы можем создать искусственную нейросеть. Она возникает, когда мы начинаем соединять нейроны друг с другом, со входными данными и выходными узлами, которые соответствуют ответам сети на изучаемую задачу. На рис. 1.9 показан простейший пример искусственной нейросети, схожей по архитектуре с той, что была описана в 1943 году в работе Маккаллоу и Питтса. В нижний слой поступают входные данные. Верхний (выходные узлы) вычисляет ответ. Средний слой (слои) нейронов именуется скрытым, и здесь

Рис.14 Основы глубокого обучения
 – вес соединения i-го нейрона в k-м слое с j-м нейроном в (k + 1) – м слое. Эти веса образуют вектор параметров , и, как и ранее, наша способность решать задачи при помощи нейросетей зависит от нахождения оптимальных значений для .

В этом примере соединения устанавливаются только от нижних слоев к верхним. Отсутствуют связи между нейронами одного уровня, нет таких, которые передают данные от высшего слоя к низшему. Подобные нейросети называются сетями с прямым распространением сигнала, и мы начнем с них, потому что их анализировать проще всего. Такой разбор (процесс выбора оптимальных значений для весов) мы предложим в главе 2. Более сложные варианты связей будут рассмотрены в дальнейших главах.

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

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

2. В этом примере у каждого слоя один набор нейронов, но это не необходимое и не рекомендуемое условие. Чаще в скрытых слоях нейронов меньше, чем во входном: так сеть обучается сжатому представлению информации. Например, когда глаза получают «сырые» пиксельные значения, мозг обрабатывает их в рамках границ и контуров. Скрытые слои биологических нейронов мозга заставляют нас искать более качественное представление всего, что мы воспринимаем.

3. Необязательно, чтобы выход каждого нейрона был связан с входами всех нейронов следующего уровня. Выбор связей здесь – искусство, которое приходит с опытом. Этот вопрос мы обсудим детально при изучении примеров нейросетей.

4. Входные и выходные данные – векторные представления. Например, можно изобразить нейросеть, в которой входные данные и конкретные пиксельные значения картинки в режиме RGB представлены в виде вектора (см. рис. 1.3). Последний слой может иметь два нейрона, которые соотносятся с ответом на задачу: [1, 0], если на картинке собака; [0, 1], если кошка; [1, 1], если есть оба животных; [0, 0], если нет ни одного из них.

Заметим, что, как и нейрон, можно математически выразить нейросеть как серию операций с векторами и матрицами. Пусть входные значение i-го слоя сети – вектор x = [x1 x2xn]. Нам надо найти вектор y = [y1 y2 … ym], образованный распространением входных данных по нейронам. Мы можем выразить это как простое умножение матрицы, создав матрицу весов размера n m и вектор смещения размера m. Каждый столбец будет соответствовать нейрону, причем j-й элемент сопоставлен весу соединения с j-м входящим элементом. Иными словами, y = (WTx + b), где функция активации применяется к вектору поэлементно. Эта новая формулировка очень пригодится, когда мы начнем реализовывать эти сети в программах.

Линейные нейроны и их ограничения

Большинство типов нейронов определяются функцией активации f, примененной к логиту logit z. Сначала рассмотрим слои нейронов, которые используют линейную функцию f(z) = az + b. Например, нейрон, который пытается подсчитать стоимость блюда в кафе быстрого обслуживания, будет линейным, a = 1 и b = 0. Используя f(z) = z и веса, эквивалентные стоимости каждого блюда, программа присвоит линейному нейрону на рис. 1.10 определенную тройку из бургеров, картошки и газировки, и он выдаст цену их сочетания.

Рис.15 Основы глубокого обучения

Рис. 1.10. Пример линейного нейрона

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

Нейроны с сигмоидой, гиперболическим тангенсом и усеченные линейные

На практике для вычислений применяются три типа нелинейных нейронов. Первый называется сигмоидным и использует функцию:

Рис.16 Основы глубокого обучения

Интуитивно это означает, что, если логит очень мал, выходные данные логистического нейрона близки к 0. Если логит очень велик – то к 1. Между этими двумя экстремумами нейрон принимает форму буквы S, как на рис. 1.11.

Рис.17 Основы глубокого обучения

Рис. 1.11. Выходные данные сигмоидного нейрона с переменной z

Нейроны гиперболического тангенса (tanh-нейроны) используют похожую S-образную нелинейность, но исходящие значения варьируют не от 0 до 1, а от 1 до 1. Формула для них предсказуемая: f(z) = tanh(z). Отношения между входным значением y и логитом z показаны на рис. 1.12. Когда используются S-образные нелинейности, часто предпочитают tanh-нейроны, а не сигмоидные, поскольку у tanh-нейронов центр находится в 0.

Рис.18 Основы глубокого обучения

Рис. 1.12. Выходные данные tanh-нейрона с переменной z

Еще один тип нелинейности используется нейроном с усеченным линейным преобразованием (ReLU). Здесь задействована функция f(z) = max(0, z), и ее график имеет форму хоккейной клюшки (рис. 1.13).

Рис.19 Основы глубокого обучения

Рис. 1.13. Выходные данные ReLU-нейрона с переменной z

ReLU в последнее время часто выбирается для выполнения многих задач (особенно в системах компьютерного зрения) по ряду причин, несмотря на свои недостатки[8]. Этот вопрос мы рассмотрим в главе 5 вместе со стратегиями борьбы с потенциальными проблемами.

Выходные слои с функцией мягкого максимума

Часто нужно, чтобы выходной вектор был распределением вероятностей по набору взаимоисключающих значений. Допустим, нам нужно создать нейросеть для распознавания рукописных цифр из набора данных MNIST. Каждое значение (от 0 до 9) исключает остальные, но маловероятно, чтобы нам удалось распознать цифры со стопроцентной точностью. Распределение вероятностей поможет понять, насколько мы уверены в своих выводах. Желаемый выходной вектор приобретает такую форму, где

Рис.20 Основы глубокого обучения
:

[p0 p1 p2 p3p9].

Для этого используется особый выходной слой, именуемый слоем с мягким максимумом (softmax). В отличие от других типов, выходные данные нейрона в слое с мягким максимумом зависят от выходных данных всех остальных нейронов в нем. Нам нужно, чтобы сумма всех выходных значений равнялась 1. Приняв zi как логит i-го нейрона с мягким максимумом, мы можем достичь следующей нормализации, задав выходные значения:

Рис.21 Основы глубокого обучения

При сильном предсказании одно из значений вектора будет близко к 1, остальные – к 0. При слабом останется несколько возможных значений, каждое из которых характеризуется своим уровнем вероятности.

Резюме

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

Глава 2. Обучение нейросетей с прямым распространением сигнала

Проблема фастфуда

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

Рис.15 Основы глубокого обучения

Рис. 2.1. Нейрон, который мы хотим обучить решать проблему фастфуда

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

Мы хотим обучить один линейный нейрон решать эту задачу. Как?

Один из вариантов – разумно подбирать примеры для обучения. Для одного обеда купим один бургер, для второго – одну порцию картошки, для третьего – один стакан газировки. В целом разумный подбор примеров – хорошая идея. Многие исследования показывают, что, создав хорошую подборку данных для обучения, вы сможете заметно повысить эффективность нейросети. Но проблема использования только этого подхода в том, что в реальных ситуациях он редко приближает нас к решению. Например, при распознавании изображений аналога ему нет и решения мы не найдем.

Нам нужно найти вариант, который поможет решать задачу в общем случае. Допустим, у нас очень большой набор обучающих примеров. Это позволит нам вычислить, какие выходные значения выдаст нейросеть на i-м примере, при помощи простой формулы. Мы хотим обучить нейрон и подбираем оптимальные веса, чтобы свести к минимуму ошибки при распознавании примеров. Можно сказать, мы хотим свести к минимуму квадратичную ошибку во всех примерах, которые встретим. Формально, если мы знаем, что t(i) – верный ответ на i-й пример, а y(i) – значение, вычисленное нейросетью, мы хотим свести к минимуму значение функции потерь E:

Рис.22 Основы глубокого обучения

Квадратичная ошибка равна 0, когда модель дает корректные предсказания для каждого обучающего примера. Более того, чем ближе E к 0, тем лучше модель. Наша цель – выбрать такой вектор параметров (значения всех весов в этой модели), чтобы E было как можно ближе к 0.

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

Хорошее замечание, но, к сожалению, актуальное не для всех случаев. Мы применяем здесь линейный нейрон, но на практике они используются редко, ведь их способности к обучению ограничены. А когда мы начинаем использовать нелинейные нейроны – сигмоиду, tanh или усеченный линейный, о которых мы говорили в конце предыдущей главы, – мы не можем задать систему уравнений! Так что для обучения явно нужна стратегия получше[9].

Градиентный спуск

Визуализируем для упрощенного случая то, как свести к минимуму квадратичную ошибку по всем обучающим примерам. Допустим, у линейного нейрона есть только два входа (и соответственно только два веса – w1 и w2). Мы можем представить себе трехмерное пространство, в котором горизонтальные измерения соответствуют w1 и w2, а вертикальное – значению функции потерь E. В нем точки на горизонтальной поверхности сопоставлены разным значениям весов, а высота в них – допущенной ошибке. Если рассмотреть все ошибки для всех возможных весов, мы получим в этом трехмерном пространстве фигуру, напоминающую миску (рис. 2.2).

Рис.23 Основы глубокого обучения

Рис. 2.2. Квадратичная поверхность ошибки для линейного нейрона

Эту поверхность удобно визуализировать как набор эллиптических контуров, где минимальная ошибка расположена в центре эллипсов. Тогда мы будем работать с двумерным пространством, где измерения соответствуют весам. Контуры сопоставлены значениям w1 и w2, которые дают одно и то же E. Чем ближе они друг к другу, тем круче уклон. Направление самого крутого уклона всегда перпендикулярно контурам. Его можно выразить в виде вектора, называемого градиентом.

Пора разработать высокоуровневую стратегию нахождения значений весов, которые сведут к минимуму функцию потерь. Допустим, мы случайным образом инициализируем веса сети, оказавшись где-то на горизонтальной поверхности. Оценив градиент в текущей позиции, мы можем найти направление самого крутого спуска и сделать шаг в нем. Теперь мы на новой позиции, которая ближе к минимуму, чем предыдущая. Мы проводим переоценку направления самого крутого спуска, взяв градиент, и делаем шаг в новом направлении. Как показано на рис. 2.3, следование этой стратегии со временем приведет нас к точке минимальной ошибки. Этот алгоритм известен как градиентный спуск, и мы будем использовать его для решения проблемы обучения отдельных нейронов и целых сетей[10].

Рис.24 Основы глубокого обучения

Рис. 2.3. Визуализация поверхности ошибок как набора контуров

Дельта-правило и темп обучения

Прежде чем вывести точный алгоритм обучения фастфудного нейрона, поговорим о гиперпараметрах. Помимо весов, определенных в нашей нейросети, обучающим алгоритмам нужен ряд дополнительных параметров. Один из этих гиперпараметров – темп обучения.

На каждом шаге движения перпендикулярно контуру нам нужно решать, как далеко мы хотим зайти, прежде чем заново вычислять направление. Это расстояние зависит от крутизны поверхности. Почему? Чем ближе мы к минимуму, тем короче должны быть шаги. Мы понимаем, что близки к минимуму, поскольку поверхность намного более плоская и крутизну мы используем как индикатор степени близости к этому минимуму. Но если поверхность ошибки рыхлая, процесс может занять много времени. Поэтому часто стоит умножить градиент на масштабирующий коэффициент – темп обучения. Его выбор – сложная задача (рис. 2.4).

Рис.25 Основы глубокого обучения

Рис. 2.4. Если темп обучения слишком велик, возникают проблемы со сходимостью

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

Теперь мы готовы вывести дельта-правило для обучения линейного нейрона. Чтобы вычислить, как изменять каждый вес, мы оцениваем градиент: по сути, частную производную функции потерь по каждому из весов. Иными словами, нам нужен такой результат:

Рис.26 Основы глубокого обучения

Применяя этот метод изменения весов при каждой итерации, мы получаем возможность использовать градиентный спуск.

Градиентный спуск с сигмоидными нейронами

В этом и следующем разделах мы будем говорить об обучении нейронов и нейросетей, использующих нелинейности. В качестве образца возьмем сигмоидный нейрон, а расчеты для других нелинейных нейронов оставим читателям как упражнение. Для простоты предположим, что нейроны не используют смещение, хотя наш анализ вполне можно распространить и на такой случай. Допустим, смещение – вес входа, на который всегда подается 1.

Напомним механизм, с помощью которого логистические нейроны вычисляют выходные значения на основе входных:

Рис.27 Основы глубокого обучения

Нейрон определяет взвешенную сумму входящих значений – логит z. Затем он передает этот логит в нелинейную функцию для вычисления выходного значения y. К счастью для нас, эти функции имеют очень красивые производные, что значительно упрощает дело! Для обучения нужно вычислить градиент функции потерь по весам. Возьмем производную логита по входным значениям и весам:

Рис.28 Основы глубокого обучения

Кроме того, как ни удивительно, производная выходного значения по логиту проста, если выразить ее через выходное значение:

Рис.29 Основы глубокого обучения

Теперь можно использовать правило дифференцирования сложной функции, чтобы вычислить производную выходного значения по каждому из весов:

Рис.30 Основы глубокого обучения

Объединяя полученные результаты, мы можем вычислить производную функции потерь по каждому весу:

Рис.31 Основы глубокого обучения

Итоговое правило изменения весов будет выглядеть так:

Рис.32 Основы глубокого обучения

Как вы видите, новое правило очень похоже на дельта-правило, за исключением дополнительных множителей для учета логистического компонента сигмоидного нейрона.

Алгоритм обратного распространения ошибок

Теперь мы готовы приступить к проблеме обучения многослойных нейросетей, а не только одиночных нейронов. Обратимся к подходу обратного распространения ошибок, предложенному Дэвидом Румельхартом, Джеффри Хинтоном и Рональдом Уильямсом в 1986 году[11]. В чем основная идея? Мы не знаем, что делают скрытые нейроны, но можем вычислить, насколько быстро меняется ошибка, если мы вносим корректировки в эти процессы. На основе этого мы способны определить, как быстро трансформируется ошибка, если изменить вес конкретного соединения. По сути, мы пытаемся найти наибольший уклон! Единственная сложность в том, что приходится работать в пространстве с очень большим числом измерений. Начнем с вычисления производных функции потерь по одному обучающему примеру.

Каждый скрытый нейрон может влиять на многие выходные нейроны. Нам нужно учесть несколько эффектов ошибки, чтобы получить нужную информацию. В качестве стратегии выберем динамическое программирование. Получив производные функций потерь для одного слоя скрытых нейронов, мы применим их для вычисления производных функций потерь на выходе более низкого слоя. Когда мы найдем такие производные на выходе из скрытых нейронов, несложно будет получить производные функций потерь для весов входов в скрытый нейрон. Для упрощения введем дополнительные обозначения (рис. 2.5).

Рис.33 Основы глубокого обучения

Рис. 2.5. Справочная диаграмма для вывода алгоритма обратного распространения ошибок

Нижний индекс будет обозначать слой нейронов; символ y – как обычно, выходное значение нейрона, а z – логит нейрона. Начнем с базового случая проблемы динамического программирования: вычислим производные функции потерь на выходном слое (output).

Рис.34 Основы глубокого обучения

Теперь сделаем индуктивный шаг. Предположим, у нас есть производные функции потерь для слоя j. Мы собираемся вычислить производные функции потерь для более низкого слоя i. Для этого необходима информация о том, как выходные данные нейрона в слое i воздействуют на логиты всех нейронов в слое j. Вот как это сделать, используя то, что частная производная логита по входящим значениям более низкого слоя – это вес соединения wij:

Рис.35 Основы глубокого обучения

Далее мы видим следующее:

Рис.36 Основы глубокого обучения

Сведя эти факты воедино, мы можем выразить производные функций потерь слоя i через производные функций потерь слоя j:

Рис.37 Основы глубокого обучения

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

Рис.38 Основы глубокого обучения

Наконец, чтобы завершить алгоритм, как и раньше, мы суммируем частные производные по всем примерам в нашем наборе данных (dataset). Это дает нам следующую формулу изменения:

Рис.39 Основы глубокого обучения

На этом описание алгоритма обратного распространения ошибок закончено!

Стохастический и мини-пакетный градиентный спуск

В алгоритмах, описанных в предыдущем разделе, мы использовали так называемый пакетный градиентный спуск. Идея в том, что мы при помощи всего набора данных вычисляем поверхность ошибки, а затем следуем градиенту, определяем самый крутой уклон и движемся в этом направлении. Для поверхности простой квадратичной ошибки это неплохой вариант. Но в большинстве случаев поверхность гораздо сложнее. Для примера рассмотрим рис. 2.6.

Рис.40 Основы глубокого обучения

Рис. 2.6. Пакетный градиентный спуск чувствителен к седловым точкам, что может привести к преждевременному схождению

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

Другой возможный подход – стохастический градиентный спуск (СГС). При каждой итерации поверхность ошибки оценивается только для одного примера. Этот подход проиллюстрирован на рис. 2.7, где поверхность ошибки не единая статичная, а динамическая. Спуск по ней существенно улучшает нашу способность выходить из плоских областей.

Рис.41 Основы глубокого обучения

Рис. 2.7. Стохастическая поверхность ошибки варьирует по отношению к пакетной, что позволяет решить проблему седловых точек

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

Это, в свою очередь, приводит к тому, что спуск займет слишком много времени. Один из способов решения проблемы – использование мини-пакетного градиентного спуска. При каждой итерации мы вычисляем поверхность ошибки по некой выборке из общего набора данных (а не одному примеру). Это и есть мини-пакет (minibatch), и его размер, как и темп обучения, – гиперпараметр. Мини-пакеты уравновешивают эффективность пакетного градиентного спуска и способность избегать локальных минимумов, которую предоставляет стохастический градиентный спуск. В контексте обратного распространения ошибок изменение весов выглядит так:

Рис.42 Основы глубокого обучения

Это идентично тому, что мы вывели в предыдущем разделе. Но вместо того чтобы суммировать все примеры в наборе данных, мы обобщаем все примеры из текущего мини-пакета.

Переобучение и наборы данных для тестирования и проверки

Одна из главных проблем искусственных нейросетей – чрезвычайная сложность моделей. Рассмотрим сеть, которая получает данные от изображения из базы данных MNIST (2828 пикселов), передает их в два скрытых слоя по 30 нейронов, а затем в слой с мягким максимумом из 10 нейронов. Общее число ее параметров составляет около 25 тысяч. Это может привести к серьезным проблемам. Чтобы понять почему, рассмотрим еще один упрощенный пример (рис. 2.8).

Рис. 2.8. Две модели, которыми может быть описан наш набор данных: линейная и многочлен 12-й степени

У нас есть ряд точек на плоской поверхности, задача – найти кривую, которая наилучшим образом опишет этот набор данных (то есть позволит предсказывать координату y новой точки, зная ее координату x). Используя эти данные, мы обучаем две модели: линейную и многочлен 12-й степени. Какой кривой стоит доверять? Той, которая не попадает почти ни в один обучающий пример? Или сложной, которая проходит через все точки из набора? Кажется, можно доверять линейному варианту, ведь он кажется более естественным. Но на всякий случай добавим данных в наш набор! Результат показан на рис. 2.9.

Рис.44 Основы глубокого обучения

Рис. 2.9. Оценка модели на основе новых данных показывает, что линейная модель работает гораздо лучше, чем многочлен 12-й степени

Вывод очевиден: линейная модель не только субъективно, но и количественно лучше (по показателю квадратичной ошибки). Но это ведет к очень интересному выводу по поводу усвоения информации и оценки моделей машинного обучения. Строя очень сложную модель, легко полностью подогнать ее к обучающему набору данных. Ведь мы даем ей достаточно степеней свободы для искажения, чтобы вписаться в имеющиеся значения. Но когда мы оцениваем такую модель на новых данных, она работает очень плохо, то есть слабо обобщает. Это явление называется переобучением. И это одна из главных сложностей, с которыми вынужден иметь дело инженер по машинному обучению. Нейросети имеют множество слоев с большим числом нейронов, и в области глубокого обучения эта проблема еще значительнее. Количество соединений в моделях составляет миллионы. В результате переобучение – обычное дело (что неудивительно).

Рассмотрим, как это работает в нейросети. Допустим, у нас есть сеть с двумя входными значениями, выходной слой с двумя нейронами с функцией мягкого максимума и скрытый слой с 3, 6 или 20 нейронами. Мы обучаем эти нейросети при помощи мини-пакетного градиентного спуска (размер мини-пакета 10); результаты, визуализированные в ConvNetJS, показаны на рис. 2.10[12].

Рис.45 Основы глубокого обучения

Рис. 2.10. Визуализация нейросетей с 3, 6 и 20 нейронами (в таком порядке) в скрытом слое

Уже из этих изображений очевидно, что с увеличением числа соединений нейросети усиливается тенденция к переобучению. Усугубляется она и с углублением нейросетей. Результаты показаны на рис. 2.11, где используются сети с 1, 2 или 4 скрытыми слоями, в каждом из которых по 3 нейрона.

Рис.46 Основы глубокого обучения

Рис. 2.11. Визуализация нейросетей с 1, 2 и 4 скрытыми слоями (в таком порядке), по 3 нейрона в каждой

Отсюда следуют три основных вывода. Во-первых, инженер по машинному обучению всегда вынужден искать компромисс между переобучением и сложностью модели. Если модель недостаточно сложна, она может оказаться недостаточно мощной для извлечения всей полезной информации, необходимой для решения задачи. Но если она слишком сложна (особенно когда у нас есть ограниченный набор данных), высока вероятность, что понадобится переобучение. Глубокое обучение связано с решением очень сложных задач при помощи сложных моделей, поэтому необходимо принимать дополнительные меры против возможного переобучения. О многих из них мы будем говорить в этой главе, а также в следующих.

Во-вторых, неприемлемо оценивать модель на основе данных, с помощью которых мы ее обучали. Так, пример на рис. 2.8 дает ошибочное представление о том, что модель многочлена 12-й степени лучше линейной. В результате мы почти никогда не обучаем модель на полном наборе данных. Как показано на рис. 2.12, мы делим данные на наборы для обучения и тестирования.

Рис.47 Основы глубокого обучения

Рис. 2.12. Мы часто делим данные на несовпадающие наборы для обучения и тестирования, чтобы дать справедливую оценку нашей модели

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

В-третьих, вероятно, наступит момент, когда модель вместо исследования полезных признаков начнет переобучаться. Чтобы этого избежать, нужно предусмотреть немедленное завершение процесса при переобучении, что позволит избежать некорректных обобщений. Для этого тренировочный процесс делится на эпохи. Эпоха – одна итерация обучения на всем наборе. Если у нас есть набор размера d и мы проводим мини-пакетный градиентный спуск с размером пакета b, эпоха будет эквивалентна d/b обновлений. В конце каждой эпохи нужно измерить, насколько успешно наша модель обобщает. Для этого мы вводим дополнительный проверочный набор, показанный на рис. 2.13. В конце эпохи он покажет нам, как модель будет работать с еще не известными ей данными. Если точность на обучающем наборе будет возрастать, а для проверочного останется прежней или ухудшится, пора прекратить процесс: началось переобучение.

Рис.48 Основы глубокого обучения

Рис. 2.13. В глубоком обучении часто используется проверочный набор, препятствующий переобучению

Читать бесплатно другие книги:

Майлз Роби двадцать лет готовит бургеры в “Имперском гриле”, эта работа стоила ему высшего образован...
Шаол Эстфол, капитан королевской гвардии Адарлана и ближайший друг Селены Сардотин, в битве с демона...
С тех пор как открылась академия «Пандемониум», жители Клыково потеряли покой. Странные происшествия...
Отпуск в Черногории, что может быть лучше или хуже, вот вам и предстоит разобраться в этом вопросе!...
ПАМЯРКОТЫ — это небольшие смешные, иронические, сатирические рассказы в стихотворной форме. А с учет...
Говорят, волки любят только один раз в жизни. Их любовь - это звериная одержимость, подчиняющая себе...