Implémentation de l'apprentissage automatique sur un appareil iOS à l'aide de Core ML, Swift et Neural Engine

Bonjour habr! En prévision du début du cours avancé "Développeur iOS" , nous avons traditionnellement préparé une traduction de matériel utile pour vous.










introduction



Core ML est une bibliothèque d'apprentissage automatique publiée par Apple à la WWDC 2017.



Elle permet aux développeurs iOS d'ajouter des expériences personnalisées en temps réel à leurs applications à l'aide de modèles d'apprentissage automatique locaux avancés à l'aide du moteur neuronal.



Examen de la puce A11 Bionic





Remplissage de puces bioniques A11

Transistors: 4,3 milliards de

cœurs: 6 cœurs ARM (64 bits) - 2 haute fréquence (2,4 GHz) - 4

GPU basse consommation : 3

Neural Engine - 600 opérations de base par seconde


Le 12 septembre 2017, Apple a présenté au monde la puce A11 Bionic avec Neural Engine. Ce matériel de réseau neuronal peut effectuer jusqu'à 600 opérations de base par seconde (BOPS) et est utilisé pour FaceID, Animoji et d'autres tâches d'apprentissage automatique. Les développeurs peuvent utiliser Neural Engine à l'aide de l'API Core ML.



Core ML optimise les performances de l'appareil en utilisant les ressources CPU, GPU et Neural Engine, minimisant ainsi la mémoire et la consommation d'énergie.



L'exécution du modèle localement sur l'appareil de l'utilisateur élimine le besoin d'une connexion réseau, ce qui permet de maintenir la confidentialité des données utilisateur et améliore la réactivité de votre application.


Core ML est la base des cadres et des fonctionnalités de ce domaine. Core ML prend en charge la vision pour l'analyse d'image, le langage naturel pour le traitement de texte, la parole pour le son-texte et l'analyse sonore pour identifier les sons dans l'audio.





API Core ML

Nous pouvons facilement automatiser la tâche de création de modèles d'apprentissage automatique, ce qui inclut la formation et le test du modèle à l'aide du Playground, et l'intégration du fichier de modèle résultant dans notre projet iOS.



Conseil pour les débutants : mettez en surbrillance des étiquettes distinctes pour les tâches de classification






Schéma de principe général de Core ML



D'accord. Qu'allons-nous créer?



Dans ce tutoriel, je vais vous montrer comment créer un modèle de classificateur d'images à l'aide de Core ML, qui peut classer les images Orange et Strawberry, et ajouter ce modèle à notre application iOS.





Modèle de classificateur d'image.



Conseil pour les débutants : la classification des images fait référence aux problèmes d'apprentissage supervisé dans lesquels nous utilisons des données étiquetées (dans notre cas, l'étiquette est le nom de l'image).








Minimum requis:



  • Connaissance du langage Swift
  • Principes de base du développement IOS
  • Comprendre les concepts de programmation orientée objet




Programmes d'application:



  • X-code 10 ou version ultérieure
  • SDK iOS 11.0+
  • macOS 10.13+




Collecte de données







Lors de la collecte de données pour la classification des images, suivez les directives d'Apple.



  • 10 — , .
  • , .
  • , Create ML UI’s Augmentation: Crop, Rotate, Blur, Expose, Noise Flip.
  • : , . , .
  • , , .
  • , , -.




Une fois que vous avez collecté votre ensemble de données, divisez-le en ensembles Train et Test et placez-les dans les dossiers appropriés.







REMARQUE IMPORTANTE: assurez-vous de distribuer les images dans les dossiers appropriés du dossier de test. Parce que le nom du dossier sert d'étiquette pour nos images.






Dans notre cas, nous avons deux dossiers, chacun contenant les images correspondantes.



Création de modèle







Ne pas paniquer! Apple a rendu cela beaucoup plus facile en automatisant les jalons.



Avec Core ML, vous pouvez utiliser un modèle déjà entraîné pour classer les données d'entrée ou créer le vôtre. Le framework Vision travaille déjà avec Core ML pour appliquer des modèles de classification aux images et prétraiter ces images, et pour rendre les tâches d'apprentissage automatique plus simples et plus robustes.



Suivez simplement ces étapes.



ÉTAPE 1 : Ouvrez votre X-code.

ÉTAPE 2 : Créez un Swift Playground propre.

ÉTAPE 3 : supprimez le code généré par défaut, ajoutez le programme suivant et exécutez playground.



   import CreateMLUI //  
  
   let builder = MLImageClassifierBuilder() 
//  MLImageClassifierBuilder
 
   builder.showInLiveView() 
//   Xcode Model builder




Description:

Ici, nous ouvrons l'interface du générateur de modèle par défaut fourni par Xcode.



ÉTAPE 4 : faites glisser le dossier des exemples de formation vers la zone de formation.



Placez le dossier des échantillons de formation dans la zone de formation indiquée par les lignes pointillées.



Conseil pour les débutants : nous pouvons également fournir un nom arbitraire pour notre modèle en cliquant sur la flèche vers le bas dans la zone du didacticiel.




Étape 5 : Xcode traitera automatiquement l'image et démarrera le processus d'apprentissage. Par défaut, il faut 10 itérations pour entraîner un modèle, en fonction des caractéristiques de votre Mac et de la taille de l'ensemble de données. Vous pouvez regarder la progression de l'entraînement dans la fenêtre du terminal Playground.





J'attends pendant que le modèle est en formation.



ÉTAPE 6 : Une fois la formation terminée, vous pouvez tester votre modèle en faisant glisser et en déposant le dossier Test dans la zone de test. Xcode testera automatiquement votre modèle et affichera le résultat.





Comme vous pouvez le voir, notre modèle a classé les images avec précision.



ÉTAPE 7 : Enregistrez votre modèle.









Intégration dans l'application iOS:



ÉTAPE 1 : Ouvrez votre X-code.

ÉTAPE 2 : Créez une application iOS à page unique.

ÉTAPE 3 : Ouvrez le navigateur de projet.

ÉTAPE 4 : faites glisser le modèle entraîné vers le navigateur de projet.





Placez votre modèle dans le navigateur de projet.



ÉTAPE 5: Ouvrez Main.storyboardet créez une interface simple comme indiqué ci-dessous, ajoutez des IBOutlets et des IBActions pour les vues respectives.





Ajoutez UIImageView, UIButtons et UILabels.



ÉTAPE 6 : Ouvrez le fichier ViewController.swiftet ajoutez le code suivant en tant qu'extension.



  extension ViewController: UINavigationControllerDelegate, UIImagePickerControllerDelegate { 
 
 
       func getimage() { 
 
           let imagePicker = UIImagePickerController()
//  UIImagePickerController()
 
           imagePicker.delegate = self //  
 
           imagePicker.sourceType = .photoLibrary  //       
 
           imagePicker.allowsEditing = true  //   
 
           present(imagePicker, animated: true)  //  UIPickerView
 
       } 
 
       func imagePickerController(_ picker: UIImagePickerController, didFinishPickingMediaWithInfo : [UIImagePickerController.InfoKey: Any]) { 
 
           let fimage = info[.editedImage] as!UIImage 
//      .editedImage   info 
 
           //    UIImage
 
           fruitImageView.image = fimage  
//    UIImageView
 
           dismiss(animated: true, completion: nil)  //   ,    
 
       } 
 
       func imagePickerControllerDidCancel(_ picker: UIImagePickerController) { 
 
           dismiss(animated: true, completion: nil)  
//     ,     
 
       } 
 
   } 




Description: Ici, nous créons une extension pour notre classe ViewController et implémentons UINavigationControllerDelegate et UIImagePickerControllerDelegate pour afficher l'UIImagePickerView lorsque l'utilisateur clique sur l'UIButton PickImage. Assurez-vous de définir le contexte du délégué.







Étapes liées à l'accès au modèle Core ML dans une application iOS







ÉTAPE 1 : assurez-vous d'avoir importé les bibliothèques suivantes.



import CoreML 
 import Vision




ÉTAPE 2 : Créez une instance de notre classe Model Core ML.



let modelobj = ImageClassifier()




ÉTAPE 3 : Pour forcer Core ML à faire la classification, nous devons d'abord former une requête comme VNCoreMLRequest (VN signifie Vision)



var myrequest: VNCoreMLRequest? 
//  VNCoreMLRequest
 
myrequest = VNCoreMLRequest(model: fruitmodel, completionHandler: { (request, error) in    
//    
 
               //  ,     Core ML
 
               self.handleResult(request: request, error: error)
//  
 
                                                     })




ÉTAPE 4: assurez-vous de recadrer l'image afin qu'elle soit compatible avec le modèle Core ML. ÉTAPE 5: placez le code ci-dessus dans une fonction personnalisée qui renvoie un objet de requête.



myrequest!.imageCropAndScaleOption = .centerCrop







 func mlrequest() - > VNCoreMLRequest { 
        var myrequest: VNCoreMLRequest ? 
            let modelobj = ImageClassifier() 
        do { 
            let fruitmodel = 
                try VNCoreMLModel( 
                    for: modelobj.model) 
 
           myrequest = VNCoreMLRequest(model: fruitmodel, completionHandler: {   
                (request, error) in self.handleResult(request: request, error: error) 
          
           }) 
 
       } catch { 
           print("Unable to create a request") 
 
       } 
 
       myrequest!.imageCropAndScaleOption = .centerCrop 
        return myrequest! 
    } 




ÉTAPE 6 : Nous devons maintenant convertir notre UIImage en CIImage (CI: CoreImage) afin qu'elle puisse être utilisée comme entrée dans notre modèle Core ML. Cela peut être facilement fait en instanciant CIImage en passant UIImage dans le constructeur.



guard  let ciImage = CIImage(image: image)  else { 
       return 
    } 




ÉTAPE 7 : Nous pouvons maintenant traiter le nôtre VNCoreMLRequesten créant un gestionnaire de requêtes et en passant ciImage.



let handler = VNImageRequestHandler(ciImage: ciImage)




ÉTAPE 8 : La demande peut être satisfaite en appelant la méthode perform()et en la passant en paramètre VNCoreMLRequest.



DispatchQueue.global(qos: .userInitiated).async { 
       let handler = VNImageRequestHandler(ciImage: ciImage) 
       do { 
           try handler.perform([self.mlrequest()]) 
       } catch {  
           print("Failed to get the description")  
       }  
   } 




Description : DispatchQueue est un objet qui gère l'exécution des tâches de manière séquentielle (ou simultanée) dans le thread principal (ou d'arrière-plan) de votre application.



ÉTAPE 10 : Placez le code ci-dessus dans une fonction personnalisée comme indiqué ci-dessous.



func excecuteRequest(image: UIImage) { 
 
            guard 
            let ciImage = CIImage(image: image) 
            else { 
                return 
            } 
            DispatchQueue.global(qos: .userInitiated).async { 
                let handler = VNImageRequestHandler(ciImage: ciImage) 
                do { 
                    try handler.perform([self.mlrequest()]) 
                } catch { 
                    print("Failed to get the description") 
                } 
            } 




ÉTAPE 11 : Créez une fonction personnalisée nommée handleResult()qui prend VNRequestun objet d' erreur et un objet d'erreur comme paramètres. Cette fonction sera appelée à la fin VNCoreMLRequest.



func handleResult(request: VNRequest, error: Error ? ) { 
 
       if let classificationresult = request.results as ? [VNClassificationObservation] {//      VNClassificationObservation
 
           DispatchQueue.main.async { 
               self.fruitnamelbl.text = classificationresult.first!.identifier// UILabel          prperty
                print(classificationresult.first!.identifier)
            } 
        } 
        else { 
            print("Unable to get the results") 
        } 
    }  




Remarque : Ceci est DispatchQueue.main.asyncutilisé pour mettre à jour les objets UIKit (dans notre cas, il s'agit de UILabel) à l'aide du thread d'interface utilisateur ou du thread principal, car toutes les tâches de classification sont effectuées dans le thread d'arrière-plan.








Référencement ViewController.Swift





import UIKit 
    import CoreML 
    import Vision 
    class ViewController: UIViewController { 
        var name: String = "" 
        @IBOutlet weak 
        var fruitnamelbl: UILabel!@IBOutlet weak 
        var fruitImageView: UIImageView!override func viewDidLoad() { 
            super.viewDidLoad() 
            //       .  
        } 
        @IBAction func classifybtnclicked(_ sender: Any) { 
            excecuteRequest(image: fruitImageView.image!) 
        } 
        @IBAction func piclimage(_ sender: Any) { 
            getimage() 
        } 
        func mlrequest() - > VNCoreMLRequest { 
            var myrequest: VNCoreMLRequest ? 
                let modelobj = ImageClassifier() 
           do { 
                let fruitmodel = 
                    try VNCoreMLModel( 
                        for: modelobj.model) 
                myrequest = VNCoreMLRequest(model: fruitmodel, completionHandler: { 
                    (request, error) in self.handleResult(request: request, error: error) 
                }) 
            } catch { 
                print("Unable to create a request") 
            } 
            myrequest!.imageCropAndScaleOption = .centerCrop 
            return myrequest! 
        } 
        func excecuteRequest(image: UIImage) { 
            guard 
            let ciImage = CIImage(image: image) 
            else { 
                return 
            } 
            DispatchQueue.global(qos: .userInitiated).async { 
                let handler = VNImageRequestHandler(ciImage: ciImage) 
                do { 
                    try handler.perform([self.mlrequest()]) 
                } catch { 
                    print("Failed to get the description") 
                } 
            } 
        } 
        func handleResult(request: VNRequest, error: Error ? ) { 
            if let classificationresult = request.results as ? [VNClassificationObservation] { 
                DispatchQueue.main.async { 
                    self.fruitnamelbl.text = classificationresult.first!.identifier 
                    print(classificationresult.first!.identifier) 
                } 
            } 
            else { 
                print("Unable to get the results") 
            } 
        } 
    } 
    extension ViewController: UINavigationControllerDelegate, UIImagePickerControllerDelegate { 
        func getimage() { 
            let imagePicker = UIImagePickerController() 
            imagePicker.delegate = self 
            imagePicker.sourceType = .photoLibrary 
            imagePicker.allowsEditing = true 
            present(imagePicker, animated: true) 
        } 
        func imagePickerController(_ picker: UIImagePickerController, didFinishPickingMediaWithInfo info: [UIImagePickerController.InfoKey: Any]) { 
            let fimage = info[.editedImage] as!UIImage 
            fruitImageView.image = fimage 
            dismiss(animated: true, completion: nil) 
        } 
        func imagePickerControllerDidCancel(_ picker: UIImagePickerController) { 
            dismiss(animated: true, completion: nil) 
        } 
    }




Tout est prêt!







Démarrez maintenant votre simulateur et testez votre application.



Remarque : assurez-vous d'avoir une photo d'oranges et de fraises dans la photothèque de votre simulateur.






Cliquez sur le bouton





Choisir une image Sélectionnez une image





Cliquez sur le bouton Classer





Sélectionnez une autre image et cliquez sur Classer



Hourra:



Vous avez créé votre première application iOS à l'aide de Core ML.



Encore:






All Articles