Как понять нейронные сети? Часть 1

от автора

Предуведомления

Я обещал в предыдущей публикации в этом блоге, что напишу про еще одну книжку, которую перевел в конце прошлого года для того же издательства «Бомбора». Книжка довольно увесистая, 526 страниц, называется «Understanding Deep Learning». Автор Simon J.D. Prince. — ученый, исследователь, почетный профессор Университета Бата (University of Bath). Он был руководителем проектов в двух компаниях, известных на рынке ИИ‑продуктов: Anthropics Technology Ltd и RBC Borealis. В 2012 году вышла его первая книга «Computer Vision. Models, Learning, and Inference», которая выдержала четыре издания, была переведена на китайский и продалась в количестве более десяти тысяч экземпляров (для научного издания это много).

Как и в обзоре предыдущей книги, хочу сделать оговорку, что делаю его не как специалист по ИИ, а как читатель с базовой подготовкой в ИТ и прикладной математике в объеме технического университета по специальности «Автоматизированные системы управления» и аспирантуры по методам стохастической фильтрации (фильтр Калмана) для гироскопических и навигационных систем. То есть я хочу поделиться своим читательским опытом с теми, кто, как и я, хочет понять что происходит в отрасли ИИ и получить начальные, но не совсем уж популярные сведения по архитектуре и математическим моделям нейронных сетей.

Свой перевод я сдал в издательство с рабочим заглавием «Понимание глубокого обучения», которое, скорее всего, поменяется. Во‑первых, названия всегда придумывает отдел маркетинга, а во‑вторых, в предисловии автор пишет, что в названии книги содержится некоторая шутка или горькая ирония, потому что на момент написания книги (оригинал вышел в 2023 году) никто не понимал глубокого обучения. На Хабре очень много публикаций по этой теме, и, мне кажется, что читатели этого сайта в большинстве своем знакомы как минимум с основами, но все же рискну уточнить термины. “Глубокое обучение” — это сокращение от “обучение глубоких нейронных сетей”. Во-первых, удобнее при изложении, а во-вторых есть преемственность с названием охватывающей области исследований — машинного обучения, которое много лет развивалось без использования нейронных сетей, а теперь успешность их применения и бурный рост исследований и продуктов на их базе настолько превзошли все другие подходы, что многими термины “машинное обучение” и “глубокое обучение” воспринимаются как синонимы, хотя это пока еще не так.

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

Автор во введении ссылается на другие подобные книги, которые неизбежно выходят регулярно каждые несколько лет. Для удобства читателей они самодостаточны, изложение начинается с самых основ и продолжается до описания последних полученных результатов. Через несколько лет кто-то должен проделать эту работу заново, чтобы написать новую актуальную монографию. Так, автор считает свою книгу идейной наследницей книги “Deep Learning” (Goodfellow et al., 2016) («Глубокое обучение» (Гудфелоу и др., 2016) (ДМК, Москва, 2018), в которую вошли результаты до 2016 года, а также рекомендует более широкое, буквально энциклопедическое издание «Probabilistic Machine Learning» (Murphy, 2022,2023) (Кевин Мэрфи “Вероятностное машинное обучение”, ДМК, М, 2022)

Структура книги

Начинается все вполне невинно, в первой главе нам объясняют на примерах с картинками постановку задачи машинного обучения в трех основных разделах — обучения с учителем (инструктором) (supervised learning), обучения без учителя (unsupervised learning) и обучения с подкреплением (reinforcement learning).

Структура книги организована соответственно, в главах со второй по девятую подробно разбирается технологические процесс обучения с учителем. В главах 10-13 представлены основные типы архитектур нейронных сетей, которые используются во всех трех типах обучения. Главы с14 по 18 посвящены обучению без учителя, и только одна девятнадцатая глава представляет обучение с подкреплением. Самой интересной для меня была глава 20, которая называется “Почему глубокое обучение работает?” (так и хотелось добавить от себя “черт побери”).

История появления глубокого обучения нетипична для науки. Упорство небольшой группы ученых, работавших в течение более двадцати пяти лет в, казалось бы, ничего не сулившей области, привело к революции всей отрасли и разительному воздействию на общество. Обычно, когда исследователи изучают эзотерический и, очевидно, непрактичный уголок науки или инженерного дела, он таким и остается — эзотерическим и непрактичным. Однако, этот случай стал заметным исключением из правил. Несмотря на повсеместный скептицизм, систематические усилия Йошуа Бенжио, Джеффри Хинтона, Яна Лекуна и других в итоге принесли результат.

Напомню, что в этом году Джеффри Хинтон получил вместе с Джоном Хопфилдом Нобелевскую премию по… физике! Базовое образование Хинтона — экспериментальная психология, докторская степень — за исследования в области искусственного интеллекта. В 2018 году вместе с Бенжио и Лекуном получил премию Тьюринга, которую иногда называют “нобелевкой в области вычислений”. Праправнук Джона Буля, между прочим. Того самого, который “булева алгебра”, “булева функция” ну и все исчисление высказываний впридачу.

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

Автор создал и активно поддерживает на GitHub страницу, посвященную этой книге. Там можно найти Python Notebooks для каждого вычисления, описанного в книге. Мне самому на Питоне раньше программировать не приходилось (когда я уже закончил работать руками, Питона еще не было), поэтому я прошел два учебных курса  по Питону в обучающей программе Sololearn, чтобы понимать, что в этих блокнотах написано. Для тех, кто программирует на Питоне, эти блокноты будут не менее, если не более ценны, чем текст книги. Кстати pdf с полным текстом книги доступен на том же сайте. А если кто-то собирается в ближайшее время читать курс по глубокому обучения, на том же сайте есть обширный набор презентаций для инструкторов, а также все иллюстрации из книги в svg, pdf и pptx. А еще — обзоры, интервью, подкасты, чего там только нет. А еще — обширный список дальнейшего чтения, включающий множество самоучителей с сайта компании Borealis, с которой автор сотрудничал. Но и это еще не все! Совсем недавно, в августе этого года (я это обнаружил уже во время написания этого обзора) автор добавил дюжину иллюстраций (графиков) из книги, сделав их интерактивными. Можно играть с движками, задающими значения параметров, или перемещать точку по поверхности и смотреть, как меняются графики функций.

Одним словом, если читатель этого обзора владеет английским языком хотя бы на уровне профессионального программистского, можно в этом месте перестать читать мой пересвист, а переходить прямо на сайт GitHub: https://udlbook.github.io/udlbook/. Несмотря на то, что автор сделал текст книги общественным достоянием, я пока не могу выложить текст моего перевода, поскольку права на него я по договору передал издательству. Если издательство “Бомбора” откажется от идеи публикации этой книги, я буду думать о том, чтобы потратить время на верстку перевода (технически довольно сложную, для меня по крайней мере) и выложить на том же GitHub перевод. Но это пока прекрасные мечтания.

Пока же перейдем к обзору содержания книги.

Это всего лишь линейная регрессия

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

  • построить параметрическую модель, отображающую входные данные в выходные, 

  • подобрать ее параметры наилучшим в каком-то смысле образом (обучить модель),

  • проверить на тестовых данных, насколько хорошо модель работает, то есть предсказывает выходные данные по входным.

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

Упомяну здесь об одном тонком различии между американским и британским английским, о котором иногда забывают. В британском английском можно сказать learn не только в смысле выучить что-то или научиться чему-то. Англичанин может сказать learn в смысле научить кого-то или что-то, то есть в смысле teach. Это было одной из трудностей перевода.

В любом случае, train мы модель или learn, мы просто занимаемся подстройкой параметров модели для получения наилучших результатов. Качество подстройки (обучения) измеряется функцией потерь, в случае с линейной регрессией — просто суммой квадратов отклонения опытных данных от предсказаний модели. 

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

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

Неглубокие нейронные сети

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

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

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

Приведу ответ моего знакомого математика в том виде, в каком я его получил — последовательности реплик (поскольку разговор происходил в мессинджере):

— Надо прибавить «непрерывную» и лучше написать равномерно аппроксимировать. И ещё для простоты «на отрезке”.

— Кто это сказал мне неизвестно. Мог кто угодно сказать, Вейерштрасс (1815-1897) мог.

— Это несложное, но важное вспомогательное утверждение. Педагогически можно квалифицировать как упражнение.

— Но буквально кто угодно мог сказать, я это в школе учась придумал (как и мои одноклассники).

— Например, как построить счетное всюду плотное множество в пространстве непрерывных функций на отрезке? Взять кусочно-линейные непрерывные.

— С изломами графика в рациональных точках надо прибавить.
— Без сомнений сто лет назад оно имело статус упражнения. 200 лет назад неясно, равномерная непрерывность и сходимость это вроде Вейерштрасс, хотя что могло Коши (1789-1857) помешать — неясно.

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

На меня этот монолог произвел большое впечатление, из него можно что-то понять о том, как думают математики.

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

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

Зато тут очень пригодилась простая исследовательская визуальная метафора — изображать входные и выходные переменные, а также элементы преобразования просто кружочками со стрелочками. Каждую связку между входной переменной, элементом преобразования и выходной переменной назвали искусственным нейроном из-за отдаленного сходства с биологическими нейронами — элементарными клетками нервной системы живых существ. Можно еще и дальше спекулировать на тему этого сходства, находя аналоги между элементами искусственных и биологических нейронов, искать на рисунках дендриты и аксоны, но это упражнение мало что дает для дальнейшего понимания работы нейронных сетей. Единственный термин, который реально объясняет механизмы работы и биологического, и математического объектов –– это propagation. В биологии по-русски это называют проведением электрического возбуждения биологического нейрона, а в математике чаще называют распространением, например, распространением ограничений (constraint propagation). На этом лирическое отступление о сходстве биологических и искусственных нейронов заканчивается, тем более, что в книжке об этом даже не упоминается, насколько я помню.

Элементы (кусочки) преобразования стали называть скрытыми элементами (hidden units — не самое удачное название, на мой взгляд), а набор таких скрытых элементов, преобразующих одни и те же входы в одни и те же выходы (грубо говоря) — слоем нейронной сети. Из определения понятно, что у неглубокой сети только один слой, а если их больше одного, сеть становится глубокой.

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

Слой входных переменных, слой скрытых элементов и слой выходных элементов.

Слой входных переменных, слой скрытых элементов и слой выходных элементов.

Более развернутое определение выглядит так.

Неглубокие нейронные сети обладают одним скрытым слоем. Они (i) вычисляют несколько линейных функций от входа, (ii) пропускают каждый результат через функцию активации, а затем (iii) берут линейную комбинацию этих активаций, чтобы образовать выходы. Неглубокие нейронные сети делают предсказание значения y, базируясь на значениях x, разбивая пространство входов на непрерывную последовательность кусочно-линейных областей. При достаточном количестве скрытых элементов (нейронов) неглубокие нейронные сети могут аппроксимировать любую непрерывную функцию с заданной точностью.

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

Глубокие нейронные сети

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

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

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

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

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

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

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

Сразу возникает вопрос — а хорошо ли это? Отвечая на это вопрос, автор высказывается не вполне для меня понятно, но я постарался передать то, что я понял.

Глубокие сети могут создавать крайне большое количество линейных областей, но они содержат сложные зависимости и симметрии.Мы видели некоторые из них, когда рассматривали глубокие сети как «складки» пространства входов (рисунок 4.3). Таким образом, не вполне очевидно, что большее число областей является преимуществом, если только не (i) существуют сходные симметрии в функциях реального мира, которые мы хотим аппроксимировать или (ii) у нас есть причины верить, что отображение входов в выходы действительно включает композицию более простых функций.

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

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

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

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

Математика глубоких сетей

Ну, что ж, после этого плавного введения в основные понятия глубоких нейронных сетей все должно пойти пободрее. Поскольку обучение (подгонка) моделей сводится к поиску оптимума функции потерь, в пятой главе понятие функции потерь внезапно обобщается на стохастический случай, когда модель не вычисляет прямо значение выходных переменных, а вычисляет условное распределение вероятностей Pr(y|x) возможных значений выхода. При этом стохастическая природа объекта, который мы моделируем никак не обсуждается, а просто вбрасывается. Поэтому читатель вдруг обнаруживает себя в мире теории вероятностей и матстатистики и не сразу понимает, что уже навсегда. Для легкого понимания дальнейшего полезно прочитать или просмотреть приложение С, в котором приводятся все необходимые определения и формулы для распределения вероятностей, совместного распределения, условного распределения, правдоподобия и теоремы Байеса, куда ж без нее. Для меня с моим аспирантским курсом теории вероятности и матстатистики новыми были сведения о вычислении расстояний между распределениями, в том числе, между нормальными распределениями (метрики Кульбака-Ляйблера, Йенсена-Шеннона и Фреше, причем первую и третью в русской литературе называют расстояниями, а вторую почему-то дивергенций, загадко).

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

Следующие две главы — это вполне школьный учебный материал по вычислительным методам оптимизации функции многих переменных (правдоподобия параметров многопараметрической модели). Оказалось, что с тех пор, как нам в институте читали курс методов оптимизации, не так уж много нового придумали. По-прежнему рулит градиентный спуск, придуманный Коши еще в 1847 году, ну или, если пускаться во все тяжкие, стохастический градиентный спуск, предложенный в 1951. Идея использования импульса для ускорения спуска была предложена еще в 1964 году. В 1983 году Юрий Нестеров придумал метод ускоренного импульса, его применили к задачам ИИ аж в 2013 году, тридцать лет спустя. Относительно новая группа методов — это адаптивное обучение, начиная с AdaGrad (2011) и вплоть до метода адаптивной оптимизации импульса Adam (2015), который оказался широко применим, несмотря на некоторые проблемные ситуации, в которых его пришлось дорабатывать.

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

Вывод Саттон делает такой: закон Мура об экспоненциальном падении стоимости вычислений в очередной раз победил человеческий разум. Все попытки применения человеческих знаний проигрывают вычислительным методам, полагающимся на “грубую силу” и неудержимо растущую мощность вычислителей. Придумав графические (ко)процессоры человечество открыло ящик Пандоры (again) и теперь ИИ пожинает плоды.

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

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

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

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

Первые необъяснимые результаты

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

… продолжение следует


ссылка на оригинал статьи https://habr.com/ru/articles/862332/


Комментарии

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *