Вступление

Представьте себе приложение, которое позволяет сканировать документ, а затем задавать вопросы по его содержанию. Что-то вроде этого:

У этого приложения есть несколько проблем:

  • обнаружение краев на документе
  • сканирование и распознавание текста в документе
  • отвечать на вопросы по содержанию отсканированного документа.

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

Мы будем использовать множество интересных технологий для реализации этого приложения, таких как SwiftUI, Combine, CoreML и Vision. Для начала создайте новый проект SwiftUI (я назвал свой SmartAssistant).

Распознавание текста

Первое, что нам нужно сделать, это отсканировать документ и извлечь из него текст. Когда у нас есть строка, ее будет намного легче анализировать. Вы можете найти более подробную информацию о распознавании текста в другом моем посте Распознавание текста на iOS 13 с помощью Vision, SwiftUI и Combine.

Вкратце, нам нужно реализовать оболочку SwiftUI для VNDocumentCameraViewController, который является контроллером представления UIKit из инфраструктуры Vision. Этот контроллер показывает сканер камеры, который обнаруживает края.

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

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

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

Теперь, когда у нас есть представление сканирования, давайте интегрировать его в основное представление. Он будет отображаться как модальное представление, когда пользователь нажимает значок плюса.

Представление DocumentsList подписывается на изменения в documentsRepository и обновляет его содержимое при добавлении новых документов.

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

В этом представлении есть три переменных @State. Во-первых, нам нужно отслеживать вопрос, который задает пользователь. Строка вопроса привязана к текстовому полю. Когда вопрос меняется и пользователь нажимает кнопку «ответить», ответ меняется (подробнее об этом ниже). При изменении ответа метка, отображающая этот ответ, также должна быть обновлена.

Модель вопросов и ответов

Теперь самое интересное - как ответить на вопрос. К счастью, есть порт CoreML модели BERT. BERT означает двунаправленные представления кодировщика от трансформаторов (BERT) и является результатом исследовательской работы и статьи Джейкоба Девлина, Минг-Вей Чанга, Кентона Ли и Кристины Тутановой.

Модель принимает текст из документа и вопрос о документе на естественном английском языке. Модель отвечает местоположением отрывка в тексте документа, который отвечает на вопрос. Вы можете найти более подробную информацию о том, как работает модель CoreML, в Образце кода Apple.

По сути, он берет вопрос и содержание, в котором следует найти ответ. Он разбивает слова из обеих строковых записей на токены, используя фреймворк Естественный язык. Затем каждое слово преобразуется в идентификатор на основе предварительно определенного словаря BERTVocabulary (вы можете найти его в текстовом файле bert-base-uncased-vocab.txt в репозитории). Если словарного обозначения нет в словаре, метод ищет подтекены или фрагменты слова. Затем идентификаторы слов преобразуются в MLMultiArray и предоставляются в качестве входных данных для модели CoreML, которая выполняет прогноз. Для получения более подробной информации об этом процессе, пожалуйста, обратитесь к Образцу кода Apple.

Нам, как пользователям этой модели, достаточно позвонить:

self.answer = String (self.bert.findAnswer (для: self.question, in: self.document.content))

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

Тестирование

Вы можете попробовать протестировать несколько разных типов документов. Я пробовал сканировать страницу AppStore моего приложения Drawland (посмотрите видео выше). Я задавал несколько вопросов, например:

  • Как Drawland помогает?
  • Сколько на нем эскизов?
  • Кому это подходит?

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

Заключение

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

Одно ограничение - на данный момент модель довольно большая (более 200 МБ) и, вероятно, вы не будете использовать ее в продуктивном приложении из-за этого. Также существует ограничение на количество токенов - если у вас более 389 токенов, на ваш вопрос не будет ответа.

Вы можете найти исходный код приложения здесь.

Первоначально опубликовано на http://martinmitrevski.com 20 декабря 2019 г.