Пользовательские модели Firebase ML Kit для разработчиков iOS. Часть 2. Реализация крестиков-ноликов
В Части 1 мы создаем модель для добавления 3 чисел с плавающей запятой, чтобы понять, как модель TensorFlow Lite работает с набором Firebase ML.
Эта модель никогда не будет использоваться в реальном приложении, поэтому давайте рассмотрим более реалистичный пример. Допустим, вы создаете приложение для игры в крестики-нолики (также известное как крестики-нолики или OXO), и ваше приложение должно предлагать подсказки игроку или реализовывать ИИ.
Давайте создадим модель TensorFlow Lite, которая находит лучшие ходы для определенного состояния доски, и используем ее в нашем приложении для iOS, чтобы подсчитывать все возможные следующие ходы, которые может сделать игрок.
Шаг 1. Осмотрите модель
Модель Tic Tac Toe принимает состояние доски (сетка ячеек 3x3) и выводит следующий ход для каждой ячейки (поэтому вывод также 3x3). Это простая сеть с двумя скрытыми слоями, обученная на миллионе игр, в которые играют два случайных игрока. Обратите внимание, что модель не является идеальным игроком! (Я оставляю читателям ML переобучить модель, чтобы она стала лучшим игроком — пришлите мне свои результаты, пожалуйста)
Вы можете самостоятельно воссоздать набор данных и переобучить модель в его Tic Tac Toe Colab. Или вы можете сделать, как я, и сразу перейти к загрузке файла tictactoe.tflite.
Снова откройте модель в Netron. Вы увидите интересующие нас слои и входы и выходы:
- Тип ввода:
float32[3,3]
- Тип выхода:
float32[3,3]
Как мы вводим X
и O
как числа с плавающей запятой? Модель была построена таким образом, что если текущий игрок O
, то ячейки с O
будут закодированы как 1.0, а X
оппонента будут закодированы как -1.0. Если текущий игрок X
, то это происходит в обратном порядке (X
s равны 1,0, а O
s равны -1,0). Пустые ячейки всегда кодируются как 0.0.
Например, на доске написано:
X|O| -+-+- X|O|O -+-+- | |X
Если текущий игрок O
, входные данные для модели будут такими:
[[-1., 1., 0.], [-1., 1., 1.], [0., 0., -1.]]
Результатом модели является та же форма, где значение каждой ячейки показывает, насколько хорош ход для текущего игрока. Ясно, что лучший ход для O
— это нижняя средняя ячейка, поэтому можно надеяться, что модель выведет что-то похожее на:
[[0., 0., 0.], [0., 0., 0.], [0., 1., 0.]]
Изучив модель и поняв ее входные и выходные данные, мы теперь знаем, что нам нужно делать в коде Swift:
- Преобразуйте состояние доски в двумерный массив (3x3), где текущие ячейки игрока равны 1,0, ячейки противника равны -1,0, а пустые ячейки равны 0,0 в качестве входных данных для модели.
- Интерпретируйте выходные данные модели как 0,0 для плохого хода и 1,0 для лучшего хода.
Давайте начнем!
Шаг 2. Интегрируйте модель в свой проект iOS.
Пользовательский интерфейс приложения представляет собой доску Tic Tac Toe, которая позволяет пользователю настроить любое состояние доски и кнопку для переключения текущего игрока («Следующий ход»). Фон пустых ячеек на доске затенен в соответствии с выходными данными модели — темно-серый имеет более высокое значение и лучший ход, чем светло-серый.
1. Добавьте модель локально и в облаке. Мы уже сделали это для локальной модели в предыдущем примере. В этом примере давайте также добавим модель на сервер, чтобы мы могли обновлять нашу модель в будущем (без необходимости обновления приложения пользователями). Мы можем сделать это, разместив файл модели TensorFlow Lite в проекте Xcode для локального использования, а также загрузив файл модели TensorFlow Lite в консоль Firebase в разделе «Пользовательские модели ML Kit», чтобы сделать его доступным в облаке.
2. Подготовьте переводчика. Как и раньше, загрузите модель, настроив источники модели и создав объект ModelInterpreter
из одного из них.
Как видите, шаги по настройке локальной модели такие же. Однако есть некоторые дополнительные шаги по настройке для удаленных (в облаке) моделей. Во-первых, создайте объект CustomRemoteModel
, указав имя модели, которое вы присвоили при публикации через Firebase Console. Еще одна часть, которая нам нужна перед созданием ModelInterpreter
, — это запуск задачи загрузки модели путем передачи CustomRemoteModel
с условиями загрузки.
Затем мы можем создать ModelInterpreter
из одной из моделей, локальной или удаленной, проверив, загружена ли уже удаленная модель перед ее использованием.
3. Укажите входные и выходные данные модели. Модель Крестики-нолики имеет [3,3] в качестве входной и выходной формы. Входные данные — это текущее состояние доски, представляющее собой двумерные массивы, включающие -1 (ячейка противника), 0 (пустая ячейка), 1 (ячейка текущего игрока). Выходные данные также представляют собой двумерные массивы, которые представляют собой оценки всех ходов, как описано на шаге проверки выше.
4. Выполните вывод по входным данным. А вот и самое интересное! Каждый раз, когда состояние доски или игрок меняются в пользовательском интерфейсе, мы вызываем функцию запуска интерпретатора, чтобы получить лучшие ходы для текущего игрока.
В функции запуска довольно много проверок, чтобы убедиться, что размер ввода и вывода правильный. Если все в порядке, выходные данные будут отправлены обратно, чтобы показать результаты в контроллере представления.
Я надеюсь, что вместе эти Часть 1 и Часть 2 помогут вам начать работу с пользовательскими моделями в Firebase ML Kit и в будущем вы сможете добавлять более сложные модели в свои приложения для iOS.
Firebase ML Kit все еще находится в стадии бета-тестирования и, следовательно, может измениться — следите за официальной документацией по пользовательским моделям на iOS для получения последних примеров.
Получите полный код проекта для этих примеров на github.com/naluinui.