Implementación del aprendizaje automático en un dispositivo iOS con Core ML, Swift y Neural Engine

¡Hola habr! Anticipándonos al inicio del curso avanzado "Desarrollador iOS" , tradicionalmente hemos preparado una traducción de material útil para usted.










Introducción



Core ML es una biblioteca de aprendizaje automático lanzada por Apple en WWDC 2017.



Permite a los desarrolladores de iOS agregar experiencias personalizadas en tiempo real a sus aplicaciones utilizando modelos avanzados de aprendizaje automático local utilizando Neural Engine.



Revisión del chip biónico A11





Llenado de chips biónicos A11

Transistores: 4,3 mil millones de

núcleos: 6 núcleos ARM (64 bits) - 2 de alta frecuencia (2,4 GHz) - 4

GPU de baja potencia : 3

Neural Engine - 600 operaciones base por segundo


El 12 de septiembre de 2017, Apple presentó al mundo el chip A11 Bionic con Neural Engine. Este hardware de red neuronal puede realizar hasta 600 operaciones básicas por segundo (BOPS) y se utiliza para FaceID, Animoji y otras tareas de aprendizaje automático. Los desarrolladores pueden usar Neural Engine mediante la API Core ML.



Core ML optimiza el rendimiento en el dispositivo mediante el uso de recursos de CPU, GPU y Neural Engine, minimizando la memoria y el consumo de energía.



La ejecución del modelo localmente en el dispositivo del usuario elimina la necesidad de una conexión de red, lo que ayuda a mantener la privacidad de los datos del usuario y mejora la capacidad de respuesta de su aplicación.


Core ML es la base de los marcos y la funcionalidad de este dominio. Core ML admite Vision para el análisis de imágenes, Natural Language para el procesamiento de textos, Speech para la conversión de sonido a texto y Sound Analysis para identificar sonidos en audio.





API Core ML

Podemos automatizar fácilmente la tarea de crear modelos de aprendizaje automático, lo que incluye entrenar y probar el modelo utilizando Playground e integrar el archivo de modelo resultante en nuestro proyecto iOS.



Consejo para principiantes: resalte etiquetas separadas para tareas de clasificación.






Diagrama de bloques general de Core ML



Bueno. ¿Qué vamos a crear?



En este tutorial, le mostraré cómo construir un modelo de clasificador de imágenes usando Core ML, que puede clasificar imágenes de Orange y Strawberry, y agregar este modelo a nuestra aplicación iOS.





Modelo de clasificador de imágenes.



Consejo para principiantes : la clasificación de imágenes se refiere a problemas de aprendizaje supervisados ​​en los que usamos datos etiquetados (en nuestro caso, la etiqueta es el nombre de la imagen).








Mínimo requerido:



  • Conocimiento del lenguaje Swift
  • Conceptos básicos de desarrollo de iOS
  • Comprensión de los conceptos de programación orientada a objetos




Programas de aplicación:



  • X-code 10 o posterior
  • iOS SDK 11.0+
  • macOS 10.13+




Recopilación de datos







Al recopilar datos para la clasificación de imágenes, siga las pautas de Apple.



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




Una vez que haya recopilado su conjunto de datos, divídalo en conjuntos de entrenamiento y prueba y colóquelos en las carpetas correspondientes.







NOTA IMPORTANTE: asegúrese de distribuir las imágenes en las carpetas correspondientes dentro de la carpeta de prueba. Porque el nombre de la carpeta sirve como etiqueta para nuestras imágenes.






En nuestro caso, tenemos dos carpetas, cada una de las cuales contiene las imágenes correspondientes.



Creación de modelos







¡No entre en pánico! Apple lo ha facilitado mucho al automatizar los hitos.



Con Core ML, puede usar un modelo ya entrenado para clasificar los datos de entrada o crear el suyo propio. El marco de Vision ya está trabajando con Core ML para aplicar modelos de clasificación a imágenes y preprocesar esas imágenes, y para hacer que las tareas de aprendizaje automático sean más simples y más sólidas.



Solo sigue estos pasos.



PASO 1 : Abra su código X.

PASO 2 : Crea un Swift Playground limpio.

PASO 3 : Elimine el código generado por defecto, agregue el siguiente programa y ejecútelo playground.



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




Descripción:

Aquí abrimos la interfaz del constructor de modelos por defecto proporcionado por Xcode.



PASO 4 : Arrastre la carpeta de muestra de formación al área de formación.



Coloque la carpeta de muestra de formación en el área de formación indicada por las líneas de puntos.



Consejo para principiantes : también podemos proporcionar un nombre arbitrario para nuestro modelo haciendo clic en la flecha hacia abajo en el área del tutorial.




Paso 5 : Xcode procesará automáticamente la imagen e iniciará el proceso de aprendizaje. De forma predeterminada, se necesitan 10 iteraciones para entrenar un modelo, según las características de su Mac y el tamaño del conjunto de datos. Puede ver el progreso del entrenamiento en la ventana de la terminal Playground.





Estoy esperando mientras se entrena al modelo.



PASO 6 : Después de terminar el entrenamiento, puede probar su modelo arrastrando y soltando la carpeta Prueba en el área de prueba. Xcode probará automáticamente su modelo y mostrará el resultado.





Como puede ver, nuestro modelo ha clasificado con precisión las imágenes.



PASO 7 : Guarde su modelo.









Integración en la aplicación de iOS:



PASO 1 : Abra su código X.

PASO 2 : Cree una aplicación iOS de una sola página.

PASO 3 : Abra el navegador de proyectos.

PASO 4 : Arrastre el modelo entrenado al navegador de proyectos.





Coloque su modelo en el navegador de proyectos.



PASO 5: Abra Main.storyboardy cree una interfaz simple como se muestra a continuación, agregue IBOutlets e IBActions para las respectivas vistas.





Agregue UIImageView, UIButtons y UILabels.



PASO 6 : Abra el archivo ViewController.swifty agregue el siguiente código como extensión.



  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)  
//     ,     
 
       } 
 
   } 




Descripción: Aquí creamos una extensión para nuestra clase ViewController e implementamos UINavigationControllerDelegate y UIImagePickerControllerDelegate para mostrar UIImagePickerView cuando el usuario hace clic en PickImage UIButton. Asegúrese de establecer el contexto del delegado.







Pasos relacionados con el acceso al modelo Core ML en una aplicación iOS







PASO 1 : Asegúrese de haber importado las siguientes bibliotecas.



import CoreML 
 import Vision




PASO 2 : Cree una instancia de nuestra clase Model Core ML.



let modelobj = ImageClassifier()




PASO 3 : Para obligar a Core ML a hacer la clasificación, primero debemos realizar una solicitud como VNCoreMLRequest (VN significa Vision)



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




PASO 4: Asegúrese de recortar la imagen para que sea compatible con el modelo Core ML. PASO 5: Coloque el código anterior en una función personalizada que devuelva un objeto de solicitud.



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! 
    } 




PASO 6 : Ahora necesitamos convertir nuestro UIImage a CIImage (CI: CoreImage) para que pueda usarse como entrada para nuestro modelo Core ML. Esto se puede hacer fácilmente creando una instancia de CIImage pasando UIImage en el constructor.



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




PASO 7 : Ahora podemos procesar el nuestro VNCoreMLRequestcreando un controlador de solicitudes y pasando ciImage.



let handler = VNImageRequestHandler(ciImage: ciImage)




PASO 8 : La solicitud se puede cumplir llamando al método perform()y pasándolo como parámetro VNCoreMLRequest.



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




Descripción : DispatchQueue es un objeto que gestiona la ejecución de tareas de forma secuencial (o simultánea) en el hilo principal (o en segundo plano) de su aplicación.



PASO 10 : Coloque el código anterior en una función personalizada como se muestra a continuación.



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") 
                } 
            } 




PASO 11 : Cree una función personalizada con nombre handleResult()que tome VNRequestun objeto de error y un objeto de error como parámetros. Esta función se llamará al finalizar 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") 
        } 
    }  




Nota : Esto se DispatchQueue.main.asyncusa para actualizar objetos UIKit (en nuestro caso es UILabel) usando el UI Thread o Main Thread, ya que todas las tareas de clasificación se realizan en el hilo de fondo.








Listado 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) 
        } 
    }




¡Todo está listo!







Ahora inicie su Simulador y pruebe la aplicación.



Nota : asegúrese de tener una foto de naranjas y fresas en la biblioteca de fotos de su Simulador.






Haga clic en el botón





Seleccionar imagen Seleccione cualquier imagen





Haga clic en el botón Clasificar





Seleccione otra imagen y haga clic en Clasificar



¡Hurra!



Ha creado su primera aplicación para iOS con Core ML.



Todavía:






All Articles