Топ-разработчик Tesla — про нейронные сети и программное обеспечение 2.0

30 сентября 2018, 09:00
Топ-разработчик Tesla — про нейронные сети и программное обеспечение 2.0

Глава подразделения искусственного интеллекта Tesla Андрей Карпати рассказал о том, почему нейронные сети — это инструмент разработки будущего. Dev.by публикует перевод его статьи.

Иногда я замечаю, что люди называют нейронные сети всего лишь очередным инструментом в арсенале машинного обучения. У нейросетей есть свои достоинства и недостатки, масса сфер применения. Существует даже площадка для соревнования нейросетей под названием Kaggle. Однако такое их понимание упускает главное: нейросети — не «ещё одно» средство машинного обучения, они положат начало коренным изменениям в том, как мы пишем ПО. Нейросети — программное обеспечение нового поколения.

Нам всем знаком «классический» стек ПО 1.0 — его создают на таких языках, как Python, С++ и других. Разработчик прописывает компьютеру исчерпывающие указания, каждая строчка кода определяет поведение какой-то конкретной части программы.

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

Иллюстрация: Андрей Карпати

Иллюстрация: Андрей Карпати

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

Иллюстрация: Андрей Карпати 

Иллюстрация: Андрей Карпати 

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

Что меняется

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

  • В распознавании образов обычно применялись спроектированные признаки, которые лишь слегка дополнялись машинным обучением (например, методом опорных векторов). Теперь существуют гораздо более мощные инструменты обработки изображений — появились объёмные датасеты (например, ImageNet) и поиск архитектур свёрточных нейросетей. В последнее время мы даже себе не доверяем написание архитектур вручную и стали осуществлять поиск по ним тоже;
  • Распознавание речи раньше включало объёмную предварительную обработку, модели гауссовой смеси, скрытые марковские модели. Сегодня же оно почти полностью основано на нейросетях. Есть одна меткое, часто цитируемое ироничное высказывание Фредерика Йелинека: «Каждый раз, когда я увольняю лингвиста, качество нашей системы распознавания речи повышается»;
  • Синтез речи всегда сводился к составлению сообщения из предварительно записанных человеком элементов, но сегодня крупные новейшие свёрточные модели (вроде WaveNet) способны сами генерировать аудиосигнал;
  • В машинном переводе, как правило, используются статистические методы на основе анализа употребимости лексических единиц, но их стремительно вытесняют нейронные сети. Мои любимые архитектуры тренируются на нескольких языках, когда одна модель учится переводить текст с любого исходного на любой целевой язык почти или совсем без учителя;
  • Игры. Программы для игры в го были написаны уже давно и преимущественно вручную, но чемпионом в го всё же стала свёрточная нейросеть AlphaGo Zero, которая делает каждый следующий шаг исходя из расположения камней на доске. Я думаю, что аналогичные результаты можно в скором времени ожидать и в других играх — DOTA 2 или StarCraft;
  • Базы данных. Более традиционные системы, не связанные с искусственным интеллектом, также начинают перенимать эту технологию. Так, в работе The Case for Learned Index Structures ключевые компоненты системы управления данными заменены нейросетью.

Многие ссылки выше ведут к исследованиям, проведённым Google, потому что эта компания сегодня интенсивнее остальных переписывает свой старый код на код нового поколения. В работе One model to rule them all содержится общее описание того, какой вид это может принять в будущем, когда статистическое значение отдельных областей складывается в единое комплексное видение мира.

Преимущества программного обеспечения 2.0

Почему для сложных программ лучше использовать код нового поколения? Самый очевидный ответ на этот вопрос в том, что они будут лучше работать. Однако есть много других разумных аргументов в пользу этого стека. Давайте рассмотрим некоторые преимуществ ПО 2.0 (то есть нейросетей) перед ПО старого поколения (кодовая база на C++).

  • Вычислительная однородность. Классическая нейросеть на первом уровне имеет только две операции: матричное умножение и пороговый переход в нуле (нейроны ReLU). Сравните это с наборами команд в традиционном ПО, которые гораздо более разнородны и сложны. А так как ПО 1.0 придётся применять лишь для реализации небольшого количества элементарных вычислительных операций (например, умножение матриц), станет намного проще гарантировать стабильность и производительность;
  • Простота реализации на оборудовании. Набор инструкций нейросети относительно невелик и, как следствие, значительно проще реализовать их на оборудовании, например с помощью кастомных интегральных схем (ASIC), нейроморфных чипов и так далее. Мир изменится, когда нас будет окружать экономичный искусственный интеллект. Например, в миниатюрные и недорогие чипы можно встроить обученную свёрточную нейросеть, распознаватель и синтезатор речи, а их, в свою очередь, внедрить в небольшой протомозг и применять в любых других устройствах.
  • Неизменное время выполнения. За каждую итерацию прямого прохода классической нейросети выполняется одно и то же количество флопов. Нейросетям характерна постоянность, в отличие от «расползающегося» кода на С++, который может выполняться разными путями. Естественно, можно использовать динамические графы, но поток выполнения обычно всё равно существенно ограничен. Таким образом, мы можем быть почти полностью уверены, что случайно не окажемся в бесконечном цикле;
  • Неизменное распределение памяти. В связи с предыдущим пунктом, отсутствует динамическое распределение памяти, и поэтому низка вероятность сбросов на диск или утечек памяти, которые приходится выискивать в коде;
  • Высокая портативность. Последовательность умножения матриц ощутимо легче запускать на всевозможных вычислительных системах, чем классические бинарные файлы и скрипты;
  • Высокая гибкость. Если вы захотите удвоить скорость вашего код на С++ (при необходимости даже пожертвовав производительностью), то придётся сильно постараться, чтобы перенастроить систему под новые параметры. Но в случае с ПО 2.0 можно взять нейросеть, удалить половину каналов, переобучить её и — готово: она будет работать в два раза быстрее, но лишь немного хуже. И наоборот: если появится больше данных или вычислений, можно в любой момент усовершенствовать программу, просто добавив больше синапсов и заново обучив нейросеть;
  • Модули можно оптимальным образом соединять в целое. Наше программное обеспечение часто раскладывается на блоки, которые взаимодействуют через открытые функции, API или конечные точки. Но при взаимодействии двух модулей ПО нового поколения, которые тренировались раздельно, можно запросто использовать обратное распространение ошибки в рамках всей системы. Только подумайте, как было бы здорово, если бы ваш браузер умел автоматически переписывать низкоуровневые системные команды, чтобы быстрее загружать веб-страницы. В ПО 2.0 это будет происходить по умолчанию;
  • Оно лучше нас. Наконец, и это самое главное, нейросеть просто представляет собой более качественный код, с которым ни мой, ни ваш не идёт ни в какое сравнение во множестве востребованных направлений, по крайней мере тех, что имеют отношение к работе с изображениями, видео, звуком или речью.

Ограничения программного обеспечения 2.0

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

Стек 2.0 не защищён он досадных или — что ещё хуже — незаметных ошибок, например, когда молча перенимает смещения в обучающих данных. Такие ошибки очень сложно распознать и как следует проанализировать, потому что их количество зачастую измеряется миллионами.

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

Программирование в стеке нового поколения

ПО 1.0 — это код, который пишет программист. ПО 2.0 — это код, который создаётся через оптимизацию на основе критерия оценки (например «правильно классифицировать эти тренировочные данные»). Вероятно, в любой сфере применения, где механизм работы программы неочевиден, но мы можем всегда оценить её эффективность (например, правильно ли она классифицировала вводные изображения, выиграла ли матч в го), возможно применение ПО нового поколения, так как оптимизация позволяет найти гораздо лучший код, чем под силу написать человеку.

Имеет значение то, с какой стороны рассматривать эти тренды. Если ПО 2.0 для вас — новая и прогрессивная парадигма программирования, а нейросети — больше, чем просто годный классификатор среди инструментов машинного обучения, вы сразу поймёте его потенциал и сколько ещё предстоит работы.

В частности, есть огромное количество инструментов, помогающих человеку писать код первого поколения: мощные среды разработки с подчёркиванием синтаксиса, отладчиками, профилировщиками, интеграцией git и так далее. Для создания ПО нового поколения мы будем просто собирать и прорабатывать датасеты. К примеру, если в каких-то сложных или исключительных случаях нейросеть даёт сбой, то для корректировки её предсказаний мы будем не писать код, а вводить больше маркированных примеров по этому контексту. Кто будет разрабатывать первые IDE для программного обеспечения 2.0, которые упростят процессы сбора, визуализации, фильтрации и маркирования датасетов? Возможно, такая IDE будет выявлять изображения, которые нейросеть может посчитать маркированными неправильно, или помогать маркировать их, или же предлагать подходящие для этого примеры, исходя из неточности предсказаний нейросети.

Далее, Github — отличная площадка для кода 1.0. Появится ли свой «Github» для ПО 2.0? В таком случае в качестве репозиториев будут выступать датасеты, а коммиты заменят дополнения или изменения меток.

В кратко- и среднесрочной перспективе ПО 2.0 начнёт доминировать в любой сфере, где проводить оценки реально и незатратно, а также там, где сложно тщательно прописать сам алгоритм. А в долгосрочной перспективе у этой парадигмы светлое будущее, потому что всё больше людей начинает признавать: за разработкой общего искусственного интеллекта будет стоять именно программное обеспечение 2.0.

Обсуждение