Библиотека сайта rus-linux.net
Разработка нейронной сети на языке Python
Оригинал: Creating a Neural Network in Python
Автор: John Serrano
Дата публикации: 26 мая 2016 г.
Перевод: А.Панин
Дата перевода: 6 декабря 2016 г.
Нейронные сети являются крайне сложными программами, доступными для понимания лишь академикам и гениям, с которыми по определению не могут работать обычные разработчики, не говоря уже обо мне. Вы ведь так думаете?
Ну, на самом деле все совсем не так. После отличного выступления Луиса Моньера и Грега Ренарда в Колледже Холбертон я понял, что нейронные сети являются достаточно простыми для понимания и реализации любым разработчиком программами. Разумеется, самые сложные сети представляют собой масштабные проекты с элегантной и замысловатой архитектурой, но положенные в их основу концепции также являются более или менее очевидными. Разработка любой нейронной сети с нуля может оказаться достаточно сложной задачей, но, к счастью, существует несколько отличных библиотек, которые могут выполнять всю низкоуровневую работу за вас.
В данном контексте нейрон является довольно простой сущностью. Он принимает несколько входных значений и в том случае, если сумма этих значений превышает заданный предел, активируется. При этом каждое входное значение умножается на его вес. Процесс обучения по сути является процессом установки весов значений для генерации необходимых выходных значений. Сети, которые будут рассматриваться в данной статье, называются сетями "прямого распространения", и это означает, что нейроны в них расположены по уровням, причем их входные данные приходят с предыдущего уровня а выходные - отправляются на следующий уровень.
Существуют нейронные сети и других типов, такие, как рекуррентные нейронные сети, которые организованы отличным образом, но это тема для другой статьи.
Нейрон, работающий по описанному выше принципу, называется перцептроном и основан на оригинальной модели искусственных нейронов, которая на сегодняшний день используется крайне редко. Проблема перцептронов заключается в том, что небольшое изменение входных значений может привести к значительному изменению выходного значения из-за ступенчатой функции активации. При этом незначительное уменьшение входного значения может привести к тому, что внутреннее значение не будет превышать установленный предел и нейрон не будет активироваться, что приведет к еще более значительным изменениям состояния следующих за ним нейронов. К счастью, эта проблема легко решается с помощью более плавной функции активации, которая используется в большинстве современных сетей.
Однако, наша нейронная сеть будет настолько простой, что для ее создания вполне подойдут перцептроны. Мы будем создавать сеть, выполняющую логическую операцию "И". Это означает, что нам понадобятся два входных нейрона и один выходной нейрон, а также несколько нейронов на промежуточном "скрытом" уровне. На иллюстрации ниже показана архитектура данной сети, которая должна быть вполне очевидной.
Моньер и Ренард использовали сценарий convnet.js для создания демонстрационных сетей для своего выступления. Convnet.js может использоваться для создания нейронных сетей непосредственно в вашем веб-браузере, что позволяет вам исследовать и модифицировать их практически на любой платформе. Конечно же, у данной реализации на языке JavaScript присутствуют и значительные недостатки, одним из которых является низкая скорость работы. Ну а в рамках данной статьи мы будем использовать библиотеку FANN (Fast Artifical Neural Networks). При этом на уровне языка программирования Python будет использоваться модуль pyfann, который содержит биндинги для библиотеки FANN. Вам следует установить пакет программного обеспечения с данным модулем прямо сейчас.
Импорт модуля для работы с библиотекой FANN осуществляется следующим образом:
>>> from pyfann import libfann
Теперь мы можем начать работу! Первой операцией, которую нам придется выполнить, является создание пустой нейронной сети.
>>> neural_net = libfann.neural_network()
Созданный объект neural_net
на данный момент не содержит нейронов, поэтому давайте попробуем создать их. Для этой цели мы будем использовать функцию libfann.create_standard_array()
. Функция create_standard_array()
создает нейронную сеть, в которой все нейроны соединены с нейронами из соседних уровней, поэтому ее можно назвать "полностью соединенной" сетью. В качестве параметра функция create_standard_array()
принимает массив с числовыми значениями, соответствующими количеству нейронов на каждом из уровней. В нашем случае это массив [2, 4, 1]
.
>>> neural_net.create_standard((2, 4, 1))
После этого нам придется установить значение скорости обучения. Данное значение соответствует количеству изменений весов в рамках одной итерации. Мы установим достаточно высокую скорость обучения, равную 0.7
, так как мы будем решать с помощью нашей сети достаточно простую задачу.
>>> neural_net.set_learning_rate(0.7)
Теперь пришло время установить функцию активации, назначение которой обсуждалось выше. Мы будем использовать режим активации SIGMOID_SYMMETRIC_STEPWISE
, который соответствует функции ступенчатой аппроксимации гиперболического тангенса. Она является менее точной и более быстрой, чем обычная функция гиперболического тангенса и отлично подходит для нашей задачи.
>>> neural_net.set_activation_function_output(libfann.SIGMOID_SYMMETRIC_STEPWISE)
Наконец, нам нужно запустить алгоритм обучения сети и сохранить данные сети в файле. Функция обучения сети принимает четыре аргумента: имя файла с данными, на основе которых будет осуществляться обучение, максимальное количество попыток запуска алгоритма обучения, количество операций обучения перед выводом данных о состоянии сети, а также частота ошибок.
>>> neural_network.train_on_file("and.data", 10000, 1000, .00001) >>> neural_network.save("and.net")
Файл "and.data"
должен содержать следующие данные:
4 2 1 -1 -1 -1 -1 1 -1 1 -1 -1 1 1 1
Первая строка содержит три значения: количество примеров в файле, количество входных значений и количество выходных значений. Ниже расположены строки примеров, причем в строках с двумя значениями приведены входные значения, а в строках с одним значением - выходные.
Вы успешно закончили обучение сети и теперь хотите испытать ее в работе, не так ли? Но сначала нам придется загрузить данные сети из файла, в котором они были сохранены ранее.
>>> neural_net = libfann.neural_net() >>> neural_net.create_from_file("and.net")
После этого мы можем просто активировать ее аналогичным образом:
>>> print neural_net.run([1, -1])
В результате должно быть выведено значение [-1.0]
или аналогичное значение, зависящее от данных сети, сгенерированных в процессе ее обучения.
Поздравляю! Вы только что научили компьютер выполнять простейшие логические операции!