Язык для программирования нейронных сетей

Истинная реализация нейросети с нуля на языке программирования C#

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

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

На самом деле, несмотря на обилие математики, она не такая уж и запредельно сложная. Понять сатанистские каракули и письмена этого пособия сможет среднестатистический 11-классник товарищ-физмат или 1

2-курсник технарьского учебного заведения. Помимо этого, пусть книга достаточно объёмная и трудная для восприятия, но вещи, написанные в ней, реально объясняют, что «твориться у тачки под капотом». Как вы поняли я крайне рекомендую(ни в коем случае не рекламирую) «Нейронные сети. Полный курс» Саймона Хайкина к прочтению в том случае, если вам придётся столкнуться с применением/написанием/разработкой нейросетей и прочего подобного stuff’а. Хотя в ней нет материала про новомодные свёрточные сети, никто не мешает загуглить лекции от какого-нибудь харизматичного работника Yandex/Mail.ru/etc. никто не мешает.

Моя видеокарта называется ATI Radeon HD Mobility 4570. И если кто знает, как обратиться к её мощностям для параллелизации нейросетевых вычислений, пожалуйста, напишите в комментарии. Тогда вы поможете мне, и возможно у этой статьи появится продолжение. Не осуждается предложение других ЯП.

Просто, как я понял, она настолько старая, что вообще ничего не поддерживает. Может быть я не прав.

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

Здесь я не буду рассматривать код сети для распознования цифр(как упоминалось ранее), ибо я оставил его на флэшке, удалив с ноута, а искать сей носитель информации мне лень, и в связи с этим я помогу вам сконструировать многослойный полносвязный персептрон для решения задачи XOR и XAND(XNOR, хз как ещё).

Многослойный полносвязный персептрон.
Один скрытый слой.
4 нейрона в скрытом слое(на этом количестве персептрон сошёлся).
Алгоритм обучения — backpropagation.
Критерий останова — преодоление порогового значения среднеквадратичной ошибки по эпохе.(0.001)
Скорость обучения — 0.1.
Функция активации — логистическая сигмоидальная.


Потом надо осознать, что нам нужно куда-то записывать веса, проводить вычисления, немного дебажить, ну и кортежи поиспользовать. Соответственно, using’и у нас такие.

В папке release||debug этого прожекта располагаются файлы(на каждый слой по одному) по имени типа (fieldname)_memory.xml сами знаете для чего. Они создаются заранее с учётом общего количества весов каждого слоя. Знаю, что XML — это не лучший выбор для парсинга, просто времени было немного на это дело.

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

Всё остальное будет происходить внутри пространства имён, которое я назову просто: Neural Network.

Прежде всего, важно понимать, почему нейроны входного слоя я изобразил квадратами. Ответ прост. Они ничего не вычисляют, а лишь улавливают информацию из внешнего мира, то есть получают сигнал, который будет пропущен через сеть. Вследствие этого, входной слой имеет мало общего с остальными слоями. Вот почему стоит вопрос: делать для него отдельный класс или нет? На самом деле, при обработке изображений, видео, звука стоит его сделать, лишь для размещения логики по преобразованию и нормализации этих данных к виду, подаваемому на вход сети. Вот почему я всё-таки напишу класс InputLayer. В нём находиться обучающая выборка организованная необычной структурой. Первый массив в кортеже — это сигналы-комбинации 1 и 0, а второй массив — это пара результатов этих сигналов после проведения операций XOR и XAND(сначала XOR, потом XAND).

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

Ладно у нас есть нейроны, но их необходимо объединить в слои для вычислений. Возвращаясь к моей схеме выше, хочу объяснить наличие чёрного пунктира. Он разделяет слои так, чтобы показать, что они содержат. То есть один вычислительный слой содержит нейроны и веса для связи с нейронами предыдущего слоя. Нейроны объединяются массивом, а не списком, так как это менее ресурсоёмко. Веса организованы матрицей(двумерным массивом) размера(нетрудно догадаться) [число нейронов текущего слоя X число нейронов предыдущего слоя]. Естественно, слой инициализирует нейроны, иначе словим null reference. При этом эти слои очень похожи друг на друга, но имеют различия в логике, поэтому скрытые и выходной слои должны быть реализованы наследниками одного базового класса, который кстати оказывается абстрактным.

Класс Layer — это абстрактный класс, поэтому нельзя создавать его экземпляры. Это значит, что наше желание сохранить свойства «слоя» выполняется путём наследования родительского конструктора через ключевое слово base и пустой конструктор наследника в одну строчку(ибо вся логика конструктора определена в базовом классе, и её не надо переписывать).

Теперь непосредственно классы-наследники: Hidden и Output. Сразу два класса в цельном куске кода.

В принципе, всё самое важное я описал в комментариях. У нас есть все компоненты: обучающие и тестовые данные, вычислительные элементы, их «конгламераты». Теперь настало время всё связать обучением. Алгоритм обучения — backpropagation, следовательно критерий останова выбираю я, и выбор мой — есть преодоление порогового значения среднеквадратичной ошибки по эпохе, которое я выбрал равным 0.001. Для поставленной цели я написал класс Network, описывающий состояние сети, которое принимается в качестве параметра многих методов, как вы могли заметить.

Результат обучения.

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

За сим всё, буду рад ответить на вопросы в комментариях, а пока извольте, новые дела ждут.
P.S.: Для желающих потыкать в код клацать.

UPD1(22.10.2020): господи как давно это было, надеюсь больше не буду писать такие статьи. Скорее всего в то время хотел поделиться с сообществом таким кодом, но так в ML никто не пишет)

Источник

Нейросети. Самый полный гайд. Часть 1 для чего нужны нейросети

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

Первая часть. Для чего нужны нейросети.

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

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

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

3. Создание алгоритма.

4. Запись алгоритма, на каком либо компьютерном языке.

5. Тестирование и отладка.

6. Проведение расчетов и анализ результатов.

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

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

Пример: «сделай мне бутер», это не детерминированная команда.

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

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

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

1. Исходные данные и результат.

Исходные данные: Робот – 1 штука. Ноги – 6 штук. Суставы на ногах – 3 штуки на каждой. Степени свободы у каждого сустава – по одной. Начальные координаты каждой ноги и сустава. Начальные углы в суставах робота. Начальная координата центра робота.

Результат: робот сместился на Х метров в указанном направлении.

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

3. Написание Алгоритма.

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

4. Превратим всё это в строчки кода.

5. Зальём в голову микрочип робота.

6. Отправим робота на прогулку.

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

Разумеется возникла идея создать такой алгоритм который мог бы подстроится к изменениям прям на ходу. Ведь паук в природе как то передвигается если ему оторвать ногу. Это и было зарождением нейросетей. По сути нейросеть – это такой алгоритм, который не нужно записывать в привычном понимании. Мы строим некую логическую конструкцию с начальными параметрами, а дальше она сама обучается, по каким-нибудь правилам, и принимает решение в каждом конкретном случае самостоятельно, исходя из старого опыта. История возникновения нейросетей отправляет нас прямиком к 1943 год, т.е. нейросети придумали сразу, как только появились ЭВМ. Но вот беда, в те времени один нейрон был размером с холодильник, а для серьёзных задач нейронов требовались сотни и даже тысячи. Почесав затылки, тогдашние программисты и инженеры сказали что мы и так всё сделаем без ваших нейросетей и отринули данную идею. Вновь к нейросетям вернулись только через 30 лет, за это время компьютеры шагнули невероятно далеко, на целых 4 поколения. В 71-м как вы помните, изобрели первый процессор. А в 75-м на этих крутейших по тем временам компам японский программист Кунихико Фукусима создал так называемый когнитрон – нейронную сеть умеющую выполнять логическую операцию «или». Вдумайтесь 30 лет от задумки да простейшей реализации.

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

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

Создание искусственного интеллекта – тоже пример использования нейросетей. Голова у Яндекс Алисы, или эпловской Сири, не из классических алгоритмов состоит, а из множества нейрончиков. Именно нейросети распознают вашу речь когда вы спрашиваете что то у гугла, и делают подборку песен, которая вам скорее всего понравиться. А ещё они всё больше вытесняет работников техподдержки, заставляя нас кричать в трубку: «Я хочу поговорить с человеком!». Если честно, всего 6 лет назад когда я смотрел фильм «Элизиум: Рай не на Земле», я и представить не мог себя в ситуации когда я буду спорить с роботом, и просить его переключить на человека. Но я думаю что с подобной проблемой сталкивались уже многие. Сейчас способности ИИ, оставляют желать лучшего, но скорость развития этих гомункулов поражает. И спустя те же 6 лет, человек в тех поддержке будет такой же редкостью, как сегодня использование DVD-дисков.

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

Источник

Поделиться с друзьями
admin
Оцените автора
( Пока оценок нет )
Как переводится?
Adblock
detector