Простая нейросеть. Как создать нейронную сеть без навыков программирования. Что такое нейрон

Nokia 20.04.2019
Nokia

Что мы будем делать? Мы попробуем создать простую и совсем маленькую нейронную сеть , которую мы объясним и научим что-нибудь различать. При этом не будем вдаваться в историю и математические дебри (такую информацию найти очень легко) — вместо этого постараемся объяснить задачу (не факт, что удастся) вам и самим себе рисунками и кодом.
Многие из терминов в нейронных сетях связаны с биологией, поэтому давайте начнем с самого начала:

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

Возбудитель может быть и внутренним (например, образ или идея):

А теперь взглянем на основные и упрощенные части мозга :

Мозг вообще похож на кабельную сеть.

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

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

Разумеется, это всё упрощения и обобщения, но благодаря им мы можем описать простую
нейронную сеть:

И описать её формализовано с помощью графа:

Тут требуются некоторые пояснения. Кружки — это нейроны, а линии — это связи между ними, и, чтобы не усложнять на этом этапе, взаимосвязи представляют собой прямое передвижение информации слева направо . Первый нейрон в данный момент активен и выделен серым. Также мы присвоили ему число (1 — если он работает, 0 — если нет). Числа между нейронами показывают вес связи.

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

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

Когда на них направляют безопасную струю воздуха, кролики, как и люди, моргают:

Эту модель поведения можно нарисовать графами:

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

Введем еще один элемент — безопасный звуковой сигнал:

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

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

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

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

Чтобы обучить кролика, повторим действия:

Для первых трех попыток схемы будут выглядеть так:

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

Мы убрали воздействие воздухом, но кролик все еще моргает, услышав звуковой сигнал! Объяснить это поведение может наша последняя схемка:

Мы обучили кролика реагировать на звук морганием.

В условиях реального эксперимента такого рода может потребоваться более 60 повторений для достижения результата.

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

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

Мы можем изобразить (схематично), что делает кнопка при нажатии следующим образом:

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

Нажмите на 3-ю кнопку, чтобы получить свой ужин.

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

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

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

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

Var inputs = ; var weights = ; // Для удобства эти векторы можно назвать

Следующий шаг — создание функции, которая собирает входные значения и веса и рассчитывает значение на выходе:

Function evaluateNeuralNetwork(inputVector, weightVector){ var result = 0; inputVector.forEach(function(inputValue, weightIndex) { layerValue = inputValue*weightVector; result += layerValue; }); return (result.toFixed(2)); } // Может казаться комплексной, но все, что она делает — это сопоставляет пары вес/ввод и добавляет результат

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

EvaluateNeuralNetwork(inputs, weights); // 0.00

Живой пример: Neural Net 001 . Следующим шагом в усовершенствовании нашей нейросети будет способ проверки её собственных выходных или результирующих значений сопоставимо реальной ситуации, давайте сначала закодируем эту конкретную реальность в переменную:

Чтобы обнаружить несоответствия (и сколько их), мы добавим функцию ошибки:

Error = Reality - Neural Net Output

С ней мы можем оценивать работу нашей нейронной сети:

Но что более важно — как насчет ситуаций, когда реальность дает положительный результат?

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

Error = Desired Output - Neural Net Output

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

Var input = ; var weights = ; var desiredResult = 1;

И новую функцию:

Function evaluateNeuralNetError(desired,actual) { return (desired — actual); } // After evaluating both the Network and the Error we would get: // "Neural Net output: 0.00 Error: 1"

Живой пример: Neural Net 002 . Подведем промежуточный итог . Мы начали с задачи, сделали её простую модель в виде биологической нейронной сети и получили способ измерения её производительности по сравнению с реальностью или желаемым результатом. Теперь нам нужно найти способ исправления несоответствия — процесс, который как и для компьютеров, так и для людей можно рассматривать как обучение.

Как обучать нейронную сеть?

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

В природе под алгоритмами обучения понимаются изменения физических или химических
характеристик нейронов после проведения экспериментов:

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

Var learningRate = 0.20; // Чем больше значение, тем быстрее будет процесс обучения:)

И что это изменит?

Это изменит веса (прям как у кролика!), особенно вес вывода, который мы хотим получить:

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

Function learn(inputVector, weightVector) { weightVector.forEach(function(weight, index, weights) { if (inputVector > 0) { weights = weight + learningRate; } }); }

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

// Original weight vector: // Neural Net output: 0.00 Error: 1 learn(input, weights); // New Weight vector: // Neural Net output: 0.20 Error: 0.8 // Если это не очевидно, вывод нейронной сети близок к 1 (выдача курицы) — то, чего мы и хотели, поэтому можно сделать вывод, что мы движемся в правильном направлении

Живой пример: Neural Net 003 . Окей, теперь, когда мы движемся в верном направлении, последней деталью этой головоломки будет внедрение повторов .

Это не так уж и сложно, в природе мы просто делаем одно и то же снова и снова, а в коде мы просто указываем количество повторов:

Var trials = 6;

И внедрение в нашу обучающую нейросеть функции количества повторов будет выглядеть так:

Function train(trials) { for (i = 0; i < trials; i++) { neuralNetResult = evaluateNeuralNetwork(input, weights); learn(input, weights); } }

Ну и наш окончательный отчет:

Neural Net output: 0.00 Error: 1.00 Weight Vector: Neural Net output: 0.20 Error: 0.80 Weight Vector: Neural Net output: 0.40 Error: 0.60 Weight Vector: Neural Net output: 0.60 Error: 0.40 Weight Vector: Neural Net output: 0.80 Error: 0.20 Weight Vector: Neural Net output: 1.00 Error: 0.00 Weight Vector: // Chicken Dinner !

Живой пример: Neural Net 004 . Теперь у нас есть вектор веса, который даст только один результат (курицу на ужин), если входной вектор соответствует реальности (нажатие на третью кнопку). Так что же такое классное мы только что сделали?

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

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

  • Механизм хранения изученных весов не предусмотрен, поэтому данная нейронная сеть забудет всё, что знает. При обновлении или повторном запуске кода нужно не менее шести успешных повторов, чтобы сеть полностью обучилась, если вы считаете, что человек или машина будут нажимать на кнопки в случайном порядке… Это займет какое-то время.
  • Биологические сети для обучения важным вещам имеют скорость обучения 1, поэтому нужен будет только один успешный повтор.
  • Существует алгоритм обучения, который очень напоминает биологические нейроны, у него броское название: правило widroff-hoff , или обучение widroff-hoff .
  • Пороги нейронов (1 в нашем примере) и эффекты переобучения (при большом количестве повторов результат будет больше 1) не учитываются, но они очень важны в природе и отвечают за большие и сложные блоки поведенческих реакций. Как и отрицательные веса.

Заметки и список литературы для дальнейшего чтения

Я пытался избежать математики и строгих терминов, но если вам интересно, то мы построили перцептрон , который определяется как алгоритм контролируемого обучения (обучение с учителем) двойных классификаторов — тяжелая штука. Биологическое строение мозга — тема не простая, отчасти из-за неточности, отчасти из-за его сложности. Лучше начинать с Neuroscience (Purves) и Cognitive Neuroscience (Gazzaniga). Я изменил и адаптировал пример с кроликом из Gateway to Memory (Gluck), которая также является прекрасным проводником в мир графов. Еще один шикарный ресурс An Introduction to Neural Networks (Gurney), подойдет для всех ваших нужд, связанных с ИИ.
А теперь на Python! Спасибо Илье Андшмидту за предоставленную версию на Python:

Inputs = weights = desired_result = 1 learning_rate = 0.2 trials = 6 def evaluate_neural_network(input_array, weight_array): result = 0 for i in range(len(input_array)): layer_value = input_array[i] * weight_array[i] result += layer_value print("evaluate_neural_network: " + str(result)) print("weights: " + str(weights)) return result def evaluate_error(desired, actual): error = desired - actual print("evaluate_error: " + str(error)) return error def learn(input_array, weight_array): print("learning...") for i in range(len(input_array)): if input_array[i] > 0: weight_array[i] += learning_rate def train(trials): for i in range(trials): neural_net_result = evaluate_neural_network(inputs, weights) learn(inputs, weights) train(trials)

А теперь на GO! За эту версию благодарю Кирана Мэхера.

Package main import ("fmt" "math") func main() { fmt.Println("Creating inputs and weights ...") inputs:= float64{0.00, 0.00, 1.00, 0.00} weights:= float64{0.00, 0.00, 0.00, 0.00} desired:= 1.00 learningRate:= 0.20 trials:= 6 train(trials, inputs, weights, desired, learningRate) } func train(trials int, inputs float64, weights float64, desired float64, learningRate float64) { for i:= 1; i < trials; i++ { weights = learn(inputs, weights, learningRate) output:= evaluate(inputs, weights) errorResult:= evaluateError(desired, output) fmt.Print("Output: ") fmt.Print(math.Round(output*100) / 100) fmt.Print(" Error: ") fmt.Print(math.Round(errorResult*100) / 100) fmt.Print(" ") } } func learn(inputVector float64, weightVector float64, learningRate float64) float64 { for index, inputValue:= range inputVector { if inputValue > 0.00 { weightVector = weightVector + learningRate } } return weightVector } func evaluate(inputVector float64, weightVector float64) float64 { result:= 0.00 for index, inputValue:= range inputVector { layerValue:= inputValue * weightVector result = result + layerValue } return result } func evaluateError(desired float64, actual float64) float64 { return desired - actual }

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

Теория

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

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

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

Электромеханический мозг с моторчиком

Машина Розенблатта называлась Mark I Perceptron. Она предназначалась для распознавания изображений - задачи, с которой компьютеры до сих пор справляются так себе. Mark I был снабжен подобием сетчатки глаза: квадратной матрицей из 400 фотоэлементов, двадцать по вертикали и двадцать по горизонтали. Фотоэлементы в случайном порядке подключались к электронным моделям нейронов, а они, в свою очередь, к восьми выходам. В качестве синапсов, соединяющих электронные нейроны, фотоэлементы и выходы, Розенблатт использовал потенциометры. При обучении перцептрона 512 шаговых двигателей автоматически вращали ручки потенциометров, регулируя напряжение на нейронах в зависимости от точности результата на выходе.

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

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

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

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

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

Практика

Итак, давай попробуем построить простейшую нейронную сеть своими руками и разберемся в ее работе по ходу дела. Мы будем использовать Python с библиотекой Numpy (можно было бы обойтись и без Numpy, но с Numpy линейная алгебра отнимет меньше сил). Рассматриваемый пример основан на коде Эндрю Траска.

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

Продолжение доступно только подписчикам

Вариант 1. Оформи подписку на «Хакер», чтобы читать все материалы на сайте

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

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

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

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

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

Идея нейросети заключается в том, чтобы собрать сложную структуру из очень простых элементов. Вряд ли можно считать разумным один-единственный участок мозга - а вот люди обычно на удивление неплохо проходят тест на IQ. Тем не менее до сих пор идею создания разума «из ничего» обычно высмеивали: шутке про тысячу обезьян с печатными машинками уже сотня лет, а при желании критику нейросетей можно найти даже у Цицерона, который ехидно предлагал до посинения подбрасывать в воздух жетоны с буквами, чтобы рано или поздно получился осмысленный текст. Однако в XXI веке оказалось, что классики ехидничали зря: именно армия обезьян с жетонами может при должном упорстве захватить мир.

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

Работает перцептрон проще некуда: он получает несколько исходных чисел, умножает каждое на «ценность» этого числа (о ней чуть ниже), складывает и в зависимости от результата выдаёт 1 или –1. Например, мы фотографируем чистое поле и показываем нашему нейрону какую-нибудь точку на этой картинке - то есть посылаем ему в качестве двух сигналов случайные координаты. А затем спрашиваем: «Дорогой нейрон, здесь небо или земля?» - «Минус один, - отвечает болванчик, безмятежно разглядывая кучевое облако. - Ясно же, что земля».

«Тыкать пальцем в небо» - это и есть основное занятие перцептрона. Никакой точности от него ждать не приходится: с тем же успехом можно подбросить монетку. Магия начинается на следующей стадии, которая называется машинным обучением . Мы ведь знаем правильный ответ - а значит, можем записать его в свою программу. Вот и получается, что за каждую неверную догадку перцептрон в буквальном смысле получает штраф, а за верную - премию: «ценность» входящих сигналов вырастает или уменьшается. После этого программа прогоняется уже по новой формуле. Рано или поздно нейрон неизбежно «поймёт», что земля на фотографии снизу, а небо сверху, - то есть попросту начнёт игнорировать сигнал от того канала, по которому ему передают x-координаты. Если такому умудрённому опытом роботу подсунуть другую фотографию, то линию горизонта он, может, и не найдёт, но верх с низом уже точно не перепутает.

Чтобы нарисовать прямую линию, нейрон исчеркает весь лист

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

Первые нейросети

Перцептроны устроены не намного сложнее, чем любые другие элементы компьютера, которые обмениваются единицами и нулями. Неудивительно, что первый прибор, устроенный по принципу нейросети - Mark I Perceptron, - появился уже в 1958 году, всего через десятилетие после первых компьютеров. Как было заведено в ту эпоху, нейроны у этого громоздкого устройства состояли не из строчек кода, а из радиоламп и резисторов. Учёный Фрэнк Розенблатт смог соорудить только два слоя нейросети, а сигналы на «Марк-1» подавались с импровизированного экрана размером в целых 400 точек. Устройство довольно быстро научилось распознавать простые геометрические формы - а значит, рано или поздно подобный компьютер можно было обучить, например, чтению букв.

Розенблатт и его перцептрон

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

Впрочем, были среди пионеров кибернетики и неисправимые скептики, самым грозным из которых оказался бывший однокурсник Розенблатта, Марвин Минский. Этот учёный обладал не менее громкой репутацией: тот же Азимов отзывался о нём с неизменным уважением, а Стэнли Кубрик приглашал в качестве консультанта на съёмки «Космической одиссеи 2001 года». Даже по работе Кубрика видно, что на самом деле Минский ничего не имел против нейросетей: HAL 9000 состоит именно из отдельных логических узлов, которые работают в связке друг с другом. Минский и сам увлекался машинным обучением ещё в 1950-х. Просто Марвин непримиримо относился к научным ошибкам и беспочвенным надеждам: недаром именно в его честь Дуглас Адамс назвал своего андроида-пессимиста.

В отличие от Розенблатта, Минский дожил до триумфа ИИ

Сомнения скептиков того времени Минский подытожил в книге «Перцептрон» (1969), которая надолго отбила у научного сообщества интерес к нейросетям. Минский математически доказал, что у «Марка-1» есть два серьёзных изъяна. Во-первых, сеть всего с двумя слоями почти ничего не умела - а ведь это и так уже был огромный шкаф, пожирающий уйму электричества. Во-вторых, для многослойных сетей алгоритмы Розенблатта не годились: по его формуле часть сведений об ошибках сети могла потеряться, так и не дойдя до нужного слоя.

Минский не собирался сильно критиковать коллегу: он просто честно отметил сильные и слабые стороны его проекта, а сам продолжил заниматься своими разработками. Увы, в 1971 году Розенблатт погиб - исправлять ошибки перцептрона оказалось некому. «Обычные» компьютеры в 1970-х развивались семимильными шагами, поэтому после книги Минского исследователи попросту махнули рукой на искусственные нейроны и занялись более перспективными направлениями.

Эпоха застоя

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

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

1993 год: капча уже морально устарела

К середине 1990-х исследователи сошлись на том, что самое полезное свойство нейросетей - их способность самостоятельно придумывать верные решения. Метод проб и ошибок позволяет программе самой выработать для себя правила поведения. Именно тогда стали входить в моду соревнования самодельных роботов, которых программировали и обучали конструкторы-энтузиасты. А в 1997 году суперкомпьютер Deep Blue потряс любителей шахмат, обыграв чемпиона мира Гарри Каспарова.

Строго говоря, Deep Blue не учился на своих ошибках, а попросту перебирал миллионы комбинаций

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

Вторая «оттепель» ИИ случилась, только когда изменилась сама философия программирования.

Нейросети наших дней

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

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

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

Так и произошло третье пришествие перцептронов - на этот раз уже под знакомыми нам названиями «нейросети» и «глубинное обучение». Неудивительно, что новостями об успехах ИИ чаще всего делятся такие крупные корпорации как Google и IBM. Их главный ресурс - огромные дата-центры, где на мощных серверах можно тренировать многослойные нейросети. Эпоха машинного обучения по-настоящему началась именно сейчас, потому что в интернете и соцсетях наконец-то накопились те самые big data, то есть гигантские массивы информации, которые и скармливают нейросетям для обучения.

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

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

В сфере развлечений компьютеры продвинулись не хуже, чем в науке. За счёт машинного обучения им наконец поддались игры, алгоритмы выигрыша для которых придумать ещё сложнее, чем для шахмат. Недавно нейросеть AlphaGo разгромила одного из лучших в мире игроков в го, а программа Libratus победила в профессиональном турнире по покеру. Более того, ИИ уже постепенно пробирается и в кино: например, создатели сериала «Карточный домик» использовали big data при кастинге, чтобы подобрать максимально популярный актёрский состав.

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

«Ты всего лишь машина. Только имитация жизни. Разве робот сочинит симфонию? Разве робот превратит кусок холста в шедевр искусства?» («Я, робот»)

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

Игры с ботами

Развлекаться с недоученными нейросетями очень весело: они порой выдают такие ошибки, что в страшном сне не приснится. А если ИИ начинает учиться, появляется азарт: «Неужто сумеет?» Поэтому сейчас набирают популярность интернет-игры с нейросетями.

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

Другое развлечение с «угадайкой» предлагает ИИ от Google : нужно накалякать за двадцать секунд рисунок к заданному слову, а нейросеть потом пробует угадать, что это было. Программа очень смешно промахивается, но порой для верного ответа хватает всего пары линий - а ведь именно так узнаём объекты и мы сами.

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

Революция откладывается

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

Главная слабость нейросетей в том, что каждая из них заточена под определённую задачу. Если натренировать сеть на фотографиях с котиками, а потом предложить ей задачку «отличи небо от земли», программа не справится, будь в ней хоть миллиард нейронов. Чтобы появились по-настоящему «умные» компьютеры, надо придумать новый алгоритм, объединяющий уже не нейроны, а целые сети, каждая из которых занимается конкретной задачей. Но даже тогда до человеческого мозга компьютерам будет далеко.

Сейчас самой крупной сетью располагает компания Digital Reasoning (хотя новые рекорды появляются чуть ли не каждый месяц) - в их творении 160 миллиардов элементов. Для сравнения: в одном кубическом миллиметре мышиного мозга около миллиарда связей. Причём биологам пока удалось описать от силы участок в пару сотен микрометров, где нашлось около десятка тысяч связей. Что уж говорить о людях!

Один слой умеет узнавать людей, другой - столы, третий - ножи…

Такими 3D-моделями модно иллюстрировать новости о нейросетях, но это всего лишь крошечный участок мышиного мозга

Кроме того, исследователи советуют осторожнее относиться к громким заявлениям Google и IBM. Никаких принципиальных прорывов в «когнитивных вычислениях» с 1980-х годов не произошло: компьютеры всё так же механически обсчитывают входящие данные и выдают результат. Нейросеть способна найти закономерность, которую не заметит человек, - но эта закономерность может оказаться случайной. Машина может подсчитать, сколько раз в твиттере упоминается «Оскар», - но не сможет определить, радуются пользователи результатам или ехидничают над выбором киноакадемии.

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

Сказки про Скайнет


Хотя нам самим сложно удержаться от иронии на тему бунта роботов, серьёзных учёных не стоит даже и спрашивать о сценариях из «Матрицы» или «Терминатора»: это всё равно что поинтересоваться у астронома, видел ли он НЛО. Исследователь искусственного интеллекта Элиезер Юдковски, известный по роману « », написал ряд статей, где объяснил, почему мы так волнуемся из-за восстания машин - и чего стоит опасаться на самом деле.

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

Бояться надо не врагов, а чересчур усердных друзей. У любой нейросети есть мотивация: если ИИ должен гнуть скрепки, то, чем больше он их сделает, тем больше получит «награды». Если дать хорошо оптимизированному ИИ слишком много ресурсов, он не задумываясь переплавит на скрепки всё окрестное железо, потом людей, Землю и всю Вселенную. Звучит безумно - но только на человеческий вкус! Так что главная задача будущих создателей ИИ - написать такой жёсткий этический кодекс, чтобы даже существо с безграничным воображением не смогло найти в нём «дырок».

* * *

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

Сделай сам


Нейронную сеть можно сделать с помощью спичечных коробков - тогда у вас в арсенале появится фокус, которым можно развлекать гостей на вечеринках. Редакция МирФ уже попробовала - и смиренно признаёт превосходство искусственного интеллекта. Давайте научим неразумную материю играть в игру «11 палочек». Правила просты: на столе лежит 11 спичек, и в каждый ход можно взять либо одну, либо две. Побеждает тот, кто взял последнюю. Как же играть в это против «компьютера»? Очень просто.

  1. Берём 10 коробков или стаканчиков. На каждом пишем номер от 2 до 11.
  2. Кладём в каждый коробок два камешка - чёрный и белый. Можно использовать любые предметы - лишь бы они отличались друг от друга. Всё - у нас есть сеть из десяти нейронов!

Теперь начинается игра.

  1. Нейросеть всегда ходит первой. Для начала посмотрите, сколько осталось спичек, и возьмите коробок с таким номером. На первом ходу это будет коробок №11.
  2. Возьмите из нужного коробка любой камешек. Можно закрыть глаза или кинуть монетку, главное - действовать наугад.
  3. Если камень белый - нейросеть решает взять две спички. Если чёрный - одну. Положите камешек рядом с коробком, чтобы не забыть, какой именно «нейрон» принимал решение.
  4. После этого ходит человек - и так до тех пор, пока спички не закончатся.

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

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



Рекомендуем почитать

Наверх