Разное

Пример нейронной сети: Нейронные сети: практическое применение / Хабр

Содержание

Нейронные сети: практическое применение / Хабр

Наталия Ефремова погружает публику в специфику практического использования нейросетей. Это — расшифровка доклада Highload++.

Добрый день, меня зовут Наталия Ефремова, и я research scientist в компании NtechLab. Сегодня я буду рассказывать про виды нейронных сетей и их применение.

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

Первая часть моего доклада будет направлена тем, кто незнаком с нейронными сетями. Я занимаюсь непосредственно deep learning. В этой области я работаю более 10 лет. Хотя она появилась чуть меньше, чем десятилетие назад, раньше были некие зачатки нейронных сетей, которые были похожи на систему deep learning.


В последние 10 лет deep learning и компьютерное зрение развивались неимоверными темпами. Все, что сделано значимого в этой области, произошло в последние лет 6.

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

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

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

Итак, первая часть доклада будет посвящена сверточным нейронным сетям. Я расскажу, как работают convolutional neural network (CNN), распознавание изображений на примере из распознавания лиц. Немного расскажу про рекуррентные нейронные сети recurrent neural network (RNN) и обучение с подкреплением на примере систем deep learning.

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

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

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

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

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

В далекие 60-е годы прошлого века, когда только начиналось изучение зрительных зон мозга, первые эксперименты проводились на животных, потому что не было fMRI. Исследовали мозг с помощью электродов, вживлённых в различные зрительные зоны.

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

Таким же способом были открыты еще многие важные свойства зрительных зон, которые мы используем в deep learning сейчас. Одно из важнейших свойств — это увеличение рецептивных полей наших клеток по мере продвижения от первичных зрительных зон к височным долям, то есть более поздним зрительным зонам. Рецептивное поле — это та часть изображения, которую обрабатывает каждая клеточка нашего мозга. У каждой клетки своё рецептивное поле. Это же свойство сохраняется и в нейронных сетях, как вы, наверное, все знаете.

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

Здесь вы видите примеры сложности стимулов, различных двухмерных форм, которые распознаются в зонах V2, V4 и различных частях височных полей у макак. Также проводятся некоторое количество экспериментов на МРТ.

Здесь вы видите, как проводятся такие эксперименты. Это 1 нанометровая часть зон IT cortex’a мартышки при распознавании различных объектов. Подсвечено то, где распознается.

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

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

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

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

Простейший перцептрон способен выполнять только самые простые операции. Для того, чтобы выполнять более сложные вычисления, нам нужна структура с большим количеством скрытых слоёв.

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

Итак, что происходит при распознавании изображения, я расскажу на примере лиц.

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

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

Сейчас это происходит не так. Мы разбиваем наше изображение либо на пиксели, либо на некие патчи: 2х2, 3х3, 5х5, 11х11 пикселей — как удобно создателям системы, в которой они служат входным слоем в нейронную сеть.

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

Условно все эти части можно разделить на три класса, мы их обозначим X, W и Y, где Х — это наше входное изображение, Y — это набор лейблов, и нам нужно получить наши веса. Как мы вычислим W?

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

Этот процесс происходит итеративно, мы постоянно уменьшаем, пока не находим то значение веса W, которое нас достаточно устроит.

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

Перед вами первая сеть, которая победила на международном соревновании ImageNet в 2012 году. Это так называемый AlexNet. Это сеть, которая впервые заявила о себе, о том, что существует convolutional neural networks и с тех самых пор на всех международных состязаниях уже convolutional neural nets не сдавали своих позиций никогда.

Несмотря на то, что эта сеть достаточно мелкая (в ней всего 7 скрытых слоёв), она содержит 650 тысяч нейронов с 60 миллионами параметров. Для того, чтобы итеративно научиться находить нужные веса, нам нужно очень много примеров.

Нейронная сеть учится на примере картинки и лейбла. Как нас в детстве учат «это кошка, а это собака», так же нейронные сети обучаются на большом количестве картинок. Но дело в том, что до 2010 не существовало достаточно большого data set’a, который способен был бы научить такое количество параметров распознавать изображения.

Самые большие базы данных, которые существовали до этого времени: PASCAL VOC, в который было всего 20 категорий объектов, и Caltech 101, который был разработан в California Institute of Technology. В последнем была 101 категория, и это было много. Тем же, кто не сумел найти свои объекты ни в одной из этих баз данных, приходилось стоить свои базы данных, что, я скажу, страшно мучительно.

Однако, в 2010 году появилась база ImageNet, в которой было 15 миллионов изображений, разделённые на 22 тысячи категорий. Это решило нашу проблему обучения нейронных сетей. Сейчас все желающие, у кого есть какой-либо академический адрес, могут спокойно зайти на сайт базы, запросить доступ и получить эту базу для тренировки своих нейронных сетей. Они отвечают достаточно быстро, по-моему, на следующий день.

По сравнению с предыдущими data set’ами, это очень большая база данных.

На примере видно, насколько было незначительно все то, что было до неё. Одновременно с базой ImageNet появилось соревнование ImageNet, международный challenge, в котором все команды, желающие посоревноваться, могут принять участие.

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

Условно ее можно разделить на 2 части: те, которые учатся, и те, которые не учатся.

Чёрным обозначены те части, которые не учатся, все остальные слои способны обучаться. Существует множество определений того, что находится внутри каждого сверточного слоя. Одно из принятых обозначений — один слой с тремя компонентами разделяют на convolution stage, detector stage и pooling stage.

Не буду вдаваться в детали, еще будет много докладов, в которых подробно рассмотрено, как это работает. Расскажу на примере.

Поскольку организаторы просили меня не упоминать много формул, я их выкинула совсем.

Итак, входное изображение попадает в сеть слоёв, которые можно назвать фильтрами разного размера и разной сложности элементов, которые они распознают. Эти фильтры составляют некий свой индекс или набор признаков, который потом попадает в классификатор. Обычно это либо SVM, либо MLP — многослойный перцептрон, кому что удобно.

По образу и подобию с биологической нейронной сетью объекты распознаются разной сложности. По мере увеличения количества слоёв это все потеряло связь с cortex’ом, поскольку там ограничено количество зон в нейронной сети. 269 или много-много зон абстракции, поэтому сохраняется только увеличение сложности, количества элементов и рецептивных полей.

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

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

Есть люди, которые утверждают, что человек всегда распознаёт лучше, чем сеть. Так ли это?

В 2014 году ученые решили проверить, насколько мы хорошо распознаем в сравнении с нейронными сетями. Они взяли 2 самые лучшие на данный момент сети — это AlexNet и сеть Мэттью Зиллера и Фергюса, и сравнили с откликом разных зон мозга макаки, которая тоже была научена распознавать какие-то объекты. Объекты были из животного мира, чтобы обезьяна не запуталась, и были проведены эксперименты, кто же распознаёт лучше.

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

Оказалось, что в нормальных условиях клетки мозга реагировали так же хорошо, как и state of the art model на тот момент, то есть сеть Мэттью Зиллера.

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

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

На примере этого изображения рассмотрим, что делает каждая из задач.

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

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

Затем мы можем этот вектор признаков сравнить со всеми векторами признаков, которые хранятся у нас в базе данных, и получить отсылку на конкретного человека, на его имя, на его профиль — всё, что у нас может храниться в базе данных.

Именно таким образом работает наш продукт FindFace — это бесплатный сервис, который помогает искать профили людей в базе «ВКонтакте».

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

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

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

Очень быстрый поиск, затрачивается 0,5 секунд на обработку 1 миллиарда фотографий. Нами разработан уникальный индекс быстрого поиска. Также мы можем работать с изображениями низкого качества, полученных с CCTV-камер. Мы можем обрабатывать это все в режиме реального времени. Можно загружать фото через веб-интерфейс, через Android, iOS и производить поиск по 100 миллионам пользователей и их 250 миллионам фотографий.

Как я уже говорила мы заняли первое место на MegaFace competition — аналог для ImageNet, но для распознавания лиц. Он проводится уже несколько лет, в прошлом году мы были лучшими среди 100 команд со всего мира, включая Google.

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

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

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

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

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

В 2005 году на состязании Emotion Recognition in the Wild специально для распознавания эмоций команда из Монреаля представила рекуррентную систему, которая выглядела очень просто. У нее было всего несколько свёрточных слоев, и она работала исключительно с видео. В этом году они добавили также распознавание аудио и cагрегировали покадровые данные, которые получаются из convolutional neural networks, данные аудиосигнала с работой рекуррентной нейронной сети (с возвратом состояния) и получили первое место на состязании.

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

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

Все, наверное, слышали про успехи deep reinforcement learning в Atari и в го.

Кто слышал про Atari? Ну кто-то слышал, хорошо. Про AlphaGo думаю слышали все, поэтому я даже не буду рассказывать, что конкретно там происходит.

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

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

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

Дело в том, что ни одна нейронная сеть, даже deep learning на данный момент, не может справится с этой задачей достаточно эффективно, поэтому deep learning только исключительно кусочки того, что нужно сделать роботам. Например, недавно Сергей Левин предоставил систему, которая учит робота хватать объекты.

Вот здесь показаны опыты, которые он проводил на своих 14 роботах-манипуляторах.

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

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

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

Итак, ученые Стэнфорда недавно придумали очень необычное применение нейронной сети CNN для предсказания бедности. Что они сделали?

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

Учёные собирали дневные и ночные карты со спутников и скармливали их нейронной сети в течение некоторого времени.

Нейронная сеть была преднастроена на ImageNet’е. То есть первые слои фильтров были настроены так, чтобы она умела распознавать уже какие-то совсем простые вещи, например, крыши домов, для поиска поселения на дневных картах. Затем дневные карты были сопоставлены с картами ночной освещенности того же участка поверхности для того, чтобы сказать, насколько есть деньги у населения, чтобы хотя бы освещать свои дома в течение ночного времени.

Здесь вы видите результаты прогноза, построенного нейронной сетью. Прогноз был сделан с различным разрешением. И вы видите — самый последний кадр — реальные данные, собранные правительством Уганды в 2005 году.

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

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

И последнее применение о котором я хотела бы поговорить — семантическая сегментация 3D изображений в медицине. Вообще medical imaging — это сложная область, с которой очень сложно работать.

Для этого есть несколько причин.

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

Но как обошли этот вопрос в данном случае? CNN была двупотоковая. Одна часть обрабатывала более нормальное разрешение, другая — чуть более ухудшенное разрешение для того, чтобы уменьшить количество слоёв, которые нам нужно обучать. За счёт этого немного сократилось время на тренировку сети.

Где это применяется: определение повреждений после удара, для поиска опухоли в мозгу, в кардиологии для определения того, как работает сердце.

Вот пример для определения объема плаценты.

Автоматически это работает хорошо, но не настолько, чтобы это было выпущено в производство, поэтому пока только начинается. Есть несколько стартапов для создания таких систем медицинского зрения. Вообще в deep learning очень много стартапов в ближайшее время. Говорят, что venture capitalists в последние полгода выделили больше бюджета на стартапы обрасти deep learning, чем за прошедшие 5 лет.

Эта область активно развивается, много интересных направлений. Мы с вами живем в интересное время. Если вы занимаетесь deep learning, то вам, наверное, пора открывать свой стартап.

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

Доклад: Нейронные сети — практическое применение.

Принципы построения нейронных сетей. Пишем простую нейросеть на JavaScript

Рассмотрим базовые принципы работы нейронных сетей, узнаем про Brain.js и попробуем подкрепить теорию на практике. Напишем свою первую нейронную сеть, которая будет уметь чуть больше чем ничего, но чуть меньше чем что-то. Статья не претендует на пособие по разработке нейронных сетей, я постараюсь дать Вам базовые знания и представления о работе нейросетей, которыми обладаю сам>

Введем понятие ИНС — искусственная нейронная сеть. т.e. сеть построенная при помощи компьютерной системы;

НС — нейронная сеть мозга человека.

Что такое ИНС?

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

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

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

Нейронная сеть (биологическая нейронная сеть) — совокупность нейронов головного и спинного мозга центральной нервной системы (ЦНС) и ганглия периферической нервной системы (ПНС), которые связаны или функционально объединены в нервной системе, выполняют специфические физиологические функции.

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

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

Давайте более подробно разберем это определение. Из него следует что нейронная сеть представляет собой некоторое количество нейронов, связанных между собой. Сколько нейронов в мозге человека? По подсчетам многих ученых, мозг человека состоит из порядка 100 миллиардов нейронов (плюс-минус пара миллиардов). Именно эта цифра долгие годы приводилась в учебниках по нейробиологии и психологии. Каждый из нейронов является вычислительной единицей, которая обрабатывает входящую информацию и передает ее дальше. Для получения информации у нейрона есть входные каналы, которые называются синапсы. Синапсы это каналы, по которым в нейрон поступает информация из других нейронов. На рисунке синапсы обозначены буквой W, а другие нейроны буквой X. Каждый синапс обладает весом, чем больше вес синапса, тем больше результат работы нейрона будет преобладать в дальнейших вычислениях. Рассмотрим работу синапсов на примере изображения:

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

Важно понимать что ИНС оперирует данными в диапазоне от 0 до 1. Вычисление веса в сумматоре производится пос следующей формуле:

(L1 * W1) +  (L2 * W2) + (L3 * W3) = W

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

(0.35 * 0.1) + (0.12 * 0.3) + (0.6 * 0.2) = 0.191

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

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

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

Линейная функция

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

Сигмоид

Это самая распространенная функция активации, ее диа

от одного нейрона до глубоких архитектур / Хабр

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

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

Иллюстративный материал

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

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

Фреймворк

Для демонстрации конфигураций и результатов предлагаю взять популярный фреймворк Keras, написанный на Python. Хотя вы можете использовать любой другой инструмент для работы с нейросетями — чаще всего различия будут только в наименованиях.

Самая простая нейросеть

Самой простой из возможных конфигураций нейросетей является один нейрон с одним входом и одним выходом без активации (или можно сказать с линейной активацией f(x) = x):
N.B. Как видите, на вход сети подаются два значения — x и единица. Последняя необходима для того, чтобы ввести смещение b. Во всех популярных фреймворках входная единица уже неявно присутствует и не задаётся пользователем отдельно. Поэтому здесь и далее будем считать, что на вход подаётся одно значение.

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

import matplotlib.pyplot as plt
import numpy as np

# накидываем тысячу точек от -3 до 3
x = np.linspace(-3, 3, 1000).reshape(-1, 1)

# задаём линейную функцию, которую попробуем приблизить нашей нейронной сетью
def f(x):    
    return 2 * x + 5

f = np.vectorize(f)

# вычисляем вектор значений функции
y = f(x)

# создаём модель нейросети, используя Keras
from keras.models import Sequential
from keras.layers import Dense

def baseline_model():
    model = Sequential()
    model.add(Dense(1, input_dim=1, activation='linear'))
    model.compile(loss='mean_squared_error', optimizer='sgd')
    return model

# тренируем сеть
model = baseline_model()
model.fit(x, y, nb_epoch=100, verbose = 0)

# отрисовываем результат приближения нейросетью поверх исходной функции
plt.scatter(x, y, color='black', antialiased=True)
plt.plot(x, model.predict(x), color='magenta', linewidth=2, antialiased=True)
plt.show()

# выводим веса на экран
for layer in model.layers:
    weights = layer.get_weights()
    print(weights)

Как видите, наша простейшая сеть справилась с задачей приближения линейной функции линейной же функцией на ура. Попробуем теперь усложнить задачу, взяв более сложную функцию:

def f(x):    
    return 2 * np.sin(x) + 5

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

[array([[ 0.69066334]], dtype=float32), array([ 4.99893045], dtype=float32)]

Первое число — это вес w, второе — смещение b. Чтобы убедиться в этом, давайте нарисуем прямую f(x) = w * x + b:

def line(x):
    w = model.layers[0].get_weights()[0][0][0]
    b = model.layers[0].get_weights()[1][0]
    
    return w * x + b

# отрисовываем результат приближения нейросетью поверх исходной функции
plt.scatter(x, y, color='black', antialiased=True)
plt.plot(x, model.predict(x), color='magenta', linewidth=3, antialiased=True)
plt.plot(x, line(x), color='yellow', linewidth=1, antialiased=True)
plt.show()

Всё сходится.

Усложняем пример

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

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

def baseline_model():
    model = Sequential()
    model.add(Dense(5, input_dim=1, activation='linear'))
    model.add(Dense(1, input_dim=5, activation='linear'))
    model.compile(loss='mean_squared_error', optimizer='sgd')
    return model

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

f(x) = w1′ * (w1 * x + b1) +… + w5′ (w5 * x + b5) + b

Т.е. опять же является линейной функцией. Чтобы сделать поведение нашей сети более интересным, добавим нейронам внутреннего слоя функцию активации ReLU (выпрямитель, f(x) = max(0, x)), которая позволяет сети ломать прямую на сегменты:

def baseline_model():
    model = Sequential()
    model.add(Dense(5, input_dim=1, activation='relu'))
    model.add(Dense(1, input_dim=5, activation='linear'))
    model.compile(loss='mean_squared_error', optimizer='sgd')
    return model

Максимальное количество сегментов совпадает с количеством нейронов на внутреннем слое. Добавив больше нейронов можно получить более точное приближение:

Дайте больше точности!

Уже лучше, но огрехи видны на глаз — на изгибах, где исходная функция наименее похожа на прямую линию, приближение отстаёт.

В качестве стратегии оптимизации мы взяли довольно популярный метод — SGD (стохастический градиентный спуск). На практике часто используется его улучшенная версия с инерцией (SGDm, m — momentum). Это позволяет более плавно поворачивать на резких изгибах и приближение становится лучше на глаз:

# создаём модель нейросети, используя Keras
from keras.models import Sequential
from keras.layers import Dense
from keras.optimizers import SGD

def baseline_model():
    model = Sequential()
    model.add(Dense(100, input_dim=1, activation='relu'))
    model.add(Dense(1, input_dim=100, activation='linear'))
    
    sgd = SGD(lr=0.01, momentum=0.9, nesterov=True)
    model.compile(loss='mean_squared_error', optimizer=sgd)
    return model

Усложняем дальше

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

def f(x):
    return x * np.sin(x * 2 * np.pi) if x < 0 else -x * np.sin(x * np.pi) + np.exp(x / 2) - np.exp(0)

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

Дайте больше нелинейности!

Давайте попробуем заменить служивший нам в предыдущих примерах верой и правдой ReLU (выпрямитель) на более нелинейный гиперболический тангенс:

def baseline_model():
    model = Sequential()
    model.add(Dense(20, input_dim=1, activation='tanh'))
    model.add(Dense(1, input_dim=20, activation='linear'))
    
    sgd = SGD(lr=0.01, momentum=0.9, nesterov=True)
    model.compile(loss='mean_squared_error', optimizer=sgd)
    return model

# тренируем сеть
model = baseline_model()
model.fit(x, y, nb_epoch=400, verbose = 0)

Инициализация весов — это важно!

Приближение стало лучше на сгибах, но часть функции наша сеть не увидела. Давайте попробуем поиграться с ещё одним параметром — начальным распределением весов. Используем популярное на практике значение ‘glorot_normal’ (по имени исследователя Xavier Glorot, в некоторых фреймворках называется XAVIER):

def baseline_model():
    model = Sequential()
    model.add(Dense(20, input_dim=1, activation='tanh', init='glorot_normal'))
    model.add(Dense(1, input_dim=20, activation='linear', init='glorot_normal'))
    
    sgd = SGD(lr=0.01, momentum=0.9, nesterov=True)
    model.compile(loss='mean_squared_error', optimizer=sgd)
    return model

Уже лучше. Но использование ‘he_normal’ (по имени исследователя Kaiming He) даёт ещё более приятный результат:

Как это работает?

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

f(x) = w1′ * tanh(w1 * x + b1) +… + w5′ * tanh(w5 * x + b5) + b

# с помощью матрицы весом моделируем выход каждого отдельного нейрона перед суммацией
def tanh(x, i):
    w0 = model.layers[0].get_weights()
    w1 = model.layers[1].get_weights()
    
    return w1[0][i][0] * np.tanh(w0[0][0][i] * x + w0[1][i]) + w1[1][0]

# рисуем функцию и приближение
plt.scatter(x, y, color='black', antialiased=True)
plt.plot(x, model.predict(x), color='magenta', linewidth=2, antialiased=True)

# рисуем разложение
for i in range(0, 10, 1):
    plt.plot(x, tanh(x, i), color='blue',
         linewidth=1)

plt.show()

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

За границей области обучения

Давайте посмотрим, что происходит за границей области обучения сети, в нашем случае это [-3, 3]:
Как и было понятно из предыдущих примеров, за границами области обучения все гиперболические тангенсы превращаются в константы (строго говоря близкие к нулю или единице значения). Нейронная сеть не способна видеть за пределами области обучения: в зависимости от выбранных активаторов она будет очень грубо оценивать значение оптимизируемой функции. Об этом стоит помнить при конструировании признаков и входных данный для нейросети.

Идём в глубину

До сих пор наша конфигурация не являлась примером глубокой нейронной сети, т.к. в ней был всего один внутренний слой. Добавим ещё один:

def baseline_model():
    model = Sequential()
    model.add(Dense(50, input_dim=1, activation='tanh', init='he_normal'))
    model.add(Dense(50, input_dim=50, activation='tanh', init='he_normal'))
    model.add(Dense(1, input_dim=50, activation='linear', init='he_normal'))
    
    sgd = SGD(lr=0.01, momentum=0.9, nesterov=True)
    model.compile(loss='mean_squared_error', optimizer=sgd)
    return model

Можете сами убедиться, что сеть лучше отработала проблемные участки в центре и около нижней границы по оси абсцисс:Пример работы с одним внутренним слоем

N.B. Слепое добавление слоёв не даёт автоматического улучшения, что называется из коробки. Для большинства практических применений двух внутренних слоёв вполне достаточно, при этом вам не придётся разбираться со спецэффектами слишком глубоких сетей, как например проблема исчезающего градиента. Если вы всё-таки решили идти в глубину, будьте готовы много экспериментировать с обучением сети.

Количество нейронов на внутренних слоях

Просто поставим небольшой эксперимент:

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

Количество эпох

Выводы

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

19 отличных бесплатных нейросетей | Компьютерра

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

Из 2D в 3D

На этом сервисе вы сможете вдохнуть новую жизнь в свои старые фотографии, сделав их объемными. Весь процесс занимает меньше минуты, необходимо загрузить изображение и через несколько секунд получить 3D-модель, которую можно покрутить и рассмотреть во всех деталях. Впрочем, есть два нюанса — во-первых, фотография, должна быть портретной (для лучшего понимания требований на главной странице сайта представлены наиболее удачные образцы снимков, которые ранее загружали другие пользователи; во-вторых, детализация получаемой модельки зачастую оставляет желать лучшего, особенно, если фотография в низком разрешении. Однако авторы разрешают не только ознакомиться с результатом в окне браузера, но и скачать получившийся файл в формате obj к себе на компьютер, чтобы затем самостоятельно его доработать.

Как найти: http://cvl-demos.cs.nott.ac.uk/vrn/

Нейминг брендов

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

Как найти: https://namelix.com/

Выбор досуга

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

Как найти: http://www.gnod.com/

Рай для искусствоведа

Google специально для поклонников современного (и не только) искусства запустила проект Google Arts & Culture, в котором можно подобрать произведения по вашему вкусу как от малоизвестных, так и от малоизвестных авторов. Большая часть контента здесь на английском, но если вы не дружите с языками, можно воспользоваться встроенным переводчиком.

Как найти: https://artsandculture.google.com/project

Озвучивание картинок

Японская студия Qosmo разработала очень необычную нейросеть Imaginary Soundscape, которая воспроизводит звук, соответствующий тому или иному изображению. В качестве источника информации вы можете указать ссылку на любую картинку в Интернете, загрузить свой файл либо выбрать случайную локацию на Google Maps.

Как найти: http://imaginarysoundscape2.qosmo.jp/

Не умеешь рисовать – тогда тебе к нам!

Если вы пробовали использовать рукописный ввод на своем смартфоне, эта нейросеть покажется вам до боли знакомой: она превращает любые каракули в аккуратные 2D-рисунки.

Как найти: https://www.autodraw.com/

Генерация людей

Thispersondoesnotexist – это один самых известных AI-проектов. Нейросеть, созданная сотрудником Uber Филиппом Ваном, выдает случайное изображение несуществующего человека при каждом обновлении страницы.

Как найти: https://thispersondoesnotexist.com/

Генерация… котов

Тот же автор разработал аналогичный сайт, генерирующий изображения несуществующих котов.

Как найти: https://thiscatdoesnotexist.com/

Быстрое удаление фона

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

Как найти: https://www.remove.bg/

Написать стихотворение

Компания ‘Яндекс’, известная своей любовью к запуску необычных русскоязычных сервисов, имеет в своем портфолио сайт, где искусственный интеллект составляет рандомные стихотворения из заголовков новостей и поисковых запросов.

Как найти: https://yandex.ru/autopoet/onegin/27

Окрашивание черно-белых фотографий

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

Как найти: https://colorize.cc/dashboard

Апскейлинг фото

Лет 10-15 назад камеры мобильных устройств не отличались высоким разрешением, и слабый сенсор в телефоне никак не мог справиться с детализированной картиной окружающего мира. Теперь же, если вы захотите повысить разрешение своих старых фотографий, это можно сделать на сервисах вроде Bigjpg и Let’s Enhance, которые позволяют увеличить размер изображения без потери в качестве.

Как найти: https://bigjpg.com/

https://letsenhance.io/

Чтение текста голосом знаменитостей

Благодаря высоким технологиям, сегодня у вас есть возможность озвучить любую фразу голосом самых известных в мире людей. Все просто: пишите текст и выбираете человека (среди последних — Дональд Трамп, Тейлор Свифт, Марк Цукерберг, Канье Уэст, Морган Фриман, Сэмюель Л Джексон и другие).

Как найти: https://voice.headliner.app/

Описание фотографий

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

Как найти: https://www.captionbot.ai/

Музыкальная шкатулка

Напоследок расскажем о целой пачке нейросетей от Google, первая из них – Infinite Drum Machine. Открыв страницу приложения, вы увидите своеобразную карту, на которой находятся самые разнообразные звуки. С помощью круглых манипуляторов можно изменять сочетание элементов, если получившийся набор покажется вам бессмысленным, нажмите кнопку Play в нижней части экрана и звуковая картина сложится сама собой.

Как найти https://aiexperiments.withgoogle.com/drum-machine

Птичий хор

Если предыдущий сервис может оказаться полезным для, например, диджеев или обычных музыкантов, то польза от управления голосами десятков тысяч певчих птиц довольно сомнительна. Кстати, коллекция звуков для Bird Sounds собиралась орнитологами со всего мира на протяжении нескольких десятилетий.

Как найти: https://aiexperiments.withgoogle.com/thing-translator

Виртуальный пианист

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

Как найти: https://experiments.withgoogle.com/ai-duet

Распознавание рисунков

Еще во время первых экспериментов с нейросетями в середине прошлого века основной задачей машинного обучения было распознавание визуальных образов. Спустя десятки лет эта технология выбралась из лабораторий и доступна всем желающим: на сайте quickdraw.withgoogle.com/ вам предложат быстро рисовать простые наброски определенных предметов, при этом ИИ будет все время комментировать происходящее на экране синтезированной речью.

Как найти: quickdraw.withgoogle.com/

Объяснение логики машинного обучения

Проект Visualizing High-Dimensional Space (“Визуализация многомерного пространства”) создавался для того, чтобы объяснить простым людям и начинающим разработчикам, как работают нейросети. Когда ИИ, оперируя большими базами данных, получает информацию (например, вашу фотографию, введенную фразу или только что нарисованное изображение), он сравнивает входящие данные с теми, что у него уже есть. VHDS наглядно демонстрирует корреляцию одного лишь выбранного вами слова с миллионами аналогичных понятий.

Как найти: https://experiments.withgoogle.com/visualizing-high-dimensional-space

Пример простой нейросети, как результат разобраться что к чему / Хабр

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

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


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

В чём смысл делать свой проект.Плюсы:

  1. Лучше понимаешь, как устроены нейронки
  2. Лучше понимаешь, как работать с уже с существующими библиотеками
  3. Параллельно изучаешь что-то новое
  4. Щекочешь своё Эго, создавая что-то своё

Минусы:

  1. Создаёшь велосипед, притом скорее всего хуже существующих
  2. Всем плевать на твой проект

Выбор языка.На момент выбора языка я более-менее знал С++, и был знаком с основами Python. Работать с нейронками проще на Python, но С++ знал лучше и нет проще распараллеливания вычислений, чем OpenMP. Поэтому я выбрал С++, а API под Python, чтобы не заморачиваться, будет создавать swig, который работает на Windows и Linux. (Пример, как сделать из кода С++ библиотеку для Python)

OpenMP и GPU ускорение.

На данный момент в Visual Studio установлена OpenMP версии 2.0., в которой есть только CPU ускорение. Однако начиная с версии 3.0 OpenMP поддерживает и GPU ускорение, при этом синтаксис директив не усложнился. Осталось лишь дождаться, когда OpenMP 3.0 будет поддерживаться всеми компиляторами. А пока, для простоты, только CPU.

Мои первые грабли.

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

Выкладывание проекта на GitHub.Я не первый, кто выкладывает своё творение на GitHub. Но в большинстве случаев, перейдя по ссылке, видишь лишь кучу кода с надписью в README.md «Это моя нейросеть, смотрите и изучайте». Чтобы быть лучше других хотя бы в этом, более-менее описал README.md и заполнил Wiki. Посыл же простой — заполняйте Wiki. Интересное наблюдение: если заголовок в Wiki на GitHub написан на русском языке, то якорь на этот заголовок не работает.

Лицензия.Когда создаёшь свой маленький проект, лицензия — это опять же способ пощекотать своё Эго. Вот интересная статья на тему, для чего нужна лицензия. Я же остановил свой выбор на APACHE 2.0.

Описание сети.

Характеристики:

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

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

Давайте создадим сеть, получающую на вход три параметра, имеющую три слоя с 5-ью, 4-мя и 2-мя нейронами.

import foxnn
nn = foxnn.neural_network([3, 5, 4, 2]) 

Если взглянуть на рисунок, то можно как раз увидеть: сначала 3 входных параметра, затем слой с 5-ью нейронами, затем слой с 4-мя нейронами и, наконец, последний слой с 2-мя нейронами.

По умолчанию все функции активации являются сигмоидами (мне они больше нравятся).

При желании, на любом слое можно поменять на другую функцию.

В наличии самые популярные функции активации.

nn.get_layer(0).set_activation_function("gaussian")

Легко создать обучающую выборку. Первый вектор — входные данные, второй вектор — целевые данные.

data = foxnn.train_data()
data.add_data([1, 2, 3], [1, 0]) #на вход три параметра, на выход два параметра

Обучение сети:

nn.train(data_for_train=data, speed=0.01, max_iteration=100, size_train_batch=98)

Включение оптимизации:

nn.settings.set_mode("Adam")

И метод, чтобы просто получить значение сети:

nn.get_out([0, 1, 0.1])

Немного о названии метода.

Отдельно get переводится как получить, а outвыход. Хотел получить название «дай выходное значение«, и получил это. Лишь позже заметил, что получилось выметайся. Но так забавнее, и решил оставить.

Тестирование

Уже вошло в негласную традицию тестировать любую сеть на базе MNIST. И я не стал исключением. Весь код с комментариями можно посмотреть тут. Создаёт тренировочную выборку:

from mnist import MNIST
import foxnn

mndata = MNIST('C:download/')
mndata.gz = True
imagesTrain, labelsTrain = mndata.load_training()

def get_data(images, labels):
    train_data = foxnn.train_data()
    for im, lb in zip(images, labels):
        data_y = [0, 0, 0, 0, 0, 0, 0, 0, 0, 0] # len(data_y) == 10
        data_y[lb] = 1 
        data_x = im
        for j in range(len(data_x)):
            # приводим пиксель в диапазон (-1, 1)
            data_x[j] = ((float(data_x[j]) / 255.0) - 0.5) * 2.0  
        train_data.add_data(data_x, data_y) # добавляем в обучающую выборку
    return train_data

train_data = get_data(imagesTrain, labelsTrain)

Создаём сеть: три слоя, на вход 784 параметра, и 10 на выход:

nn = foxnn.neural_network([784, 512, 512, 10])
nn.settings.n_threads = 7 # распараллеливаем процесс обучения на 7 процессов
nn.settings.set_mode("Adam") # используем оптимизацию Адама

Обучаем:

nn.train(data_for_train=train_data, speed=0.001, max_iteration=10000, size_train_batch=98)

Что получилось:

Примерно за 10 минут (только CPU ускорение), можно получить точность 75%. С оптимизацией Адама за 5 минут можно получить точность 88% процентов. В конечном итоге мне удалось достичь точности в 97%.

Основные недостатки (уже есть в планах на доработку):

  1. В Python ещё не протянуты ошибки, т.е. в python ошибка не будет перехвачена и программа просто завершится с ошибкой.
  2. Пока обучение указывается в итерациях, а не в эпохах, как это принято в других сетях.
  3. Нет GPU ускорения
  4. Пока нет других видов слоёв.
  5. Надо залить проект на PyPi.

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

P.S.: Если вам для того, чтобы разобраться, нужно создать что-то своё, не бойтесь и творите.

Наглядное введение в нейросети на примере распознавания цифр

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

Статьи на тему, что такое искусственный интеллект, давно написаны. А вот математическая сторона медали 🙂

Продолжаем серию первоклассных иллюстративных курсов 3Blue1Brown (смотрите наши предыдущие обзоры по линейной алгебре и матанализу) курсом по нейронным сетям.

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

Детально рассматривается многослойный перцептрон – базисная (но уже достаточно сложная) модель для понимания любых более современных вариантов нейронных сетей.

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

Постановка задачи распознавания цифр

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

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

Но если бы вам предложили написать программу, которая принимает на вход изображение любой цифры в виде массива 28х28 пикселей и выдает на выходе саму «сущность» – цифру от 0 до 9, то эта задача перестала бы казаться простой.

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

Активация нейронов. Слои нейросети

Так как наша сетка состоит из 28х28=784 пикселей, пусть есть 784 нейрона, содержащие различные числа от 0 до 1: чем ближе пиксель к белому цвету, тем ближе соответствующее число к единице. Эти заполняющие сетку числа назовем активациями нейронов. Вы можете себе представлять это, как если бы нейрон зажигался, как лампочка, когда содержит число вблизи 1 и гас при числе, близком к 0.

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

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

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

Назначение скрытых слоев

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

Слой образов фигур

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

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

Слой образов структурных единиц

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

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

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

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

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

Определение области распознавания

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

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

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

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

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

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

Масштабирование активации до интервала [0, 1]

Вычислив такую взвешенную сумму, вы можете получить любое число в широком диапазоне значений. Для того, чтобы оно попадало в необходимый диапазон активаций от 0 до 1, разумно использовать функцию, которая бы «сжимала» весь диапазон до интервала [0, 1].

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

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

Разговор пока шел только об одном нейроне. Каждый нейрон из первого скрытого слоя соединен со всеми 784 пиксельными нейронами первого слоя. И каждое из этих 784 соединений будет иметь свой ассоциированный с ним вес. Также у каждого из нейронов первого скрытого слоя есть ассоциированный с ним сдвиг, добавляемый к взвешенной сумме перед «сжатием» этого значения сигмоидой. Таким образом, для первого скрытого слоя имеется 784х16 весов и 16 сдвигов.

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

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

Описание нейросети в терминах линейной алгебры

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

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

Уточнение об активации нейронов

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

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

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

Дополнение: немного о функциях активации. Сравнение сигмоиды и ReLU

Затронем кратко тему функций, используемых для «сжатия» интервала значений активаций. Функция сигмоиды является примером, подражающим биологическим нейронам и она использовалась в ранних работах о нейронных сетях, однако сейчас чаще используется более простая ReLU функция, облегчающая обучение нейросети.

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

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

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

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

В общих чертах

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

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

Функция стоимости

Концептуально задача обучения нейросети сводится к нахождению минимума определенной функции – функции стоимости. Опишем что она собой представляет.

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

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

Чтобы обучать нейросеть, введем функцию стоимости (англ. cost function), которая будет как бы говорить компьютеру в случае подобного результата: «Нет, плохой компьютер! Значение активации должно быть нулевым у всех нейронов кроме одного правильного».

Задание функции стоимости для распознавания цифр

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

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

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

Это довольно трудная задача. Если наша нейросеть имеет на входе 784 пикселя, на выходе 10 значений и требует для их расчета 13 тыс. параметров, то функция стоимости является функцией от этих 13 тыс. параметров, выдает одно единственное значение стоимости, которое мы хотим минимизировать, и при этом в качестве параметров выступает вся обучающая выборка.

Как изменить все эти веса и сдвиги, чтобы нейросеть обучалась?

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

Для начала вместо того, чтобы представлять функцию с 13 тыс. входных значений, начнем с функции одной переменной С(w). Как вы, наверное, помните из курса математического анализа, для того, чтобы найти минимум функции, нужно взять производную.

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

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

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

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

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

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

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

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

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

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

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

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

Обучение на структурированных и случайных данных

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

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

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

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

Обратное распространение это ключевой алгоритм обучения нейронной сети. Обсудим вначале в общих чертах, в чем заключается метод.

Управление активацией нейрона

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

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

Варианты настройки нейросети

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

Таким образом, чтобы повысить значение этой активации, мы можем:

  1. Увеличить сдвиг b.
  2. Увеличить веса wi.
  3. Поменять активации предыдущего слоя ai.

 

Из формулы взвешенной суммы можно заметить, что наибольший вклад в активацию нейрона оказывают веса, соответствующие связям с наиболее активированными нейронами. Стратегия, близкая к биологическим нейросетям заключается в том, чтобы увеличивать веса wi пропорционально величине активаций ai соответствующих нейронов предыдущего слоя. Получается, что наиболее активированные нейроны соединяются с тем нейроном, который мы только хотим активировать наиболее «прочными» связями.

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

Обратное распространение

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

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

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

Классический градиентный спуск

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

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

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

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

Случайным образом данные обучающей выборки перемешиваются и разделяются на подгруппы, например, по 100 размеченных изображений. Далее алгоритм рассчитывает шаг градиентного спуска для одной подгруппы.

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

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

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

Дополнение. Математическая составляющая обратного распространения

Разберемся теперь немного более формально в математической подоплеке алгоритма обратного распространения.

Примитивная модель нейронной сети

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

Начнем со связи между двумя последними нейронами. Обозначим последний слой L, предпоследний L-1, а активации лежащих в них рассматриваемых нейронов a(L), a(L-1).

Функция стоимости

Представим, что желаемое значение активации последнего нейрона, данное обучающим примеров это y, равное, например, 0 или 1. Таким образом, функция стоимости определяется для этого примера как

C0 = (a(L) — y)2.

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

a(L) σ(w(L)a(L-1) + b(L)).

Для краткости взвешенную сумму можно обозначить буквой с соответствующим индексом, например z(L):

a(L)σ(z(L)).

Рассмотрим как в значении функции стоимости сказываются малые изменения веса w(L). Или математическим языком, какова производная функции стоимости по весу ∂C0/∂w(L)?

Можно видеть, что изменение C0 зависит от изменения a(L), что в свою очередь зависит от изменения z(L), которое и зависит от w(L). Соответственно правилу взятия подобных производных, искомое значение определяется произведением следующих частных производных:

∂C0/∂w(L) = ∂z(L)/∂w(L) • ∂a(L)/∂z(L) • ∂C0/∂a(L).

Определение производных

Рассчитаем соответствующие производные:

∂C0/∂a(L) = 2(a(L) — y)

То есть производная пропорциональна разнице между текущим значением активации и желаемым.

Средняя производная в цепочке является просто производной от масштабирующей функции:

∂a(L)/∂z(L) = σ'(z(L))

И наконец, последний множитель это производная от взвешенной суммы:

∂z(L)/∂w(L) = a(L-1)

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

Конечное выражение:

∂C0/∂w(L) = 2(a(L) — y) σ'(z(L)) a(L-1)

Обратное распространение

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

∂C/∂w(L) = 1/n Σ ∂Ck/∂w(L)

Полученное усредненное значение для конкретного w(L) является одним из компонентов градиента функции стоимости. Рассмотрение для сдвигов идентично приведенному рассмотрению для весов.

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

Модель со множеством нейронов в слое

Однако как осуществить переход от слоев, содержащих по одному нейрону к исходно рассматриваемой нейросети. Все будет выглядеть аналогично, просто добавится дополнительный нижней индекс, отражающий номер нейрона внутри слоя, а у весов появятся двойные нижние индексы, например, jk, отражающие связь нейрона j из одного слоя L с другим нейроном k в слое L-1.

Конечные производные дают необходимые компоненты для определения компонентов градиента ∇C.

Потренироваться в описанной задаче распознавания цифр можно при помощи учебного репозитория на GitHub и упомянутого датасета для распознавания цифр MNIST.

Нейросети: путь прогресса или бомба замедленного действия? | Технологии | Блог

Человеческий мозг — восхитительное устройство. Он вдохновляет современных исследователей, которые создают искусственные нейроны, словно ученики скульптора, копирующие бюст Сократа. И результат тому — искусственная нейронная сеть (ИНС), одно из самых обсуждаемых явлений современности.

Почему нейронная, почему сеть

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

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

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

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

Кому это выгодно

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

Нейросети для развлечений

Искусственными нейронными сетями сейчас пользуются люди, далекие от сложных математических моделей. Когда создатели ПО поняли, что нейросети — это как минимум весело, рынок приложений для смартфонов наводнился программами для работы с изображениями на основе искусственных нейронных сетей. ПО для обработки изображений (DeepDream, Prisma, Mlvch), «старения»,замены лиц на фотографиях и видео моментально стало вирусным. На самом деле, это весомое оружие в век соцсетей. Приложения типа знаменитого FaceApp могут не только позабавить — с ними можно здорово изменить внешность: нанести профессиональный мейкап, изменить волосы, скорректировать черты лица и даже добавить эмоции и мимику. Причем сейчас все это выглядит настолько натуралистично, что едва ли с первого взгляда заподозришь подвох.

Нейросети знают многое о человеческих лицах: по фотографии они могут определить возраст, пол, настроение, спрогнозировать, как лицо будет выглядеть в старости, анимировать статическое изображение, заставив Барака Обаму говорить то, что он не говорил, и оживить знаменитую Мону Лизу. По фотографии теперь можно найти человека, а китайские нейросети Megvii даже ищут собак по изображению носа. Причем ИНС работает не только с изображениями, но и со звуком. Массачусетский технологический институт недавно представил нейросеть (Speech3Face), определяющую национальность, пол и возраст человека по голосу.

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

Нейросети на службе правительства

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

Уже есть несколько примеров проектов внедрения искусственных нейронных сетей в России. В ГИБДД хотят научить нейросеть обнаруживать факт кражи автомобильных номеров. По изображению автомобиля ИНС сможет установить, соответствует ли машина своему номеру. Это поможет своевременно выявлять подделку или кражу номеров. Руководитель Департамента транспорта Москвы Максим Ликсутов подтвердил, что данная программа сейчас проходит тестирование.

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

Нейросети и бизнес

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

В банковской сфере нейросети уже применяются для анализа кредитной истории клиентов и принятия решений о выдаче кредита. Так, в 2018 году «Сбербанк» уволил 14 тысяч сотрудников, которых заменила «Интеллектуальная система управления» на основе нейросети. Вместо людей рутинные операции теперь выполняет обучаемый искусственный интеллект. По словам Германа Грефа, подготовку исковых заявлений нейросети проводят лучше штатных юристов. Также финансисты обращаются к прогностическим способностям искусственного интеллекта для работы с плохо предсказуемыми биржевыми индексами.

Нейросети в сфере искусства

Что будет, если нейросеть познакомить с шедеврами мировой живописи и предложить написать картину? Будет новое произведение искусства. Предложите нейросети сочинения Баха, и она придумает похожую мелодию, книги Джоан Роулинг – она напишет книгу «Гарри Поттер и портрет того, что похоже на большую кучу золы». Книга «День, когда Компьютер написал роман», созданная японской нейросетью, даже получила премию HoshiShinichiLiteraryAward.

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

В 2018 году на аукционе «Сотбис» за полмиллиона долларов был продан необыкновенный лот: «Эдмонд де Белами, из семьи де Белами. Состязательная нейронная сеть, печать на холсте, 2018. Подписана функцией потерь модели GAN чернилами издателем, из серии одиннадцати уникальных изображений, опубликованных Obvious Art, Париж, в оригинальной позолоченной деревянной раме». Робби Баррат, художник и программист, научил нейросети живописи настолько, что теперь она уходит с молотка как шедевры искусства.

Появились нейросети-композиторы и даже сценаристы. Уже снят короткометражный фильм по сценарию, написанному искусственным интеллектом («Sunspring») — вышло бессмысленно и беспощадно, как заправский артхаус. Тем временем нейросеть от Яндекса произвела на свет пьесу для симфонического оркестра с альтом и альбом «Нейронная оборона» в стиле группы «Гражданская оборона», а позже начала писать музыку в стиле известных исполнителей, например группы Nirvana. А нейросеть под названием Dadabots имеет свой канал на YouTube, где генерируется deathmetal музыка.

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

Нейросети в медицине

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

В открытом доступе появились даже приложения для диагностики на основе нейросетей, например SkinVision, которое работает с фотографиями родинок и определяет доброкачественность или злокачественность вашего невуса. Точность приложения — 83 %.

Скайнет готовится к атаке?

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

  • Фейки. Благодаря возможностям нейросетей появились программы для замены лиц и даже времени года на фото и видео. Как, например, нейросеть Nvidia на основе генеративной состязательной сети (GAN). Страшно представить, какие фото и видео можно получить, если применять подобные программы с целью создания убедительных фейков. Также нейросеть может на основе короткого фрагмента голоса создать синтетический голос, полностью идентичный оригиналу. Подделать чью-то речь? Легко. Подделать чью-то фотографию? Проще простого.
  • Трудности понимания. Когда процесс обучения нейросети завершается, человеку становится трудно понять, на каких основаниях она принимает решения. До сих пор непонятно, как у ИНС получилось обыграть лучшего игрока мира в Го. В этом смысле нейросеть — ящик Пандоры.
  • Оружие хакеров и мошенников. Считается, что хакеры могут использовать возможности нейросетей для преодоления систем антивирусной защиты и создания нового поколения вредоносных программ. Также нейросети соблазнительны для мошенников, например, искусственный интеллект, способный имитировать общение с живым человеком и заполучать доверие.

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

  • Злой суперкомпьютер. Создание искусственного интеллекта, превышающего возможности человеческого разума чревато последствиями. Об этом уже создано множество научно-фантастических книг и фильмов. Может, конечно, все не будет так страшно и фантастично, как в фильме «Превосходство», но оценить риски заранее практически невозможно, а соблазн развивать нейросети все больше и больше слишком велик.

Выводы и прогнозы

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

Так как искусственный интеллект уже начал выполнять человеческие задачи, миллионы квалифицированных специалистов могут постепенно лишаться рабочих мест. Работодателю будет проще запустить нейросеть, чем нанимать человека. По тонкому замечанию Антона Балакирева, руководителя интернет-портала Robo-sapiens.ru, нейросети не уходят на пенсию, не страдают алкоголизмом и депрессией. Идеальный работник.

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

Учебное пособие по нейронной сети

: пример TensorFlow ANN

  • Home
  • Testing

      • Back
      • Agile Testing
      • BugZilla
      • Cucumber
      • 000
      • 000
      • 000 J2000 Testing
      • 000 JB
      • 9000
      • Назад
      • JUnit
      • LoadRunner
      • Ручное тестирование
      • Мобильное тестирование
      • Mantis
      • Почтальон
      • QTP
      • Назад
      • Центр качества (ALM)
      • SAP Testing
      • Управление тестированием
      • TestLink
  • SAP

      • Назад
      • A BAP
      • APO
      • Начинающий
      • Basis
      • BODS
      • BI
      • BPC
      • CO
      • Назад
      • CRM
      • Crystal Reports
      • Crystal Reports
      • Заработная плата
      • Назад
      • PI / PO
      • PP
      • SD
      • SAPUI5
      • Безопасность
      • Менеджер решений
      • Successfactors
      • SAP Tutorials

      4

    • Web
    • Apache
    • AngularJS
    • ASP.Net
    • C
    • C #
    • C ++
    • CodeIgniter
    • СУБД
    • JavaScript
    • Назад
    • Java
    • JSP
    • Kotlin
    • Linux
    • Linux
    • Kotlin
    • Linux
    • js

    • Perl
    • Назад
    • PHP
    • PL / SQL
    • PostgreSQL
    • Python
    • ReactJS
    • Ruby & Rails
    • Scala
    • SQL
    • 000

    • SQL
    • 000

      0003 SQL

      000

      0003 SQL

      000

    • UML
    • VB.Net
    • VBScript
    • Веб-службы
    • WPF
  • Обязательно учите!

      • Назад
      • Бухгалтерский учет
      • Алгоритмы
      • Android
      • Блокчейн
      • Business Analyst
      • Создание веб-сайта
      • CCNA
      • Облачные вычисления
      • 0003 COBOL
      • 000 Compiler
          9000 Встроенный

        • 000 9000 Compiler
        • Ethical Hacking
        • Учебные пособия по Excel
        • Программирование на Go
        • IoT
        • ITIL
        • Jenkins
        • MIS
        • Сетевые подключения
        • Операционная система
        • 000
        • Назад
        • Назад
        • Назад
        • Назад

        .

        Все, что вам нужно знать о нейронных сетях и обратном распространении информации — Машинное обучение — легко и весело | Гаврил Огняновский

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

        Изображение 12: Функция общих затрат. источник: coursera.org

        Так как это тип задачи классификации y может принимать только дискретные значения {0,1}.Он может быть только в одном классе. Например, если мы классифицируем изображения собак (класс 1), кошек (класс 2) и птиц (класс 3). Если входное изображение — собака. Выходные классы будут иметь значение 1 для класса собаки и значение 0 для других классов.

        Это означает, что мы хотим, чтобы наша гипотеза удовлетворяла

        Изображение 13: Значения диапазона функции гипотез

        Вот почему мы определим нашу гипотезу как

        Изображение 14: Функция гипотезы

        Где g в данном случае будет сигмоидной функцией, поскольку это функция имеет значения диапазона между (0,1).

        Наша цель — оптимизировать функцию стоимости, поэтому нам нужно найти минимум Дж (θ) . Но сигмовидная функция является «невыпуклой» функцией (« Image 15 »), что означает наличие нескольких локальных минимумов. Поэтому не гарантируется схождение (поиск) к глобальному минимуму. Нам нужна «выпуклая» функция в алгоритме градиентного спуска, чтобы иметь возможность найти глобальный минимум (минимизировать J (θ)). Для этого мы используем функцию log .

        Изображение 15: Выпуклая и невыпуклая функции.источник: researchgate.com

        Вот почему мы используем следующую функцию стоимости для нейронных сетей

        Изображение 16: Функция стоимости нейронной сети. источник: coursera.org

        В случае, если обозначенное значение y равно 1 , гипотеза будет -log (h (x)) или -log (1-h (x)) иначе.

        Интуиция довольно проста, если мы посмотрим на графики функций. Давайте сначала рассмотрим случай, когда y = 1 .Тогда -log (h (x)) будет выглядеть как на графике ниже. И нас интересует только интервал (0,1) оси x, поскольку гипотеза может принимать значения только в этом диапазоне ( «Изображение 13» )

        Изображение 17: Функция стоимости -log (h (x)). источник: desmos.com

        Из графика видно, что если y = 1 и h (x) приближается к значению 1 ( ось x ), стоимость приближается значение 0 ( h (x) -y будет 0 ), поскольку это правильный прогноз.В противном случае, если h (x) приближается к 0 , функция затрат стремится к бесконечности (очень большие затраты).

        В другом случае, когда y = 0 , функция стоимости равна -log (1-h (x))

        Изображение 18: -log (1-h) функция стоимости. источник: desmos.com

        Из приведенного здесь графика видно, что если h (x) приближается к значению 0 , стоимость приближается к 0 , поскольку в данном случае это также правильный прогноз.

        Начиная с y (обозначенное значение) всегда равно 0 или 1 , мы можем записать функцию стоимости в одном уравнении.

        Изображение 19: Уравнение функции затрат. источник: coursera.org

        Если мы полностью напишем нашу функцию стоимости с суммированием, мы получим:

        Изображение 20: Функция стоимости в случае одного выходного узла. источник: coursera.org

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

        Изображение 21: Функция обобщенной стоимости. источник: coursera.org

        Правые части уравнений представляют «регуляризацию» функции стоимости. Эта регуляризация предотвращает «переоснащение» данных за счет уменьшения величины / значений θ.

        Этот процесс прямого распространения фактически получает выходное значение нейронной сети на основе заданного входа. Этот алгоритм используется для расчета стоимости.Он выполняет тот же математический процесс, что и описанный в разделе 2 «Математика представления моделей». Где в итоге получаем значение нашей гипотезы «Изображение 7» .

        После того, как мы получили значение h (x) (гипотеза), мы используем уравнение функции затрат ( «Изображение 21» ), чтобы вычислить стоимость для данного набора входных данных.

        Изображение 22: Расчет прямого распространения

        Здесь мы можем заметить, как работает прямое распространение и как нейронная сеть генерирует прогнозы .

        Мы хотим минимизировать функцию стоимости J (θ) , используя оптимальный набор значений для θ (веса). Обратное распространение — это метод, который мы используем для вычисления частной производной Дж (θ) .

        Это значение частной производной затем используется в алгоритме градиентного спуска ( «Изображение 23» ) для вычисления значений θ для нейронной сети, которые минимизируют функцию стоимости J (θ) .

        Изображение 23: Общая форма градиентного спуска. источник: coursera.org

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

        1. Установить a (1) = X ; для обучающих примеров
        2. Выполните прямое распространение и вычислите a (l) для других слоев (l = 2… L)
        3. Используйте y и вычислите значение дельты для последний слой δ (L) = h (x) — y
        4. Вычислить δ (l) значений в обратном направлении для каждого слоя (описано в разделе «Математика за обратным распространением»)
        5. Вычислить производные значения Δ (l) = (a (l)) ^ T ∘ δ (l + 1) для каждого слоя, что представляет собой производную стоимости Дж (θ) относительно θ (l) для слоя l

        Обратное распространение — это определение того, как изменение весов влияет на общую стоимость в нейронной сети.

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

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

        Почему деривативы?

        Производная функции (в нашем случае J (θ) ) по каждой переменной (в нашем случае вес θ ) говорит нам о чувствительности функции по отношению к этой переменной или как изменение переменной влияет на значение функции .

        Давайте посмотрим на простой пример нейронной сети

        Изображение 24: Простая нейронная сеть

        Есть два входных узла x и y . Функция вывода вычисляет произведение x и y . Теперь мы можем вычислить частные производные для обоих узлов.

        Изображение 25: Производные по y и x функции f (x, y) = xy

        Частная производная по x говорит, что если x для некоторого значения ϵ , тогда это увеличит функцию (продукт xy ) на 7 и частную производную относительно y говорит, что если y увеличение значения для некоторого значения ϵ , тогда функция увеличится на .

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

        Математика обратного распространения

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

        Изображение 26: Нейронная сеть

        В этой модели мы получили 3 выходных узла ( K ) и 2 скрытых слоя. Как определено ранее, функция стоимости для нейронной сети:

        Изображение 27: Функция обобщенных затрат. источник: coursera.org

        Нам нужно вычислить частную производную J (θ) по каждому параметру θ .Мы собираемся опустить резюмирование, так как мы используем векторизованную реализацию (умножение матриц). Также мы можем опустить регуляризацию (правая часть уравнения выше), и мы вычислим ее отдельно в конце. Поскольку это сложение, производная может быть вычислена независимо.

        ПРИМЕЧАНИЕ. Будет использоваться векторизованная реализация, поэтому мы рассчитываем сразу для всех обучающих примеров.

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

        Изображение 28: Производные правила

        Теперь мы определяем основное уравнение для нашей модели нейронной сети, где l — это нотация слоя, а L — для последнего слоя.

        Изображение 29: Исходные уравнения модели нейронной сети

        В нашем случае L имеет значение 4, так как у нас есть 4 слоя в нашей модели. Итак, давайте начнем с вычисления частной производной по весам между 3-м и 4-м слоями.

        Изображение 30: Производная параметров θ между 3-м и 4-м слоями

        Шаг (6) — сигмовидная производная
        Чтобы объяснить шаг (6) , нам нужно вычислить частную производную сигмоидной функции.

        Изображение 31: Производная сигмоидной функции

        В случае последнего слоя L мы получили

        Изображение 32: Уравнение выходного слоя

        итак,

        Изображение 33: Уравнение выходного слоя

        Шаг (11) — Избавьтесь от суммирование (Σ)
        Также на последнем шаге (11) важно отметить, что нам нужно умножить δ на транспонирования , чтобы избавиться от суммирования (1 … М для обучающих примеров).
        δ матрица с размерами
        [number_of_training_examples, output_layer_size] , так что это также означает, что мы избавимся от второго суммирования (1… K для количества выходных узлов).
        a — матрица с размерами
        [hidden_layer_size, number_of_training_examples]

        Теперь мы продолжим со следующей производной для параметров θ между 2-м и 3-м слоями.Для этого вывода мы можем начать с шага (9) ( «Изображение 30» ). Поскольку θ (2) находится внутри функции a (3) , нам нужно применить «Правило цепочки» при вычислении производной (шаг (6) из правил производных на «Изображение 28»).

        Изображение 34: Производная параметров θ между 2-м и 3-м слоями

        Теперь мы получили производную для параметра θ между 2-м и 3-м слоями. Нам осталось вычислить производную для параметра θ между входным слоем и вторым слоем.Сделав это, мы увидим, что тот же процесс (уравнения) будет повторяться, поэтому мы можем вывести общие δ и производные уравнения. Снова продолжаем с шага (3) ( «Изображение 34» ).

        Изображение 35: Производная параметров θ между входом и 2-м слоем

        Из приведенного выше уравнения мы можем вывести уравнения для параметра δ и производной относительно параметра θ .

        Изображение 36: Рекурсивное уравнение δ Изображение 37: Производная J (стоимости) относительно θ в уравнении уровня l

        В конце мы получаем три матрицы (такие же, как θ весовых матриц) с теми же размерами, что и θ весовых матриц и вычисленных производных для каждого параметра θ .

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

        Изображение 38: Уравнение регуляризации для функции стоимости

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

        Изображение 39: Уравнение регуляризации для градиента (частная производная)

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

        Реализация кода

        Теперь мы можем реализовать все уравнения в коде, где мы имеем

        .Учебное пособие по нейронной сети

        — Искусственный интеллект | Deep Learning

        Neural Network Tutorial:

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

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

        • Ограничения однослойного персептрона
        • Что такое многослойный персептрон (искусственная нейронная сеть)?
        • Как работают искусственные нейронные сети?
        • Вариант использования

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

        Теперь я начну с обсуждения ограничений однослойного персептрона.

        Ограничения однослойного перцептрона:

        Итак, есть две основные проблемы:

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

        Однослойные перкпетроны не могут классифицировать нелинейно разделимые точки данных

        Давайте разберемся в этом на примере логического элемента XOR.Рассмотрим диаграмму ниже:

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

        Сложные задачи, которые включают множество параметров, не могут быть решены однослойными персептронами:

        Здесь я также объясню на примере.

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

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

        • Google Реклама
        • Личная электронная почта
        • Продажа рекламы на соответствующих сайтах
        • Справочная программа
        • Блоги и так далее. . .

        Принимая во внимание все имеющиеся факторы и варианты, маркетинговая команда должна выбрать стратегию для проведения оптимального и эффективного маркетинга, но эта задача слишком сложна для анализа человеком, потому что количество параметров довольно велико.Эту проблему придется решать с помощью Deep Learning. Рассмотрим диаграмму ниже:

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

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

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

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

        По всем этим причинам однослойный персептрон нельзя использовать для сложных нелинейных задач.

        Далее в этом руководстве по нейронной сети я сосредоточусь на многослойных персептронах (MLP).

        Что такое многослойный персептрон?

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

        Рассмотрим схему ниже:

        • Узлы ввода — узлы ввода предоставляют информацию из внешнего мира в сеть и вместе называются «Уровень ввода». Никакие вычисления не выполняются ни в одном из узлов ввода — они просто передают информацию скрытым узлам.
        • Скрытые узлы — Скрытые узлы не имеют прямой связи с внешним миром (отсюда и название «скрытые»). Они выполняют вычисления и передают информацию от входных узлов к выходным узлам.Набор скрытых узлов образует «Скрытый слой». Хотя сеть будет иметь только один входной слой и один выходной слой, она может иметь ноль или несколько скрытых слоев. Многослойный персептрон имеет один или несколько скрытых слоев.
        • Узлы вывода — Узлы вывода вместе называются «Уровень вывода» и отвечают за вычисления и передачу информации из сети во внешний мир.

        Да, вы угадали, я приведу пример, чтобы объяснить — как работает искусственная нейронная сеть .

        Предположим, у нас есть данные футбольной команды Chelsea . Данные содержат три столбца. В последней колонке указано, выиграл ли «Челси» матч или проиграл. Две другие колонки посвящены преимуществу мячей в первом тайме и владению мячом во втором тайме. Владение мячом — это количество времени, в течение которого команда владеет мячом в процентах. Итак, если я говорю, что команда владеет мячом на 50% в одном тайме (45 минут), это означает, что команда владела мячом 22,5 минуты из 45.

        9011 9011

        9011 9011

        Отрыв от ворот в первом тайме Владение мячом во втором тайме Выиграл или проиграл (1,0)?
        0 80% 1
        0 35% 0
        1 42% 1
        -1 75% 1

        Столбец «Окончательный результат» может иметь два значения 1 или 0, указывающие, выиграл ли «Челси» матч или нет.Например, мы видим, что если в первом тайме отрыв мячей 0 голов, а в следующем тайме «Челси» владеет мячом на 80%, то «Челси» выигрывает матч.

        Теперь предположим, что мы хотим предсказать, выиграет ли «Челси» матч или нет, если отрыв мячей в первом тайме равен 2, а владение мячом во втором тайме составляет 32%.

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

        Процесс обучения многослойного персептрона называется алгоритмом Backpropagation . Я бы порекомендовал вам пройти через блог Backpropagation .

        Рассмотрим диаграмму ниже:

        Прямое распространение:

        Здесь мы будем распространяться вперед, то есть вычислить взвешенную сумму входных данных и добавить смещение. В выходном слое мы будем использовать функцию softmax, чтобы получить вероятности выигрыша или проигрыша «Челси».

        Если вы обратили внимание на диаграмму, вероятность выигрыша составляет 0,4, а вероятность проигрыша — 0,6. Но, по нашим данным, мы знаем, что когда отрыв мячей в первом тайме равен 1, а владение мячом во втором тайме составляет 42%, «Челси» выиграет. Наша сеть сделала неверный прогноз.

        Если мы видим ошибку (Сравнение сетевого вывода с целевым), это 0,6 и -0,6.

        Обратное распространение и обновление веса:

        Я бы порекомендовал вам обратиться к блогу Backpropagation .

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

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

        Шаг — 1: Сначала мы вычисляем ошибку, рассмотрим уравнение ниже:

        Шаг — 2: На основе полученной ошибки он вычислит скорость изменения ошибки w.r.t изменение веса.

        Шаг — 3: Теперь, основываясь на этом изменении веса, мы рассчитаем новое значение веса.

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

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

        Теперь я могу подать вход в нашу сеть. Если я увеличу отрыв от ворот в первом тайме как 2, а владение мячом во втором тайме как 32%, наша сеть предскажет, выиграет ли «Челси» тот матч или нет.

        Теперь в этом руководстве по нейронной сети мы немного повеселимся на практике. Я буду использовать TensorFlow для моделирования многоуровневой нейронной сети.

        Сценарий использования:

        Давайте посмотрим на формулировку нашей проблемы:

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

        Первые четыре столбца — это характеристики, а последний столбец — метки.

        Данные были взяты из изображений, сделанных с подлинных и поддельных образцов, похожих на банкноты. Окончательные изображения имеют размер 400 × 400 пикселей. За счет линзы объекта и расстояния до исследуемого объекта в оттенках серого были получены снимки с разрешением около 660 dpi.Инструмент Wavelet Transform использовался для извлечения функций из изображений.

        Для реализации этого варианта использования мы будем использовать следующую блок-схему:

        Давайте выполним это сейчас:

        
        импортировать matplotlib.pyplot как plt
        импортировать тензорный поток как tf
        импортировать numpy как np
        импортировать панд как pd
        из sklearn.preprocessing import LabelEncoder
        из sklearn.utils import shuffle
        из sklearn.model_selection import train_test_split
        
        # Чтение набора данных
        def read_dataset ():
            df = pd.read_csv ("C: UsersSaurabhPycharmProjectsNeural Network Tutorialbanknote.csv ")
            # print (len (df.columns))
            X = df [df.columns [0: 4]]. Значения
            y = df [df.columns [4]]
        
            # Кодировать зависимую переменную
            Y = one_hot_encode (y)
            печать (X.shape)
            возврат (X, Y)
        
        
        # Определить функцию кодировщика.
        def one_hot_encode (метки):
            n_labels = len (метки)
            n_unique_labels = len (np.unique (метки))
            one_hot_encode = np.zeros ((n_labels, n_unique_labels))
            one_hot_encode [np.arange (n_labels), labels] = 1
            вернуть one_hot_encode
        
        
        # Прочитать набор данных
        X, Y = read_dataset ()
        
        # Перемешайте набор данных, чтобы перемешать строки.X, Y = перемешать (X, Y, random_state = 1)
        
        # Преобразование набора данных в поезд и тестовую часть
        train_x, test_x, train_y, test_y = train_test_split (X, Y, test_size = 0.20, random_state = 415)
        
        # Наблюдайте за формой обучения и тестирования.
        печать (train_x.shape)
        печать (train_y.shape)
        печать (test_x.shape)
        
        # Определить важные параметры и переменную для работы с тензорами
        learning_rate = 0,3
        training_epochs = 100
        cost_history = np.empty (shape = [1], dtype = float)
        n_dim = X.shape [1]
        print ("n_dim", n_dim)
        n_class = 2
        model_path = "C: UsersSaurabhPycharmProjectsNeural Network TutorialBankNotes"
        
        # Определить количество скрытых слоев и количество нейронов для каждого слоя
        n_hidden_1 = 4
        n_hidden_2 = 4
        n_hidden_3 = 4
        n_hidden_4 = 4
        
        х = tf.заполнитель (tf.float32, [None, n_dim])
        W = tf.Variable (tf.zeros ([n_dim, n_class]))
        b = tf.Variable (tf.zeros ([n_class]))
        y_ = tf.placeholder (tf.float32, [None, n_class])
        
        
        # Определить модель
        def Multilayer_perceptron (x, веса, смещения):
        
            # Скрытый слой с активациями RELUd
            layer_1 = tf.add (tf.matmul (x, weights ['h2']), biases ['b1'])
            layer_1 = tf.nn.relu (слой_1)
        
            # Скрытый слой с сигмовидной активацией
            layer_2 = tf.add (tf.matmul (layer_1, weights ['h3']), biases ['b2'])
            слой_2 = tf.nn.relu (слой_2)
        
            # Скрытый слой с сигмовидной активацией
            layer_3 = tf.add (tf.matmul (layer_2, weights ['h4']), biases ['b3'])
            layer_3 = tf.nn.relu (layer_3)
        
            # Скрытый слой с активацией RELU
            layer_4 = tf.add (tf.matmul (layer_3, weights ['h5']), biases ['b4'])
            layer_4 = tf.nn.sigmoid (layer_4)
        
            # Выходной слой с линейной активацией
            out_layer = tf.matmul (layer_4, weights ['out']) + biases ['out']
            return out_layer
        
        
        # Определить веса и смещения для каждого слоя
        
        веса = {
            'h2': tf.Переменная (tf.truncated_normal ([n_dim, n_hidden_1])),
            'h3': tf.Variable (tf.truncated_normal ([n_hidden_1, n_hidden_2])),
            'h4': tf.Variable (tf.truncated_normal ([n_hidden_2, n_hidden_3])),
            'h5': tf.Variable (tf.truncated_normal ([n_hidden_3, n_hidden_4])),
            'out': tf.Variable (tf.truncated_normal ([n_hidden_4, n_class]))
        }
        biases = {
            'b1': tf.Variable (tf.truncated_normal ([n_hidden_1])),
            'b2': tf.Variable (tf.truncated_normal ([n_hidden_2])),
            'b3': tf.Variable (tf.truncated_normal ([n_hidden_3])),
            'b4': tf.Переменная (tf.truncated_normal ([n_hidden_4])),
            'out': tf.Variable (tf.truncated_normal ([n_class]))
        }
        
        # Инициализировать все переменные
        
        init = tf.global_variables_initializer ()
        
        saver = tf.train.Saver ()
        
        # Назовите вашу модель определенной
        y = многослойный_перцептрон (x, веса, смещения)
        
        # Определить функцию затрат и оптимизатор
        cost_function = tf.reduce_mean (tf.nn.softmax_cross_entropy_with_logits (logits = y, labels = y_))
        training_step = tf.train.GradientDescentOptimizer (скорость_учения) .minimize (cost_function)
        
        сесс = tf.Сессия ()
        сесс.run (инициализация)
        
        # Рассчитать стоимость и точность для каждой эпохи
        
        mse_history = []
        точность_history = []
        
        для эпохи в диапазоне (training_epochs):
            сесс.run (training_step, feed_dict = {x: train_x, y_: train_y})
            cost = sessions.run (cost_function, feed_dict = {x: train_x, y_: train_y})
            cost_history = np.append (cost_history, стоимость)
            правильное_предсказание = tf.equal (tf.argmax (y, 1), tf.argmax (y_, 1))
            точность = tf.reduce_mean (tf.cast (правильное_предсказание, tf.float32))
            # print ("Точность:", (сесс.запустить (точность, feed_dict = {x: test_x, y_: test_y})))
            pred_y = sessions.run (y, feed_dict = {x: test_x})
            mse = tf.reduce_mean (tf.square (pred_y - test_y))
            mse_ = sessions.run (mse)
            mse_history.append (mse_)
            точность = (сесс.run (точность, feed_dict = {x: train_x, y_: train_y}))
            precision_history.append (точность)
        
            print ('эпоха:', эпоха, '-', 'стоимость:', стоимость, "- MSE:", mse_, "- Точность поезда:", точность)
        
        save_path = saver.save (сессия, путь_модели)
        print ("Модель сохранена в файле:% s"% save_path)
        
        #Plot Accuracy Graph
        plt.сюжет (точность_история)
        plt.xlabel ('Эпоха')
        plt.ylabel ('Точность')
        plt.show ()
        
        # Распечатать окончательную точность
        
        правильное_предсказание = tf.equal (tf.argmax (y, 1), tf.argmax (y_, 1))
        точность = tf.reduce_mean (tf.cast (правильное_предсказание, tf.float32))
        print ("Test Accuracy:", (sessions.run (precision, feed_dict = {x: test_x, y_: test_y})))
        
        # Вывести итоговую среднеквадратичную ошибку
        
        pred_y = sessions.run (y, feed_dict = {x: test_x})
        mse = tf.reduce_mean (tf.square (pred_y - test_y))
        print ("MSE:% .4f"% sessions.run (mse))
        
         

        После запуска этого кода вы получите следующий результат:

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

        Ниже приведен график зависимости эпох от точности:

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

        Надеюсь, вам понравилось читать это руководство по нейронной сети. Ознакомьтесь с другими блогами этой серии:

        Что такое глубокое обучение?

        Учебное пособие по глубокому обучению

        Учебное пособие по TensorFlow

        Обратное распространение

        После этого учебного курса по нейронной сети вскоре появятся блоги разных типов с разными типами нейронных сетей. Сверточная нейронная сеть и рекуррентная нейронная сеть.

        Оцените Deep Learning with TensorFlow Training от Edureka, надежной компании онлайн-обучения с сетью из более чем 250 000 довольных учащихся по всему миру. Курс Edureka Deep Learning with TensorFlow Certification Training помогает учащимся стать экспертами в обучении и оптимизации базовых и сверточных нейронных сетей с использованием проектов и заданий в реальном времени, а также таких понятий, как функция SoftMax, нейронные сети с автокодированием, ограниченная машина Больцмана (RBM).

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

        .

        Машинное обучение для начинающих: введение в нейронные сети | Виктор Чжоу

        Простое объяснение того, как они работают и как реализовать их с нуля на Python.

        Вот кое-что, что может вас удивить: нейронные сети не такие уж и сложные! Термин «нейронная сеть» часто используется как модное слово, но на самом деле они зачастую намного проще, чем люди думают.

        Этот пост предназначен для начинающих и предполагает НУЛЕВОЕ предварительное знание машинного обучения .Мы поймем, как работают нейронные сети, реализуя одну с нуля на Python.

        Приступим!

        Примечание: я рекомендую прочитать этот пост на victorzhou.com — большая часть форматирования в этом посте выглядит там лучше.

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

        Здесь происходит 3 вещи.Сначала каждый вход умножается на вес:

        Затем все взвешенные входы складываются вместе со смещением b:

        Наконец, сумма проходит через функцию активации:

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

        Сигмоидальная функция выводит только числа в диапазоне (0,1). Вы можете представить себе это как сжатие (−∞, + ∞) до (0,1) — большие отрицательные числа становятся ~ 0, а большие положительные числа становятся ~ 1.

        Напоминание: большая часть форматирования в этой статье выглядит лучше в исходном сообщении на victorzhou.com.

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

        w = [0, 1] — это просто способ записи w 1 = 0, w 2 = 1 в векторной форме. Теперь давайте введем нейрону x = [2, 3]. Мы будем использовать скалярное произведение, чтобы писать более кратко:

        Нейрон выводит 0.999 с учетом входных данных x = [2,3]. Это оно! Этот процесс передачи входных данных вперед для получения выходных данных известен как с прямой связью .

        Пора реализовать нейрон! Мы будем использовать NumPy, популярную и мощную вычислительную библиотеку для Python, чтобы помочь нам в математических вычислениях:

        Распознать эти числа? Это тот пример, который мы только что сделали! Получаем тот же ответ 0,999.

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

        Эта сеть имеет 2 входа, скрытый слой с 2 ​​нейронами ( h 1 и h 2) и выходной слой с 1 нейроном ( o 1). ).Обратите внимание, что входы для o 1 — это выходы из h 1 и h 2 — вот что делает эту сеть.

        Скрытый слой — это любой слой между входным (первым) и выходным (последним) слоями. Может быть несколько скрытых слоев!

        Давайте воспользуемся сетью, изображенной выше, и предположим, что все нейроны имеют одинаковые веса w = [0,1], одинаковое смещение b = 0 и одинаковую функцию активации сигмовидной кишки. Пусть h 1, h 2, o 1 обозначают выходы нейронов, которые они представляют.

        Что произойдет, если мы передадим на вход x = [2, 3]?

        Выход нейронной сети для входа x = [2,3] составляет 0,7216. Довольно просто, правда?

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

        Давайте реализуем прямую связь для нашей нейронной сети. Вот снова изображение сети для справки:

        Мы снова получили 0,7216! Похоже, работает.

        Допустим, у нас есть следующие измерения:

        Давайте обучим нашу сеть предсказывать пол человека с учетом его веса и роста:

        Мы представим мужчину с 0 и женщину с 1, а также перенесем данные в упростить использование:

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

        Мы будем использовать среднеквадратичную ошибку . (MSE) потеря:

        Давайте разберем это:

        • n — это количество выборок, которое равно 4 (Алиса, Боб, Чарли, Диана).
        • y представляет прогнозируемую переменную, т. Е. Пол.
        • y_true — это истинное значение переменной («правильный ответ»). Например, y_true для Алисы будет 1 (женщина).
        • y_pred — это предсказанное значение переменной. Это то, что выводит наша сеть.

        ( y_true y_pred ) ² известна как ошибка квадрата . Наша функция потерь просто берет среднее значение по всем квадратам ошибок (отсюда и название означает ошибку в квадрате ). Чем лучше наши прогнозы, тем меньше будут наши потери!

        Лучшие прогнозы = меньшие убытки.

        Обучение сети = попытка минимизировать ее потери.

        Допустим, наша сеть всегда выводит 00 — другими словами, она уверена, что все люди — мужчины 🤔. Какой была бы наша потеря?

        Код: MSE Loss

        Вот код для расчета потерь для нас:

        Если вы не понимаете, почему этот код работает, прочтите краткое руководство NumPy по операциям с массивами.

        Ницца. Вперед!

        Нравится этот пост? Я пишу много статей по ML для начинающих. Подпишитесь на мою рассылку, чтобы получать их в свой почтовый ящик!

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

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

        Для простоты представим, что у нас есть только Алиса в нашем наборе данных:

        Тогда среднеквадратичная потеря ошибки — это просто квадрат ошибки Алисы:

        Еще один способ думать о потерях — это как функция весов и смещений.Обозначим каждый вес и смещение в нашей сети:

        Затем мы можем записать потерю как многопараметрическую функцию:

        Представьте, что мы хотим настроить на 1. Как изменились бы потери L , если бы мы изменили w 1? На этот вопрос может ответить частная производная. Как рассчитать?

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

        Если у вас возникли проблемы с чтением этого: форматирование для приведенной ниже математики выглядит лучше в исходном сообщении на victorzhou.com.

        Для начала давайте перепишем частную производную в терминах ∂ y_pred / w 1 вместо:

        Это работает из-за правила цепочки.

        Мы можем вычислить ∂ L / y_pred , потому что мы вычислили L = (1− y_pred ) ² выше:

        Теперь давайте разберемся, что делать с ∂ y_pred / w 1.Как и раньше, пусть h 1, h 2, o 1 будут выходами нейронов, которые они представляют. Тогда

        f — это функция активации сигмовидной кишки, помните?

        Поскольку w 1 влияет только на h 1 (не h 2), мы можем написать

        More Chain Rule.

        Мы делаем то же самое для ∂ h 1 / ∂ w 1:

        Как вы уже догадались, Chain Rule.

        x 1 здесь вес, а x 2 высота. Это уже второй раз, когда мы видим f ′ ( x ) (производное сигмовидной функции)! Получим это:

        Мы будем использовать эту красивую форму для f ′ ( x ) позже.

        Готово! Нам удалось разбить ∂ L / w 1 на несколько частей, которые мы можем вычислить:

        Эта система вычисления частных производных путем работы в обратном направлении известна как backpropagation , или «backprop».

        Уф. Это было много символов — ничего страшного, если вы еще немного запутались. Давайте рассмотрим пример, чтобы увидеть это в действии!

        Мы продолжим притворяться, что в нашем наборе данных есть только Алиса:

        Давайте инициализируем все веса до 1 и все смещения до 0.Если мы сделаем прямой проход через сеть, мы получим:

        Сеть выводит y_pred = 0,524, что не очень благоприятно для Male (0) или Female (1). Рассчитаем ∂ L / w 1:

        Напоминание: мы вывели f ′ ( x ) = f ( x ) ∗ (1− f ( x ) )) для нашей сигмовидной функции активации ранее.

        Мы сделали это! Это говорит нам о том, что если бы мы увеличили w 1, L в результате увеличили бы tiiiny bit.

        Теперь у нас есть все необходимые инструменты для обучения нейронной сети! Мы будем использовать алгоритм оптимизации, называемый стохастическим градиентным спуском (SGD), который сообщает нам, как изменить наши веса и смещения, чтобы минимизировать потери. По сути, это просто уравнение обновления:

        η — это константа, называемая скоростью обучения , которая контролирует, насколько быстро мы тренируемся. Все, что мы делаем, это вычитаем η w 1 / ∂ L из w 1:

        • Если ∂ L / w 1 положительно, w 1 уменьшится, что составит уменьшение L .
        • Если ∂ L / w 1 отрицательно, w 1 увеличится, что приведет к уменьшению L .

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

        Наш процесс обучения будет выглядеть так:

        1. Выберите один образец из нашего набора данных. Это то, что делает его стохастическим градиентным спуском — мы работаем только с одним образцом за раз.
        2. Рассчитайте все частные производные потерь по весам или смещениям (например, ∂ L / w 1, ∂ L / ∂ w 2 и т. Д.).
        3. Используйте уравнение обновления для обновления каждого веса и смещения.
        4. Вернитесь к шагу 1.

        Давайте посмотрим на это в действии!

        Теперь , наконец, пора реализовать полную нейронную сеть:

        Вы можете запускать / играть с этим кодом самостоятельно. Он также доступен на Github.

        Наши потери неуклонно уменьшаются по мере того, как сеть учится:

        Теперь мы можем использовать сеть для предсказания пола:

        Вы сделали это! Краткий обзор того, что мы сделали:

        • Представлено нейронов , строительных блоков нейронных сетей.
        • Используется сигмовидная активационная функция в наших нейронах.
        • Видел, что нейронные сети — это просто нейроны, соединенные вместе.
        • Создан набор данных с весом и ростом в качестве входных данных (или с характеристиками ) и полом в качестве выходных данных (или метка ).
        • Узнал о функциях потерь и среднеквадратичной ошибке (MSE) потери.
        • Понятно, что обучение сети сводит к минимуму ее потери.
        • Используется обратного распространения ошибки для вычисления частных производных.
        • Использовал стохастический градиентный спуск (SGD) для обучения нашей сети.

        Еще многое предстоит сделать:

        Я могу написать на эти или похожие темы в будущем, поэтому подпишитесь, если вы хотите получать уведомления о новых сообщениях.

        Спасибо за чтение!

        .

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

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