Введение или о каком ИИ я говорю
В первую очередь меня интересует универсальный ИИ как машина достижения сложных целей. То есть некий программно-аппаратный комплекс, которому можно сказать: сделай самолёт, который будет стоить 100$, летать на 1000 километров со скоростью 800 км/ч и перевозить 5 человек. Или так: вылечи человека такого-то от рака на терминальной стадии.
ИИ должен с такими задачами уметь справляться, если это вообще физически возможно. А если невозможно, то достигать результата, максимально похожего на заданный.
На данный момент я вижу два пути, как получить универсальный ИИ.
Первый путь - это системы, подобные reinforcement learning. Они подключаются в сенсорам и исполнительным механизмам некоего робота, и ещё у них есть сигнал награды. Reinforcement learning (далее RL) действует так, чтобы получать в среднем как можно больше награды. И канал вознаграждения - это основной способ сообщить ИИ, чего мы от него хотим.
Второй путь - это системы, подобные GPT-3, генераторы текстов. О них скажу всего пару слов. Они берут начало текста и продлевают - так, чтобы выглядело связно. Часто эти тексты звучат глубоко и здорово, но… Если вы спросите GPT-3 “почему астрология - это самообман” - он подробно это аргументирует. А если спросить его же “почему астрология - это реально эффективная практика” - наш продлеватель текстов опять же, подробно аргументирует. На вопрос “эффективна ли астрология?” GPT-3 ответит, исходя из контекста. Эти особенности не позволяют просто в лоб применять GPT-3 и его аналоги для создания хороших планов.
Проблемы с Reinforcement Learning и подобными системами
Я бы разделил проблемы на две большие группы.
Первая группа - это проблемы, которые RL в принципе мог бы решить, если бы у него было больше данных, больше вычислительных мощностей, более ёмкие буферы данных и нейросети.
Вторая группа - это проблемы с написанием ТЗ. В голове задание звучит хорошо, но записать его в виде правила выдачи подкреплений не выходит.
Проблемы данных, памяти и вычислительной мощности
Проблема размерности
Наверное, одна из наиболее известных трудностей RL и машинного обучения вообще. Если сенсоров много - например, на входе цветная картинка 224х224, то нужно очень много данных, чтобы чему-то обучиться. Даже если мы предсказываем по картинке не сигнал награды, а, например, следующий кадр, нам нужно очень много примеров, чтобы научиться предсказывать верно. Нейросеть изначально не понимает, что вот эта кучка пикселей - это снаряд, который в нас летит, и от которого надо увернуться, а вон та другая кучка - это число, которое показывает очки здоровья, и которое хорошо предсказывает, сколько нам осталось жить. Нейросеть изначально не понимает концепцию цифр.
Проблема решается сжатием картинки в маленький информативный вектор. Есть два основных способа это сделать:
1) Взять готовую нейросеть, умеющую классифицировать изображения на много классов. Отрезать последний слой, взять выход предпоследнего. Там будет вектор размерности ~1000-2000 элементов. Это намного меньше, чем исходная картинка, но этот вектор остаётся очень информативным.
2) Обучить автоэнкодер. Автоэнкодер - это нейросеть, у которой есть “узкое место”, то есть промежуточный слой малого размера. На вход нейросеть получает кадр, на выходе должна воспроизвести его же. Если отрезать все слои, что идут после “узкого места”, получится нейронка, создающая из картинки то самое сжатое представление.
Если RL будет обучаться по сжатым представлениям, он потребует значительно меньше данных.
Проблема опасных исследований
Обычно RL стартует с пустой памятью. Его поведение случайно. Со временем RL накапливает больше данных и обучается управлять условным роботом более-менее сносно. Или так и не обучается - как повезёт.
А теперь представим себе, что мы такой RL поместили в продакшн. На бирже торговать или искать новый способ изготавливать скрепки. Пока RL будет экспериментировать и познавать мир, он допустит множество ошибок, и это серьёзно навредит бизнесу.
Как с этим бороться?
Можно сделать мир-симуляцию, и гонять RL в нём. А лишь потом, когда он научится справляться, выпускать ИИ в реальный мир. Очевидный минус - для некоторых случаев мы не можем сделать симуляцию. Мы сами слишком плохо знаем интересующую нас среду.
Запустить в среду другого игрока - человека или иную систему управления. Залогировать их действия и передать в RL так, будто это его собственный опыт. Например, человек играет в Doom, игра записывается на видео, все ключевые переменные записываться, все действия записываются. Затем нейросеть в RL учится по кадру с экрана и текущему действию предсказывать, сколько будет награды. Таким образом у RL на момент выхода в мир уже будет какая-то стратегия - теоретически она должна быть не хуже, чем у живого игрока, но на практике это не всегда выполняется. Сигналы подкрепления проставить ретроспективно - мы же этими сигналами хотим гнать ИИ к какому-то результату, значит, у нас есть какое-то правило, по которому входящий кадр называется "хорошим" или "плохим".
Проблема отдалённой цели
Допустим, мы даём RL задачу: пройти уровень из Doom. Награда даётся только за полное успешное прохождение.
Наивный RL будет очень долго и бесплодно искать, какое же действие приведёт к награде. Он же не знает, что в шутере надо ходить по коридорам и стрелять монстров, и что конец уровня - это дверь в надписью Exit.
Если у RL есть эвристика любопытства, то ситуация немного улучшается - ИИ будет искать места, где он ещё не был, совершать действия, которых не совершал, и со временем попробует всё, что можно, в том числе дверь с надписью Exit. После этого он должен смекнуть, в чём была задача.
Но всё равно, люди гораздо быстрее бы поняли, куда идти.
Как решать проблему?
Дать RL человеческий опыт. Или опыт некоего другого бота. Так он хоть поймёт, к чему стремиться.
Сделать несколько миниатюрных уровней, где прямо перед RL находится та самая дверь с переходом на новый уровень. Можно даже просто записать ему в память видео, как кто-то другой проходит такой мини-уровень и получает награду.
Дать подсказку через канал подкрепления: пусть RL получает небольшие награды за подбор предметов и убийства врагов, и небольшие наказания за ранения. Это похоже на то, как человек проходил бы первый шутер в своей жизни - он бы воспринимал аптечки и победы как награды, а ранения - как наказания. Но есть вариант, что RL найдёт какой-то возобновляемый источник наград и вообще не захочет покидать уровень.
Явным образом описать цель: отснять эту дверь с разных ракурсов, получить её сжатое представление. Все кадры проверять на предмет того, насколько они похожи на эту дверь - и давать пропорциональную награду. Таким образом может получиться, что RL станет целенаправленно искать объекты, похожие на дверь с надписью Exit. Недостаток в том, что он может “залипнуть” на какую-нибудь другую дверь - ну да, степень сходства 5%, но зато можно просто смотреть на дверь и бесконечно получать небольшие награды. Возможно, стоит совместить такое описание цели с эвристикой любопытства - пусть награда от созерцания двери будет пропорциональна и её новизне, и её похожести на Ту Самую Дверь.
Распространённый частный случай. Допустим, у RL очень много опыта взаимодействия с миром, но его нужно натравливать на разные цели. Сегодня он собирает аптечки, завтра стреляет монстров, послезавтра ищет ключи… Применительно к реальному миру: сегодня RL придумывает умный способ вернуть паралитику способность ходить, а завтра изобретает план, как лечить рак. Всё это в одном и том же мире, одними и теми же инструментами, но он должен быстро сориентироваться и понять, что от него хотят на этот раз, а не пытаться методом тыка разобраться, за что дают награды.
Скорее всего, у такого RL должен быть некий канал, через который ему подаётся описание цели. В самом простом случае у ИИ есть помимо вектора входных данных ещё и вектор желаемых входных данных. И награда равна степени сходства этих двух векторов.
Хорошо, допустим, ИИ играет в шахматы. Целевое состояние - это поставленный мат. Мы не можем предложить нашему ИИ некий конкретный кадр с поставленным матом и сказать: своди ситуацию к такой. Во-первых, обычно это невозможно. Во-вторых, ИИ постарается поставить фигуры максимально похоже на то, как было в кадре, а примерное совпадение необязательно означает близость к мату.
Есть вариант создать много целевых состояний и обучить некую нейросеть отличать целевое состояние от не-целевого. А затем использовать что-то вроде Model-Based подхода. ИИ будет “в воображении” генерировать траекторию изменений мира - он же знает по прошлому опыту, как изменяются входные кадры, и как на них влияют активные действия. Можно каждому придуманному кадру (или сжатому представлению кадра, или сжатому представлению от цепочки кадров) поставить в соответствие награду. Награду проставляет та самая нейросеть, которая пыталась выучить правило, чем целевые кадры отличаются от не-целевых.
Далее ИИ обучается целиком в воображении - либо он подбирает конкретный план, ведущий к целевому состоянию, либо разрабатывает некое правило соответствия кадр->действие, либо учится делать прогноз (кадр, действие)->суммарная награда в некоем горизонте планирования.
Таким образом можно было бы свести реальные эксперименты в физическом мире к массивному перебору в воображении.
Есть и другое решение. Допустим, мы создадим некий язык для взаимодействия с ИИ. Он будет кратко и сжато описывать сложные цели. На вход RL будет получать и картинку с сенсоров, и некое символическое описание текущей цели. Это может быть или картинка, или текст, сжатый в вектор, или какая-то иная форма языка. В любом случае, RL должен иметь достаточно статистики, чтобы понять: описание цели никак не влияет на физику окружающего мира, но влияет на то, за что будут давать награды.
Например, если мы делаем ИИ, который ищет пропавших людей дронами, описанием цели может быть фотография человека, либо сжатое представление этой фотографии, либо сжатое представление от словесного описания внешности.
Проблемы на уровне ТЗ
Допустим, мы хотим создать универсальный ИИ, который сможет лечить неоперабельный рак. Допустим так же, что универсальный ИИ мы уже делать умеем - это просто достаточно хороший RL.
Но какое тело мы дадим нашему ИИ? Для RL важно, чтобы было конкретное тело, у которого одни и те же датчики и исполнительные органы в разное время имеют примерно одинаковый смысл. Это означает, что не выйдет сделать его неким просто абстрактным интеллектом, который свободно подключается к любому оборудованию. Не то, чтобы это вообще невозможно - но нейросетям будет очень тяжело обучиться в таком случае.
Итак, можно сделать для ИИ гуманоидное тело. Оно достаточно универсально, а где универсальности не хватает, можно использовать различные интерфейсы - например, у ИИ будет инфракрасный термометр с цифровым дисплеем, отвёртка и микроскоп. Вполне человеческие инструменты, не интегрированные в корпус - такие, которые можно быстро взять в руку и быстро заменить на что-то иное.
Другой вариант - можно сделать что-то вроде автоматизированного цеха. Множество видеокамер на манипуляторах, роботизированные руки, большое число инструментов и станков.
Необязательно ставить задачу именно вылечить человека напрямую - можно ставить задачу сделать некий механизм, который вылечит. Или некое лекарство. Впрочем, высокоразвитый RL с богатым опытом и сам понимает эти возможности.
А теперь ключевой вопрос: как сформировать сигнал подкрепления? Как постфактум определить, решена ли задача?
Человек бы решал задачу так: он бы провёл ряд измерений - рентген, анализ крови, попросил бы пациента описать своё состояние… Наверное, врач мог бы полнее раскрыть эту тему.
Есть другой вариант: если мы хотим ретроспективно оценить, здоров ли пациент, надо за ним наблюдать. Смотреть, насколько он справляется со своими обычными делами, и смотреть, сколько он проживёт. В конце концов, если все анализы показывают, что человек болен, а человек явно ведёт себя как здоровый, не чувствует дискомфорта и доживает до 110 лет - значит, проблема в анализах.
Но как это всё выразить в терминах прямых наблюдений?
Допустим, мы упрощаем задачу: ИИ, ты должен сделать, чтобы рентгеновский снимок выглядел вот так (и в фотошопе убираем с реального снимка опухоль). Или делаем нейросеть, которая отличает “здоровые” снимки от “больных”.
Это бы сработало, если бы рентген был одним из входных сенсоров, интегрированных в ИИ. Причём даже не сам рентген, а вся процедура, как провести рентгеновский снимок. Если же мы говорим ИИ “надо сделать, чтобы снимок выглядел вот так”, ИИ может этот снимок нарисовать или снять на рентген что-то постороннее.
У человека есть “концепция объективной реальности” - понимание, что в реальном мире есть некоторые явления, которые можно измерять. Есть процедуры измерения. И эта процедура делает так, что реальные переменные отображаются на наших приборах. И мы хотим управлять именно реальными переменными, а не только теми, что показаны на приборах. Пока ИИ управляет, скажем, ракетой, он не может разрушить корреляцию между приборами и реальным миром. Но если ему дать рентгеновский аппарат, который управляется робо-руками, то ИИ мигом себя “ослепит” и нарисует картинку, как всё замечательно по приборам.
Можно ли с этим бороться? Можно ли запретить ИИ ослеплять свои приборы?
В какой-то мере. Например, можно обучить нейросеть-ревизора, которая по наблюдаемым кадрам будет проверять, верно ли проходят измерения. Но эту нейросеть можно обмануть, потому что она не дообучается, а RL дообучается постоянно. Можно этого ревизора тоже дообучать - скорее всего, вручную заносить в датасет ситуации, где ИИ всё-таки сумел её обмануть.
![С точки зрения наблюдающей за видео нейросетью, рука находится близко к жёлтому шару. Фактически они просто на одной линии С точки зрения наблюдающей за видео нейросетью, рука находится близко к жёлтому шару. Фактически они просто на одной линии](https://habrastorage.org/getpro/habr/upload_files/d17/1ed/e74/d171ede74bf378de570b9c05dfc19280.gif)
Ещё есть вариант вынести процедуры контроля за пределы той территории, где ИИ активно работает. ИИ может запросить рентген, но делать его будут люди. В такой ситуации может выйти, что RL сможет “хакнуть” людей - убедить их совершить подлог, спровоцировать на ошибку или сделать роботов, которые выйдут за пределы цеха и сами неправильно сделают рентген. Будет ли ИИ всё это делать?
По моему опыту, ИИ обычно идёт по наиболее простому пути. То есть зависит от того, до чего ИИ раньше догадается - как вылечить пациента или взломать систему контроля.
Наконец, можно создать автоматическую систему контроля, работающую наподобие GAN. ИИ (не именно хирург, а просто какая-то система RL) ищет способы подделать, например, рентгенограмму тестовой мишени. Затем тестовая мишень уезжает за пределы цеха, и её отснимает простенький необучаемый робот. Если результаты “тупого” робота и “умного” разошлись - значит, произошёл взлом, и обучаемая нейронка-ревизор добавит этот случай в датасет. А взломщик получит свою награду.
А потом всякий раз, когда RL проводит планирование, его план проверяет ревизор - нет ли там подлога. В данной ситуации хитрого ИИ будет останавливать опытный надсмотрщик, который насмотрелся на не менее хитрого ИИ в контролируемых условиях.
Пару слов об ИИ-безопасности
Есть множество статей о том, как хрупки человеческие ценности и о том, как сложно их записать в виде правила подкрепления. Есть страшные истории о том, как ИИ, которому поручено делать скрепки, будет их делать, пока не израсходует все атомы во Вселенной - просто потому, что это естественная линия поведения для оптимизатора.
Обычно в таких историях говорится, что ИИ должен быть самоулучшаемый - то есть RL должен уметь влезать в свой код и как-то его улучшать, а потом улучшенный код будет снова улучшать себя. Автору этой статьи не доводилось видеть научных работ по RL, способному к рекурсивному самоулучшению. Рекурсивное самоулучшение чего-то вроде эволюции - это пожалуйста, но эволюция не умеет решать задачи RL.
Есть очевидный способ сделать RL самоулучшающимся. В список возможных действий (наряду с вперёд-назад-стрелять) добавить какие-либо действия с гиперпараметрами: изменить шаг обучения нейронки, изменить коэффициент дисконтирования, изменить размер буфера памяти… Это несерьёзное самоулучшение, но даже оно наталкивается на ряд сложностей.
В первую очередь, рекурсивная самоулучшающася система нестабильна. Она может выкрутить размер буфера памяти, например, в такие значения, что ИИ начнёт сильно тормозить.
И исправить эту ошибку ему будет очень сложно, это займёт кучу времени. Либо же ИИ может поменять параметры так, что он станет хуже обучаться. И тогда он не сможет сделать выводов из своей ошибки. Либо же он может изменить параметр дисконтирования или любопытства - и тогда изменятся его “жизненные приоритеты”, то есть он уже не будет решать наши задачи.
На каждое из этих изменений можно придумать хак, как его не допустить, но в первоначальной концепции предполагалось, что ИИ будет знать, какие изменения к каким последствиям приведут, и что он не сможет радикально сломать свои механизмы в один ход. В реальности такая осведомлённость ИИ неочевидна, а критические ошибки, срывающие рекурсивное самоулучшение, всё-таки не исключены.
Другой момент заключается в том, что RL идёт по наиболее очевидному пути. Если есть простой способ достичь цели, система не будет искать сложный. Конечно, сложность выражается во внутренних концепциях RL - например, он может в шутерах разбивать локацию не на дороги и стены, а на теневые и светлые зоны. А противников видеть не как объекты, а как изменения текстуры. За счёт этого стратегии поведения будут не вполне человеческие.
Так вот, если проще не взламывать защиту, а решать задачу, то ИИ именно этим и займётся. Судя по наблюдениям автора, ИИ гораздо чаще взламывает системы, которые можно взломать чуть-чуть, и это уже принесёт отдачу. Например, однажды автор этой статьи делал ИИ для торговли на бирже. Провёл тестирование на симуляторе биржи и получил странный результат: ИИ научился делать 1000$ из 100$ на интервалах в полчаса. Как? Оказалось, в симуляторе можно брать кредит, и ограничения нет. ИИ стал понемногу наращивать объём кредита, и добрался до десяти миллионов долларов. Покупал на всё акции, потом продавал и возвращал кредит. В случае, если контролирующая система - это нейросеть, она будет давать чуть-чуть разные значения награды за чуть-чуть разные наблюдения. В результате можно, двигаясь малыми шагами, подобрать такие входные данные, на которые нейросеть будет отвечать неоправданно большой наградой. Так что если мы хотим, чтобы нейросеть проверяла, справился ли RL, это должна быть или очень надёжная нейросеть, или она должна дообучаться, получая всё новые примеры хаков, или RL не должен иметь возможности много экспериментировать с ней.
Подводя итоги
Когда-то я думал, что создать сильный ИИ (в смысле универсальный оптимизатор) - это вполне достаточно, чтобы решить любую решаемую задачу. Но когда стал размышлять, как решить конкретную нерешённую задачу с помощью современного ИИ - оказалось, что очень тяжело сформулировать понятное техзадание. RL можно встроить в работающую инфраструктуру - например, регулировать цены на товары. База данных на входе, база данных на выходе - в таких условиях RL работает хорошо. Никаких чудес, но довольно эффективно.
Кроме того, воплощённый ИИ можно обучать конкретной задаче в хорошо защищённом цеху, а затем включать, чтобы он решил одну конкретную задачу. Например, нашёл способ открыть запертую дверь.
Но это всё, как мы понимаем, не похоже на сингулярность силами одного ИИ.
Я задумывал эту статью как способ спровоцировать диалог. Наверняка я где-то неправ и есть более хитрые решения, чем те, до которых мне удалось додуматься. Так что развёрнутые комментарии и интересные споры приветствуются!