и
IT 12.08.2020

Как работает нейронная сеть: обучение, функции активации и потери

15 мин.

Что такое нейросеть?

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

Более простыми словами, это некий чёрный ящик, который превращает входные данные в выходные, или, говоря более математическим языком, является отображением пространства входных признаков X в пространство выходных признаков Y: X → Y. То есть мы хотим найти какую-то функцию F, которая сможет выполнять это преобразование. Для начала этой информации нам будет достаточно. Для более подробного ознакомления рекомендуем ознакомиться с этой статьёй на хабре.

Искусственный нейрон

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

Не пугайтесь, ничего сложного здесь нет. Давайте рассмотрим все подробно слева направо.

Входы, веса и сумматор

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

Поступившие на входы сигналы умножаются на свои веса. Сигнал первого входа ​( x_1 )​ умножается на соответствующий этому входу вес ​( w_1 )​. В итоге получаем ​( x_1w_1 )​. И так до ​( n )​-ого входа. В итоге на последнем входе получаем ​( x_nw_n )​.

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

[ x_1w_1+x_2w_2+cdots+x_nw_n = sumlimits^n_{i=1}x_iw_i ]

Математическая справка Сигма – Википедия

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

Рассмотрим простейший вариант записи:

[ sumlimits^5_{i=1}i=1+2+3+4+5 ]

Таким образом снизу сигмы мы присваиваем переменной-счетчику ​( i )​ стартовое значение, которое будет увеличиваться, пока не дойдет до верхней границы (в примере выше это 5).

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

Пусть у нас есть ​( n ) магазинов. У каждого магазина есть свой номер: от 1 до ​( n )​. Каждый магазин приносит прибыль. Возьмем какой-то (неважно, какой) ​( i )​-ый магазин. Прибыль от него равна ​( p_i )​.

Если мы хотим посчитать общую прибыль от всех магазинов (обозначим ее за ​( P )​), то нам пришлось бы писать длинную сумму:

[ P = p_1+p_2+cdots+p_i+cdots+p_n ]

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

[ P=sumlimits^n_{i=1}p_i ]

Словами: «Просуммируй прибыли всех магазинов, начиная с первого и заканчивая ​( n )​-ым». В виде формулы это гораздо проще, удобнее и красивее.

Результатом работы сумматора является число, называемое взвешенной суммой.

Взвешенная сумма (Weighted sum) (​( net )​) — сумма входных сигналов, умноженных на соответствующие им веса.

[ net=sumlimits^n_{i=1}x_iw_i ]

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

Функция активации

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

  • Сигмоида: f(x) = 1 / (1 + e-x)
  • Гиперболический тангенс: f(x) = tanh(x)
  • ReLU: f(x) = max(x,0)

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

Хватит бла бла, давайте писать код

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

  1. Вектор (входные, выходные);
  2. Матрица (каждый слой содержит матрицу весовых коэффициентов);
  3. Нейросеть.

1. Вектор:

  • Вектор можно создавать из количества элементов (длины);
  • Вектор можно создавать из перечисления вещественных чисел;
  • Можно получать значения по индексу i.
  • Можно изменять значения по индексу i.

Напишем же это:

class Vector { public double[] v; // значения вектора public int n; // длина вектора // конструктор из длины public Vector(int n) { this.n = n; // копируем длину v = new double[n]; // создаём массив } // создание вектора из вещественных значений public Vector(params double[] values) { n = values.Length; v = new double[n]; for (int i = 0; i < n; i++) v[i] = values[i]; } // обращение по индексу public double this[int i] { get { return v[i]; } // получение значение set { v[i] = value; } // изменение значения } }

2. Матрица:

  • Матрицу можно создавать из числа строк, столбцов и генератора случайных чисел для заполнения случайными значениями;
  • Можно получать значения по индексам i и j;
  • Можно изменять значения по индексам i и j;

Напишем же это:

class Matrix { double[][] v; // значения матрицы public int n, m; // количество строк и столбцов // создание матрицы заданного размера и заполнение случайными числами из интервала (-0.5, 0.5) public Matrix(int n, int m, Random random) { this.n = n; this.m = m; v = new double[n][]; for (int i = 0; i < n; i++) { v[i] = new double[m]; for (int j = 0; j < m; j++) v[i][j] = random.NextDouble() – 0.5; // заполняем случайными числами } } // обращение по индексу public double this[int i, int j] { get { return v[i][j]; } // получение значения set { v[i][j] = value; } // изменение значения } }

3. Сама нейросеть:

class Network { Matrix[] weights; // матрицы весов слоя int layersN; // число слоёв // создание сети из массива количества нейронов в каждом слое public Network(int[] sizes) { Random random = new Random(DateTime.Now.Millisecond); // создаём генератор случайных чисел layersN = sizes.Length – 1; // запоминаем число слоёв weights = new Matrix[layersN]; // создаём массив матриц // для каждого слоя создаём матрицы весовых коэффициентов for (int k = 1; k < sizes.Length; k++) { weights[k – 1] = new Matrix(sizes[k], sizes[k – 1], random); } } // получение выхода сети (прямое распространение) Vector Forward(Vector input) { Vector output; // будущий выходной вектор for (int k = 0; k < layersN; k++) { output = new Vector(weights[k].n); // создаём новый выходной вектор для каждого слоя for (int i = 0; i < weights[k].n; i++) { double y = 0; // неактивированный выход нейрона for (int j = 0; j < weights[k].m; j++) y += weights[k][i, j] * input[j]; // выполняем активацию с помощью сигмоидальной функции output[i] = 1 / (1 + Math.Exp(-y)); // выполняем активацию с помощью гиперболического тангенса // output[i] = Math.Tanh(y); // выполняем активацию с помощью ReLU // output[i] = Math.Max(0, y); } } return output; } }

Прямое распространение ошибки

Прямое распространение ошибки
Прямое распространение

Зададим начальные веса случайным образом:

  • w1
  • w2
  • w3

Умножим входные данные на веса для формирования скрытого слоя:

  • h1 = (x1 * w1) + (x2 * w1)
  • h2 = (x1 * w2) + (x2 * w2)
  • h3 = (x1 * w3) + (x2 * w3)

Выходные данные из скрытого слоя передается через нелинейную функцию (функцию активации), для получения выхода сети:

  • y_ = fn(h1 , h2, h3)

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

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

  • Суммарная ошибка (total_error) вычисляется как разность между ожидаемым значением «y» (из обучающего набора) и полученным значением «y_» (посчитанное на этапе прямого распространения ошибки), проходящих через функцию потерь (cost function).
  • Частная производная ошибки вычисляется по каждому весу (эти частные дифференциалы отражают вклад каждого веса в общую ошибку (total_loss)).
  • Затем эти дифференциалы умножаются на число, называемое скорость обучения или learning rate (η).

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

В результате получатся следующие обновленные веса:

  • w1 = w1 — (η * ∂(err) / ∂(w1))
  • w2 = w2 — (η * ∂(err) / ∂(w2))
  • w3 = w3 — (η * ∂(err) / ∂(w3))

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

карлон data scientist
Популярный мем о том, как Карлсон стал Data Science разработчиком

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

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

Частные производные

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

Разберем необходимость частных производных на примере.

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

основы - нейронная сеть

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

частные производные

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

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

нейронные сети частная производная

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

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

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

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

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

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

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

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

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

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

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

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

Одна итерация МОР даёт небольшой процент уменьшения ошибки, поэтому повторять их необходимо снова и снова пока показатель ошибки не будет приближен к 0.

Метод упругого распространения

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

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

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

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

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

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

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

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

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

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

Генетический Алгоритм

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

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

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

Другие вариации обучения

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

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

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

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

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

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

Есть ещё несколько методов обучения:

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

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

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

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

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

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

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

ПОСМОТРИТЕ ВИДЕО(ЭТО ВАЖНО):

НЕЙРОТЕХНОЛОГИИ СЕГОДНЯ

  • Понимание устройства и принципов работы головного мозга человека — одна из главных проблем мировой науки. Организация Объединенных Наций назвала первое десятилетие XXI века декадой изучения мозга.
  • Объем рынка нейротехнологий составляет 180 млрд долларов США.
  • Многие государства готовы вкладывать деньги в научно-исследовательские проекты по изучению мозга. Самые крупные из них:
    – BRAIN Initiative — США, 3 млрд долларов;
    – Human Brain Project — ЕС, 1 млрд. 190 млн. евро;
    – Blue Brain — Швейцария, 100 млн. евро.
  • По данным Российской венчурной компании, областями, где нейроразработки уже сегодня находят практическое применение, являются:
    – медицина (кохлеарные импланты — электронные устройства, возвращающие слух, протезы);
    – военное применение (управление сложной техникой, включая дистанционное управление боевыми роботами);
    – индустрия развлечений (создание нейроигр).

Выводы

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

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

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

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

Источники

  • https://programforyou.ru/poleznoe/pishem-neuroset-pryamogo-rasprostraneniya
  • https://neuralnet.info/chapter/%D0%BE%D1%81%D0%BD%D0%BE%D0%B2%D1%8B-%D0%B8%D0%BD%D1%81/
  • https://neurohive.io/ru/osnovy-data-science/osnovy-nejronnyh-setej-algoritmy-obuchenie-funkcii-aktivacii-i-poteri/
  • https://livesurf.ru/zhurnal/6068-metody-obucheniya-nejronnyx-setej.html
  • https://habr.com/ru/post/351922/
  • https://intalent.pro/industry/neyrotehnologii.html
[свернуть]
Оцените статью
Понравилась статья?
Комментарии (0)
Комментариев нет, будьте первым кто его оставит

Комментарии закрыты.