Machine Learning op iOS met CoreML en React-Native

Als je net als ik bent, en je er altijd van gedroomd hebt om een ​​applicatie te ontwikkelen die in staat is om een ​​hotdog te onderscheiden van de teckel van je buren met behulp van je iPhone, dan is deze tutorial iets voor jou. Om dit te doen, zullen we React-Native en machine learning gebruiken. Laten we gaan !
Machine learning-oplossingen zijn al lang beschikbaar in de cloud via API's, maar ze vereisten een internetverbinding en de verwerkingstijd kon tegelijkertijd lang en duur zijn.
Met de release van iOS 11 heeft Apple zijn Machine Learning-bibliotheek, CoreML, beschikbaar gemaakt voor ontwikkelaars. Nu is het niet langer nodig om een ​​krachtige server te hebben om verzoeken te verwerken of om een ​​API van derden aan te roepen. CoreML regelt alles met de rekenkracht van je smartphone.
Bent u benieuwd hoe u het kunt integreren in uw applicaties? Het is makkelijker dan je zou denken.
Laten we als voorbeeld de beroemde parodie-applicatie nemen Geen Hotdog, ontdekt in de serie Silicon Valley, die, wanneer de gebruiker zijn smartphone op een object richt, hem onmiddellijk vertelt of deze naar een hotdog kijkt of niet.
Geen hotdog

Wat leer je in dit deel

  • Installeer uw omgeving
  • Data verzamelen
  • Creëer uw beeldclassificatiemodel met Turi Create
  • Herken een hotdog met de camera van je iPhone

Vereisten

  • macOS 10.12+
  • of Linux (met glibc 2.12+)
  • of Windows 10 (via WSL)

  • Python 2.7, 3.5 of 3.6

  • een x86_64-architectuur

  • Xcode 9

  • iOS 11 +

Wat is TuriCreate?

Het is een tool die "de ontwikkeling van aangepaste machine learning-modellen vereenvoudigt", die vervolgens kan worden gebruikt in toepassingen die de CoreML-bibliotheek gebruiken.
Turi Create is gebaseerd op het Deep Learning-framework Apache's MXNet
Turi Create biedt ontwikkelaars flexibele technologie om afbeeldingen te classificeren, objecten te detecteren, aanbevelingssystemen te ontwerpen, enz.
De tool is uiterst gebruiksvriendelijk, flexibel en snel.

zijn installatie

Zoals met veel Machine Learning-tools, python is de taal die wordt gebruikt. Maar maak je geen zorgen, de code is heel eenvoudig te begrijpen.
Het wordt aanbevolen om een ​​virtuele omgeving te gebruiken, virtualenv, het commando invoeren

pip install virtualenv

Als je pip, de Python-pakketbeheerder, niet hebt, kun je het installeren met: Homebrew door het commando in te voeren

brew install pip

Vervolgens,

// Créer un environnement virtuel Python
cd ~
virtualenv venv
// Activer votre environnement virtuel
source ~/venv/bin/activate
// Installer Turi Create
pip install -U turicreate

Data verzamelen

Voordat we een model kunnen trainen, hebben we gegevens nodig.
Deze gegevens zijn terug te vinden op de website IMAGEnet dat is een zeer grote beelddatabase, met meer dan 14 miljoen resultaten.
Voor ons project hebben we twee categorieën afbeeldingen nodig: Hotdog en... Niet Hotdog.
Hier is de link voor de eerste categorie: http://www.image-net.org/synset?wnid=n07697537.

U kunt ook alle links ophalen met behulp van de openbare API, via de knop Download in het tabblad Downloads

http://www.image-net.org/api/text/imagenet.synset.geturls?wnid=n07697537

turicreate-easy-scripts gebruiken

U vindt op de repository turicreate-easy-scripts een reeks scripts die uw leven gemakkelijker zullen maken.
Dus na het klonen van de repo's en het installeren van de afhankelijkheden vanuit de map download-image :

cd download-images
npm install

U kunt de opdracht uitvoeren:

node imagenet-downloader.js http://www.image-net.org/api/text/imagenet.synset.geturls?wnid=n07697537 hotdog

En krijg een map vol met foto's van hotdogs.
Het enige dat overblijft is hetzelfde te doen voor Not Hotdog. Dus kies de categorie(ën) die je het leukst vindt en categoriseer ze als niet-hotdog

node imagenet-downloader.js http://image-net.org/api/text/imagenet.synset.geturls?wnid=n00021939 not-hotdog

Train het model

Nadat de afbeeldingen zijn geüpload en gecategoriseerd, hoeft u alleen nog het classificatiemodel te trainen.
Om dit te doen, kunt u het python-script gebruiken dat beschikbaar is gemaakt in de eerder gedownloade repository

cd train-model
python train-model.py


U krijgt na ongeveer tien minuten (of meer afhankelijk van het aantal te verwerken afbeeldingen) een bestand Classifier.mlmodel die we nu kunnen gebruiken.
gifml

Een React-Native-project maken

Eerst moet u een nieuw React-Native-project maken.
Open uw terminal, navigeer naar uw projectenmap en voer de volgende opdracht in:

react-native init notHotDog (ou tout autre nom)

Na een paar minuten is alles geïnstalleerd en ben je klaar om verder te gaan.

Installeer de CoreML-bibliotheek

We zullen de bibliotheek gebruiken reactie-native-core-ml-afbeelding

npm install --save react-native-core-ml-image
react-native link

Ga naar uw project, vervolgens naar de map "ios" en dubbelklik op het bestand notHotDog.xcodeproj om het in Xcode te openen

Configureer het project

Standaard zijn React-Native-projecten geconfigureerd om voornamelijk Objective-C te gebruiken. De boekenwinkel reactie-native-core-ml-afbeelding omdat het in Swift is geschreven, zal het nodig zijn om enkele parameters in het project te wijzigen
Allereerst zullen we een Swift-bestand aan het project moeten toevoegen


De naam doet er niet toe, hij wordt toch niet gebruikt. Er verschijnt dan een bericht waarin wordt gesuggereerd dat u een "Objective-C Bridging Header" maakt: dit is het bestand dat wordt gebruikt om de koppeling te maken tussen Swift en de headerbestanden van de Objective-C-klassen

Ten slotte, aangezien de bibliotheek in Swift 4.0 wordt geschreven, moet u de versie van Swift specificeren die u wilt gebruiken (3.2 is de standaardversie).
Klik op de hoofdmap van het project (notHotDog), selecteer het tabblad "Build Settings" en verander dan helemaal onderaan de versie van de Swift-taal die moet worden gebruikt.

Importeer het CoreML-model in het project

Voordat we verder gaan met het programmeergedeelte, hoeven we alleen ons beeldclassificatiemodel in het notHotDog-project te importeren.
Slepen en neerzetten sjabloon Classifier.mlmodel en hernoem het notHotDog.mlmodelc (nee, dat is geen typfout)

CoreML werkt niet rechtstreeks met _.mlmodel-bestanden, je moet ze eerst vertalen naar _.mlmodelc (c voor gecompileerd), maar ons Python-script heeft daar al voor gezorgd. (zie laatste regel van het bestand train_model.py)

# Export for use in Core ML
model.export_coreml('Classifier.mlmodel')

Toegang tot de camera toestaan

Klik in het Info.plist-bestand op het plusje rechts van elk item en voeg "Privacy - Beschrijving cameragebruik" toe, zoals hieronder wordt weergegeven

Dat is het voor de opstelling! Het blijft alleen om dit alles uit te voeren.
gif-code

Implementeer de code

Het eerste dat u moet doen, is de bibliotheek importeren reactie-native-core-ml-afbeelding in het project. Voor dit voorbeeld bevindt alle code zich in het bestand App.js

import CoreMLImage from 'react-native-core-ml-image'

Vervang vervolgens de volledige methode render() door het volgende:

render() {
    let classification = null;
    if (this.state.bestMatch) {
      if (this.state.bestMatch.identifier && this.state.bestMatch.identifier === "hotdog") {
        classification = "Hotdog";
      } else {
        classification = "Not hotdog";
      }
    }
    return (
      <View style={styles.container}>
          <CoreMLImage modelFile="notHotDog" onClassification={(evt) => this.onClassification(evt)}>
              <View style={styles.container}>
                <Text style={styles.info}>{classification}</Text>
              </View>
          </CoreMLImage>
      </View>
    );
  }

De werkwijze opClassificatie stelt ons in staat om updates te ontvangen wanneer een nieuw object is geclassificeerd. Het retourneert de volgende gegevens:

[
{
identifier: "hotdog",
confidence: 0.87
},
{
identifier: "not-hotdog",
confidence: 0.4
}
]

We hoeven alleen de methode te implementeren opClassificatie wie verantwoordelijk is voor het vinden van de beste classificatie.

const BEST_MATCH_THRESHOLD = 0.5;
/** */
onClassification(classifications) {
    let bestMatch = null;
    if (classifications && classifications.length) {
      classifications.map(classification => {
        if (!bestMatch || classification.confidence > bestMatch.confidence) {
          bestMatch = classification;
        }
      });
      if (bestMatch.confidence >= BEST_MATCH_THRESHOLD) {
        this.setState({
          bestMatch: bestMatch
        });
      }
      else {
        this.setState({
          bestMatch: null
        });
      }
    }
    else {
      this.setState({
        bestMatch: null
      });
    }
  }

Op basis van eerdere gegevens wordt bestMatch

{
identifier: "hotdog",
confidence: 0.87
}

Hier is de volledige code:

import React, { Component } from "react";
import { Platform, StyleSheet, Text, View } from "react-native";
import idx from "idx";
const BEST_MATCH_THRESHOLD = 0.5;
import CoreMLImage from "react-native-core-ml-image";
export default class App extends Component<{}> {
  constructor() {
    super();
    this.state = {
      bestMatch: null
    };
  }
  onClassification(classifications) {
    let bestMatch = null;
    if (classifications && classifications.length) {
      classifications.map(classification => {
        if (!bestMatch || classification.confidence > bestMatch.confidence) {
          bestMatch = classification;
        }
      });
      if (bestMatch.confidence >= BEST_MATCH_THRESHOLD) {
        this.setState({
          bestMatch: bestMatch
        });
      } else {
        this.setState({
          bestMatch: null
        });
      }
    } else {
      this.setState({
        bestMatch: null
      });
    }
  }
  classify() {
    if (idx(this.state, _ => _.bestMatch.identifier)) {
      if (this.state.bestMatch.identifier === "hotdog") {
        return "Hotdog";
      } else {
        return "Not hotdog";
      }
    }
  }
  render() {
    return (
      <View style={styles.container}>
        <CoreMLImage
          modelFile="notHotDog"
          onClassification={evt => this.onClassification(evt)}
        >
          <View style={styles.container}>
            <Text style={styles.info}>{classify()}</Text>
          </View>
        </CoreMLImage>
      </View>
    );
  }
}
const styles = StyleSheet.create({
  container: {
    flex: 1,
    justifyContent: "center",
    alignItems: "center",
    backgroundColor: "transparent"
  },
  info: {
    fontSize: 20,
    color: "#ffffff",
    textAlign: "center",
    fontWeight: "900",
    margin: 10
  }
});

Het enige wat u hoeft te doen is de code op uw iPhone uit te voeren (de camera werkt niet op de simulator).
Als je alles goed hebt gedaan, vraagt ​​de app je om toegang tot je camera en kun je een hotdog onderscheiden van de teckel van je buurman.
Bedankt voor het lezen van mij. Als je het artikel leuk vond, aarzel dan niet om het op sociale netwerken te delen!
Artikel geschreven door Jeremia Zarca.