TF Jam - Съемка обручей с машинным обучением

МЕНЮ


Искусственный интеллект
Поиск
Регистрация на сайте
Помощь проекту

ТЕМЫ


Новости ИИРазработка ИИВнедрение ИИРабота разума и сознаниеМодель мозгаРобототехника, БПЛАТрансгуманизмОбработка текстаТеория эволюцииДополненная реальностьЖелезоКиберугрозыНаучный мирИТ индустрияРазработка ПОТеория информацииМатематикаЦифровая экономика

Авторизация



RSS


RSS новости


В этой статье мы углубимся в использование Unity3D и TensorFlow,чтобы научить ИИ выполнять простую внутриигровую задачу: бросать шары в обруч. Полный исходный код доступен на Github , если у вас есть какие-либо вопросы, свяжитесь со мной в Twitter .

Введение в нашу игру

Есть игра, в которой у игроков одна главная цель: забрать мяч в корзину. Это звучит не так уж и сложно, но когда ваша кровь накачивается, ваше сердце колотится, толпа приветствует - ну, это довольно сложно сделать такой выстрел. Я говорю о классической американской игре в баскетбол ? Нет, никогда не слышал об этом. Я говорю о классической аркадной игре Midway NBA Jam .

Если вы когда-либо играли в NBA Jam или в какую-либо игру, которую он вдохновил (включая реальную лигу NBA, которая, как мне кажется, пришла после NBA Jam), то вы знаете, что механика для стрельбы по мячу, с точки зрения игрока, довольно проста. Вы держите и отпускаете кнопку съемки с идеальным временем.Задумывались ли вы, как этот выстрел происходит с точки зренияигры, хотя? Как выбирается дуга мяча? Насколько сильно брошен мяч? Как компьютер узнает угол съемки?

Если вы были умным, склонным к математике человеком, вы могли бы найти ответы на эти вопросы ручкой и бумагой, однако автору этого блога не удалось выполнить алгебру 8-го класса, так что… эти «умные» ответы исключены. Мне нужно пойти по этому поводу по-другому.

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

Начиная

Нам понадобится несколько вещей, чтобы пройти через этот проект.

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

Скачать проект

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

Примечание. Вам нужно будет загрузить импортируемый пакет активов ML-Agents Unity для использования в Tensorflow в C #. Если вы получите какие-либо ошибки, касающиеся того, что Tensorflow не найден в Unity, убедитесь, что вы следовали документации по настройке Unity для TensorflowSharp.

Какова наша цель?

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

Если вы заинтересованы в том, как сделать более сложные AI в Unity, вам следует проверить гораздо более полный проект ML-Agents из Unity. Методы, о которых я расскажу здесь, разработаны так, чтобы быть простыми, доступными и не обязательно отражающими лучшие практики (я тоже учусь!)

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

Корзина и мяч

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

Если вы не знакомы с Unity, просто знайте, что это игровой движок, который позволяет вам создавать 2D и 3D игры для всех платформ.Он имеет встроенную физику, базовое 3D-моделирование и отличную среду выполнения сценариев ( Mono ), которая позволяет нам писать нашу игру на C # .

Я не художник, но я обошел некоторые блоки и собрал эту сцену.

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

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

Если мы посмотрим на OnTriggerEnterметод в/Assets/BallController.cs(сценарий, который будет иметь каждый экземпляр нашего баскетбола), вы увидите, как эти два триггера используются вместе.

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

Делать снимки

Открывай /Assets/BallSpawnerController.cs. Это сценарий, который живет на нашем шутере и выполняет работу по порождению баскетбольных мячей и попыткам делать удары. Проверьте этот фрагмент ближе к концу DoShoot()метода.

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

Если у вас все еще есть /Assets/BallController.csоткрытый, вы можете взглянуть на наш Start()метод. Этот код вызывается, когда мы создаем новый баскетбол.

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

Давайте попробуем запустить все это и посмотрим, как поживает наш звездный шутер. Вы можете нажать кнопку ? Play (Play) в редакторе Unity, и мы увидим…

Наш игрок, которого ласково называют «Красным», почти готов сразиться со Стефом Карри.

Так почему же Red такой ужасный? Ответ лежит в одной строке, вAssets/BallController.csкоторой говорится float force = 0.2f. Эта линия делает смелое утверждение, что каждый выстрел должен быть точно таким же. Вы заметите, что Unity воспринимает эту «точно такую ??же» вещь буквально. Один и тот же объект с одинаковыми силами, повторяющийся снова и снова, всегда будет подпрыгивать одинаковым образом. Ухоженная.

Это, конечно, не то, что мы хотим. Мы никогда не научимся стрелять, как Леброн, если мы никогда не попробуем ничего нового, так что давайте добавим остроты.

Рандомизация снимков, сбор данных

Мы можем ввести некоторый случайный шум, просто изменив силу на случайную.

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

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

А пока мы не хотим делать снимки только с одного места. Мы хотим, чтобы красный успешно стрелял (когда ему повезет) с любого расстояния. В Assets/BallSpawnController.cs, обратите внимание на эти строки и раскомментировать MoveToRandomDistance().

Если мы запустим это, мы увидим, как Ред с энтузиазмом прыгает по площадке после каждого выстрела.

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

Каждый успешный выстрел фиксирует количество успешных выстрелов до сих пор, расстояние от обруча и силу, необходимую для выстрела. Хотя это довольно медленно, давайте нарастим это.Вернитесь туда, где мы добавили MoveToRandomDistance()вызов, и измените 0,3f (задержка 300 миллисекунд на выстрел) на0.05f(задержка 50 миллисекунд).

Теперь нажмите play и наблюдайте за нашими удачными выстрелами.

Теперь , что хороший режим тренировки! Из прилавка сзади видно, что мы успешно забиваем около 6,4% ударов. Стеф Карри, он не.Говоря об обучении, мы на самом деле чему-то учимся ? Где находится TensorFlow? Почему это интересно? Ну, это следующий шаг. Теперь мы готовы взять эти данные из Unity и построить модель для прогнозирования требуемой силы.

Предсказания, модели и регрессия

Проверка наших данных в Google Sheets

Перед тем, как мы углубимся в TensorFlow, я хотел взглянуть на данные, поэтому позволил Unity работать до тех пор, пока Red не выполнит около 50 выстрелов. Если вы посмотрите в корневой каталог проекта Unity, вы должны увидеть новый файлsuccessful_shots.csv. Это сырая свалка от Unity каждого удачного снимка, который мы сделали! У меня есть Unity export, чтобы я мог легко проанализировать его в электронной таблице.

.csvФайл имеет только три строки index, distanceи force. Яимпортировал этот файл в Google Sheets и создал график рассеянияс линией тренда, которая позволит нам получить представление о распределении наших данных.

Вау! Посмотри на это. Я имею в виду, посмотри на это. Я имею в виду, вау ... Хорошо, хорошо, я признаю, я не был уверен, что это означало поначалу тоже. Позвольте мне сломать то, что мы видим

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

Практически вы можете прочитать это как «TensorFlow будет оченьхорош в этом».

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

Создание нашей модели TensorFlow.js

Откройте tsjs/index.jsфайл в вашем любимом редакторе. Этот файл не связан с Unity и является просто сценарием для обучения нашей модели на основе данных в successful_shots.csv.

Вот весь метод, который обучает и сохраняет нашу модель ...

Как видите, тут не так много. Мы загружаем наши данные из.csvфайла и создаем серию точек X и Y (звучит очень похоже на наш Google Sheet выше!). Оттуда мы просим модель «соответствовать» этим данным. После этого мы сохраняем нашу модель для будущего потребления!

К сожалению, TensorFlowSharp не ожидает модель в формате, который может сохранить Tensorflow.js. Так что нам нужно сделать волшебный перевод, чтобы иметь возможность втянуть нашу модель в Unity. Я включил несколько утилит, чтобы помочь с этим. Общий процесс состоит в том, что мы переведем нашу модель TensorFlow.js Formatтуда, Keras Formatгде мы можем создать контрольную точку,которую мы объединяем с нашей, Protobuf Graph Definitionчтобы получить ту, Frozen Graph Definitionкоторую мы можем втянуть в Unity.

К счастью, если вы хотите подыграть, вы можете пропустить все этои просто запустить, tsjs/build.shи если все пойдет хорошо, он автоматически выполнит все шаги и выведет замороженную модель в Unity.

Внутри единства, мы можем смотреть на GetForceFromTensorFlow()в ,Assets/BallSpawnController.csчтобы увидеть , что взаимодействуя с нашей моделью выглядит.

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

Когда вы используете model.predict в TensorFlow.js , он автоматически предоставит ваши входные данные в правильный узел входного графа и предоставит вам выходные данные из правильного узла после завершения вычисления. Однако TensorFlowSharp работает по-другому и требует от нас непосредственного взаимодействия с узлами графа через их имена.

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

Это игровой день!

Используя систему выше, я создал несколько вариантов нашей модели. Вот красная стрельба с использованием модели, обученной только на 500 удачных выстрелов.

Мы видим увеличение в 10 раз сделанных корзин! Что произойдет, если мы потренируем Red в течение пары часов и соберем 10 000 или 100 000 успешных снимков? Конечно, это улучшит его игру еще дальше! Хорошо, я оставлю это на ваше усмотрение.

Я настоятельно рекомендую вам проверить исходный код на Githubи написать мне, если вы сможете преодолеть 60% успеха (спойлер: победить 60% - это 100%, вернитесь и посмотрите на первый гиф, чтобы увидеть, насколько хорошо вы можете тренировать Red) !)


Источник: medium.com

Комментарии: