В статье приводится описание программной реализации интеллектуального чат-бота, функциональность которого имеет необходимый минимум для самостоятельного обучения, но подразумевает хотя бы небольшое первичное обучение. Реализованы безусловные и модифицируемые рефлексы, цепочки памяти, одношаговый прогноз и простейшее инстинктивное поведение. Однако построение моделей понимания и глубоких стратегий реагирования пока еще не доступно. Интерфейс бота предельно прост и состоит из одной Web-страницы с окном ввода и двумя окнами вывода. В одном из них бот пишет ответы, в другом отражается техническая информация (логи), по которой можно судить о процессах, происходящих у бота в данный момент.
Принципиальное отличие от существующих на данный момент чат-ботов это построение реагирования как достаточно близкое к природной реализации нервной системы. Данный проект наглядно демонстрирует, что нет никаких принципиальных сложностей, чтобы программно реализовать нервную систему по принципу иерархии индивидуальной адаптивности. И хотя бот еще не может «думать», как это обычно представляется «как человек», но он уже чувствует, у него есть примитивные цели и стремления. Может это даже и интереснее, так как позволяет глубже понять, как вообще возник феномен сознания, когда постепенно двигаясь от простейшего «алгоритмического реагирования» вдруг «неожиданно» приходишь к осознанному. Неожиданно взять в кавычки, потому, что на самом деле это закономерно и неизбежно.
А вот что действительно оказалось неожиданным:
Интерфейс программы выполнен с использованием Web-технологий: html, php, javascript, ajax. Программная часть выполнена на языке Go, но это совершенно не принципиально и программа может быть реализована в любом другом варианте.
В открытом доступе в интернете, как это обычно делается, бота нет. Потому, что такое «всеобщее обучение», без тщательного прохождения первичных авторитарных стадий прошивки, просто приведет к тому, что получится бестолковое, хаотичное реагирование. Но для интересующихся этой темой, возможно скачать интерфейс и программный код после соответствующей заявки, которую можно оставить в обсуждении. При этом подразумевается, что вы знакомы с web-программированием и Go. В проекте нет ничего секретного, он создавался параллельно с основным проектом от Николая Дмитриевича Петрийчука fornit.ru/bot2 как один из вариантов построения адаптационной схемы в ее простейшем исполнении.
Так же есть Блок-схема проекта
Основной принцип реагирования, по которому строится активность чат-бота – это стабилизация его базовых состояний, выводимых из равновесия внешними воздействиями в виде фраз оператора и внутренней пульсацией. Ответная реакция может быть двух типов:
В первом случае действия бота аналогичны рефлексам животных, его ответные реплики жестко привязаны к определенным комбинациям внешних раздражителей, которые далее будем называть «внешним контекстом», и текущему внутреннему состоянию бота, который соответственно назовем «внутренним контекстом». В результате получаем вариабельность реагирования, когда на одну и туже фразу оператора бот может отвечать по разному, смотря по тому, в каком внутреннем контексте он сейчас находится. Такое реагирование можно назвать пассивной адаптацией.
Во втором случае все сложнее. Здесь появляются такие понятия как «цель» и «смысл». Потому, что бот используя прошлый опыт общения, пытается прогнозировать дальнейшее развитие диалога и выстраивает свое реагирование исходя из этого. Здесь он уже не просто реагирует, а скорее провоцирует оператора на нужные фразы, которые стабилизируют его текущее состояние. Для этого бот должен «понимать», что он говорит, фразы должны иметь для него определенный «смысл». И тогда этот процесс правильнее уже называть не стабилизацией, как простейший вариант рефлекторного реагирования, а адаптацией, как процесс «взаимной стабилизации» состояний участников диалога: бот провоцирует реагировать оператора, оператор провоцирует бота. Такое реагирование можно назвать активной адаптацией.
Когда говорим об «интеллекте бота», то имеется в виду второй вариант реагирования. Основой для него служит первый вариант, как подготовительный и без которого второй не возможен. Но первый возможен без второго, как если бы у животного удалили лобные доли, и оно бы реагировало только с помощью тех рефлексов, которые ему удалось сформировать прежде. При этом активное реагирование так же можно условно разделить на подвиды:
В данной модели бота реализованы только первые два варианта, остальные предполагается развить в следующей версии.
Конечно, сами по себе фразы никак не воздействуют на бота, они лишь служат маркерами такого воздействия, как например рычание животного служит признаком его агрессивного состояния и возможного нападения, а мурлыканье кошки наоборот, показывает ее хорошее настроение и отсутствие агрессии. Но для того, чтобы можно было давать такие оценки и получать соответствующие изменения состояния бота, фразам нужно придать «значимость» – как если бы они действительно являлись признаками физического взаимодействия между ботом и оператором. Например, слово «тепло» для бота должно быть не просто комбинацией байтов, оно должно определенным образом изменять его внутреннее состояние и провоцировать его ответную реакцию точно так же, как реальное тепло вызывает соответствующую реакцию животного. Только в этом случае слова приобретают для бота определенный смысл.
Но такое буквальное реагирование на слова и фразы соответствует сенсорному восприятию через органы чувств и предполагается реализовать в следующей версии программы, как ассоциативное реагирование. Здесь же рассматривается более простая рефлекторная модель.
Живым организмам для функционирования необходимо поддерживать внутренний баланс своих систем жизнеобеспечения, этот процесс называют гомеостазом. Потому, что все рефлекторные действия животного энергозатратны и провоцируют внешние ответные реакции окружающей среды, которые могут быть негативными или позитивными, в простейшем определении дающие или отбирающими энергию. Поэтому, что бы ни делал живой организм, это неизбежно сдвинет его гомеостаз и потребуется возвращать критически важные параметры в норму. Чат-боту такая система так же необходима по тем же причинам, так как фразы оператора, как уже было рассмотрено выше, выводят из равновесия его базовые состояния и нужно их стабилизировать. Кроме того, нужно чтобы были еще и внутренние причины, сдвигающие базовые состояния, иначе при отсутствии внешних раздражителей у бота будет прекращаться рефлекторная деятельность. У животных такие внутренние потребности вытекают из особенностей образа жизни и строения организма, например, постоянные потери энергии вынуждают его искать способы ее восполнения (питаться), потребность размножения заставляет искать партнера и т. д. В простейшем случае боту можно обойтись одной базовой внутренней потребностью, присущей всем без исключения живым организмам – восполнение энергии. А чтобы сделать ее необходимой вне зависимости он внешних воздействий, добавить пульсацию – постоянное ритмическое уменьшение энергии небольшими порциями. Если к этому добавить энергетическое воздействие фраз оператора, которые могут давать или отнимать порции энергии, то в результате получится, что боту уже на первичном рефлекторном уровне придется на них реагировать, иначе он потеряет всю энергию, что будет равносильно смерти.
Тут нужно сделать уточнение. Прекращение активности бота при нулевом уровне энергии само по себе не означает для него автоматическое стремление избегать этого, являясь аналогом инстинкта самосохранения у живых организмов. У них для решения такой проблемы необходим инстинкт размножения, чтобы при отсутствии желания жить вид просто выбывал из эволюционной гонки и не мог передать такое «порочное» поведение потомкам. Боту же потребность в поддержании энергетического баланса нужно просто ввести изначально, сделав ее потребностью по умолчанию, если все другие не актуальны. Только в этом случае его активность будет постоянной, реагируя либо на внешние раздражители, либо на изменение внутренних базовых параметров.
Оценить степень воздействия фаз оператора на себя бот может только на основании прежнего опыта, который еще нужно накопить, и авторитарной оценки своих сообщений самим оператором. В данной модели, где нет дерева ассоциативных связей, накапливаемый опыт это в первую очередь авторитарные оценки оператора, которые он задает, указывая тон своего сообщения. По мере накопления опыта в цепочках памяти, о которых будет рассказано ниже в соответствующем разделе, бот даже сможет ориентировочно прогнозировать реакцию оператора на один шаг вперед.
Оценку сообщений через тон можно сравнить с попыткой понять кошку, ориентируясь на ее шипение, мурлыканье или равнодушный взгляд в сторону. За неимением другой ассоциативной базы это, тем не менее, достаточно для построения своей ответной рефлекторной базы, но конечно в довольно грубой форме.
Чтобы сдвинуть величину базового состояния на какое то значение, нужно задать шаг сдвига. При пульсации он постоянный, но при оценке через тон фразы оператора можно сделать его зависимым от длины фразы. Продолжая аллегорию с животным, есть разница в значимости между коротким "гав", и долгим, заливистым лаем. Поэтому бот определяет величину сдвига в соответствии с количеством символов во фразе. А знак смотрится по тону сообщения: (-) негативный, (+) позитивный. Другим вариантом было бы указывать тон в конкретных значениях, например от -5 до +5. Но это усложнило бы интерфейс и общение, заставляя оператора напрягаться в конкретной оценке.
Поэтому для указания значимости сообщения, добавлен интерфейс в виде переключателей, расположенный прямо под окном ввода сообщений оператора, позволяющий ему давать свою простейшую оценку предыдущим сообщениям бота в виде тона своего ответного сообщения: негативный – нейтральный – позитивный. При этом программно реализовано, что негативный тон уменьшает уровень заряда текущей базовой потребности на некоторую величину, зависящую от длины сообщения, позитивный увеличивает, а нейтральный оставляет без изменений. Во время диалога с ботом оператор обязательно должен указывать степень своего воздействия, при этом подразумевается, что он не обманывает бота и всегда верно указывает тон сообщения. Это важно, так как иначе будут не верно записаны цепочки памяти и неадекватно сдвигаться уровни базовых состояний.
Может показаться, что тон сообщения это просто оценка оператором предыдущего ответа бота по принципу «верно/не верно». По результативности это действительно похоже. Но по принципу действия совершенно иное. В системе реагирования бота нет понятий «правильно/не правильно», вместо них используется «стало лучше/стало хуже», потому, что то, что «правильно» в одной ситуации может быть «не правильным» в другой. Эта относительность понятий «плохо/хорошо» и не позволяет использовать их в качестве оценки сообщений. Но они используются как основа, по которой формируется оценка «стало лучше/стало хуже». Подробнее об этом ниже, в соответствующем разделе. Но сначала рассмотрим, каким образом бот вообще может воспринимать фразы оператора так, чтобы они что то меняли внутри него и вынуждали адаптироваться.
Алгоритм стабилизации базовой потребности бота использует ее разделение на три энергетических зоны: пониженной, повышенной и комфортной. Первые две являются граничными, комфортная зона находится между ними, но не обязательно посередине. Первичная рефлекторная активность направлена на то, чтобы по возможности оставаться в комфортной зоне. Выход за ее пределы в любую сторону означает выход из равновесия: недостаток или избыток энергии. Стабилизация потребности означает выполнение рефлекса, позволяющего получить энергию или сбросить лишнюю. У бота такими рефлексами являются его фразы, провоцирующие собеседника на ответные фразы, значимость которых сдвигает величину базовых потребностей бота. Уровнями этих состояний так же можно управлять с пульта оператора, нажимая соответствующий элемент на матрице значений.
Однако использование только одной базовой потребности слишком упрощает реагирование бота, поэтому изначально задаются несколько. В этом случае боту необходимо выбирать из них текущую актуальную и стабилизировать сначала ее, а затем наиболее актуальную из оставшихся. Актуальность определяется по принципу: какая из потребностей находится в наибольшем удалении от своей комфортной зоны. Внешнее воздействие сдвигает уровень потребностей бота, кроме того имеется постоянная пульсация с тем же эффектом для них, в результате получается, что базовые потребности периодически в разной степени выходят из зоны комфорта, поочередно становясь актуальными для стабилизации. Это создает эффект автоматического переключения базовых потребностей, которая активирует разные группы рефлексов на одинаковые внешние раздражители, создавая вариабельность реагирования в зависимости от текущего внутреннего состояние бота.
Процесс адаптации состояния бота подразумевает наличие у него трех состояний: «норма» – когда адаптации не требуется, «плохо» – когда нужно активировать специфические рефлексы, «хорошо» – когда в результате адаптации бот вернулся в состояние «норма». Для определения этих состояний нужны специфические сенсор, которые определяются из следующих соображений.
Если представить базовую потребность в виде шкалы значений, например от 0 до 100 условных единиц, то на ней можно выделить три зоны: недостатка, нормы и избытка. Потому, что любой механизм имеет набор характеристик с оптимальными значениями, при которых он наиболее эффективно функционирует, и от которых определяются области с недостаточными и избыточными значениями, при которых функциональность механизма соответственно затухает либо становится чрезмерно активной. Представим, что у нас есть 2 датчика активирующиеся в некотором диапазоне недостатка и избытка значений базовой потребности. Если диапазоны датчиков перекрываются, то при каком либо значении потребности в пределах шкалы возможны ситуации:
В третьем случае одновременная активация сенсоров показывает, что значение потребности лежит в зоне перекрытия, которая и определяет зону «норма». Если диапазоны датчиков не перекрываются, то зона «норма» будет определяться состоянием, когда ни один датчик не активен, как «мертвая зона».
Каждый датчик активирует свои специфические рефлексы, сдвигающие уровень потребности в зону нормы. Для первой схемы попадание в зону «норма» активирует оба датчика, что требует наличие между ними взаимного торможения, чтобы не запускать одновременно оба типа рефлексов. Для второй схемы рефлекторная деятельность просто прекращается, потому, что ни один датчик не активен.
В программной реализации вместо датчиков просто устанавливаются диапазоны значений, при которых определяются соответствующие зоны, но если делать схему на дискретных элементах, то лучше использовать пару сенсоров с перекрытием и взаимным торможением или разрывом. Потому, что в ситуации, когда значение будет близко к граничной зоне, возможно одновременное срабатывание двух соседних датчиков, что для схемы из 3 датчиков будет означать неопределенность результата. А в схеме из 2 такое срабатывание наоборот, является определителем зоны комфорта. То есть у нее в принципе не возможно зависание.
Диапазоны реагирования бота можно устанавливать с пульта оператора прямо по ходу диалога, нажимая ближайший элемент справа и слева от зоны комфорта, сдвигая, расширяя или сужая тем самым комфортную зону. Это вызовет пропорциональные изменения боковых зон плохо/хорошо. На схеме синим цветом показана зона «недостатка», красным «Избытка», а зеленым – комфортная зона.
Можно поступить проще, не разбивая базовую потребность на шкалу значений и не определяя зоны, если состояние «норма» определять просто как стабильное, когда в течении какого то времени не происходит никаких изменений. Тогда изменение состояния будет означать переход в состояние «плохо», а возврат в состояние покоя – «хорошо». При этом оба эти состояния так же должны поддерживаться ограниченное время, иначе «норма» никогда не наступит. По сравнению с первым вариантом со шкалой и зонами тут даже появляется новое свойство: привыкание. В самом деле, если после отработки рефлексов наступает состояние покоя, которое отличается от прежнего состояния, то это означает, что организм приспособился к нему и сумел нейтрализовать внешнее воздействие, либо воздействие пропало, что так же может означает успешность адаптации. Например, сунув руку в теплую воду и ощущая поначалу тепло, это ощущение затем пропадает и «перестает замечаться». Такие изменения понятия «норма» позволяют более гибко адаптироваться, провоцируя поиск специфических рефлексов для адаптации в новой среде.
Однако при таком упрощении есть и недостаток. Представим ситуацию: при выходе из стабильного состояния и возврата в него после выполнения рефлекса, в памяти зафиксировалось, что рефлекс для данной ситуации оказался удачный. Затем через некоторое время в той же ситуации после выполнения другого рефлекса он так же оказался удачным. Но возникает вопрос: какой из них лучше? Упрощенная схема не позволяет это определить, потому, что в ней лишь фиксируется переход из состояния «норма» в «плохо» и обратно через «хорошо». А насколько «плохо» по сравнению с другим «плохо», и соответственно понятие не просто опять «хорошо», но «лучше, чем в прошлый раз» определить не возможно. Потому, что для этого нужно фиксировать значения «плохо/хорошо» по какой то шкале и сравнивать их.
Первая схема как раз позволяет это сделать, подробнее об этом ниже в разделе «стало лучше/стало хуже». При этом она позволяет так же проявлять и свойство «привыкание», если сделать зону «норма» плавающей, за счет динамического изменения ширины зон «недостатка» и «избытка». Это предполагается сделать в следующей версии бота, а в текущей пока зоны фиксированы и могут изменяться только вручную с пульта оператором.
Первичными сенсорами бота, распознающими введенный оператором текст, являются составляющие слов: корни, окончания, суффиксы, приставки. У бота они записаны в файле matrix_utf8.txt, который автоматически пополнятся, если встречаются новые варианты сенсоров. Распознавание введенного оператором текста в виде сенсоров происходит в файле sent_prepare.php.
Вторичными сенсорами, называемые макросенсоры, являются устойчивые фразы и выражения, которые фиксируются в файле makro_sensors.txt, который так же автоматически пополняется по мере надобности ботом. Данные в файле представлены уже в виде кодов файла первичных сенсоров matrix_utf8.txt. Распознавание текста в базе сенсоров происходит в последовательности:
Приоритет отдается более крупному сенсору (макросенсору), поэтому при положительном результате поиск в следующей по приоритету группе прекращается. При этом, благодаря тому, что во фразе могут встречаться макросенсоры, распозннающие ее часть, становится возможным реагировать на фразу целиком, не имея при этом более крупного макросенсора на всю фразу. Такой макросенсор активируется во всех фразах, где он встречается и запустит свой рефлекс, тем самым делая не обязательным формирование сенсора на всю фразу.
На пульте оператора можно визуально оценить первичный разбор фразы оператора ботом при помощи специального раздела:
После активации первичных и вторичных сенсоров происходит активация рефлексов бота в виде ответных фраз. Тут нужно сделать важное уточнение: сенсоры и макросенсоры запрещено модифицировать и удалять, только добавлять новые. На это есть серьезные причины:
Строго говоря, есть некоторое лукавство, когда сразу задается готовая матрица первичных сенсоров в виде корней, окончаний и т. д. Для полноты эксперимента стоило бы создать процедуру автоматического выделения из массивов введенного текста этих начальных примитивов. Это позволило бы например убрать привязку к русскому языку. В следующей версии это предполагается сделать, хотя уже видятся определенные трудности, связанные с тем, что это не просто статистическая обработка.
Безусловные рефлексы у живых организмов являются врожденными, у бота они так же прошиваются как реакция по умолчанию при отсутствии личного опыта. То есть изначально нужен хоть какой-то минимум ответных фраз, чтобы получить ответную реакцию оператора и запустить процесс адаптации.
Безусловные рефлексы бота являются маркерами его внутреннего состояния, например, при выходе уровня энергии в зону недостачи, бот выдает фразу: «мало энергии». Это может служить для оператора побуждением к каким то действиям, например, сдвинуть ползунок уровня энергии в сторону увеличения. По большому счету это реакция бота на отсутствие активности оператора, так как постоянная пульсация сдвигает уровни базовых состояний, и для запуска процесса адаптации нужна обратная связь с оператором. Кроме того, первичное вербальное реагирование животных – это указание своего внутреннего состояния. Детеныш скулит, если ему плохо, делая это рефлекторно, без понимания смысла такого рефлекса и его причины, и это служит сигналом матери, которая способна в отличие от детеныша найти причину и правильно среагировать. Аналогично безусловные рефлексы бота можно соотнести с такими «хныканьем».
Можно было бы ввести такое же безусловно-рефлекторное реагирование и на фразы оператора, но так как строго однотипное реагирование при диалоге мало продуктивно в плане адаптации, то такие рефлексы большей частью будут не востребованы. Поэтому для рефлекторно-вербального реагирования используется более продвинутый вариант.
Модифицируемые рефлексы бота нельзя соотнести с безусловными рефлексами животных по причине их модификации, через добавление новых и блокировки старых, что противоречит определению безусловных рефлексов. Как происходит модификация будет подробно рассказано ниже в разделе импринтинг. Поэтому введено новое определение как модифицируемого рефлекса.
Запуск модифицируемого рефлекса происходит по схеме: после активации вторичных сенсоров (пусковых макросенсоров) бота на фразу оператора, ищется связанный с ними рефлекс, с учетом текущего внутреннего контекста реагирования, под которым имеется в виду уровень текущей базовой потребности. Если он не находится, то ищется рефлекс в базе синонимов для найденных пусковых макросенсоров. Такое реагирование является мгновенным и не требует глубокого анализа кроме непосредственного поиска рефлекса.
По схеме видно, что на один и тот же раздражитель возможно разное реагирование, в зависимости от значения текущей активной базовой потребности. Но так же возможно, что одна реакция будет ответом на несколько раздражителей. Это произойдет в случае, если один и тот же рефлекс записан для разных базовых потребностей.
Каждый рефлекс привязан не к конкретному значению базовой потребности, а к ее определенному диапазону значений и запускается соответственно при 2 условиях: если активен специфический внешний раздражитель (макросенсор) и значение базовой потребности лежит в пределах пускового диапазона рефлекса. Это позволяет говорить о диапазоне реагирования на один раздражитель. При этом рефлексы располагаются по величине отклика пропорционально изменению значения базовой потребности. Например, в случае бота для потребности «энергетический баланс» и раздражителя фразы «привет, как дела?» диапазон реагирования может быть представлен следующей линейкой рефлексов: «хорошо – так себе – нормально – плохо – скверно». В итоге пять рефлексов-фраз активируются пятью соответствующими диапазонами значений базовой потребности при одном и том же раздражителе.
Такая схема выбрана по следующим соображениям:
Пункты 6 и 7 в данной модели бота не реализованы, но заложена основа для их дополнения в следующей версии программы.
Дальнейшим развитием рефлекторного реагирования является использование рефлексов в виде цепочек.
Под инстинктами у бота подразумеваются цепочки безусловных и модифицируемых рефлексов, выполняемых последовательно. Например, при отсутствии подходящего рефлекса запускается инстинкт: «Не понимаю, что я должен ответить?» Бот переключается в режим обучения с учителем, спрашивает у него вариант ответа, тот отвечает, Бот сохраняет ответ как новый рефлекс. Если на ответную фразу нет синонима, то Бот так же спрашивает: «Что значит […]?» Оператор отвечает, дает синоним, Бот сохраняет его и переключается в прерванный режим диалога. Как видим, здесь инстинкты, это просто более сложные сценарии реагирования, устойчивые цепочки рефлексов с управляющей их ветвлением связью с оператором, позволяющие организовывать простейшие многоуровневые диалоги. В качестве примера можно посмотреть в нейроконструкторе схему прошивка новых рефлексов
Несмотря на кажущуюся простоту, такая схема из последовательно активирующихся рефлексов позволяет создавать достаточно сложные варианты реагирования с различными вариантами ветвления. Кроме того, инстинкты позволяют организовывать простейшие рефлекторные варианты проявления инициативы бота. Например, при выходе из зоны энергетического баланса в зону недостачи, активируется инстинкт «Я голоден»: бот просит покормить его, например, просто сдвинув вручную уровень энергии на пульте или сделать тоже самое через «энергетическую фразу» с положительным тоном. При получении желаемого результата бот может поблагодарить, а при не получении – повторно попросить. Другой пример: при выходе из зоны комфорта потребности общения, бот активирует инстинкт «Давай поговорим», а для потребности к обучению инстинкт «Можно спросить?», служащий для заполнения массива синонимов.
Так как рефлексы являются установленными алгоритмами реагирования на конкретные раздражители, то возникает проблема при изменении в худшую сторону оценки выполнения рефлекса, в результате чего прежде успешно работающий рефлекс становится не актуальным, то есть приводящий не к улушению, а ухудшению состояния. Его нужно заменить на другой, более подходящий. И тут возникают проблемы:
Первая и третья проблемы решаются созданием новых специфических сенсоров, определяющих стало ли лучше или хуже после выполнения рефлекса. Причем формируются они на базе уже существующих сенсоров «Плохо – Норма – Хорошо». Для этого нужно просто добавить возможность запоминать состояние до выполнения рефлекса и сравнивать его с состоянием после. Если после выполнения уровень текущей актуальной базовой потребности стал ближе к ее зоне комфорта – значит «стало лучше», если разрыв еще больше увеличился – «стало хуже». Поэтому, например, сама по себе активация датчика «Плохо» не означает, что «стало хуже», важно именно изменение состояния базовой потребности после выполнения рефлекса. Соответственно, при нахождении в зоне пониженного уровня, улучшение означает рефлекс, увеличивающий «уровень заряда» потребности, а при нахождении в зоне повышенного уровня наоборот, «лучше» будет его понизить. Например, если сильно замерз, то раздражитель «тепло» будет восприниматься положительно, так как согревает, приближая к комфортной зоне температуры. А если наоборот, перегрелся на жаре, то «тепло» будет восприниматься негативно, так как еще больше нагревает, увеличивая удаление от зоны комфортной температуры. Аналогично для раздражителя «холод», только уже в обратной связи: при жаре это благо, при морозе зло.
При активации сенсоров стало «лучше/стало хуже» автоматически возникает регистрация необходимости изменений, так как их реагирование происходит только при выходе из зоны комфорта, то есть если внешнее воздействие вывело базовую потребность из нормы. Тем самым отсекаются изменения, на которые не стоит отвлекаться, если они не вывели потребность из зоны комфорта. Это реализация ориентировочного рефлекса на стороне гомеостаза.
Решение второй проблемы поиска нового варианта реагирования является основной причиной, по которой нервной системе пришлось эволюционировать до уровня человеческого интеллекта. Особи, способные эффективно формировать новые модели поведения при изменении внешних условий, очевидно, получают существенное преимущество в эволюционной гонке. Но такой навык возник не сразу, а явился результатом последовательного адаптационного усложнения, когда каждое возникающее изменение служит основой для возникновения последующего. Это приводит к тому, что мутационные изменения могут происходить только в последних достижениях и не должны затрагивать старых, которые наоборот, максимально тщательно оберегаются от каких либо модификаций. Это можно сравнить с постройкой дома, начиная с фундамента, потом стены и только в конце крыша. Нельзя строя стены менять фундамент, иначе все здание обрушится.
Одним из первых таких усложнений схемы рефлекторного реагирования стала способность запоминать ответные реакции после выполнение рефлекса. В природной нервной системе для этого используются закольцовки, позволяющие удерживать активность нейрона после того, как пропал его пусковой стимул. Это послужило толчком для эволюции рефлекторного реагирования.
Если после выполнения рефлекса запоминать ответную внешнюю реакцию, становится возможным простейшее прогнозирование результата. Это позволит например блокировать рефлекс, если он привел к ухудшению ситуации.
Это простейший способ модификации рефлексов через блокировку тех, что стали неадекватны ситуации. Так как старый рефлекс теперь заблокирован, то как уже говорилось выше в разделе про диапазоны реагирования, оставшиеся рефлексы автоматически расширяют свои рецептивные поля, и два соседних с заблокированным рефлексы перекрывают его рецептивное поле, становясь в грубом приближении временной альтернативой реагирования. Это простейший случай замещения рефлекса, без поиска нового варианта, который вытекает из принципа выстраивания рефлексов бота в виде отсортированных диапазонов.
Однако просто блокируя ставшим не адекватным рефлекс и «передавая управление» его диапазоном соседним рефлексам, мы тем самым делаем реагирование все более неадекватным, так как оставшиеся рефлексы расширяя свои рецептивные поля реагируют все более «грубо». В таком случае нужно искать новый рефлекс.
В самом простом случае, эта проблема на уровне жизни множества поколений решается путем естественного отбора случайных мутаций рефлексов, которые оказывались удачными. Но для уровня жизни одной особи полагаться на случайность, генерируя хаотичную реакцию, не слишком удачное решение, так как большинство таких «находок» скорей всего будут ошибочными. Нужно что то более надежное. И таким критерием выступает прежний опыт взрослых особей, который нужно научиться передавать молодым. И так как цепочки памяти уже есть, естественным путем возникает механизм передачи опыта между особями при помощи навыка наблюдения и повторения чужих действий. У бота таким «взрослым учителем» выступает оператор.
Появление цепочек памяти бота из нескольких фраз диалога с привязкой к ним оценок (тона сообщения) и состояния на момент фразы текущей базовой потребности является начальным личным опытом, который можно использовать в рефлекторных реакциях, без привлечения глубокого анализа. Например, просто повторив этот опыт. Такая модель является пожалуй самым простым, и потому самым древним алгоритмом самообучения - импринтингом: если не знаешь как реагировать, реагируй так, как делают другие. Логика тут очевидно простая: если это их не убило, значит что-то в этом есть и это стоит перенять. У животных первый учитель это обычно родитель, и в этот период детеныш максимально точно фиксирует все его повадки, которые он способен выделить из общей картины поведения родителя. У бота в стадии рефлекторного реагирования тоже нет иных вариантов обогатить свою первичную рефлекторную базу, кроме как просто копировать реакции оператора.
Пример части диалога с таким самообучением:
Оператор: привет, как дела?В результате бот запомнил ответ оператора «отлично, рад за тебя!» на свою фразу «нормально», и если оператор скажет «нормально» бот ответит: «отлично, рад за тебя!» При условии, что тон следующего в цепочке сообщения «взаимно» будет подходящим ситуации, то есть сдвигающий текущий базовый параметр бота в нужную ему сторону. Здесь как мы видим, происходит фиксация не только чужих, но и своих сообщений по причине, что оценивается предыдущее сообщение, а не текущее. Чтобы потом бот мог прогнозировать, что будет, если он скажет фразу оператора, то есть участники диалога как бы меняются ролями, и бот пытается заново прокрутить записанный когда то фрагмент диалога – скопировать модель поведения собеседника, не понимая при этом ни ее смысла, ни целей.
Процедура записи нового рефлекса запускается по факту не удачного использования старого. При этом у бота предусмотрен счетчик попыток, который накручивается в минус при неудачных использованиях рефлекса и в плюс при удачных. Изначально все рефлексы имеют состояния счетчика 0, а фильтр блокировки рефлекса настроен на значение счетчика > -2. То есть после двух не удачных попыток рефлекс блокируется. Однако поиск нового варианта в ячейках памяти начинается уже после 1 неудачной попытки. Новый рефлекс подставляется в диапазон реагирования рядом со старым, который пока еще не заблокирован, но сдвинут в результате подстановки в сторону. Основания для такой логики следующие:
Теперь в отличие от простой блокировки бот сначала пытается на основании своего прошлого опыта сам найти подходящий рефлекс, и только если это не удается, запускается инстинкт «Не понимаю, что я должен ответить?». Конечно такая «аналитика» пока еще никак не учитывает общий контекст и тему диалога, но это уже шаг вперед от более примитивного рефлекторного реагирования. На основе базы ответов оператора в дальнейшем будет строиться более глубокий ассоциативный анализ.
Теперь рассмотрим более подробно интерфейс и функции чат-бота. Проект имеет следующую структуру:
Функции, запускаемые при пульсации с частотой 1 сек
После активации бота запускаются специальные служебные функции, тактируемые частотой пульсации в 1 сек. Одни из них служат для определения текущего внутреннего состояния бота, другие запускают вспомогательные программы при активации их пусковых триггеров.
Определяется текущая актуальная базовая потребность по признаку максимальной удаленности от ее зоны комфорта и определяется текущий контекст реагирования бота по признаку, в какой зоне находится уровень текущей базовой потребности.
Чтобы значения базовых потребностей не выходили за пределы 0 – 100, программно введено ограничение: при достижении граничных значений дальнейшие изменения возможны только в противоположную от границы сторону.
Инстинкты и безусловные рефлексы запускаются по таймеру по алгоритму:
Сном функция названа условно, так как необходимые служебные процедуры нужно запускать в «режиме тишины», при отсутствии внутренних и внешних активностей. Под такими процедурами подразумевается обновление файлов данных массивов, которое происходит по таймеру каждые 5 сек для тех массивов, у которых активен флаг обновления. Так сделано в целях исключить нагрузку на ресурсы при перезаписи больших объемов данных.
Пульт, или окно программы, это основной интерфейс общения с ботом. В окне ввода оператор печатает текст и отправляет его боту через кнопку «Послать», в окне вывода читает ответные сообщения бота. Справа расположено окно текущих событий бота, где отражается информация о произошедших изменениях в файлах данных, активности служебных процедур и некоторые другие технические данные, позволяющие оперативно наблюдать реакцию бота, например в виде служебных сообщений о редактировании массивов.
Бот в своем развитие проходит несколько стадий, которые задаются выбором в списке под окном ввода оператора:
При этом окно ввода меняет интерфейс, позволяя кроме непосредственно диалога, так же заполнять массивы рефлексов и ассоциаций в диалоговом режиме.
Хотя бот может автоматически пополнять базу рефлексов прямо по ходу диалога, все таки желательно сформировать какой то их начальный объем. Это делается в режиме авторитарного обучения на первой стадии, когда оператор указывает диапазоны реагирования с привязкой их к пусковым стимулам: «пусковая фраза» и «базовая потребность». Коды рефлексов хранятся в файле reflexes.txt, расшифровка кодов в reflexes_list.txt.
Здесь оператором задается строка в определенном формате для записи одиночного рефлекса или диапазона. Формат записи:
[пусковой макросенсор] = [рефлекс 1] – [рефлекс 2] – [рефлекс 3]…
Это означает, что можно привязывать сразу несколько ответных фраз, разделив их через –. В этом случае каждый ответный рефлекс привязывается к диапазону, соответствующему его порядковому номеру в строке. Например:
Оператор вводит: привет = здравствуй – привет – отстань
В файле reflexes.txt после обновления появляется запись: 0||3245||3269|3245|3555||0|0|0
Которая в расшифровке кодов в файле reflexes_list.txt выглядит так:
0||привет||здравствуй|привет|отстань||0|0|0Если указать один рефлекс, то он привязывается ко всем значениям текущего базового параметра.
Если повторно указать пусковой макросенсор для нового диапазона рефлексов, то он добавится к старому. При этом возможны два варианта:
Например:
Существующий диапазон реагирования из одного рефлекса:
0||кто ты||нейробот||0|0|0
Оператор вводит: кто ты = бот – дед пихто
В данном случае оператор ввел антагонистическую пару, которая разделившись пополам добавилась по обоим сторонам диапазона. Рассмотрим это более подробно.
Первоначально у бота был один рефлекс на все уровни базовой потребности к которым он был привязан, в данном случае к потребности №0 (Энергобаланс). То есть при любом значении энергии бот реагировал на пусковой макросенсор «кто ты» ответным рефлексом «нейробот».
Затем оператор добавил диапазон из пары значений в расчете, чтобы левый рефлекс активировался при значении уровня энергии в зоне недостатка энергии, а правый – избытка. Получившийся в итоге диапазон реагирования распределил диапазоны активации рефлексов:
Если бы оператор добавил любое другое четное количество рефлексов, то диапазоны активации распределились бы аналогично пропорционально их количеству в строке реагирования. При этом важно следить, чтобы они соответствовали своей зоне на шкале базовой потребности.
Правильно подобранные рефлексы в данном случае означают, что на них оператор будет реагировать нужным боту образом, переключая тон своего ответного сообщения. Поэтому к зоне недостатка энергии привязан рефлекс «Бот» в расчете, что оператор поставит ответный тон «позитивный», который как раз и нужен боту для улучшения состояния за счет добавления порции энергии от позитивного тона. А для зоны избытка энергии боту нужен негативный тон, поэтому он провоцирует на него оператора рефлексом «дед пихто», ожидая ответной негативной реакции.
Логично возникает вопрос – откуда известно, как среагирует оператор, почему считается, что ответ «бот» воспримется им позитивно, а «дед пихто» негативно? В данном случае просто закладывается такое правило, исходя из представлений оператора, как бы он среагировал на месте бота. Это как бы импринтинг наоборот, когда оператор учит бота по образу своему и подобию. Других вариантов прошивки на рефлекторном уровне просто нет. Кроме того, в дальнейшем эти рефлексы могут быть заблокированы, в линейку диапазона из ячеек памяти добавлены другие. Можно было бы вместо диапазонов прошивать по одному рефлексу, и в дальнейшем постепенно через блокировки/добавления новых сформировался бы нужный диапазон. Просто диапазоном быстрее, тем более, что для простых реакций несложно подобрать сразу правильную расстановку рефлексов.
Здесь нужно выбрать щелчком мыши нужный элемент, указывающий, к какой базовой потребности привязывается диапазон.
Безусловные рефлексы у бота привязаны только к базовым потребностям, поэтому интерфейс для их прошивки проще.
Безусловные рефлексы так же задаются диапазонами. После переключения в соответствующий пункт из выпадающего списка в поле ввода оператора появляется расшифровка кодов безусловного рефлекса, привязанного к выбранному значению в матрице «Привязать к базовой потребности» в формате ввода:
[рефлекс 1] – [рефлекс 2] – [рефлекс 3]…
Но диапазон будет показан, только если он есть в базе, в противном случае будет пустое окно в котором нужно ввести нужный диапазон безусловного реагирования и нажать кнопку «Послать». При удачно записи рефлекса появится соответствующие записи в консоли текущих события бота.
Аналогичным образом редактируется существующий диапазон путем удаления или добавления рефлексов в окне ввода.
На этом этапе бот начинает активно реагировать согласно сформированной в первой стадии рефлекторной базе. При этом продолжается обучение, но уже с использованием инстинктов, заложенных в программе.
В окне ввода оператор так же вводит текст, указывает цель диалога, тон сообщения и нажимает кнопку «Отправить», получая в нижнем окне ответ бота. В консоли текущих событий при этом отражаются изменения, произошедшие в процессе реакции бота. Основные события бота в процессе прошивки:
Все обновления происходят по таймеру с периодичностью 5 сек при условии, что в данный момент нет активных процессов, например не завершено предыдущее обновление или исполняется какая-то цепочка инстинкта.
Подстановка нового рефлекса из цепочек памяти делается для его будущего применения как пробный вариант, и для более точного на данном, полу-авторитарном этапе обучения, в случае, если не найден подходящий рефлекс, бот активирует инстинкт «Не понимаю, что я должен ответить?»
В окне ответа бот задает вопрос, а в консоли событий отражается активация рефлекса. Оператор должен ввести в окне ввода ответ, который бот запишет как рефлекс и активирует обновление баз, которое произойдет через 5 сек. Если же в течении 20 сек оператор ничего не сделает, произойдет сброс инстинкта.
Рассмотрим формирование нового одиночного рефлекса на примере инстинкта - диалога и событий бота, фиксируемых в файле log.txt
Оператор: как делаЗдесь бот не найдя подходящего рефлекса, просто запускает инстинкт, оператор дает вариант ответа, бот фиксирует его как новый рефлекс. Это простейший вариант авторитарного обучения в режиме диалога.
Более сложный вариант, c формированием цепочек памяти и редактированием существующих рефлексов. Сдвинем уровень базовой потребности №0 (Энергия) в зону недостатка, чтобы активировались привязанные к ней рефлексы. Она автоматически станет текущей актуальной, если все прочие в зоне комфорта или их удаление от зоны меньше, чем у №0.
Исходные рефлексы (в расшифровке кодов):
Формат записи рефлекса:
пусковая базовая потребность || пусковой макросенсор || список макросенсоров рефлекса через | || список уровней доступа через |
Массив цепочек памяти пустой. Текст диалога с событиями бота:
1|Оператор: привет, как дела?Первая цифра в строке сообщений оператора это код его тона сообщения (-1 негативный, 0 нейтральный, 1 позитивный) . Во всех сообщениях тон позитивный. Первая цифра в строке бота это его код текущего базового контекста (-1 плохо, 0 норма, 1 хорошо).
В первой паре диалога после фразы оператора с кодом тона +1 состояние бота улучшилось, так как его уровень текущей базовой потребности был в зоне недостатка (-1 плохо). Улучшение зафиксировало положительную оценку для применения рефлекса, поэтому уровень доступа повысился на 1 для рефлексов «нормально» и «привет», которые активировались на соответствующую пару пусковых макросенсоров оператора «привет» и «как дела».
Во второй паре диалога произошло аналогичное улучшение состояния бота по той же причине, что он еще не попал в зону в комфорта. И так же увеличился счетчик удачных применений рефлекса «взаимно» на 1. Кроме того, зафиксировалась цепочка памяти из ответа бота из первой пары и реакции оператора на этот ответ из второй.
В результате диалога сформировалось три цепочки памяти, и для 4 использованных ботом рефлексов счетчик удачных применений увеличился на 1.
Измененный массив рефлексов:
0||ты слишком груб||сам такой||0
0||как дела||нормально||1
0||о чем||обо всем|о чем нибудь|ни о чем||0|0|0
0||привет||здравствуй|привет|отстань||0|1|0
0||кто ты||бот|нейробот|дед пихто||0|0|0
0||хочешь поболтать||охотно|почему бы и нет|отстань||0|1|0
0||рад за тебя||взаимно||1
Измененный массив цепочек памяти:
0||нормально||рад за тебя/1/0
0||взаимно||хочешь поболтать/1/0
0||почему бы и нет||о чем/1/0
Сдвинем теперь уровень базовой потребности №0 в зону избытка так, чтобы она стала актуальной и повторим тот же диалог с уже измененными исходными данными.
1|Оператор: привет, как дела?В первой паре позитивный тон оператора привел к ухудшению состояния бота, кроме того, так как уровень базовой потребности, к которой привязан рефлекс, теперь в зоне избытка, то активируется другой рефлекс из диапазона «отстань», соответствующей этой зоне. А так как для пускового макросенсора «как дела» есть только один рефлекс, то он и активируется для любой зоны как единственный. В итоге получилась несколько странная ответная фраза бота «нормально отстань».
По той же причине единственного рефлекса в диапазоне реакция бота на фразу оператора «рад за тебя» во второй паре диалога осталась прежней ответная реакция «взаимно».
В третьей паре она уже изменилась, и из диапазона пусковой фразы оператора «хочешь поболтать» был выбран рефлекс «остань».
В четвертой паре оператор для фразы «ты слишком груб» изменил тон на негативный, что отразилось улучшением состояния для бота, так как в зоне повышенного уровня энергии, в которой он находился, улучшением будет уменьшение энергии. И выдал единственный для этой фразы раздражителя рефлекс «сам такой». Получилось, что бот спровоцировал своей грубостью оператора на негативный тон, что зафиксировалось в строке диапазона рефлекса «отстань» для фразы «хочешь поболтать» как его удачное применение увеличением счетчика на 1. А вот для первых трех рефлексов счетчик уменьшился на -1, обнулившись до исходного состояния.
Измененный массив рефлексов:
0||ты слишком груб||сам такой||0
0||как дела||нормально||0
0||о чем||обо всем|о чем нибудь|ни о чем||0|0|0
0||привет||здравствуй|привет|отстань||0|0|0
0||кто ты||бот|нейробот|дед пихто||0|0|0
0||хочешь поболтать||охотно|почему бы и нет|отстань||0|0|1
0||рад за тебя||взаимно||0
Измененный массив рефлексов:
0||нормально||рад за тебя/1/0
0||взаимно||хочешь поболтать/1/0
0||почему бы и нет||о чем/1/0
0||отстань||ты слишком груб/-1/0
Теперь рассмотрим ситуацию с добавлением нового рефлекса из цепочек памяти. Для этого нужно спровоцировать ситуацию, когда нет подходящего рефлекса, но есть подходящий ситуации опыт в цепочках памяти. Сдвинем уровень энергии снова в зону недостатка и запустим следующий короткий диалог:
1|Оператор: привет, как дела?Во второй паре диалога произошло следующее: поиск рефлекса для фразы «взаимно» не дал результата и бот обратился к цепочкам памяти. Там обнаружилась подходящая цепочка «0||взаимно||хочешь поболтать/1/0» с запомненным тоном сообщения +1, что как раз необходимо для улучшения состояния бота в текущей ситуации, так как он находится в зоне недостатка энергии. В итоге бот создал новый пробный рефлекс на эту пусковую фразу и запустил его на исполнение.
Измененный массив рефлексов:
0||как дела||нормально||1
0||о чем||обо всем|о чем нибудь|ни о чем||0|0|0
0||привет||здравствуй|привет|отстань||0|0|0
0||кто ты||бот|нейробот|дед пихто||0|0|0
0||хочешь поболтать||охотно|почему бы и нет|отстань||0|0|1
0||взаимно||хочешь поболтать||0
0||рад за тебя||взаимно||0
0||ты слишком груб||сам такой||0
Активность чат-бота провоцируется изменением его базовых состояний, под которыми подразумеваются глобальные переменные, меняющие свои значения от 0 до 100 условных единиц. Изменения происходят по двум причинам:
Каждую фразу оператор сопровождает указанием тона сообщения, который может быть 3 типов, и который определяет значимость фразы:
Величина изменения зависит от длины сообщения оператора. При этом меняется только одно, текущее актуальное базовое состояние при условии, что на фразу оператора есть связанный с ним рефлекс.
У бота после запуска происходит постоянная пульсация с частотой 1сек, при которой одни базовые состояния увеличиваются с каждым тактом на фиксированную величину, а другие уменьшаются. Поэтому, даже если не будет никаких фраз от оператора, у бота все равно будут меняться базовые состояния, что спровоцирует его на активность.
Общий, глобальный смысл реагирования бота это стабилизация его базовых состояний. Она может быть 2 типов:
Стабилизация базовых состояний это общая, глобальная потребность бота, которую удобнее рассматривать как совокупность более частных потребностей: если все базовые состояния стремятся к стабильности, то это можно рассматривать как частные базовые потребности бота – стабилизировать все базовые состояния. Поэтому далее так и будем их называть – базовые потребности.
У базовой потребности различают три энергетических зоны:
Задавая граничные пределы комфортной зоны, и подразумевая общий предел зоны от 0 до 100 условных единиц, определяется цель стабилизации базовой потребности: находиться в комфортной зоне. При этом определяются три базовых рецептора, активация которых запускает соответствующий процесс стабилизации:
Для стабилизации необходима оценка успешности применяемых действий (рефлексов). Она определяется сравнением состояния до выполнения стабилизирующего действия и после. Если результатом стало приближение к зоне комфорта, действие считается успешным, если удаление – не успешным. Такая оценка сигнализируется при помощи двух сенсоров: стало лучше и стало хуже соответственно.
Ответные рефлексы бота запускаются двумя типами раздражителей:
Они могут быть пусковыми как оба вместе, так и каждый по отдельности.
Постоянная пульсация, тон сообщений оператора постоянно выводят базовые потребности бота в разной степени из зоны комфорта в одну из других зон. Это создает эффект автоматического переключения актуальности базовых потребностей, которая активирует разные группы рефлексов на одинаковые фразы-раздражители, создавая вариабельность реагирования в зависимости от текущего внутреннего состояния бота.
При этом привязка к уровню потребности делается не на конкретное значение, а на диапазон. Рефлексы, активируемые одной пусковой фразой и отсортированные по адекватности значениям базовой потребности, формируют диапазон реагирования, который можно расширять, добавляя в него новые рефлексы, и сужать, блокируя старые. Это приводит к тому, что диапазон реагирования для рефлексов становится динамическим, что позволяет осуществлять простейшее замещение заблокированных рефлексов соседними, увеличивая их охват (рецептивное поле). Добавление новых рефлексов наоборот, сужает рецептивные поля рефлексов, делая их реагирование более точным.
Прогностическое реагирование становится возможным, если запоминать цепочки диалога в виде вопрос – ответ, с привязкой к актуальной на тот момент базовой потребности и тону сообщения оператора. Это позволит в дальнейшем на фразу оператора найти его же ответ, когда бот сказал такую же ответную фразу, и при удачном применении зафиксировать ее как ответный рефлекс, добавив в диапазон реагирования. Получается, что бот использует ответные реакции оператора как свои. Это простейший способ расширения своей рефлекторной базы за счет прямого заимствования чужого опыта, который называется импринтингом. Кроме того, можно предсказывать ответную реакцию оператора, ориентируясь на прежний опыт общения с ним, но довольно грубо, так как оператор в этом случае подразумевается как такой же «просто устроенный» бот, что конечно совсем не так.
Обнаружен организм с крупнейшим геномом Новокаледонский вид вилочного папоротника Tmesipteris oblanceolata, произрастающий в Новой Каледонии, имеет геном размером 160,45 гигапары, что более чем в 50 раз превышает размер генома человека. | Тематическая статья: Тема осмысления |
Рецензия: Рецензия на книгу Дубынина В.А. Мозг и его потребности. От питания до признания | Топик ТК: Интервью с Константином Анохиным |
| ||||||||||||