Продолжение обзоров важнейших понятий глубокого обучения

Обзор обучения методом временных разниц

Здравствуйте и вновь добро пожаловать на занятия по теме «Глубокое обучение с подкреплением: глубокое обучение на языке Python, часть 7».

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

Обучение методом временных разниц является уникальным в обучении с подкреплением. Тогда как в методе Монте-Карло мы должны собирать отдачи на основе эпизода, в обучении методом временных разниц мы оцениваем отдачи, основываясь на нашей текущей оценке функции ценности. Конкретно говоря, мы рассматривали так называемый метод TD(0). Таким образом, вместо того, чтобы использовать выборку отдач G, мы используем r + γV(s’), что даёт оценку отдачи от следующего состояния и дальше. r по-прежнему является выборкой, полученной из проигрывания эпизода.

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

Это выражение полезно не только потому, что позволяет эффективно использовать место, поскольку нам приходится хранить только одно значение за раз, но и потому, что очень схоже на градиентный спуск. На самом деле в предыдущем курсе по обучению с подкреплением мы показали, что это действительно и есть частный случай градиентного спуска. Ключевым здесь является то, что коэффициент обучения не обязательно должен быть равен 1/t; он может быть любым. Обычно для него используется символ α:

Это возвращает нас к TD(0). Не забывайте, что вместо сбора отдач G мы оцениваем G, используя текущее вознаграждение и ценность следующего состояния. Одним из очевидных преимуществ этого является то, что мы получаем поистине оперативное обучение: нам нужно только дождаться времени t + 1, чтобы обновить ценность состояния в момент t:

Это возвращает нас к TD(0). Не забывайте, что вместо сбора отдач G мы оцениваем G, используя текущее вознаграждение и ценность следующего состояния. Одним из очевидных преимуществ этого является то, что мы получаем поистине оперативное обучение: нам нужно только дождаться времени t + 1, чтобы обновить ценность состояния в момент t:

Это противоположно методу Монте-Карло, в котором мы должны ждать, пока не закончится весь эпизод, прежде чем сможем вычислить отдачи и обновить ценности. Это особенно полезно для очень длинных эпизодов и неэпизодических задач. Это значит, что мы можем обучаться во время эпизода, а не ждать, пока он закончится.

Что касается проблемы управления, то мы рассмотрели два разных, но очень схожих алгоритма. Первый из рассмотренных алгоритмов называется SARSA. По сути, это итерация по стратегиям, применённая к обучению методом временных разниц. SARSA же он называется потому, что в уравнении используется пара последнее состояние – действие, вознаграждение и пара следующее состояние – действие:

Основная идея заключается в том, что действие всегда выбирается на основе текущей функции ценности, что, как мы знаем, является этапом совершенствования стратегии. Рассмотрим псевдокод, чтобы закрепить эту идею:

Q(s,a) = произвольное, Q(конечное, a) = 0

for t=1..N

    s = начальное_состояние, a = эпсилон_жадное_от(Q(s))

    while not конец игры:

        s’, r = выполнить_действие(a)

        a’ = a = эпсилон_жадное_от(Q(s’))

        Q(s,a) = Q(s,a) + alpha*[r + gamma* Q(s’,a’) – Q(s,a)]

        s = s’, a = a’

Вначале мы произвольным образом инициируем Q и нуль для любого конечного состояния. Затем мы входим в бесконечный цикл. Внутри цикла мы начинаем игру, получаем первое состояние и выбираем первое действие, основываясь на эпсилон-жадном алгоритме и текущем Q. Это называется кортежем (s, a). Внутри цикла запускается другой цикл, заканчивающийся при окончании эпизода. Мы выполняем действие a, чтобы получить следующее состояние s и вознаграждение r. После этого выбираем следующее действие на основе эпсилон-жадного алгоритма и текущего Q. Это действие a. Далее идёт обновление Q(s, a), которое зависит от Q(s, a), r и Q(s’, a’). И напоследок мы обновляем s до s и a до a.

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

Разница тут в том, что теперь отдача оценивается на основе максимума Q по всем возможным следующим действиям. Другими словами, не важно, какое действие будет предпринято следующим, поскольку мы берём максимум по всем из них, чтобы обновить Q(s, a).

Обзор методов приближений для обучения с подкреплением

Мы изучали динамическое программирование, метод Монте-Карло и обучение методом временных разниц в контексте табличных методов. Другими словами, мы рассматривали V и Q как словари, индексированные по состоянию и действию. Это хорошо работает, но только для самых маленьких задач, и не сработает для игр с миллиардами или триллионами состояний и, естественно, не сработает для игр с бесконечным количеством состояний. Именно здесь методы приближений и выходят на первый план.

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

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

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

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

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

Как вы уже знаете, градиентный спуск принимает следующую форму, а параметр, который мы обновляем, – это θ:

В общем случае θ может быть параметром нейронной сети и можно применять все методы, которые мы знаем из нейронных сетей, включая пакетный градиентный спуск, использование импульса для ускорения градиентного спуска, использование исключения и других типов регуляризации и так далее. И, конечно же, поскольку градиент может оказаться довольно-таки сложным, мы не хотим вычислять его самостоятельно, а используем библиотеки вроде Theano и Tensorflow для автоматического дифференцирования.

Обзор глубокого обучения

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

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

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

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

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

Работа с изображениями очень важна. Для человека это один из основных органов чувств, а для робота, пытающегося перемещаться в реальном мире, изображения также будут одним из основных органов восприятия. Кроме того, изображения – это то, из чего складывается состояние в видеоиграх, так что мы должны знать, как работать с изображениями, чтобы обучить агентов, способных играть в игры Atari в OpenAI Gym.

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

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

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

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

Как правило, мы думаем не с точки зрения отдельных рекуррентных связей, а, скорее, целых рекуррентных слоёв. В своём курсе по рекуррентным нейронным сетям я учил, что мы рассматриваем эти слои как «чёрные ящики» – о рекуррентных слоях полезно думать как просто о ящике, который принимает входные данные и производит некоторые выходные. То обстоятельство, что выходные данные зависят от предыдущих входных, означает, что «ящик» имеет «память» о том, что он «видел» в прошлом. Это особенно важно в контексте обучения с подкреплением, поскольку позволяет нам принимать решения не только на основе того, что мы видим сейчас, но и того, что мы видели в предыдущем кадре.

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

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

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

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

Работа с изображениями очень важна. Для человека это один из основных органов чувств, а для робота, пытающегося перемещаться в реальном мире, изображения также будут одним из основных органов восприятия. Кроме того, изображения – это то, из чего складывается состояние в видеоиграх, так что мы должны знать, как работать с изображениями, чтобы обучить агентов, способных играть в игры Atari в OpenAI Gym.

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

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

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

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

Как правило, мы думаем не с точки зрения отдельных рекуррентных связей, а, скорее, целых рекуррентных слоёв. В своём курсе по рекуррентным нейронным сетям я учил, что мы рассматриваем эти слои как «чёрные ящики» – о рекуррентных слоях полезно думать как просто о ящике, который принимает входные данные и производит некоторые выходные. То обстоятельство, что выходные данные зависят от предыдущих входных, означает, что «ящик» имеет «память» о том, что он «видел» в прошлом. Это особенно важно в контексте обучения с подкреплением, поскольку позволяет нам принимать решения не только на основе того, что мы видим сейчас, но и того, что мы видели в предыдущем кадре.

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

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

Андрей Никитенко
Андрей Никитенко
Задать вопрос эксперту
Понравилась статья? Поделить с друзьями:
Добавить комментарий

;-) :| :x :twisted: :smile: :shock: :sad: :roll: :razz: :oops: :o :mrgreen: :lol: :idea: :grin: :evil: :cry: :cool: :arrow: :???: :?: :!: