
Il y a deux ans, Sundar Pichai, le chef de Google, a déclaré que la société du mobile-first devient d'abord l'IA et se concentre sur l'apprentissage automatique. Un an plus tard, le Kit d'apprentissage machine est sorti - un ensemble d'outils avec lesquels vous pouvez utiliser efficacement ML sur iOS et Android.
Il y a beaucoup de discussions sur le ML Kit aux États-Unis, mais il n'y a presque aucune information en russe. Et puisque nous l'utilisons pour certaines tâches dans Yandex.Money, j'ai décidé de partager mon expérience et de montrer avec des exemples comment l'utiliser pour faire des choses intéressantes.
Je m'appelle Yura et j'ai travaillé l'année dernière dans l'équipe Yandex.Money sur un portefeuille mobile. Nous parlerons de l'apprentissage automatique sur mobile.
Remarque Rédaction: ce billet est une nouvelle du rapport de Yuri Chechetkin «Du mobile d'abord à l'IA d'abord» du métaphone Yandex.Money Android Paranoid .
Qu'est-ce que le kit ML?
Il s'agit du SDK mobile de Google qui facilite l'apprentissage automatique sur les appareils Android et iOS. Il n'est pas nécessaire d'être un expert en ML ou en intelligence artificielle, car en quelques lignes de code vous pouvez implémenter des choses très complexes. De plus, il n'est pas nécessaire de savoir comment fonctionnent les réseaux de neurones ou l'optimisation des modèles.
Que peut faire le kit ML?
Les fonctionnalités de base sont assez larges. Par exemple, vous pouvez reconnaître du texte, des visages, rechercher et suivre des objets, créer des étiquettes pour les images et vos propres modèles de classification, scanner des codes-barres et des balises QR.
Nous avons déjà utilisé la reconnaissance de code QR dans l'application Yandex.Money.
Il y a aussi un kit ML
- Reconnaissance historique;
- Définition de la langue dans laquelle le texte est écrit;
- Traduction de textes sur l'appareil;
- Réponse rapide à une lettre ou un message.
En plus d'un grand nombre de méthodes prêtes à l'emploi, il existe un support pour les modèles personnalisés, ce qui donne pratiquement des possibilités infinies - par exemple, vous pouvez coloriser des photographies en noir et blanc et les faire colorier.
Il est important que vous n'ayez pas besoin d'utiliser de services, d'API ou de backend pour cela. Tout peut être fait directement sur l'appareil, donc nous ne chargeons pas le trafic des utilisateurs, nous n'obtenons pas un tas d'erreurs liées au réseau, nous n'avons pas à traiter un tas de cas, par exemple, le manque d'Internet, la perte de connexion, etc. De plus, sur l'appareil, il fonctionne beaucoup plus rapidement que via un réseau.

Reconnaissance de texte
Tâche: compte tenu d'une photographie, vous devez faire encercler le texte dans un rectangle.
Nous commençons par la dépendance de Gradle. Il suffit de connecter une dépendance, et nous sommes prêts à travailler.
dependencies {
Il convient de spécifier des métadonnées indiquant que le modèle sera téléchargé sur l'appareil lors du téléchargement de l'application à partir du Play Market. Si vous ne le faites pas et accédez à l'API sans modèle, nous obtiendrons une erreur et le modèle devra être téléchargé en arrière-plan. Si vous devez utiliser plusieurs modèles, il est conseillé de les spécifier séparés par des virgules. Dans notre exemple, nous utilisons le modèle OCR, et le nom du reste peut être trouvé dans la documentation .
<application ...> ... <meta-data android:name="com.google.firebase.ml.vision.DEPENDENCIES" android:value="ocr" /> <!-- To use multiple models: android:value="ocr,model2,model3" --> </application>
Après la configuration du projet, vous devez définir les valeurs d'entrée. ML Kit fonctionne avec le type FirebaseVisionImage, nous avons cinq méthodes, dont j'ai écrit la signature ci-dessous. Ils convertissent les types habituels d'Android et de Java en types de ML Kit, avec lesquels il est pratique de travailler.
fun fromMediaImage(image: Image, rotation: Int): FirebaseVisionImage fun fromBitmap(bitmap: Bitmap): FirebaseVisionImage fun fromFilePath(context: Context, uri: Uri): FirebaseVisionImage fun fromByteBuffer( byteBuffer: ByteBuffer, metadata: FirebaseVisionImageMetadata ): FirebaseVisionImage fun fromByteArray( bytes: ByteArray, metadata: FirebaseVisionImageMetadata ): FirebaseVisionImage
Faites attention aux deux derniers - ils fonctionnent avec un tableau d'octets et avec un tampon d'octets, et nous devons spécifier des métadonnées pour que ML Kit comprenne comment gérer tout cela. Les métadonnées, en fait, décrivent le format, dans ce cas, la largeur et la hauteur, le format par défaut, IMAGE_FORMAT_NV21 et la rotation.
val metadata = FirebaseVisionImageMetadata.Builder() .setWidth(480) .setHeight(360) .setFormat(FirebaseVisionImageMetadata.IMAGE_FORMAT_NV21) .setRotation(rotation) .build() val image = FirebaseVisionImage.fromByteBuffer(buffer, metadata)
Lorsque les données d'entrée sont collectées, créez un détecteur qui reconnaîtra le texte.
Il existe deux types de détecteurs, sur l'appareil et dans le cloud, ils sont créés littéralement sur une seule ligne. Il convient de noter que le détecteur de l'appareil ne fonctionne qu'avec l'anglais. Le détecteur de nuages prend en charge plus de 20 langues; elles doivent être spécifiées dans la méthode spéciale setLanguageHints.
Le nombre de langues prises en charge est supérieur à 20, elles sont toutes sur le site officiel. Dans notre exemple, uniquement l'anglais et le russe.
Après avoir entré et un détecteur, appelez simplement la méthode processImage sur ce détecteur. Nous obtenons le résultat sous la forme d'une tâche, à laquelle nous suspendons deux rappels - pour le succès et pour l'erreur. L'exception standard vient à une erreur, et le type FirebaseVisionText vient au succès de onSuccessListener.
val result: Task<FirebaseVisionText> = detector.processImage(image) .addOnSuccessListener { result: FirebaseVisionText ->
Comment travailler avec le type FirebaseVisionText?
Il se compose de blocs de texte (TextBlock), ceux-ci se composent à leur tour de lignes (Line) et de lignes d'éléments (Element). Ils sont imbriqués les uns dans les autres.
De plus, chacune de ces classes possède cinq méthodes qui renvoient des données différentes sur l'objet. Un rectangle est la zone où se trouve le texte, la confiance est la précision du texte reconnu, les points d'angle sont les points d'angle dans le sens des aiguilles d'une montre, à partir du coin supérieur gauche, les langues reconnues et le texte lui-même.
FirebaseVisionText contains a list of FirebaseVisionText.TextBlock which contains a list of FirebaseVisionText.Line which is composed of a list of FirebaseVisionText.Element. fun getBoundingBox(): Rect
À quoi ça sert?
Nous pouvons reconnaître à la fois le texte entier dans l'image et ses paragraphes, morceaux, lignes ou simplement des mots. Et à titre d'exemple, nous pouvons parcourir, à chaque étape, prendre un texte, prendre les bordures de ce texte et dessiner. Très confortable.
Nous prévoyons d'utiliser cet outil dans notre application de reconnaissance des cartes bancaires, dont les étiquettes sont situées non standard. Toutes les bibliothèques de reconnaissance de cartes ne fonctionnent pas bien, et pour les cartes personnalisées, le kit ML serait très utile. Puisqu'il y a peu de texte, il est très facile de traiter de cette façon.
Reconnaissance d'objets sur la photo

En utilisant l'outil suivant comme exemple, je voudrais montrer que le principe de fonctionnement est à peu près le même. Dans ce cas, reconnaissance de ce qui est représenté sur l'objet. Nous créons également deux détecteurs, l'un sur l'appareil, l'autre sur le cloud, nous pouvons spécifier la précision minimale comme paramètres. La valeur par défaut est 0,5, indiquée 0,7 et prête à l'emploi. Nous obtenons également le résultat sous la forme de FirebaseImageLabel, c'est une liste d'étiquettes, chacune contenant un ID, une description et une précision.
Harold cache le bonheur

Vous pouvez essayer de comprendre à quel point Harold cache la douleur et s'il est heureux en même temps. Nous utilisons un outil de reconnaissance faciale qui, en plus de reconnaître les traits du visage, peut dire à quel point une personne est heureuse. Il s'est avéré que Harold est heureux à 93%. Ou il cache très bien la douleur.

De facile à facile, mais un peu plus compliqué. Modèles personnalisés.
Tâche: classification de ce qui est représenté sur la photo.
J'ai pris une photo de l'ordinateur portable et reconnu le modem, l'ordinateur de bureau et le clavier. Sonne comme la vérité. Il y a mille classificateurs, et il en prend trois qui décrivent le mieux cette photo.

Lorsque vous travaillez avec des modèles personnalisés, nous pouvons également travailler avec eux à la fois sur l'appareil et via le cloud.
Si nous travaillons à travers le cloud, vous devez aller dans la console Firebase, dans l'onglet ML Kit, et appuyer sur personnalisé, où nous pouvons télécharger notre modèle sur TensorFlow Lite, car ML Kit fonctionne avec des modèles avec cette résolution. Si nous l'utilisons sur un appareil, nous pouvons simplement placer le modèle dans n'importe quelle partie du projet comme un atout.

Nous soulignons la dépendance vis-à-vis de l'interpréteur, qui peut fonctionner avec des modèles personnalisés, et n'oubliez pas la permission de travailler avec Internet.
<uses-permission android:name="android.permission.INTERNET" /> dependencies {
Pour les modèles qui se trouvent sur l'appareil, vous devez indiquer dans Gradle que le modèle ne doit pas être compressé, car il peut être déformé.
android {
Lorsque nous avons tout configuré dans notre environnement, nous devons définir des conditions spéciales, qui incluent, par exemple, l'utilisation du Wi-Fi, nécessitent également une charge et nécessitent que l'appareil soit inactif sont disponibles avec Android N - ces conditions indiquent que le téléphone est en charge ou en mode veille.
var conditionsBuilder: FirebaseModelDownloadConditions.Builder = FirebaseModelDownloadConditions.Builder().requireWifi() if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
Lorsque nous créons un modèle distant, nous définissons les conditions d'initialisation et de mise à jour, ainsi que l'indicateur indiquant si notre modèle doit être mis à jour. Le nom du modèle doit correspondre à celui que nous avons spécifié dans la console Firebase. Lorsque nous avons créé le modèle distant, nous devons l'enregistrer dans le gestionnaire de modèles Firebase.
val cloudSource: FirebaseRemoteModel = FirebaseRemoteModel.Builder("my_cloud_model") .enableModelUpdates(true) .setInitialDownloadConditions(conditions) .setUpdatesDownloadConditions(conditions) .build() FirebaseModelManager.getInstance().registerRemoteModel(cloudSource)
Nous faisons les mêmes étapes pour le modèle local, spécifions son nom, le chemin d'accès au modèle et l'enregistrons dans le gestionnaire de modèles Firebase.
val localSource: FirebaseLocalModel = FirebaseLocalModel.Builder("my_local_model") .setAssetFilePath("my_model.tflite") .build() FirebaseModelManager.getInstance().registerLocalModel(localSource)
Après cela, vous devez créer ces options où nous spécifions les noms de nos modèles, installer le modèle distant, installer le modèle local et créer un interpréteur avec ces options. Nous pouvons spécifier soit un modèle distant, soit seulement un modèle local, et l'interprète comprendra lui-même avec lequel travailler.
val options: FirebaseModelOptions = FirebaseModelOptions.Builder() .setRemoteModelName("my_cloud_model") .setLocalModelName("my_local_model") .build() val interpreter = FirebaseModelInterpreter.getInstance(options)
ML Kit ne sait rien du format des données d'entrée et de sortie des modèles personnalisés, vous devez donc les spécifier.
Les données d'entrée sont un tableau multidimensionnel, où 1 est le nombre d'images, 224x224 est la résolution et 3 est une image RVB à trois canaux. Eh bien, le type de données est en octets.
val input = intArrayOf(1, 224, 224, 3)
Les valeurs de sortie sont de 1000 classificateurs. Nous définissons le format des valeurs d'entrée et de sortie en octets avec les tableaux multidimensionnels spécifiés. En plus des octets, float, long, int sont également disponibles.
Maintenant, nous définissons les valeurs d'entrée. Nous prenons Bitmap, le compressons à 224 par 224, le convertissons en ByteBuffer et créons des valeurs d'entrée à l'aide de FirebaseModelInput à l'aide d'un générateur spécial.
val bitmap = Bitmap.createScaledBitmap(yourInputImage, 224, 224, true) val imgData = convertBitmapToByteBuffer(bitmap) val inputs: FirebaseModelInputs = FirebaseModelInputs.Builder() .add(imageData) .build()
Et maintenant, quand il y a un interpréteur, le format des valeurs d'entrée et de sortie et les valeurs d'entrée elles-mêmes, nous pouvons exécuter la demande en utilisant la méthode run. Nous transférons tout ce qui précède en tant que paramètres et, par conséquent, nous obtenons FirebaseModelOutput, qui contient à l'intérieur un générique du type que nous avons spécifié. Dans ce cas, il s'agissait d'un tableau d'octets, après quoi nous pouvons commencer le traitement. C'est exactement le millier de classificateurs que nous avons demandé, et nous affichons, par exemple, le top 3 le plus adapté.
interpreter.run(inputs, inputOutputOptions) .addOnSuccessListener { result: FirebaseModelOutputs -> val labelProbArray = result.getOutput<Array<ByteArray>>(0)
Mise en œuvre en un jour
Tout est assez facile à implémenter, et la reconnaissance d'objets avec des outils intégrés peut être réalisée en une seule journée. L'outil est disponible sur iOS et Android, en plus, vous pouvez utiliser le même modèle TensorFlow pour les deux plateformes.
En outre, il existe des tonnes de méthodes disponibles qui peuvent couvrir de nombreux cas. La plupart des API sont disponibles sur l'appareil, c'est-à-dire que la reconnaissance fonctionnera même sans Internet.
Et surtout - la prise en charge de modèles personnalisés qui peuvent être utilisés comme vous le souhaitez pour n'importe quelle tâche.
Liens utiles
Documentation du kit ML
Projet de démonstration du kit Github ML
Apprentissage automatique pour mobile avec Firebase (Google I / O'19)
SDK Machine Learning pour les développeurs mobiles (Google I / O'18)
Création d'un scanner de carte de crédit à l'aide du kit Firebase ML (Medium.com)