Как стать автором
Обновить
66.23
red_mad_robot
№1 в разработке цифровых решений для бизнеса

Инструменты Apple для машинного обучения

Время на прочтение 10 мин
Количество просмотров 20K


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


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


Машинное обучение


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


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


BNNS и CNN


Apple использует технологии машинного обучения на своих устройствах уже довольно давно: Mail определяет письма, содержащие спам, Siri помогает быстро узнать ответы на интересующие вопросы, Photos распознает лица на изображениях.


На WWDC16 компания представила два API на базе нейронных сетей — Basic Neural Network Subroutines (BNNS) и Convolutional Neural Networks (CNN). BNNS — часть системы Accelerate, которая является основой для выполнения быстрых вычислений на CPU, а CNN — библиотеки Metal Performance Shaders, использующей GPU. Подробнее об этих технологиях можно узнать, к примеру, здесь.


Core ML и Turi Create


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



С помощью Core ML можно реализовать множество функций:


  • определение объектов на фото и видео;
  • предиктивный ввод текста;
  • отслеживание и распознавание лиц;
  • анализ движений;
  • определение штрихкодов;
  • понимание и распознавание текста;
  • распознавание изображений в реальном времени;
  • стилизация изображений;
  • и многое другое.

Core ML, в свою очередь, использует низкоуровневые Metal, Accelerate и BNNS, и поэтому результаты вычислений происходят очень быстро.


Ядро поддерживает нейронные сети, обобщенные линейные модели (generalized linear models), генерацию признаков (feature engineering), древовидные алгоритмы принятия решений (tree ensembles), метод опорных векторов (support vector machines), пайплайн модели (pipeline models).


Но Apple изначально не показала собственных технологий для создания и обучения моделей, а лишь сделала конвертер для других популярных фреймворков: Caffe, Keras, scikit-learn, XGBoost, LIBSVM.


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


В конце года компания представила Turi Create — фреймворк для обучения моделей, основной идеей которого была простота в использовании и поддержка большого числа сценариев — классификация изображений, определение объектов, рекомендательные системы, и множество других. Но Turi Create, несмотря на свою относительную простоту в использовании, поддерживал только Python.


Create ML


И вот в этом году Apple, помимо Core ML 2, наконец показала собственный инструмент для обучения моделей — фреймворк Create ML, использующий нативные технологии Apple — Xcode и Swift.


Он работает быстро, а создание типовых моделей с помощью Create ML становится по-настоящему простым.


На WWDC были озвучены впечатляющие показатели Create ML и Core ML 2 на примере приложения Memrise. Если раньше на обучение одной модели с использованием 20 тысяч изображений требовалось 24 часа, то Create ML сокращает это время до 48 минут на MacBook Pro и до 18 минут — на iMac Pro. Размер обученной модели уменьшился с 90MB до 3MB.


Create ML позволяет использовать в качестве исходных данных изображения, тексты и структурированные объекты — например, таблицы.



Классификация изображений


Посмотрим для начала, как работает классификация изображений. Для обучения модели нам нужен исходный набор данных: возьмем три группы фотографий животных: собак, кошек и птиц и распределим их по папкам с соответствующими названиями, которые и станут названиями категорий модели. Каждая группа содержит по 100 изображений с разрешением до 1920х1080 пикселей и размером до 1Mb. Фотографии должны по возможности максимально отличаться, чтобы обученная модель не полагалась на такие признаки, как цвет на изображении или окружающее пространство.



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


Apple предоставляет два способа взаимодействия с Create ML: с помощью UI в MacOS Playground’е Xcode и программно — с CreateMLUI.framework и CreateML.framework. Используя первый способ, достаточно написать пару строк кода, перенести выбранные изображения в указанную область, и подождать, пока обучится модель.



На Macbook Pro 2017 в максимальной комплектации обучение заняло 29 секунд для 10 итераций, а размер обученной модели составил 33Kb. Выглядит впечатляюще.


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


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


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



Эта технология называется transfer learning (перенос обучения). С ее помощью можно изменить архитектуру предварительно обученной сети так, чтобы она подходила для решения новой задачи. Измененная сеть затем обучается на новом наборе данных.


Create ML во время обучения извлекает из фото около 1000 отличительных признаков. Это могут быть формы объектов, цвет текстур, расположение глаз, размеры, и множество других.
Следует отметить, что исходный набор данных, на котором обучена используемая нейронная сеть, как и наш, может содержать фотографии кошек, собак и птиц, но в нем не выделяются конкретно именно эти категории. Все категории образуют иерархию. Поэтому и просто применить в чистом виде эту сеть нельзя — необходимо дообучить ее на наших данных.


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



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



Для каждого изображения отображается показатель confidence — насколько точно с помощью нашей модели была распознана категория.


Практически для всех фотографий, за редким исключением, этот показатель составил 100%. Я специально добавил в тестовый датасет изображение, которое вы видите выше, и, как можно заметить, Create ML распознал в нем на 86% собаку и на 13% птицу.


Обучение модели завершено, и все, что нам остается, сохранить файл *.mlmodel и добавить его в свой проект.



Для тестирования модели я написал простое приложение, использующее фреймворк Vision. Он позволяет работать с моделями Core ML и решать с их помощью такие задачи, как классификация изображений или обнаружение объектов.


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


Инициализируем Core ML модель для работы с Vision и настроим запрос:


func setupVision() {
    guard let visionModel = try? VNCoreMLModel(for: AnimalsClassifier().model)
        else { fatalError("Can't load VisionML model") }

    let request = VNCoreMLRequest(model: visionModel) { (request, error) in
        guard let results = request.results else { return }
        self.handleRequestResults(results)
    }

    requests = [request]
}

Добавим метод, который будет обрабатывать полученные результаты VNCoreMLRequest. Отобразим только те, у которых показатель confidence больше 70%:


func handleRequestResults(_ results: [Any]) {
    let categoryText: String?

    defer {
        DispatchQueue.main.async {
            self.categoryLabel.text = categoryText
        }
    }

    guard let foundObject = results
        .compactMap({ $0 as? VNClassificationObservation })
        .first(where: { $0.confidence > 0.7 })
        else {
            categoryText = nil
            return
    }

    let category = categoryTitle(identifier: foundObject.identifier)
    let confidence = "\(round(foundObject.confidence * 100 * 100) / 100)%"
    categoryText = "\(category) \(confidence)"
}

И последнее — добавим метод делегата AVCaptureVideoDataOutputSampleBufferDelegate, который будет вызываться при каждом новом кадре с камеры и выполнять запрос:



func captureOutput(
    _ output: AVCaptureOutput,
    didOutput sampleBuffer: CMSampleBuffer,
    from connection: AVCaptureConnection) {
    guard let pixelBuffer = CMSampleBufferGetImageBuffer(sampleBuffer) else {
        return
    }

    var requestOptions: [VNImageOption: Any] = [:]
    if let cameraIntrinsicData = CMGetAttachment(
        sampleBuffer,
        key: kCMSampleBufferAttachmentKey_CameraIntrinsicMatrix,
        attachmentModeOut: nil) {
        requestOptions = [.cameraIntrinsics:cameraIntrinsicData]
    }
    let imageRequestHandler = VNImageRequestHandler(
        cvPixelBuffer: pixelBuffer,
        options: requestOptions)

    do {
        try imageRequestHandler.perform(requests)
    } catch {
        print(error)
    }
}

Проверим, насколько хорошо справляется со своей задачей модель:



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


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


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


Еще одна интересная функция, представленная в Vision только в этом году — возможность распознавания объектов на изображении в реальном времени. Она представлена классом VNRecognizedObjectObservation, позволяющим получить категорию объекта и его расположение — boundingBox.



Сейчас Create ML не позволяет создавать модели для реализации этого функционала. Apple предлагает в этом случае воспользоваться Turi Create. Процесс не сильно сложнее вышеописанного: необходимо подготовить папки-категории с фотографиями и файл, в котором для каждого изображения будут указаны координаты прямоугольника, где находится объект.


Natural Language Processing


Cледующая функция Create ML — обучение моделей для классификации текстов на естественном языке — например, для определения эмоциональной окраски предложений или выявления спама.



Для создания модели мы должны собрать таблицу с исходным набором данных — предложениями или целыми текстами, отнесенными к определенной категории, и обучить с помощью нее модель, используя объект MLTextClassifier:


let data = try MLDataTable(contentsOf: URL(fileURLWithPath: "/Users/CreateMLTest/texts.json"))
let (trainingData, testingData) = data.randomSplit(by: 0.8, seed: 5)
let textClassifier = try MLTextClassifier(trainingData: trainingData, textColumn: "text", labelColumn: "label")

try textClassifier.write(to: URL(fileURLWithPath: "/Users/CreateMLTest/TextClassifier.mlmodel"))

В данном случае обученная модель имеет тип Text Classifier:



Табличные данные


Рассмотрим подробнее другую особенность Create ML — обучение модели с помощью структурированных данных (таблиц).


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


Итак, у нас есть таблица с абстрактными данными о квартирах в Москве в виде csv-файла: известна площадь каждой квартиры, этаж, количество комнат и координаты (широта и долгота). Помимо этого, известна стоимость каждой квартиры. Чем ближе к центру или чем больше площадь, тем выше цена.



Задачей Create ML будет построение модели, способной на основе указанных признаков предсказать цену квартиры. Такая задача в машинном обучении называется задачей регрессии и является классическим примером обучения с учителем.


Create ML поддерживает множество моделей — Linear Regression, Decision Tree Regression, Tree Classifier, Logistic Regression, Random Forest Classifier, Boosted Trees Regression, и др.


Мы воспользуемся объектом MLRegressor, который на основе входных данных сам подберет оптимальный вариант.
Сначала инициализируем объект MLDataTable содержимым нашего csv-файла:


let trainingFile = URL(fileURLWithPath: "/Users/CreateMLTest/Apartments.csv")
let apartmentsData = try MLDataTable(contentsOf: trainingFile)

Разделяем исходный набор данных на данные для обучения модели и тестирования в процентном соотношении 80/20:


let (trainingData, testData) = apartmentsData.randomSplit(by: 0.8, seed: 0)

Создаем модель MLRegressor, указывая данные для обучения и название колонки, значения которой хотим предсказывать. Специфичный для задачи тип регрессора (linear, decision tree, boosted tree или random forest) будет выбран автоматически на основе исследования входных данных. Также мы можем указать feature columns — конкретные колонки-параметры для анализа, но в данном примере в этом нет необходимости, будем использовать все параметры. В конце сохраним обученную модель и добавим в проект:


let model = try MLRegressor(trainingData: apartmentsData, targetColumn: "Price")

let modelPath = URL(fileURLWithPath: "/Users/CreateMLTest/ApartmentsPricer.mlmodel")
try model.write(to: modelPath, metadata: nil)


В этом примере мы видим, что тип модели уже Pipeline Regressor, а в поле Description указан выбранный автоматически тип регрессора — Boosted Tree Regression Model. Параметры Inputs и Outputs соответствуют колонкам таблицы, но тип данных у них стал Double.


Теперь проверим получившийся результат.
Инициализируем объект модели:


let model = ApartmentsPricer()

Вызываем метод prediction, передавая в него указанные параметры:


let area = Double(areaSlider.value)
let floor = Double(floorSlider.value)
let rooms = Double(roomsSlider.value)
let latitude = annotation.coordinate.latitude
let longitude = annotation.coordinate.longitude

let prediction = try? model.prediction(
    area: area,
    floor: floor,
    rooms: rooms,
    latitude: latitude,
    longitude: longitude)

Отображаем предсказанное значение стоимости:


let price = prediction?.price
priceLabel.text = formattedPrice(price)

Меняя точку на карте или значения параметров, получаем довольно близкую к нашим тестовым данным стоимость квартиры:



Заключение


Сейчас фреймворк Create ML — один из самых простых способов работы с технологиями машинного обучения. Он пока не позволяет создавать модели для решения некоторых задач: распознавания объектов на изображении, стилизации фото, определения похожих изображений, распознавания физических действий на основе данных акселерометра или гироскопа, с чем, например, справляется Turi Create.


Но стоит отметить, что Apple довольно серьезно продвинулась в данной сфере за прошедший год, и, наверняка, вскоре мы увидим развитие описанных технологий.

Теги:
Хабы:
+31
Комментарии 25
Комментарии Комментарии 25

Публикации

Информация

Сайт
redmadrobot.ru
Дата регистрации
Дата основания
Численность
1 001–5 000 человек
Местоположение
Россия