5 июля в 19:30

Тестирование и обзор Core ML tutorial

На WWDC’17 Apple представила новый фреймворк для работы с технологиями машинного обучения Core ML. На основе него в iOS реализованы собственные продукты Apple: Siri, Camera и QuickType. Core ML позволяет упростить интеграцию машинного обучения в приложения и создавать различные «умные» функции с помощью пары строчек кода.


image


Возможности Core ML


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


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

Core ML позволяет легко импортировать в ваше приложение различные алгоритмы машинного обучения, такие как: tree ensembles, SVMs и generalized linear models. Он использует низкоуровневые технологии, такие как Metal, Accelerate и BNNS. Результаты вычислений происходят почти мгновенно.


image


Vision


Фреймворк Vision работает на основе Core ML и помогает с отслеживанием и распознаванием лиц, текста, объектов, штрих-кодов. Также доступно определение горизонта и получение матрицы для выравнивания изображения.


NSLinguisticTagger


С iOS 5 Apple представила NSLinguisticTagger, который позволяет анализировать естественный язык, поддерживает множество языков и алфавитов. C выходом iOS 11 класс усовершенствовали, теперь ему можно скормить строку с текстом на разных языках и он вернет доминирующий язык в этой строке и еще много других улучшений. NSLinguisticTagger тоже использует машинное обучение для глубокого понимания текста и его анализа.


Core ML Model


На промо странице Core ML Apple предоставила 4 модели. Все они анализируют изображения. Модели Core ML работают локально и оптимизированы для работы на мобильных устройствах, сводя к минимуму объем используемой памяти и энергопотребление.
Вы можете сгенерировать собственные модели с помощью Core ML Tools.


image


Рабочий способ загружать модели во время выполнения:



  1. Положить файл модели в таргет приложения.
  2. Скомпилировать новую модель из .mlmodel в .mlmodelc, не изменяя её интерфейс.
  3. Положить эти файлы на сервер.
  4. Скачать их внутри приложения.
  5. Инициализировать новую модель, например:


CoreMLModelClass.init(contentOf: URL)

Работоспособность после выпуска приложения в App Store не протестирована.


Особенности Core ML


  • Решение от Apple не может принимать данные и обучать модели. Только принимать некоторые типы обученных моделей, преобразовывать их в собственный формат и делать прогнозы.
  • Модель не сжимается.
  • Она никак не шифруется. Вам придется позаботиться о защите данных самому.

Тестируем Core ML


Я подготовил тестовый проект с использованием Core ML. Мы сделаем простой локатор котов, который позволит отличить все в этой вселенной от кота.


image


Создаем проект и выбираем Single View Application. Предварительно нужно скачать Core ML модель, которая и будет анализировать объекты с камеры. В этом проекте я использую Inception v3. Далее нужно перенести модель в Project Navigator, Xcode автоматически сгенерирует интерфейс для нее.
На сториборд добавляем на весь экран View, туда мы будем выводить изображение с камеры. Поверх добавляем Visual Effect View и Label. Прокидываем аутлеты в ViewController.
Не забудьте в plist добавить разрешение на использование камеры.


image


Нам нужно вывести изображение с камеры в реальном времени, для этого создадим AVCaptureSession и очередь для получения новых кадров DispatchQueue. Добавим на наш View слой AVCaptureVideoPreviewLayer, на него будет выводится изображение с камеры, также нужно создать массив VNRequest — это запросы к Vision. Сразу в viewDidLoad проверим доступность камеры.


import UIKit
import AVFoundation
import Vision

class ViewController: UIViewController {

    @IBOutlet var resultLabel: UILabel!
    @IBOutlet var resultView: UIView!

    let session = AVCaptureSession()
    var previewLayer: AVCaptureVideoPreviewLayer!
    let captureQueue = DispatchQueue(label: "captureQueue")
    var visionRequests = [VNRequest]()

    override func viewDidLoad() {
        super.viewDidLoad()

        guard let camera = AVCaptureDevice.default(for: .video) else {
            return
        }
        do {
            previewLayer = AVCaptureVideoPreviewLayer(session: session)
            resultView.layer.addSublayer(previewLayer)
        } catch {
            let alertController = UIAlertController(title: nil, message: error.localizedDescription, preferredStyle: .alert)
            alertController.addAction(UIAlertAction(title: "Ok", style: .default, handler: nil))
            present(alertController, animated: true, completion: nil)
        }
    }
}

Далее настраиваем cameraInput и cameraOutput, добавляем их к сессии и стартуем ее для получения потока данных.


let cameraInput = try AVCaptureDeviceInput(device: camera)
let videoOutput = AVCaptureVideoDataOutput()
videoOutput.setSampleBufferDelegate(self, queue: captureQueue)
videoOutput.alwaysDiscardsLateVideoFrames = true
videoOutput.videoSettings = [kCVPixelBufferPixelFormatTypeKey as String: kCVPixelFormatType_32BGRA]

session.sessionPreset = .high
session.addInput(cameraInput)
session.addOutput(videoOutput)

let connection = videoOutput.connection(with: .video)
connection?.videoOrientation = .portrait
session.startRunning()

Теперь нам нужно инициализировать Core ML модель для Vision и настроить запрос.


guard let visionModel = try? VNCoreMLModel(for: Inceptionv3().model) else {
    fatalError("Could not load model")
}

let classificationRequest = VNCoreMLRequest(model: visionModel, completionHandler: handleClassifications)
classificationRequest.imageCropAndScaleOption = VNImageCropAndScaleOptionCenterCrop
visionRequests = [classificationRequest]

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


private func handleClassifications(request: VNRequest, error: Error?) {
    if let error = error {
        print(error.localizedDescription)
        return
    }
    guard let results = request.results as? [VNClassificationObservation] else {
        print("No results")
        return
    }

    var resultString = "Это не кот!"
    results[0...3].forEach {
            let identifer = $0.identifier.lowercased()
            if identifer.range(of: "cat") != nil {
            resultString = "Это кот!"
        }
    }
    DispatchQueue.main.async {
        self.resultLabel.text = resultString
    }
}

Последнее, что нам осталось сделать – добавить метод делагата AVCaptureVideoDataOutputSampleBufferDelegate, который вызывается при каждом новом кадре, полученном с камеры. В нем мы конфигурируем запрос и выполняем его.


extension ViewController: 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, kCMSampleBufferAttachmentKey_CameraIntrinsicMatrix, nil) {
            requestOptions = [.cameraIntrinsics: cameraIntrinsicData]
        }

        let imageRequestHandler = VNImageRequestHandler(cvPixelBuffer: pixelBuffer, orientation: 1, options: requestOptions)
        do {
            try imageRequestHandler.perform(visionRequests)
        } catch {
            print(error)
        }
    }
}

Готово! Вы написали приложение, которое отличает котов от всех остальных объектов!


Ссылка на репозиторий.


Выводы


Несмотря на особенности, Core ML найдет свою аудиторию. Если вы не готовы мириться с ограничениями и небольшими возможностями, существуют много сторонних фреймворков. Например, YOLO или Swift-AI.

Автор: @dmrozov
MobileUp
рейтинг 59,79
Компания прекратила активность на сайте

Комментарии (2)

  • 0
    «Core ML позволяет легко импортировать в ваше приложение различные типы нейронных сетей, таких как: tree ensembles, SVMs и generalized linear models»

    Вот так сижу, строю тут случайные леса — а, оказывается, с нейронными сетями работаю :-)
    Вероятно, корректнее было бы говорить о различных алгоритмах машинного обучения.
    • 0

      Спасибо, поправил!

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

Самое читаемое Разработка