Проблески Разума. Как создать искусственный интеллект. (Завершение цикла "О чём молчит Пенроуз")
В этой части, ни много, ни мало, рассказано об алгоритме, который лежит в основе интеллектуальной деятельности. Параллельно мы попытаемся ответить на вопрос как похожие явления могли возникнуть в естественном интеллекте. Всех секретов интеллекта мы, конечно, не раскроем, сумермозг не создадим, но принципы, главное направление куда дальше копать, мы узнаем. Узнаем мы побольше и про человеческий интеллект. Будут и практические наброски алгоритмов, которые можно прямо сейчас программировать на компьютере.
Но сначала вкратце, до чего мы дошли в предыдущих частях (http://dima78.livejournal.com/tag/penrose). Я уже и сам забыл, что там было, так что придётся и для себя напомнить, иначе даже не смогу рассказывать дальше. :) Кто помнит - пропускаем это раздел.
Что было в прошлых частях
Пенроуз, в своих замечательных книжках, считает, что мозг способен выдавать абсолютно истинные суждения, и утверждает, что в основе мыслительных процессов лежат физические процессы, которые могут выполнять вечные вычисления за конечное время. Причём вычисляют эти процессы не абы что, а абсолютную и неопровержимую истину в самом прямом смысле этого слова. И мозг может "дёргать" эти процессы, чтобы подумать. И именно поэтому для работы мозга нужны такие процессы. И, хотя сегодняшней физике такие процессы неизвестны, Пенроуз полагает, что более глубокий уровень мироздания составляет иная реальность, основанная на таких вот процессах.
Во многом Пенроуз прав насчёт этой иной реальности, и даже более того, как-нибудь мы расскажем не менее интересные и похожие идеи насчёт того, что лежит в основах мироздания. Но всё-таки Пенроуз поторопился, перескочил, так сказать несколько ступенек. Подавляющее (если не всё) большинство интеллектуальной деятельности можно объяснить более прозаическими и приземлёнными вещами.
Несомненная заслуга Пенроуза в том, что он убедительно объяснил, почему интеллектуальная деятельность никак не может быть основана на формальной логике (или другими словами, на строгих алгоритмах). Точнее, Пенроуз показал, что абсолютно истинная логика (она же в понимании Пенроуза интеллектуальная деятельность) невозможна на известных физических процессах. Но мы поняли это по-своему, а именно, что интеллектуальная деятельность не нуждается в абсолютно истинной логике. Или, другими словами, человеческий интеллект правдоподобен, он выдаёт хорошие приближения к истине, но вероятность ошибки всё-же есть. А это кардинально меняет дело, а именно, совершенно меняет подходы к тому, как объяснить естественный интеллект, и как построить искусственный интеллект. И такой интеллект можно промоделировать на машине Тьюринга, запрограммировать на обычном компьютере, правда, лучше иметь архитектуру большей мощности и с присущим параллелизмом, например, квантовую или оптическую.
Теперь напомним, что за сыр-бор вокруг истиной и не истиной логики. Математические и компьютерные вычисления, человеческие размышления, логические построения и умозаключения связывают с понятием алгоритма или формальной системы (фактически это одно и тоже). Выполнение алгоритма (оно же применение правил формальной системы) это и есть модель всяческих вычислений, размышлений и прочих физических процессов (или, как минимум, достаточно хорошее приближение). Алгоритм - это набор инструкций, которые последовательно по шагам может выполнить какой-то абстрактный компьютер (машина Тьюринга).
Есть понятие строгого алгоритма (оно же полная и непротиворечивая формальная система). На одном и том же наборе входных данных, строгий алгоритм за конечное число шагов выдаст один и тот же ответ. В применении к формальным системам и логическим рассуждениям это значит, что за конечное время для исходных условий можно найти истинный (непротиворечивый и однозначный) ответ. Такие вычисления ещё называют детерминированными.
Но есть и недетерминированные (нестрогие) алгоритмы, в которых эти условия не соблюдаются (они же неполные/противоречивые формальные системы). Для алгоритма несоблюдение условия конечности означает, что неизвестно закончит ли алгоритм своё вычисление, и непонятно как об этом узнать заранее. Недетерминированный алгоритм может закончить своё вычисление, а может и блуждать вечно, но что именно он сделает - это загадка, отгадывать которую можно вечно. Для формальных систем доказательство истинности или ложности исходного утверждения непонятно закончится когда-нибудь или будет продолжаться вечно. Противоречивость значит, что внутри формальной системы можно подобрать разные цепочки правил, которые для исходного утверждения выдадут и истинный и ложный ответ. Для алгоритма это значит, что на одних и тех же данных могут быть получены разные результаты.
Многие, в том числе Пенроуз, говорят, что интеллектуальная деятельность основана на строгой формальной логике. Но тут есть глобальная засада. Давно доказанная теорема Гёделя говорит, что формальная система не может быть одновременно полной и непротиворечивой. Полнота означает, что формальная система знает о своей области знаний всё. В том числе такая система может судить об истинности самой себя. Если формальную систему создаст кто-то извне, то она сможет работать, выдавая правильные результаты и нисколько не заботясь о том, правильно ли её создал этот кто-то. Если же формальная система попытается убедиться в том, что она сделана правильно, то ничего у неё не получится. Потому что наша система непротиворечива, но не полна. Если же система сможет судить о правильности самой себя (полна), то у такой системы будут внутренние противоречия, и результаты её деятельности необязательно правильные. Почему? В том числе и потому, что вопрос самопроверки (самопознания, саморефлексирования) относится к разряду вечных вычислений.
Что из этого следует? Получается (по Пенроузу), что человеческий интеллект - это полная и непротиворечивая система, потому что может генерировать истинные высказывания и в тоже время следить за правильностью самой себя. Но по теореме Гёделя это невозможно. Вот и приходится привлекать для работы интеллекта неизвестные физические процессы, которые в краткий миг могут окинуть взглядом вечность, найти ответ и вернуть этот ответ в мозг. Но как мы уже заметили, интеллект вовсе не обязан быть полным и непротиворечивым, хотя при этом может очень правдоподобно прикидываться истинным и непогрешимым.
Вторая засада - физике неизвестны сущности, которыми оперирует формальная логика. А именно, формальные рассуждения часто основаны на понятиях натуральных чисел, понятиях истинности и ложности. Натуральные числа это такие, в которых 1+1 = 2, 2+1 = 3 и так далее. Истина = 1, ложь = 0, отрицание истины = ложь. Все единицы абсолютно равны друг другу, перестановка слагаемых суммы не меняет, и так далее. Да вот беда, нет в нашем мире таких частиц, таких вещей или процессов, которые можно было бы однозначно сопоставить натуральным числам, и при этом, чтобы правила арифметики выполнялись для этих сущностей в любых диапазонах. В некоторых диапазонах арифметика приблизительно верна, но за пределами начинаются глобальные сбои. Поэтому формальная логика, грубо говоря, оперирует сама не понимая чем, сущностями, суть которых довольно таки расплывчата. Причём арифметика сама не относится к полным и непротиворечивым системам, такой вот забавный факт. Да и вообще, похоже, таких понятий как абсолютная истина, натуральные числа, в принципе не может существовать. Как именно и почему, будет в следующих частях.
Что из этого следует? Все процессы, все вычисления, происходящие хоть в мозгу, хоть в компьютерах, по сути своей или неполны, или противоречивы, хотя при этом дают хорошее правдоподобное приближение к полным и непротиворечивым вычислениям.
Почему Пенроузу не нравятся противоречивые формальные системы, почему Пенроуз отказывает им в праве быть основой интеллектуальной деятельности? Как мы помним, в противоречивой формальной системе, для одних и тех же данных, можно вывести и истинное и ложное утверждение, вплоть до того, что 1 = 2 и так далее. На этом основании Пенроуз намекает, что противоречивые системы будут всегда(!) выдавать противоречивые результаты. Отсюда же у Пенроуза вытекает весьма узкая трактовка хаотических процессов, он считает, что это просто случайные процессы, которые в среднем можно промоделировать строгой формальной системой.
На самом же деле, противоречивые системы могут в большинстве случаев сходиться к истинному результату, совсем не обязательно, что внутренние противоречия будут сразу же доминировать и разрушать систему. Могут быть такие системы, в которых противоречия минимизируются. И даже будучи запущенными на абстрактном компьютере, они останутся недетерминированными, они будут неполны и противоречивы, но в большинстве случаев они будут выдавать правдоподобный результат. Почему Пенроуз решил, что противоречивые системы всегда будут разрушаться своими противоречиями? Об этом Пенроуз молчит...
Дальше - больше. Как мы видели в предыдущих частях, процессы нашего мира, что в компьютерах, что в мозгах, все они по своей сути расплывчаты и противоречивы. Но в большинстве случаев они выдают правильный результат. Связано это с тем, что процессы эти состоят или из многократного повторения похожих вычислений, или из большого числа похожих элементов, таким образом, что сочетание этих повторений или элементов в большинстве случаев выдаёт стабильный и правильный результат. При этом, конечно, сохраняется очень маленький шанс, что небольшое внутренне противоречие разрастётся и разрушит всю систему. Но в большинстве случаев система как бы гармонизируется, элементы, воздействуя друг на друга, минимизируют внутренние противоречия. Далеко не все процессы в нашем мире высокогармонизированы, но такие процессы есть, и происходящее в компьютерах и в мозгу к ним относится. Откуда происходит такая гармонизация в нашем мире - тема следующих частей. Остаётся и крохотный шанс, что в наших мировоззрениях, в нашей интеллектуальной деятельности мы в чём-то глобально не правы, что есть небольшая чревоточина в наших суждениях, которая может на корню перевернуть всё наше представление о мироздании. Но и об этом в следующих частях.
Изначально человеческое мышление основано как раз на таких процессах. Нет длинных логических цепочек, нет чётких правил. Вместо этого - короткие цепочки ситуация-отклик, без длительных циклов переработки. Элементы этих цепочек имеют большое число входов, и внутри элемента входные данные распадаются на множество параллельных, дублирующих друг друга, нечётких путей, которые на выходе дают чёткое решение. Назвали мы такие элементы короткими и широкими правдоподобными правилами. Такие правила не занимаются логическим выводом, они уже "помнят" готовое решение на известные им ситуации. Механизм обучения таких правил тоже далёк от чёткого логического вывода и описан в предыдущих частях.
Такие процессы хороши для взаимодействия с реальным миром, но формальная логика им даётся тяжело. Тем не менее, человеческий интеллект может работать в режиме формальной логики, может эмулировать компьютерные вычисления. Может, но за счёт намного более "тяжёлых" процессов. Чтобы прогнать в мозгу вычисления простой логической схемы, простой программы, привлекаются мириады коротких нечётких правил, которые, в своём сочетании и дают результат, похожий на работу строгой логики. И так как правила эти предназначены совсем не для формальной логики, то их количество, привлечённое для эмуляции формальной логики будет намного более огромным, чем для взаимодействия с реальным миром. И поэтому разные животные не способны к логическим размышлениям, для этого нужен изощрённый человеческий мозг. Хотя бытовые задачи, которые разные животные решают мимоходом, компьютеру не под силу.
Но есть у таких "тяжелых" процессов и преимущество. Состоит оно в том, что мозг может производить на свет новые логические построения и компьютерные программы с высокой степенью правдоподобности, в то время как простой, но эффективный алгоритм, способен лишь бессмысленно выполнять свою работу. Сложность производных построений на многие порядки меньше, чем степень изначально задействованных в мозгу процессов. Вот этот перепад сложности и разрешает противоречие о том, что противоречивые интеллектуальные процессы создают истинные логические построения. Если этот перепад сложности не принимать во внимание, то никак не понять, откуда берутся эти истинные построения.
Задачи, требующие сложных логических построений, человек решает буквально методом "научного тыка". А именно, придумать какой-то простейший вариант, прогнать в мозгу его вычисление, увидеть неправильные моменты, придумать следующий (необязательно правильный вариант), снова проэмулировать вычисление и так далее. При хорошей тренировке, такие построения переходят в разряд быстрых автоматических действий, не требующих участия сознания (и, тем не менее, всё равно сложность их огромна), запоминаются типовые ситуации, и начинает казаться, что мозг работает как обычный компьютер (в соответствии с формальной логикой), хотя это вовсе не так.
Бывает и такое, когда мозг долго "взводится", "разгоняется" на какую-то задачу, идёт закладка начальных данных, неудачных попыток, неясных предчувствий и томлений о том, что истина где-то рядом. А потом бах, и вспышка озарения, всё становится на свои места и рождается новая истина. Может показаться, что эта истина родилась мгновенно и пришла из высших сфер. Но на самом деле эффект тот же, вспышке озарения предшествовала долгая и упорная работа, которая задействовала, изменяла и создавала мириады коротких и правдоподобных правил, пыталась их вместе как-то сочетать, гармонизировать, по большей части неудачно. И вот наступает момент, когда все эти правила уже гармонично сочетаются друг с другом, сливаются в единый гармоничный процесс, и все вместе выдают наружу новую истину.
Искусственный интеллект, следуя таким принципам, вполне может быть запрограммирован на обычных компьютерах. Естественно, программа эта изначально будет нацелена на недетерминированность и присутствие внутренних противоречий. В то время как существующие компьютерные программы, хотя и недетерменированны и противоречивы, но пишутся современные программы прицелом на то, чтобы в них было меньше недетерминированности и противоречий. Конечно, для искусственного интеллекта лучше задействовать более эффективную архитектуру, допускающую большое количество параллельных и взаимодействующих процессов. Например, квантовую или оптическую. Однопроцессорные электронные компьютеры тоже можно запрограммировать на интеллект, но мощности им, вероятно, будет недоставать.
Про "тяжёлые" процессы и гармонизацию подробно будет рассказано дальше, а сейчас приступим к конструированию искусственного интеллекта.
Кирпичики интеллекта
Начнём с того, что вкратце вспомним, что у нас уже придумали в этой области и чего не хватает. Всё это подробно расписано в предыдущих частях. Напоминаем мы это, чтобы понять почему именно так, а не иначе. Ведь сам по себе алгоритм интеллекта не так уж сложен, главное в нём - принципы, надо понять, в каком направлении двигаться и каких результатов ожидать.
Языки программирования. Бывают процедурные и предикатные. В процедурных языках программа записана в виде строгой последовательности инструкций, между которыми могут быть условные переходы.
В предикатных языках есть набор независимых правил, каждое из которых имеет свою область применения. Исполнитель в предикатных языках проверяет все правила на соответствие текущей ситуации и применяет нужные правила, которые изменяют ситуацию (внутреннее состояние), и таким образом может сам выстраивать из правил длинные логические цепочки. Естественно, это труднее для исполнителя, чем выполнение процедурной программы.
Процедурные языки хороши там, где алгоритм чётко известен и требует быстрого и эффективного выполнения. Предикатные языки хороши там, где требуется хранить человеческие знания, логические правила, и потом делать вывод на знаниях (например, оценивать разнообразные входные ситуации). В них удобно добавлять новые знания, без переписывания всей программы целиком. Есть даже модификации, в которых после ввода новых знаний вся база знаний приводится в непротиворечивое состояние. Предикатные языки (вроде Пролога) до некоторых пор считали будущим искусственного интеллекта.
Но дело в том, что процедурные и предикатные языки взаимовыражаются друг в друга и имеют одинаковые проблемы, присущие алгоритмам (формальным системам, см. выше и далее).
Во-первых, мы сталкиваемся с проблемой остановки. Алгоритм может вечно блуждать в поисках решения, хотя оно может лежать рядом, в соседней ветке. Зато алгоритм будет соответствовать полной и непротиворечивой формальной системе. Но толку для нас никакого (пока считаем, что мы не можем сделать вечное вычисление за конечное время). Если мы сделаем какое-то отсечение "длинных" веток, то алгоритм станет более практичным, но утратит полноту и непротиворечивость, станет не истинным, а правдоподобным. И здесь речь идёт не о том, что слегка расширится вероятность неправильного решения, а о том, что алгоритм сможет выдавать в корне неверные решения.
Во-вторых, правила-предикаты, составляющие логические единицы, слишком "узки". В естественном интеллекте логические единицы имеют на порядки больше входных условий и входы эти обрабатываются по нечётким критериям. Причём при таком представлении знания "размазываются", теряют свою чёткость и формализм.
Существующая нечёткая логика (есть такой раздел в науке) не годится для применения в предикатных языках вот почему. Любая нечёткость, когда встречается с другой нечёткостью при логическом выводе, может порождать множество альтернативных вариантов, разных логических цепочек. Причём варианты эти могут запросто нарастать лавинообразно. Существующая нечёткая логика, насколько мне известно, не имеет дела ни с распараллеливанием цепочек, ни с обратным их объединением. Всё что делает нечёткая логика - оперирует теми же логическими выражениями, только вместо логических нуля и единицы в ней применяется вещественный диапазон от нуля до единицы, и арифметические операции для сочетания чисел из этого диапазона.
Есть варианты "комплексной" логики, в которых при обращении импликации возникает неопределённость, которая выражается чем-то вроде мнимой единицы, и которая участвует в дальнейших вычислениях, с возможностями распараллеливания и слияния цепочек. Но пока эта тема требует дальнейшего раскрытия.
В-третьих, у нас нет алгоритма, который мог бы обучать (создавать) другие алгоритмы, в отсутствие человека, но когда есть набор обучающих ситуаций (репрезентативный набор пар правильных входных и выходных значений).
Системы распознавания образов. Хорошо подходят на роль логической единицы для нашего искусственного интеллекта. Умеют хорошо классифицировать входную ситуацию и выдавать решение на выход. Правда, только в том случае, если не нужна длительная обработка, так как внутренней памяти (состояния) и преобразования этого состояния такие системы не имеют, представляя собой скорее рефлекс "стимул-отклик". Зато с классификацией распознавалки справляются отменно. Могут даже обрабатывать сложные изображения (например, распознавать человека по изображению лица). Методы обучения систем распознавания образов эффективны и хорошо известны. Обученная на наборе известных примеров, распознавалка может улавливать скрытые закономерности и качественно обобщать опыт на неизвестные примеры.
Принципы обучения. Когда известен желаемый (эталонный) результат и реальный результат работы интеллектуальной системы, можно вычислить ошибку этой системы и подкорректировать систему, чтобы она работала в правильном направлении.
Методы коррекции (обучения) бывают точные (их ещё называют локальными), и глобальные. Локальные методы умеют вычислять ошибку по всей системе, и поэтому быстры и эффективны. Глобальные методы такого делать не умеют, они случайно изменяют параметры всей системы, смотрят, насколько успешно изменение отразилось на работе системы, и на этом основании решают, сохранять ли это изменение.
К локальным относится метод градиентного спуска, когда для ошибки можно вычислить её направление, и распространить в от входа в обратном направлении по всей системе. Такой метод, хоть он "всего-лишь" правдоподобный, даёт хорошие результаты на практике, например, для обучения многослойных персептронов (которые часто обзывают нейронными сетями). Но применим он (как и другие локальные методы) не всегда, так как структура ошибки и способ её корректирования может быть не известен.
Зато у нас есть глобальные методы обучения, генетический алгоритм и симуляция отжига, они всеядны, но очень прожорливы к вычислительным ресурсам. Они могут работать, когда о способе коррекции ошибки практически ничего не известно. Генетический алгоритм более эффективен, особенно если знать что-то о структуре решаемой задачи.
Принцип масштаба. Означает, что многократным повторением похожих процессов или сочетанием большого числа похожих элементов, можно добиться высокостабильного (или высокоправдоподобного) результата. Похожий элемент/процесс - это не значит похожий в среднем, это значит, что элементы могут противоречить и конкурировать друг с другом, могут быть нестабильны, но в итоге всё-таки сочетаются (гармонизируются) в решение с высокой степенью правдоподобности. Например, в логических цепях компьютеров, все элементарные частицы нестабильны, но срок их полураспада или очень велик, или число частиц в логическом элементе очень велико, так что распад отдельной частица практически не даёт сбой логических цепей. Другой пример, в искусственных нейронных сетях отдельная нейронная связь слабо влияет на решения, сами связи могут быть противоречивы, но в итоге нейронная сеть выдаёт в основном правильные решения.
Подытожим. У нас есть предикатные языки, которые подходят для сложных рассуждений и переработки внутреннего состояния. Есть системы распознавания образов, которые можно использовать как логические единицы для предикатных языков. Есть всеядные методы обучения, которыми мы надеемся автоматически создавать (обучать) новые алгоритмы. Есть принцип масштаба, который при потере полноты и непротиворечивости, позволит нам поддерживать высокую правдоподобность решений нашего искусственного интеллекта.
Алгоритм интеллекта
Напомню вкратце суть генетического алгоритма. Есть такой метод - случайный поиск. Генерируется случайное решение, оценивается, потом случайно изменяется. Если результат стал лучше, решение запоминается. После чего цикл повторяется. Используется такой метод, когда непонятно как вычислять решение "по науке". Получается очень долго. А если завести параллельно большое количество разных решений? Для тех из них, которые прогрессируют в успехе (качество решений хорошее или повышается со временем или по сравнению с "соседями"), создаём экземпляры-копии, и изменяем (случайно) эти экземпляры потихоньку. Те из решений, которые на фоне остальных выглядят плохо, или не повышают качество решения со временем, те экземпляры мы подвергаем всё большим случайным изменениям или вовсе удаляем, а на их место ставим вновь сгенерированные случайные решения. Естественно, плохие решения имеют меньшую вероятность быть размноженными. Есть ещё одна операция (тоже применяется случайно), когда от двух разных решений откусывается по кусочку, и эти два кусочка склеиваются в новое решение. Называется скрещивание. Чем лучше решение, тем больше вероятность, что оно подвергнется скрещиванию. В итоге можно скачком получить решение, которое имеет лучший результат, чем оба его родителя. Но может случиться и наоборот. Если решение получилось лучше, то оно в дальнейшем размножается, если хуже - то такое решение, с большой вероятностью удаляется. Наиболее эффективен такой поиск, когда мы знаем структуру решения, и применяем операции случайного изменения (мутации) и скрещивания не кромсая решение по битикам, а с учётом этой структуры.
За счёт того, что решения не просто ведутся параллельно, а постоянно сравниваются и обмениваются друг с другом, такой поиск выдаёт фантастический скачок производительности по сравнению со случайным поиском и оказывается способным перемалывать самые трудные задачи. Казалось бы, типичное случайное решение в среднем ничего интересного из себя не представляет, и эффективность его крайне низка. Но стоит только множеству решений начать взаимодействовать между собой, как нетипичный результат (хорошее решение) быстро появляется и прогрессирует. Это к слову о том, что Пенроуз советует изучать хаотические процессы в среднем, изучать типичные случаи, упирая на то, что кроме типичных случаев они ничего не могут породить, что, конечно, несправедливо. Такой поиск представляет собой иллюстрацию принципа масштаба, один из типичных гармонизирующихся процессов.
Вот это и называется генетический алгоритм, который может находить эффективные решения в самых разных областях, когда даже неизвестно как искать правильно решение "по науке". Или "научного" способа такого вовсе нет, как в случае с автоматическим написанием программ. За эффективность генетического алгоритма говорит в первую очередь то, что жизнь на Земле (а потом и разум) появились именно по таким принципам. Почему такой гармонизационный процесс возможен - тема следующих частей.
Есть такое направление в искусственном интеллекте - генетическое программирование. Каждое решение представляет собой не набор параметров, а целиком программу, записанную на процедурном языке программирования. Со всеми её циклами, условными переходами и внутренним состоянием в переменных. Соответственно результат решения - это результат выполнения этой программы. Для того чтобы создать программу, применялся генетический алгоритм, который из большого числа случайно сгенерированных программ, создавал программу, наилучшим образом решающую данную задачу. В той статье, что я видел, задача была - управление рулём машины. Т.е. результат решения - это не единственный отклик на вход, а процесс, растянутый во времени. Генетический алгоритм справился успешно и создал программу, которая правильно управляла рулём. Задача не ахти какая сложная, похожее делают и на нейронных сетях (хотя какое-то внутреннее состояние там всё равно есть, и правила взаимодействия состояния с сетью расписаны человеком). Но показателен тот факт, что автоматически была создана именно программа, имеющая внутреннее состояние, разные циклы и ветвления.
К сожалению, дальше состояние дел по этой теме я не отслеживал, и больше ничего рассказать не могу. Желающие могут поискать по словосочетанию "genetic programming". Поэтому же, дальше мы выходим за пределы изученного и вступаем в область предположений. Вполне возможно, что-то из этих предположений уже известно, и я занимаюсь изобретением велосипеда. Но всё равно интересно. :)
Посмотрим, какие свойства у программ, полученных с помощью генетического алгоритма. Такие программы могут иметь в себе бесконечные (или очень длинные) циклы, поэтому оценка пригодности должна выкидывать программы, которые работают очень долго, не выдавая видимого результата. Ход, в общем-то, правильный, но он, к сожалению, выкидывает потенциально интересные длинные логические цепочки (как их учесть ещё будет). Дальше, при скрещивании ветви программы будут бездумно кромсаться, порождая зачастую бессмысленный код. И если для простой задачи это не такая уж проблема, то для задач более сложных, получится или большое количество негодных решений, потому что самое небольшое изменение способно напрочь испортить работоспособность программы, и вероятно, в итоге толку будет мало. Или в программе будет большое количество избыточных веток, "хлама", который будет невообразимым образом сочетаться друг с другом в правильное решение. Этот "хлам" в процессе эволюции научиться переживать вносимые изменения, таким образом, чтобы изменение не ломало фатально программу. Но в любом случае, нам придётся распрощаться с идеей "тонких" логических цепочек, которые бы представляли собой такие же чёткие программы, какие пишет человек. То, что получится в результате автоматического написания программ, будет далеко от таких цепочек. Конечно, появятся алгоритмы data mining, которые смогут этот противоречивый ворох минимизировать в ясный алгоритм, но этот ясный алгоритм, для дальнейшего совершенствования в автоматическом режиме, надо будет вернуть обратно в "размазанный" вид (или размазывание произойдёт само, в процессе дальнейшего обучения). И есть подозрение, что вытащенный с помощью data mining-а алгоритм, будет иметь более узкий "кругозор" чем его исходный, "размазанный" вариант. Похожее явление описывалось в предыдущих частях про распознавание образов.
Как мы помним, предикатные языки более гибки к изменениям и приспособлены к записи человеческих знаний, потому что состоят не из жёсткого каркаса программы, а из независимых правил, которые автоматически срабатывают при наступлении подходящей ситуации (условий). Генетический алгоритм работает эффективнее, если операции учитывают структуру решения. Запись в процедурном виде заставляет генетический алгоритм бездумно кромсать программу, порождая множество неработоспособных вариантов. Поэтому запишем программу в предикатном виде, и настроим генетический алгоритм, чтобы он учитывал такую структуру. А именно, разные программы-решения смогут обмениваться не кусками битов, а целиком независимыми правилами. Случайные изменения будут работать на уровне правил. Даже более того, внутри одной программы можно иметь разное количество правил неважно в каком порядке. И правила эти могут быть как очень похожим друг на друга, так и совершенно разными. Размножать и скрещивать можно не только сами программы, но и правила внутри одной программы. А всё потому, что при выполнении программы, они сами выстроятся в правильную цепочку, потому что исполнитель не тупо идёт по веткам программы (как в процедурном языке), а подбирает правила соответственно текущей ситуации (каждое правило меняет ситуацию).
Но самое интересное, было бы сделать банк правил общим для всех программ. Программа бы в этом случае представляла собой данные о том, какие именно она правила предпочитает из общего банка, и не исключено, информацию о предпочитаемой последовательности их применения. В этом случае, критерии эффективности можно применять не только к программам, но и к правилам. Ведь каждое правило вносит вклад в несколько разных программ, и можно подсчитать, сколько из этих программ удачные, а сколько - нет. И на этом основании делать выводы об эффективности правил, и соответственно эволюционировать не только программы, но и правила (т.е. размножать, скрещивать, случайно изменять сами правила). Повышение эффективности получается от того, что похожие правила больше не дублируются в разных программах, каждая программа имеет доступ к более широкому банку правил. Но самое главное, правила оцениваются совместно, при перекрёстном использовании в разных программах, что (предположительно) резко повышает качество оценки и эволюции правил.
Вот и получилась самая простая версия искусственного интеллекта, вполне применимая в разных играх, в т.ч. компьютерных, в экспертных системах и системах управления процессами. Подойдёт такое и для моделирования black-box процессов с внутренней памятью, вместо Марковских моделей (это такие процессы, у которых видно, что на входе и выходе, но внутреннее состояние и процессы непонятны, чёрный ящик по-нашему).
Тут может возникнуть закономерное предложение, чтобы генетический алгоритм мог выделять куски программы в независимые подпрограммы, и учитывать их структуру при изменении программы. Для процедурной записи это может повысить эффективность, но всё равно не избавит от присущих ей недостатков, ведь всё равно нужна будет жёсткая последовательность инструкций, условных операторов и циклов, которую может поломать случайное изменение. В предикатной же записи процедур как таковых вообще не существует. Но зато есть возможность разбиения глобальной ситуации на набор иерархических ситуаций и на последовательность ситуаций, таким образом, чтобы с каждой подситуацией имел дело только свой набор правил. В ближайшей перспективе такое разбиение как бы должно повысить эффективность генетического алгоритма. Но дело в том, что в настоящем интеллекте взаимодействие правил носит более сложный характер, которому такое разбиение одновременно и свойственно, и не свойственно. Поэтому, навязав такое разбиение ситуации, в ближайшей перспективе мы можем получить выгоду, но в дальнейшем это будет мешать. Подробнее про это будет дальше.
Искусственный интеллект, версия 2.0
Чтобы двигаться дальше, напомню, что такое предикатные языки, что такое правила, ситуация, что такое распараллеливание на цепочки вывода.
В предикатных языках (таких, как Пролог), нет последовательности шагов в программе. Есть только набор правил, причём последовательность выполнения этих правил изначально никак не задана.
Выглядит это так:
правило n: результат если условие;
правило m: результат если условие;
и так далее.
Условие может быть достаточно сложным, включающим в себя как простейшие выражения, так и другие правила, в том числе и взаимно-рекурсивное применение. Результат выполнения правила - это тоже сложное условие, которое может обозначать как конечную ситуацию, так и часть условия для проверки применимости других правил (и самого себя тоже). Результаты эти - чёткие и однозначные.
Какой-то глобальной ситуации при выполнении предикатной программы нет. Есть начальное условие, под которое интерпретатор ищет первое попавшееся правило с подходящим условием, результат этого правила добавляется к начальному условию. Поиск подходящего правила для нового условия повторяется. В итоге получается цепочка вывода, которая может вести к правилу, обозначающему достижение конечного результата. Если интерпретатор исчерпает все доступные цепочки, то он начнёт откатываться обратно, для каждого цикла ища следующее подходящее правило, выстраивая новые цепочки.
Ещё раз обратите внимание, состояние (ситуация) представляет собой начальное условие плюс цепочку применённых правил. При откате соответственно меняется и цепочка применённых правил.
При сцеплении правил в цепочки интерпретатор вполне может впасть в бесконечный поиск, хотя решение может быть рядом. Поэтому, если интерпретатор "умный" то он умеет или распознавать места потенциального зацикливания, или может вести параллельно несколько цепочек решений, выбирая из них в итоге ту, что быстрее приведёт к конечной ситуации. С другой стороны, тому, кто пишет набор правил, надо позаботиться о том, чтобы минимизировать вероятность зацикливания.
Например, задача про миссионеров и людоедов, когда на одной лодке надо перевезти толпу миссионеров и людоедов на другой берег. Лодка вмещает только двух человек. Если людоедов на берегу останется больше чем миссионеров, то миссионеров съедят. При решении задачи на предикатном языке, расписываются допустимые ситуации, чтобы миссионеров не съели (в т.ч. рекурсивно) и допустимые перемещения лодки (в лодке должен быть всегда один или два человека). Дальше интерпретатор сам строит дерево допустимых решений, пока не приходит к ситуации, когда вся толпа оказывается на другом берегу. Цепочка правил в этом случае несёт в себе последовательность перевозок миссионеров и людоедов через речку.
Поскольку правила чётко сцепляются друг с другом в процессе поиска решения, в предикатных языках уже на уровне правил задана иерархия и последовательность их применения, нечто похожее на группировку в процедуры в процедурных языках. Но как только мы делаем сцепление между правилами менее чётким, такая группировка теряется. И как именно она возникнет заново (или как помочь ей образоваться) - это уже новый вопрос.
В предикатных языках нет никаких циклов, нет условных переходов, нет жёстко заданной последовательности действий. Исполнитель всегда "знает" что ему делать, потому что следующий шаг он подбирает под текущую ситуацию. Исполнитель подбирает только один шаг, потому что на следующем шаге он произведёт оценку изменённой ситуации и выберет новый шаг, как бы неожиданно не изменилась ситуация. Это же поможет исполнителю выпутаться, если часть его программы дала сбой или приняла неверное решение. Вместо того, чтобы катастрофически падать в неправильном направлении, исполнитель ещё раз оценит ситуацию, и, вполне возможно, следующий шаг эту ситуацию всё-таки улучшит.
Конечно, задействованные процессы намного прожорливее к вычислительным мощностям, по сравнению с процедурной записью программы. И в изначальном виде в предикатных языках далеко не всё так гладко, как описано в предыдущем абзаце.
Недостаток предикатных языков заключается в том, что область применения правил очень узкая, и выстраиваются они в слишком длинные цепочки. В интеллекте же наоборот, преобладают короткие цепочки вывода, в которых логическая единица оценивает весьма широкий массив входных условий, причём по нечётким и нелинейным критериям.
Поэтому следующим шагом в построении искусственного интеллекта надо заменить узкие чёткие правила на нечёткие и широкие, и сделать короче цепочки вывода.
Для начала сделаем глобальное состояние программы (обычный массив чисел). Часть этого массива - входные данные. Они регулярно обновляются извне. Разрешать ли программе их изменять - это не принципиальный вопрос, главное чтобы они регулярно обновлялись. Часть этого массива - внутреннее состояние программы. Оставшаяся часть - выходные данные. Внутренние и выходные ячейки отличаются только тем, что с выходных ячеек считывается решение. И входы, и выходы всегда используются для записи/чтения одного и того же параметра. Например, вход №1 - скорость, вход №2 - датчик топлива, выход №3 - изменение положения руля, выход №4 - изменение скорости. Назначаем мы номера произвольно, в процессе обучения программа сама должна научиться понимать, где какой вход и выход.
За основу правила, возьмём, например, многослойный персептрон (который часто обзывают просто нейронной сетью). Заметьте, алгоритм обучения такой нейронной сети внутри программы нам пока неизвестен. Таких нейронных сетей у нас будет много. Все вместе они будут составлять набор правил программы. В каждую нейронную сеть на вход поступает всё глобальное состояние программы (количество входов равно количеству ячеек состояния). Выходов нейронная сеть имеет немного. Каждый выход тоже соответствует какой-то из ячеек состояния. На каждой итерации, то, что получилось на выходе каждой нейронной сети, прибавляется к глобальному состоянию (значения на выходе могут быть и отрицательные). Все сети опрашиваются одновременно на основе текущего состояния, и своим суммарным воздействием создают новое состояние.
Количество выходов и их привязка для каждой сети изначально выбирается случайно. Эволюционные изменения построим таким образом, что они в большинстве случаев оставляют неизменным коммутацию между ячейками глобального состояния и входами/выходами нейронной сети. И только с небольшой вероятностью изменения могут переставить вход или выход сети на другую ячейку. Надо это потому, что пока мы считаем, что каждая ячейка - это определённый параметр (пусть даже и внутренний), поэтому, если мы переключим вход/выход сети на другой параметр, к которому он не приучен, то итог будет скорее неудачным. К сожалению, таким манёвром мы опять теряем кое-какие интересные свойства настоящего интеллекта, но зато получаем эффективность прямо сейчас. К этим свойствам мы ещё вернёмся.
В процессе эволюции может быть изменено и количество ячеек глобального состояния. Тогда все нейронные сети корректируются соответственно. Если ячейки клонируются, то клонируются соответствующие входы и выходы нейронных сетей. Если ячейки удаляются, то и соответствующие входы/выходы удаляются из всех сетей.
Есть и эволюционные изменения, которые могут увеличивать или уменьшать количество выходов отдельной нейронной сети.
Как именно программа, состоящая из набора таких нейронных сетей будет выдавать решение? Точнее, как после очередной итерации понять, что программа вынесла своё решение, и считать это решение из входных ячеек? Это тоже интересный вопрос, требующий экспериментов. Первые соображения такие. Выходные значения стабилизируются. Или есть специальные выходы, которые сигнализируют о том, что ответ готов. Выходы эти самонастраиваются в процессе эволюции.
После снятия решений программа должна работать дальше, и, скорее всего, отталкиваясь от своего внутреннего состояния. Как подтолкнуть её к дальнейшей работе, ведь программа стабилизировалась в конкретном решении? Во-первых, после снятия решения будет произведена перезапись входных ячеек актуальными данными (считаем, что пока сеть выносит решение, входные данные практически не изменились). Во-вторых, можно завести специальную входную ячейку, в которую помещать большое число при старте итерации. Дальше, есть или сама научиться изменять это число, или можно уменьшать его извне, давая сети понять, что время идёт. В общем, идей для экспериментов хватает.
Теперь пояснения, почему именно так.
В первую очередь мы отказались от выстраивания цепочек правил, и заставили каждое правило писать результат своей работы в глобальное состояние. Этим самым мы сделали невозможным построение длинных цепочек вывода и обратные откаты, зато получили более быстрый отклик и широкую и нечёткую оценку ситуации. Заметьте, параллельная обработка нескольких вариантов, где в каждом варианте своё глобальное состояние, никуда не делось. Но такого широкого ветвления, как в оригинальном предикатном интерпретаторе у нас нет. Если бы мы попытались делать ветвление цепочек вывода на широких нечётких правилах, то число вариантов катастрофически зашкалило бы ещё на ранних стадиях построения решения.
В итоге у нас получилось нечто совершенно иное, хотя вроде бы как и похожее на оригинальный вывод на предикатах. Это нечто больше неспособно к построению сложных и чётких умозаключений, но зато способно действовать в сложной, быстроменяющейся обстановке, да ещё и обладает какими-то зачатками правдоподобного логического вывода, чего не может делать исходный вариант. Вывод сложных и чётких умозаключений к нам ещё вернётся, правда неожиданным способом, а пока получившийся интеллект будет без него.
Тем не менее, получившееся нечто может решать логические задачи (вроде игры в шахматы) по своему, похоже на то, как это делает человек. Такое мышление можно назвать ситуативным. Оно отталкивается не от построения длинных логических цепочек, а от оценки того, какова текущая ситуация, и как эту ситуацию изменить. Ситуация в себя включает и внешние данные, и внутреннее состояние, то, что система "надумала" к текущему моменту. Оценка и принятие решения куда двигать дальше производится на каждом шаге, в отличие от процедурных алгоритмов и логического вывода, которые могут зарыться в длинные рассуждения, выпав из реальности. Поэтому же, случайные изменения такой вот программы не станут фатальными для работоспособности, в отличие от процедурной записи. Даже попав в непонятную ситуацию, или совершив ошибку, такая программа не впадёт в ступор, а будет пытаться что-то сделать, ведь в оценке ситуации принимает участие не небольшая ветка алгоритма, а вся совокупность правил. И пусть даже программа поначалу совершит хаотические метания, она рано или поздно попадёт в знакомую ситуацию и сможет её повернуть в нужную сторону.
Ситуативное мышление основывается на трёх вещах. Первое, это обобщение ситуации до знакомого случая (как в системах распознавания образов). Например, из разнообразного расположения фигур на шахматной доске, мыслящая система находит что-то общее, даёт оценку ситуации, есть ли угроза своим фигурам, есть ли шанс совершить атаку без потерь, дальше могут быть более конкретные ситуации-комбинации. Второе, это опыт (библиотека коротких правдоподобных правил, которые применяются для изменения ситуации к лучшему без длинного логического вывода). На основе оценки ситуации предлагаются альтернативы для изменения этой ситуации, например, приблизительные данные о том, как двигать фигуры. Синтаксический анализатор переводит эти приблизительные данные в правильные перемещения фигур на шахматной доске (если правильные перемещения подобрать нельзя, то берётся следующая альтернатива). Похожие ситуации (и соответственно решения для них) могут встретиться на любом этапе партии, и мы сразу же получаем для них решение, без длительного перебора вариантов различных ходов. Да, эти варианты "всего-лишь" правдоподобны, но они включают в себя огромный опыт реальных партий и вполне применимы для новых партий. Причём эти ситуации включают в себя некоторое знание о том, как будет развиваться партия на много ходов вперёд, но не на уровне перемещений фигур, а на уровне изменения тактической ситуации (каковая может включать в себя и бесконечные циклы, вроде поддержки равновесия для достижения ничьей). А если всё-таки они приведут к проигрышу, то библиотека будет дополнена новыми правилами, которые сработают в своей ситуации. Третье, это внутренняя проверка вероятного решения на несколько шагов вперёд (т.е. что-то придумать, а потом прикинуть, насколько хорошо это что-то изменит ситуацию, ведение нескольких альтернативных решений, наша система этого пока не умеет, она даёт только один вариант, но про это ещё будет).
Кстати, вы, может, задумывались, при изучении нейронных сетей, насчёт того, чтобы заставить их работать не только на основе входных данных, но ещё и обучить переваривать внутреннее состояние и выполнять сложные программы? Мне вот было интересно. Правда, тогда давно, я так и не придумал ничего путного, как такую сеть обучать. Зато теперь есть ответ с немного другой стороны.
Почему мы сделали много нейронных сетей, вместо одной большой, которая могла бы апдейтить целиком всё состояние? Дело в том, что для эффективной работы генетического алгоритма желательно иметь набор независимых правил, каждое из которых отвечало бы за какое-то конкретное (пусть и скрытое от нашего понимания) действие. К тому же, такие правила можно обменивать между программами, делать из них разные наборы-программы, изменять и клонировать отдельные правила, и даже формировать библиотеку наиболее успешных (или даже в будущее библиотечных) правил. Сделать такое с одной большой нейронной сетью будет тяжело. К тому же, для обычных нейронных сетей, коллектив сетей, как правило, справляется лучше, чем обычная нейронная сеть.
Из похожих соображений каждая нейронная сеть имеет только небольшое число выходов. Т.е. каждое правило компетентно за вынос своего небольшого решения. Но при этом, каждая сеть имеет входы от всего состояния, с расчётом на то, чтобы иметь глобальное видение ситуации, но при этом не реагировать на большинство случаев, не касающихся области действия конкретного правила. Каждая сеть должна научиться этому в процессе эволюции. Поэтому, даже при воздействии на глобальное состояние, отработают именно те правила, которые применимы в текущей ситуации. Вполне может быть, что следует ограничивать и количество входов, на этот счёт у меня соображений нет, здесь поможет только эксперимент.
В итоге, после обучения должна получиться программа, состоящая из набора нейронных сетей. Работа программы начинается с начального состояния, в котором заданы входные ячейки, остальные ячейки могут быть обнулены (или иметь небольшие случайные значения). На каждой итерации на вход всех сетей подаётся глобальное состояние, рассчитывается результат работы всех сетей, и к глобальному состоянию сразу прибавляется выход всех сетей. Наступает следующая итерация. Понять, что решение готово, можно, например, по тому, что выходные значения стабилизировались, или поступил сигнал на специальный выход, сигнализирующий о том, что решение готово. После чего считываются выходные значения, загружаются новые входные значения и программа продолжает работу с обновлёнными данными.
Создаётся эта программа автоматически, при помощи генетического алгоритма. Главное, чтобы у нас был хоть какой-то критерий оценки эффективности полученных программ (т.е. лучше ли одна программа чем другая), и этого достаточно, чтобы генетический алгоритм заработал. Для задач реального мира, такой критерий обычно есть. Это могут быть и наборы примеров работы, которые считаются хорошими и плохими, для разных ситуаций (системами распознавания образов тоже обучаются на примерах). Обучившись на известных примерах, программа, как и системы распознавания образов, сможет обобщать свой опыт на неизвестные примеры, в том числе такое обобщение может носить качественный характер, улавливать скрытые закономерности в наборе примеров и делать неожиданные (но правильные) выводы. Для задач, требующих точного логического вывода и чёткого решения, с этим труднее (но про это ещё будет). Могут быть и варианты, чтобы заставить программы бороться друг с другом, например, играть в шахматы, и признавать эффективной ту, что играет лучше, тогда внешняя оценка не нужна.
Генетический алгоритм случайно генерирует набор правил (нейронных сетей), и набор программ. Все правила располагаются в общем хранилище. Каждая из этих программ состоит из своего, конкретного набора правил, взятых из общего хранилища. Сами правила в хранилище, программа только ссылается на них. Для оценки эффективности все программы запускаются параллельно (каждая имеет своё состояние и набор входов-выходов). Лучшую оценку получают те программы, которые сработают быстрее и эффективнее. Штрафуются те программы, которые долго думают, или совсем не выносят решения.
Плохие программы с большей вероятностью изменяются или совсем удаляются. На их место приходят или вновь сгенерированные программы, или клонированные из существующих. Оценка программ может быть кумулятивной, т.е. накапливаться, давая программе некоторую отсрочку, чтобы эволюционировать. Хорошие программы с большей вероятностью клонируются. Происходит эволюция программ от плохих к хорошим.
После того, как достигнуто достаточно хорошее решение, самая лучшая программа выбирается как результат работы генетического алгоритма, и в дальнейшем эта программа и используется для реальных задач.
Каким эволюционным изменениям можно подвергать программы. Добавление или удаление правила из хранилища. Скрещивание с другой программой, а именно, берутся две программы, на их основе создаётся третья, которая состоит из части правил одной программы и части правил второй программы. Правила, которые надо добавить, удалить, или записать в программу при скрещивании, выбираются случайно. Хотя, если подумать, может, и найдутся способы делать это более целенаправленно, может, найдётся оценка эффективности участия правила в той или иной программе.
Каким эволюционным изменениям можно подвергать правила (нейронные сети). Как уже говорилось, одно из таких изменений, это изменение количества ячеек внутреннего состояния, которое затрагивает все правила. Потребность в увеличении или уменьшении количества ячеек состояния можно более-менее оценить по динамике работы программы, по тому, насколько часто состояния изменяются, насколько они коррелируют друг с другом, насколько воздействуют на выходные значения, и насколько в целом эффективна популяция программ. Следующие эволюционные изменения, это клонирование правил, случайное изменение правил (а именно, "встряхивание весов" нейронной сети, как при отжиге, чем ниже эффективность, тем сильнее встряхивание). Клонирование совместно с последующим изменением правил может цеплять за собой и клонирование программ. Например, в исходной программе остаётся ссылка на исходное правило, в клонированной программе - ссылка на клонированное правило. Или в исходной программе появляется ссылка дополнительно и на клон правила. Правила могут скрещиваться, когда от двух нейронных сетей берутся по куску и склеиваются в третью сеть. В правилах (нейронных сетях) может случайно меняться количество выходов, как описано выше, может меняться количество и структура внутренних связей.
Для каждого правила можно подсчитать его эффективность, на основе того, как успешны программы, в которые это правило входит. Причём, можно учесть и тот факт, что правило может входить в программу, но быть неактивным, вследствие чего не влиять на работу программы. Основываясь на такой оценке, мы можем направленно эволюционировать банк правил, а именно, чаще размножать успешные правила, и с большей вероятностью удалять или изменять неэффективные правила. Можем и создавать программы на основе самых эффективных правил. Или в процессе изменений с большей вероятностью включать в программы лучшие правила. Заметьте, в банке хранятся правила с разными областями действия, но, тем не менее, решающие общую задачу.
Но самое интересно, похоже, что для каждого правила можно рассчитать не только эффективность, но и ошибку! А именно, понять, как это правило должно было бы действовать правильно при заданных входных условиях. Ведь у нас есть примеры срабатывания правил (нейронных сетей) в хороших программах (считаем, что это были правильные решения составляющих программу правил) и примеры работы в плохих программах (считаем, что это были неправильные решения составляющих программу правил). Соответственно можно попытаться усилить хорошие решения, которые выдавала каждая нейронная сеть, и минимизировать плохие решения. Значения входов и выходов можно без проблем воспроизвести, и на их основе построить обучающую выборку, которую отдать в алгоритм обратного распространения ошибки. Главная здесь проблема - это развернуть временную последовательность того, что было на входах и выходах в обучающую выборку, вот здесь и могут быть неоднозначности. Ведь мы не можем считать, что все решения (пары вход-выход) в правильной сети были идеально правильными, а в неправильной - идеально неправильными. Может это вина совсем другого правила, которое на самом финише "затёрло" правильное решение? Ввязываться в разворачивание всей последовательности решений - безнадёжная затея. Поэтому придётся подумать над формированием выборки на основе этих временных последовательностей. И даже если при формировании обучающей выборки мы выкинем многие примеры, оставив только самые однозначные, всё равно это будет прогресс.
Посмотрим теперь, что мы имеем. А имеем мы теперь средство для автоматического написания программ, которые могут ориентироваться в задачах реального мира, гибко действовать в широком диапазоне ситуаций, восстанавливаться после ошибок, иметь кое-какую внутреннюю логику и прогнозирование/моделирование ситуации. Чего они не могут, так это развивать тонкие логические цепочки, делать длинные умозаключения. Хотя для многих задач, такой интеллект сможет делать вид, что у него происходили глубокие логические процессы, хотя на самом деле он лишь применял заготовки, полученные в ходе обучения. Не хватает такому интеллекту и самостоятельности, многое в нём ещё надо делать человеку. Да и в аппаратной части то, что мы получили, не совсем похоже на то, что придумала природа.
Искусственный интеллект, версия 3.0
Теперь добавим штуку, называющуюся эмулятор внешней среды. Нам будут нужны две разновидности, одна - для эмуляции внешней среды, вторая - для прогнозирования. Будет ещё и третья разновидность, но о ней чуть позже.
Эмулятор в режиме прогнозирования должен уметь выдать предполагаемое поведение внешней среды на небольшое количество шагов вперёд, зная историю предыдущих состояний и текущее воздействие на среду со стороны управляющей программы. Теперь программа будет воздействовать не сразу на внешнюю среду, а сначала на эмулятор. А на эмуляторе можно посмотреть прогноз, в нужную ли сторону изменилась среда от воздействия программы. Поэтому можно завести несколько экземпляров программ, обученных сходным образом, но отличающихся друг от друга. Для каждой из них в реальном времени завести свой эмулятор среды. И на каждом шаге во внешнюю среду выдавать воздействие той из программ, которая получит лучшую оценку на эмуляторе. Другой вариант - принимать то решение (необязательно лучшее), которое примет "большинством голосов" коллектив программ, тогда это решение будет отличаться надёжностью.
Эмулятор в режиме эмуляции похож на прогнозирование, но используется в процессе обучения программ, когда настоящей внешней среды нет. В предыдущей версии мы брали готовые примеры-нарезки, снятые с внешней среды. Так вот, вместо этих примеров можно создать эмулятор, обученный воссоздавать типичные ситуации внешней среды. Ведь примеров может быть очень много, и эффективнее вместо этой прорвы использовать компактный эмулятор.
Эмулятор в режиме обучения можно ставить на реальные сенсоры, и оставлять его на длительное время. Закономерный вопрос - а почему на сенсоры не поставить для обучения сразу нужную программу? Ответов здесь несколько. Во-первых, мы можем захотеть обучить следующую версию программы, и тогда нам опять понадобиться гонять реальные устройства. Во-вторых, на реальных сенсорах невозможно поэкспериментировать, правильно ли обучилась программа, или такие эксперименты могут быть дорогие, а эмулятор может работать в режиме прогнозирования.
Кроме этого, эмулятор можно настроить на то, чтобы он мог, во-первых, выдавать случайные отклонения от поведения среды, и, во-вторых, комбинировать разные временные последовательности из поведения среды. Поскольку эмулятор обучен на внешней среде, то такие комбинации будут "придуманы" правдоподобно. Что расширяет набор примеров для обучения программ.
Естественно, всё происходящее в реальном времени может опять-таки быть записано и использовано для автоматического дообучения программ.
Программы для эмулятора можно делать по той же технологии, которая описана выше.
Если внешняя среда очень сложная (как при игре в шахматы), то эмулятор будет построен по технологии, очень близкой к самой управляющей программе. Вплоть до того, что при обучении программы будут играть друг с другом, и выживать будет сильнейшая программа. Эмулятор для прогнозирования может быть донастроен так, чтобы не просто искать лучший ход, но и чтобы подстраиваться к стилю игры противника. Таким образом, при игре с человеком, в "мозгу" машины будет происходить целое сражение между многими программами и их противниками-эмуляторами, прежде чем вынести окончательное решение.
Таким образом, применяя эмулятор внешней среды, мы повышаем и качество обучения программ, и качество принятия решений в реальном времени.
Есть ли в естественном интеллекте такое распараллеливание, с конкурентным принятием решений и эмулятором среды? Думается да, но вряд ли в таком прямом виде. То, что образовалось в ходе естественной эволюции наверняка сложнее и эффективнее. Но здесь, для простоты и скорейшего достижения эффекта мы ввели конкуренцию и эмулятор искусственно.
После введения эмулятора внешней среды и конкурентного коллективного решения, можно вводить новые свойства нашего искусственного интеллекта.
Блуждающие фоновые решения. Не обязательно после принятия решения заставлять все программы перестраиваться на осмысление следующего шага. Можно оставить некоторые (хорошие по каким-то критериям) программы продолжать долго думать над прошлыми ситуациями. Вполне может быть, что они всё-таки что-то надумают, и это что-то окажется полезно или в текущей (пусть даже изменившейся) ситуации, или окажется полезно для дальнейшего обучения. Например, отставшая программа может разгадать замысел врага или найти интересное тактическое решение. Тогда можно будет попытаться развернуть текущую ситуацию к этому решению (искусственный интеллект "передумал"), а если партия к тому времени уже закончена (или ушла в другом направлении), то найденное решение можно будет использовать в обучении. Как именно осуществляются оба этих варианта - это темы отдельных исследований. Искусственный интеллект при этом всё время будет в "онлайне", и будет думать, самосовершенствоваться, вести диалоги сам с собой, почти как человек.
Взрыв вариантов. Можно попробовать обнаруживать ситуации, когда отдельная программа (или коллектив программ) стоит на развилке, когда обнаруживается неоднозначная ситуация, и эту ситуацию принудительно разветвлять в новые ветки решений (программа + эмулятор). Опять же, как детектировать такие ситуации, как их ветвить - тема отдельных исследований, непаханое поле. Пока это только на уровне идеи, идеи о том, что при неоднозначностях интеллект должен уметь делать ветвление вариантов. Но ветвление это совсем не то, что перебор дерева решений. Это скорее как размазывание волновой функции, как комплексная арифметика, когда операции с неоднозначностью (мнимой единицей) выдают несколько вариантов, которые в дальнейшем по правилам той же арифметики взаимодействуют между собой. Также и разветвлённые решения в искусственном интеллекте должны продолжать совместное существование, продолжая связь друг с другом (как именно - тоже вопрос), и в подходящий момент времени ветви могут сходиться в единое решение. Причём ветвление наступать будет не тупо, как при переборе вариантов, а именно в те моменты, где оно наиболее интересно.
Как именно можно будет обнаружить точку потенциального ветвления? Для обычных нейронных сетей есть алгоритмы, увеличивающие ёмкость нейронной сети, если её не хватает для обработки данных, и уменьшающие ёмкость сети, если она избыточна для принятия решений. Изменение ёмкости в нейронной сети это добавление и удаление весов-связей между нейронами и самих нейронов (читай добавление/удаление строк в нелинейной матрице и обнуление элементов, не влияющих на решение). Есть целое направление про нейронные деревья, которые нарастают по мере надобности. Так и в коллективе программ, можно проверять, над чем "думают" разные программы, похожие ситуации минимизировать и пытаться сгенерировать новые направления "мысли". В оценке этого, в первую очередь нам помогут эмуляторы, надо смотреть насколько похожее они выдают видение внешней среды.
Можно проверять и отдельные программы, насколько они однозначно выдают решение. Если программа блуждает между несколькими решениями, или не сходится к решению, то можно на эту ситуацию кинуть дополнительные программы, инициализированные этой же ситуацией, но со случайными отклонениями, чтобы стимулировать "ход альтернативных мыслей". Может ветвление пригодиться и при обучении, когда можно будет определить, насколько программа неоднозначна в решении, и разделять неоднозначные случаи на несколько более однозначных программ, с тем, чтобы они более успешно работали совместно в коллективе. Но опять же, всё это пока только красивые идеи, идеи для экспериментов.
Они будут видеть сны
Хорошо, когда у нас есть примеры правильного поведения, или можно проэмулировать реакцию среды. Для естественного интеллекта (и будущего искусственного) такая роскошь не всегда доступна. Интеллект пытается что-то сделать со средой, из этого что-то получается правильно, что-то нет, что-то остаётся с непонятными последствиями. Как на основе этого обучаться?
Для этого введём третью разновидность эмулятора внешней среды. Она будет запоминать проявления внешней среды, то, что делал искусственный интеллект в ответ на эти проявления, и к чему это привело. Это не исключает того, что по мере накопления опыта такой эмулятор сможет совмещать в себе и две предыдущие разновидности - эмуляцию и прогнозирование среды, и будет построен на принципах, аналогичных нашему искусственному интеллекту.
Как обучаться, когда нет чёткой информации, какие действия правильные, а какие нет? Небольшое отступление. Сети Хопфилда обучаются на примерах путём "суммаризации" всех примеров, без критической оценки, без коррекции ошибок. Обученная сеть Хопфилда по частичному или зашумленному образу в процессе итерации (схождения к энергетическому минимуму данного образа) может воссоздать исходный образ. Так вот, после обучения в сети иногда получаются ложные образы. Для того, чтобы ложные образы устранить, обучающие примеры запускают на вход, и если сеть сходится к ложному образу, то такой образ затирается. В некотором роде сеть "видит сны" на основе ранее полученной информации, и во сне ложная информация замещается правильной информацией. Сети Хопфилда применяются для простых образов, но нам интересен именно принцип.
Похожим путём мы можем пойти и здесь. После накопления информации от внешней среды интеллект от внешней среды отключается и работает только с эмулятором. Эмулятор воспроизводит ситуации, и если интеллект выдал хорошее решение, то это решение усиливается, если плохое, то это решение заменяется на что-то другое. На случайное, например. Главное, чтобы новое решение не было похоже на плохое. При этом строим изменения таким образом, чтобы накопленные хорошие решения не потерялись, и новые плохие решения не появились.
Как минимум, такая перестройка может осуществляться при помощи генетического алгоритма. Не исключено, что возможна и перекрёстная оценка каждого правила, составляющего программу, так, что можно будет точно вычислять ошибку и коррекцию для каждого правила. Ведь кое-какая информация о том, хорошо или плохо отработала программа, у нас есть. Тяжелее здесь в том плане, что если решение принимал коллектив программ, то информация о правильности решения известна только для победившей программы. Но зато у нас есть информация о поведении программ, длительная по времени, и из неё уже можно вытягивать подробности.
Вот и получается, если искусственный интеллект поставить в условия естественного, то появятся длительные фазы бодрствования, во время которого путём проб и ошибок накапливается информация, и после них фазы сна, во время которых эта информация качественно переваривается. Сам этот процесс получится длительным и кропотливым. В естественном интеллекте, такой механизм, единожды появившись в процессе эволюции, быстро показал свою полезность и размножился на последующие поколения. Штука как бы и не очень сложная для того, чтобы появится во время эволюции.
Они будут чувствовать боль
Другой вариант обучения, когда информация о правильности действий недоступна. Напомню, при обучении методом отжига, для перестройки решения применяются случайные изменения параметров целиком по всему решению. Сила таких изменений (температура) начинается с высокой, и постепенно уменьшается, когда решение сходится к лучшему варианту. Если изменения нас не устраивают, сила изменений (температура отжига) увеличивается в поисках более подходящего варианта.
Поэтому в процессе эволюции выработался механизм боли. Неправильное действие - и мы мгновенно чувствуем, как наши нейронные связи пожирает жестокое пламя. Такая встряска не проходит бесследно. Последствия неправильного действия оказываются буквально выжженными в наших нейронных связях. Да так, что мы избегаем всеми силами повторения этих неправильных действий. Механизм простой, но эффективный.
В искусственном интеллекте обучение может дополняться более интенсивным темпом случайных изменений, более высоким темпом целенаправленных изменений, если интеллект выдаёт плохие решения. Такие дополнения могут применяться как на уровне коллектива программ, так и на уровне отдельных программ или правил. "Плохие" правила или программы могут оказаться буквально сожжёнными в результате неправильных действий, в то же время хорошие правила и программа сохраняться и приумножатся, но как огня будут "бояться" неправильных действий.
На более высоком уровне интеллекта "боль" будет проявляться и в плане того, что "голова раскалывается от идей", "невозможно собраться с мыслями" и т.п. Состояние хорошего решения будет сопровождаться чёткостью мысли, гармонией и "душевным равновесием".
Ансамбли правил
Представим, что в процессе эволюционного обучения, какая-то часть правил клонируется так, что они остаются взаимосвязанными с родительским экземпляром. Например, они остаются присоединены к одним и тем же входам и выходам, активируются практически одновременно. При этом правила друг от друга всё-таки отличаются, и дальнейшая их эволюция может идти разными путями. Теперь сделаем так, чтобы при изменениях эта часть правил оставалась по большей части взаимосвязанной, т.е. чтобы выходы, выходы, активация и выдаваемые решения во многом совпадали. При этом правила ансамбля могут участвовать в других местах, в том числе и в других ансамблях.
Получится, что решения ансамбль выносит совместно всеми своими правилами. За счёт коллективной работы решение получится качественней (по крайней мере, так и получается для обычных нейронных сетей). Но при этом, ансамбль будет иметь ещё и какое-то новое, качественно иное представление ситуации, сможет действовать далеко за пределами исходной ситуации, за счёт того, что правила из ансамбля участвуют в других местах (и ансамблях) программы (а это уже предположение, касающееся именно ансамблей, участвующих в программе). Можно сказать, видение ситуации будет более высокоуровневое, более обобщённое, более расширенное и обогащённое опытом других ситуаций. Таким образом, в пограничных или новых ситуациях, ансамбль сможет генерировать (можно даже сказать, фантазировать) новую реальность, продолжающую по смыслу старую, ту, что он видел во время обучения.
Тут начинают потихоньку проявляться такие вещи как абстракции-категории, ассоциативное мышление. Начинают проявляться "тяжёлые" логические цепочки, которые за счёт на порядки более высокого видения ситуации могут выдавать "тонкие" логические цепочки, близкие к формальной логике и строгим алгоритмам.
При встрече с новыми ситуациями, программе, имея в запасе такие ансамбли, будет намного легче переносить и обобщать свой опыт на новые ситуации.
Всё это пока что красивые предположения, но, по всей видимости, дело идёт именно в таком направлении. Как именно такие ансамбли образовались и поддерживаются в мозгу - пока непонятно (но согласитесь, эволюционно это выглядит достаточно просто). Как ансамбли поддерживать и вести в программе - тоже вопрос. Видимо никакой чёткой фиксации правил на ансамбли нет, всё решается динамически, путём сочетания правил, имеющих совместимость под конкретную ситуацию, всё по тем же принципам конкуренции и взаимодействия. При этом правила и ансамбли так же динамически смогут выстраиваться в иерархию, и, тем не менее, никакой постоянной иерархии не будет, не будет метауровней и переходов между ними, не будет никакой чёткой формализации с выделением связей система-подсистема. Подробнее о том, за счёт чего это может образоваться, будет дальше. И согласитесь, с точки зрения естественного хода вещей, всё выглядит достаточно просто.
И снова волны, частоты и голография
В нашей программе искусственного интеллекта, разделение на конкурирующие программы и альтернативное видение ситуации задаётся искусственно. Точно также искусственно вводится глобальное состояние, к которому имеют доступ все правила и тактовый генератор, который в каждый новый момент активирует все правила и обновляет ситуацию. Но в мозгу ничего такого нет, и, тем не менее, что-то очень похожее там образовалось естественным путём.
Что у нас есть, так это свойство естественного нейрона накапливать потенциал, и при превышении критического порога разряжаться серией сигналов по своим выходам (помните про частотные нейронные сети в предыдущих частях?). Эти серии, в свою очередь, с каждым разом поднимают (или понижают) потенциалы нейронов, которые присоединены к входам исходного нейрона. Пороговые потенциалы, частота и длительность разрядки - параметры, видимо настраивающиеся в процессе обучения.
Вот и получается, что не нужен ни тактовый генератор, ни циклы и условные переходы, ни глобальное состояние и принудительное распараллеливание ситуации.
Коллективы таких нейронов уже несут в себе и внутреннее состояние, и сложную итеративную логику, и условную обработку.
Причём пачки нейронов могут объединяться в альтернативные (параллельные) цепочки, каждая со своим видением ситуации, и на выходе, все эти цепочки сами между собой конкурируют за то, чьё решение будет подано на выход. И такая обработка вполне поддаётся моделированию на обычных компьютерах. Другое дело, что поначалу она, скорее всего, будет более прожорлива к ресурсам, чем модель интеллекта с принудительным распараллеливанием, но в перспективе, менее регулируемая модель, думается, окажется более эффективной.
Теперь вспоминаем про ансамбли и метаансамбли. Получается, что по отдельным ансамблям бродят целые волновые фронты, которые на разных ансамблях в сочетании дают сложные волновые паттерны, может даже и посложнее чем голографические образы. Вот эти волновые паттерны и сцепляют динамически отдельные нейроны (или правила-сети в нашем искусственном интеллекте) в ансамбли и метаансамбли.
Посмотрите, как всё получилось естественно, и, тем не менее, прагматично. Не надо выдумывать отдельно никакие частотные и голографические сети, не надо их мучить и заставлять распознавать образы. Достаточно применить эффективный и естественный ход вещей, как все эти частотно-голографические свойства проявились сами, как побочный эффект.
Исходная ситуация, попав в мозг, расщепляется на многие альтернативные цепочки, вызывает целые бури волн изменений нейронных потенциалов, и в итоге получает намного более сложное и качественное представление. На выходе же, вся эта обработка опять свёртывается в узкие пределы, которые нужно выдать во внешний мир.
Ассоциации, категории, обобщения и прочая философия
В разделе про ансамбли мы упомянули, что для правил хорошо бы участвовать в разных местах программы, отчего правила научатся качественно обобщать опыт из совершенно разнородных ситуаций. А именно, они будут на пути высокоуровневых абстрагирований, таких как ассоциативное мышление и категоризация. Например, смогут вынести что-то общее из понятий "белое" и "пушистое" и применить это в ситуации "летает". Такая обработка сделает мышление намного мощнее и позволит в динамике выстраивать ансамбли правил под совершенно разнородные ситуации.
Чтобы получить такие свойства, мы искусственно ввели ансамбли и их поддержание. Какими ещё способами можно получить свойства, позволяющие правилу, будучи обученным под одни ситуации (понятия), принимать участие и дообучаться в совершенно отличных ситуациях (для других понятий, как в примере про белое/пушистое/летает)?
Пока вырисовывается два варианта.
Вариант первый, динамическое сочетание входов и выходов. Помните, вначале мы поставили жёсткое соответствие входов и выходов правил (нейронных сетей) с ячейками глобального состояния? Эволюционные изменения при этом были настроены так, чтобы по минимуму изменять эти соответствия. В следующем варианте, без глобального состояния, входы и выходы разных правил-сетей тоже жёстко соединялись друг с другом.
Теперь разрешим в процессе работы и в процессе обучения входам и выходам менять положение друг относительно друга. Возникает два вопроса. Во-первых, как определить, насколько совместимы элементы полученной комбинации, насколько это соединение эффективно решает задачу? Во-вторых, как быстро подобрать совместимые/эффективные комбинации входов и выходов, ведь комбинаций очень много?
Самый простой вариант - каждому входу и выходу правила сопоставить признак-совместимость, которая меняется эволюционно, и, может быть, есть способ донастраивать эту совместимость более точно, в процессе обучения, по результатам работы правил. (Может ли совместимость выходов вычисляться в процессе работы правила? Было ли бы это эффективно?) Для входов и выходов во внешнюю среду тоже понадобиться набор совместимостей, который будет частью общего набора. При работе программы соединяться правила будут только с учётом совместимости входов-выходов. Задача подбора такой совместимости нелёгкая в вычислительном плане, но всё-таки и не совсем тяжёлая. Возможно, в этом подборе помогут алгоритмы сетей Хопфилда, которые умеют делать похожие вещи.
Следующий вариант - по-разному комбинировать в процессе обучения входы и выходы разных правил и накапливать информацию об эффективности (совместимости) разных комбинаций. При реальной работе поступать, как и выше - комбинировать входы в соответствии с совместимостью.
Предыдущие варианты подходят для реализации искусственного интеллекта, но такого комбинирования входов и выходов в естественном интеллекте, похоже, нет. Зато есть карты признаков, см. про свёрточные сети и неокогнитрон в предыдущих частях. И такие карты, похоже, существуют в естественном интеллекте.
Смысл карт признаков такой. Есть набор правил, есть набор входных ячеек. Каждое правило сканирует входные ячейки с помощью подвижного окна, и все ячейки из окна попадают на вход правила. Результат работы правила записывается в ячейку карты признаков, соответствующую положению окна на входных ячейках. В итоге для каждого правила получится карта признаков, в которой места наилучшего срабатывания правила будут иметь самые высокие значения. В следующем слое все карты признаков составляют вход для нового набора правил, которые опять составляют свои карты признаков. Обучаться правила могут обратным распространением ошибки. Как такие правила обучать в составе программы - вопрос открытый.
Карты признаков хорошо проявили при распознавании изображений, при искажениях, связанных с изменением масштаба, ракурса, поворота и при деформациях, специфических для изображённого объекта.
Поэтому карты признаков хороший кандидат для экспериментов по динамическому сочетанию входов и выходов для правил, составляющих программу.
Вариант второй, частотное сочетание входов и выходов. В этом варианте переставлять входы и выходы не надо. В частотных нейронных сетях (или в программах, построенных на таких сетях) каждый нейрон представляет собой как простейший частотный фильтр, так и простейший генератор частоты. Причём фильтр этот может быть настроен на разные гармоники одновременно (за счёт чего ёмкость и возможности частотных сетей выше, чем у обычных сетей). Точно также любое сочетание нейронов является одновременно сложным частотным фильтром и сложным частотным генератором. (В нашем искусственном интеллекте такой нейрон - эквивалент единичного правила, представленного небольшой нейронной сетью).
Поэтому по одним и тем же нейронам могут на разных частотах могут бродить сигналы, относящиеся к совершенно разнородным сущностям. Но так как разные частоты влияют на одни и те же нейроны (сочетания нейронов), то разные частоты (и сущности, ими обрабатываемые) влияют друг на друга. Поэтому, если наш интеллект построен на принципах частотной обработки сигналов (как упоминалось выше в разделе про частоты), то у этого интеллекта похоже уже есть способность к обобщению разнородных сущностей и к некоторому философскому абстрагированию. Хотя, может есть дополнительные технические решения, которые ускорят формирование таких обобщений в частотных сетях.
И немножко в заключение. Такие вот способы перекомбинирования входов и выходов дают не только высокоуровневые свойства, вроде ассоциативного мышления и качественных обобщений, но и более прозаические. Что будет, если в электрической схеме перепутать провода? Скорее всего, это будет фатально для схемы. А вот для мозга необязательно. Проводились опыты (на животных), когда мозг буквально резали на куски и перемешивали, после чего складывали обратно и отпускали животное. Через некоторое время животное приходило в норму и жило дальше. Полезное свойство, правда?
Нет никаких метауровней
Когда-то я ломал голову над тем, как же в интеллектуальных системах выстраивается логическая иерархия, как происходят логические построения, когда над одним кристально чётким уровнем выстраивается другой, обобщающий в себя несколько уровней пониже. В трудах по искусственному интеллекту (и не только) красиво расписывалось как эволюционируют системы, накапливают в себе сложность, переходят с одного уровня на другой.
В реальных системах всегда оказывалось, что как бы хорошо ни продумывались нижние уровни, в них всегда накапливаются какие-то неувязки, изменения, которые не могут быть согласованы с верхними уровнями, эти изменения рано или поздно ломают всю систему, требуя капитальной перестройки всей иерархии. Выход был таким - не завязываться сильно на такие иерархии, оставлять свободу действий, чтобы, если надо, можно было работать в обход формальной иерархии. И это не признак плохо спроектированной системы, это реалии жизни.
Конечно, правильная система минимизирует бардак, на то она и система. Но это не значит, что в такой системе полностью отсутствуют неформальные связи. Хорошая система, при всей своей правильности, должна нести элемент собственного уничтожения. Элемент, вступающий в действие, когда система уже не сможет справляться со своими задачами, элемент, который полностью перестраивает систему под новые реалии.
Так и в искусственном интеллекте, похоже, нет места никаким логическим уровням и метапереходам (особенно ввиду предыдущего раздела про ассоциации и обобщения). Все правила (они же нейроны в нашем понимании), принимают одновременное участие в принятии решений любых уровней. Правила-нейроны могут динамически выстраиваться в разнообразные ансамбли, в разнообразные иерархии. Но даже при таком динамическом выстраивании у них не будет иерархической строгости, элемент с нижнего уровня может запросто повлиять на верхний уровень, да так, что полностью его перестроит.
В каждом конкретном случае применения правил можно выстроить свою иерархию. Но эта иерархия не статическая, как это происходит при различных формализациях. В интеллекте всё зависит от того, с какой стороны потянуть, под каким углом посмотреть. Для каждого угла выстроиться своя иерархия, и таких "углов зрения" может быть очень много. Внутри же интеллекта никакой чёткой иерархии, по-видимому, нет (имеется в виду не "аппаратный" уровень, определяющий, какой отдел мозга за какие органы отвечает).
Квантовая генетика
Много интересного рассказано про квантовые вычисления и квантовые свойства интеллекта. Некоторые даже считают, что мозг может напрямую "дёргать" квантовые процессы, чтобы подумать.
Вкратце, суть квантовых вычислений сводится к следующему. Исходные данные наносятся на небольшое количество элементарных частиц. В процессе решения данные начинают обрабатываться одновременно огромным количеством разных способов, причём эти способы друг с другом общаются, узнают у кого решение лучше, у кого хуже, плохие решения ослабляются, хорошие - усиливаются.
Происходит это за счёт того, что при запуске квантовых вычислений каждая частица полностью "чувствует" состояние всех остальных частиц, участвующих в вычислении, причём чувствует мгновенно, и без существенных затрат энергии. При запуске решения, частицы погружаются в "размазанное" ("спутанное") состояние, которое невозможно исследовать из внешнего мира. В размазанном состоянии у каждой частицы нет чёткого физического состояния, каждая частица находится одновременно в нескольких состояниях и может участвовать в нескольких параллельных процессах (причём эти процессы "чувствуют" друг друга). Причём чем больше частиц участвует в решении, тем больше состояний одновременно может иметь одна и та же частица.
Если попытаться влезть в размазанное состояние и посмотреть что там внутри такое, то в каждый конкретный момент мы получим конкретные физические состояния частиц, без намёка на множество одновременных состояний. Причём после такого вмешательства ход решения будет полностью разрушен, множественное состояние не сможет быть восстановлено. Поэтому то, что происходит в промежутке между заданием входных данных и снятием результата решения - загадка. Получается, что небольшой объём входных данных в процессе решения порождает на многие порядки более сложное внутреннее состояние, которое непонятно как эволюционирует, не поддаётся исследованию, и, тем не менее, выдаёт правильное решение. Состояние, снятое при попытке исследования размазанного состояния, носит вероятностный характер. При правильном составлении квантового алгоритма, можно сделать так, чтобы вероятность снятия правильного решения намного превышала вероятность снятия неправильного решения (т.е. решение надо снять хотя бы несколько раз).
Казалось бы, таким образом можно получить практически забесплатно огромные вычислительные мощности. Но есть проблема - частицы решения должны быть полностью изолированы от внешнего мира, иначе внешний мир будет сбивать правильность хода решения (нарушать когерентность). Есть мнение, что полная изоляция невозможна, поскольку (как гласит квантовая физика) каждая частица, каждый квант, изначально размазаны по всей вселенной и тесно переплетены с каждой другой частицей, составляющей нашу вселенную. И, как следствие такого мнения, получается, что квантовые вычисления не погружают частицы в состояние, размазанное по альтернативным вселенным, а привлекают другие, вполне конкретные частицы из нашей же вселенной для распараллеливания вычислений. Правда, это всё равно не отменяет трудностей по исследованию внутреннего состояния.
Из этого следует несколько интересных выводов. Квантовые вычисления на высоких мощностях не смогут нас обеспечить абсолютно истинными вычислениями, но вполне пригодны для правдоподобных решений, например в искусственном интеллекте, как было описано выше. И ещё один вывод, тесно пересекающийся с предыдущим - квантовые вычисления не могут обеспечить самопознания, саморефлексии, так как являются неотъемлемой частью вселенной, и значит, не могут познать сами себя и вселенную в целом, так как являются её неотъемлемой частью. Отчего собственно и следуют квантовые неопределённости, при попытке измерения состояний квантовых частиц, как мы и отметили в предыдущих частях. Ведь невозможно полностью познать самого себя только при помощи самого себя. Квантовая неопределённость - это фактически прямое следствие теоремы Гёделя, гласящей, что формальная система не может с абсолютно истинной точностью познать саму себя.
Теперь вернёмся к интеллекту. Многими исследователями были правильно подмечены сходства свойств квантовых вычислений и интеллектуальных процессов у человека. Самые интересные нам свойства таковы. Вход и выход решений - достаточно простой набор состояний. Эти простые состояния погружают мозг в намного более сложное состояние, которое невозможно исследовать извне. Попытка исследовать это состояние, или снять решение - опять выдаёт набор простых состояний, причём эти состояния тоже вероятностны и с большей вероятностью выдают правильное решение, чем неправильное. Человеку трудно осознать это своё внутренне состояние, в отличие от входа/выхода, зато это внутреннее состояние, что называется "чувствуется". Как и в квантовых вычислениях, задание начального состояния и снятие решения - достаточно трудоёмкие процедуры. Так и человеку легко думать "у себя внутри", но чтобы передать свои мысли наружу, другому человеку - надо неплохо постараться.
Теперь остаётся только заметить, что вышеперечисленные свойства квантовых вычислений и человеческого интеллекта практически один в один применимы к ранее описанному алгоритму искусственного интеллекта, который был основан на генетическом алгоритме.
Ведь в самом деле, казалось бы, откуда в мозгу, с его волнами, частотами и нейронами может возникнуть какое-то подобие генетического алгоритма, с его хромосомами и альтернативными вариантами решений? Оказывается, если посмотреть с другой стороны, генетический алгоритм - всего лишь одно из проявлений более общего класса процессов.
Получается, что мозгу, чтобы проявлять интересные квантовые свойства, совсем необязательно дёргать квантовые процессы напрямую, есть объяснения более прагматичные. Да и самим квантовым вычислениям совсем необязательно привлекать мистику про параллельные вселенные и абсолютные истины, ведь они, вполне может быть, на микроуровне организованы в какое-то подобие генетического алгоритма, который только делает вид, что погружает частицы в размазанное состояние, а на самом деле довольствуется вычислительными ресурсами собственной вселенной.
Вполне может быть, что на стыке квантовых вычислений, генетических алгоритмов и других направлений искусственного интеллекта возникнет новая теория вычислений, которая позволит делать и более мощные квантовые компьютеры, и позволит, на основе строгого аппарата квантовой физики, точнее объяснить процессы, происходящие в интеллекте. Ведь то, к чему мы пока пришли в понимании интеллекта, напоминает анекдот "нутром чую, что 0.5 + 0.5 будет литр, но математически доказать не могу", когда сделать можем, но объяснить почему так - пока нет.
Внутреннее представление вещей
Как происходит представление внешних вещей в мозгу? Может показаться, что мозг воссоздаёт физическую модель предметов и явлений, отчего следует масса неправильных выводов. На самом деле, внутреннее представление - это совсем не то же самое, что физическая модель. Внутренняя модель правдоподобна. Внутренняя модель формирует аналог, который ухватывает только самые важные для нас свойства предмета, те свойства, которые используются в повседневном опыте. Такую внутреннюю модель иногда называют "наивной физикой". В пределах повседневного опыта, такая модель даёт пусть и неправильные, но вполне пригодные на практике результаты. Но как только мы выходим за пределы повседневного опыта, такая модель даёт сбой.
Коллектив правил, формирующих такую модель, может быть очень далёк от реального физического представления. Отчего внутреннее представление несёт в довесок множество "фантастических" свойств настоящих предметов, внутреннее представление начинает "жить своей жизнью". Например, карикатуры. Человек с лёгкостью распознаёт лицо, нарисованное на карикатуре, обученные люди могут карикатуры рисовать. Но системы распознавания лиц карикатуры ставят в тупик. И правильно, хоть в распознавалках и правдоподобная модель, она намного ближе к физической, чем человеческая.
Внутреннему представлению тоже свойственен перепад сложностей, описанный ранее. Заключается он в том, что более простой предмет или явление, порождает намного более сложное внутреннее представление, которое и является ответственным за моделирование сути вещей. Ведь интеллект не может напрямую моделировать физику. Простое представление порождает "чувство" сути вещей, когда чувствуешь почему так, но не можешь объяснить. Более сложное представление может вытягивать представление вещей на уровень понимания, фантазирования, на уровень сознательного мышления (пример с карикатурами).
Здравствуй логика
Что такое логика и откуда берётся высшая интеллектуальная деятельность?
Наш интеллект прошёл путь от простейших реакций "вход-выход" до сочетания огромного количества конкурирующих процессов, которые раскладывают входную ситуацию в намного более сложное внутреннее представление.
В итоге, для некоторых вещей могут образоваться комплексы правил огромной сложности (намного сложнее физики исходной вещи), которые и являются внутренним представлением этой вещи. Какого именно вида могут быть эти правила и как приблизительно они могут образоваться, описано выше. Но главное состоит в том, что за счёт такого перепада сложности между исходным явлением и его описанием, становится возможным качественно иное представление этого явления, позволяющее выводить новые знания об этом явлении с высокой степенью правдоподобности.
Напомню, парадокс интеллект vs алгоритм заключается в том, что алгоритм может только тупо моделировать физику вещи, без осознания сути явления, не может выводить новые знания о явлении, и даже не может гарантировать истинность своей работы. Интеллект, за счёт намного более сложного внутреннего представления сути вещей способен не только моделировать эти самые вещи, но и выводить новые знания о них, и даже давать оценку истинности суждениям относительно этой вещи, причём с высокой степенью правдоподобности.
Переход сложности, который развёртывает представление сути предметов и явлений, в представление, на многие порядки сложнее исходной "физики" предметов и явлений, является хорошим кандидатом на роль понимания. Есть разложение на сложное внутренне представление - есть понимание и качественное оперирование сутью вещей, возможно гибкое реагирование при возникновении неожиданных ситуаций. Нет такого разложения - возможна только тупая "зубрёжка", слепое следование алгоритму, не дающее вывода новых знаний и не отдающее отчёт о сути или истинности своей работы, и сбивающееся при возникновении новых факторов.
Тупое следование алгоритму не привлекает высшей интеллектуальной деятельности, поэтому является быстрым и эффективным, где нужна только чёткая реакция на типовые ситуации. Высшая интеллектуальная деятельность, с привлечением понимания, способна медленно клепать разные алгоритмы, но не способна их быстро выполнять. Возможны и сочетания этих способов.
Следующий закономерный вопрос - а можно ли понять, что происходит в процессе понимания? И такой же закономерный ответ - скорее всего да, но для этого потребуется такое представление процессов, происходящих в интеллекте, которое бы на многие порядки превосходило по сложности исходные интеллектуальные процессы. То есть, что-то об интеллекте мы можем узнать, что-то можем сделать, но полностью и качественно осознать работу человеческого интеллекта мы не в силах - банально не хватит мощности мозга. Хотя закономерности мы можем изучить и использовать, как пользуемся сейчас компьютерами, без полного осознания процессов, в них происходящих. Нереально представить себе процессы, протекающие во всех миллионах транзисторов, хотя вполне можно понять, как работают логические единицы компьютерных схем и как они объединяются в более высокие уровни. Похожее верно и для интеллекта.
Из вышесказанного становится понятно, почему понимание трудно объяснить, и почему понимание легко чувствовать, почему можно выложить логические построения, сопутствующие пониманию, и почему очень трудно воспроизвести всю ту основу, которая привела к самому пониманию. Про это будет целый раздел чуть ниже. Отсюда же становится понятным, что такое чувство, что такое ощущение состояния, почему чувства и ощущения трудно выразить, но легко прочувствовать. В общем, следствий интересных много, кому интересно - смотрите в направлении квантовых свойств сознания.
Другой вопрос заключается в том, как именно получается так, что мы осознаём самих себя, осознаём окружающий мир? Получится ли такое осознание у мыслящих машин? Этот фундаментальный философский вопрос выпадает за рамки искусственного интеллекта, но мы всё же попытаемся на него ответить в следующей части.
Продолжая мысль про перепады сложности и понимание, приходим к тому, что сверхсложное внутреннее представление, в конце концов, окажется способным генерировать очень тонкие, можно сказать острые, сверхгармонизированные грани от внутреннего представления вещей. Другими словами идеализации, или абстракции исходных вещей.
Абстракции эти обязаны своим рождением многократному сочетанию огромного количества внутренних, конфликтующих и сочетающихся процессов. Но в отличие от результатов взаимодействия большинства внутренних процессов, для абстракций результат будет носить не размытый (широкий) характер, а будет собираться как бы в остриё, в одну или несколько очень чётких граней или пиков.
Естественно, абстракции порождены, в том числе, и многократным наблюдением за проявлениями их реальных прототипов, так и многократными размышлениями с привлечением внутреннего представления предметов. Причём многократность этих наблюдений и размышлений наверняка выше, чем у остальных предметов, не дающих абстракций. И характер правил, дающих внутреннее представление абстракций, наверняка носит более упорядоченный, более приспособленный к пиковой гармонизации, вид.
Следующий шаг - такие пиковые гармонизации смогут объединяться в длинные цепочки, действующие по своим собственным законам. Таким образом, получаем новый уровень мышления, абстрактный или логический. Естественно, такой уровень намного сложнее обычного понимания, и далеко не каждое создание, наделённое пониманием, способно к сложным логическим построениям.
Такие абстрактные цепочки будут жить по своим законам, где-то напоминая исходные прототипы, где-то от них отдаляясь.
Обратите внимание, откуда взялись логические построения. Они не на алгоритмическом уровне, и даже не на следующем уровне, уровне понимания. Они составляют уже третий уровень интеллекта, некое понимание над пониманием.
Остаётся напомнить, что в процессе логических построений мозг только "делает вид" что он работает как тупой алгоритм, как примитивная машина логического вывода. На самом деле, процессы, задействованные в логических построениях, на огромные порядки сложнее, чем исходные логические построения, и за счёт такого скачка сложностей интеллекту и удаётся создавать новые логические построения и с высокой степенью точности судить об их истинности.
Точно так же мозг может и эмулировать работу компьютеров (машины Тьюринга), за счёт "тяжёлых" процессов, хотя при этом кажется, что мозг следует "тонким" алгоритмам (особенно если мозг натренирован на такую работу).
И ещё немножко про тонкие логические построения и составление алгоритмов. Непосвящённым может показаться, что при размышлениях о математических истинах или при составлении компьютерных программ, просветлённый мудрец усаживается в какое-то подобие медитации, и с помощью правильных рассуждений приходит к правильным выводам или придумывает правильную программу. На самом деле происходящее больше похоже на следующую схему.
- Придумал "что-то", начальную версию (или даже случайно сгенерировал).
- Проверил работу этого "что-то" посредством эмуляции логических рассуждений, запомнил проблемные места.
- Попытался методом тыка улучшить проблемные места (улучшил это "что-то").
- Проверил улучшенную версию, и так далее.
Ведь мозг умеет не столько генерировать на ходу правильные логические цепочки, сколько проверять работу этих цепочек посредством эмуляции логических рассуждений. Другое дело, что в мозгу имеется огромная "библиотека" шаблонов на разные ситуации, да плюс куча правдоподобных правил, как эти шаблоны друг с другом сочетать. Применяя эти правила и шаблоны, с небольшого числа попыток, удаётся построить хорошие логические рассуждения и программы. В том числе, такие правила могут включать диагностику работы разных сочетаний шаблонов, могут и пополнятся динамически, вместо того, чтобы каждый раз прогонять логические построения на всём объёме данных.
(С) Дмитрий Брилюк, http://dima78.livejournal.com/tag/science
15.09.2008, продолжение следует: как всё это применимо к человеческой деятельности.
|