Implementando o aprendizado de máquina em um dispositivo iOS usando Core ML, Swift e Neural Engine

Hello habr! Antecipando o início do curso avançado "Desenvolvedor iOS" , tradicionalmente preparamos uma tradução de material útil para você.










Introdução



Core ML é uma biblioteca de aprendizado de máquina lançada pela Apple na WWDC 2017.



Ela permite que os desenvolvedores de iOS adicionem experiências personalizadas em tempo real a seus aplicativos usando modelos de aprendizado de máquina locais avançados usando o mecanismo neural.



Revisão do Chip Bionic A11





Preenchimento de cavacos biônicos A11

Contagem de transistores: 4,3 bilhões de

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

GPUs de baixa potência : 3

mecanismo neural - 600 operações básicas por segundo


Em 12 de setembro de 2017, a Apple apresentou ao mundo o chip A11 Bionic com Neural Engine. Este hardware de rede neural pode realizar até 600 operações básicas por segundo (BOPS) e é usado para FaceID, Animoji e outras tarefas de aprendizado de máquina. Os desenvolvedores podem usar o Neural Engine usando a API Core ML.



O Core ML otimiza o desempenho no dispositivo, utilizando recursos de CPU, GPU e Neural Engine, minimizando o consumo de memória e energia.



Executar o modelo localmente no dispositivo do usuário elimina a necessidade de uma conexão de rede, o que ajuda a manter a privacidade dos dados do usuário e melhora a capacidade de resposta do seu aplicativo.


Core ML é a base para estruturas e funcionalidades deste domínio. O Core ML é compatível com Visão para análise de imagem, Linguagem Natural para processamento de texto, Fala para som para texto e Análise de Som para identificar sons em áudio.





API Core ML

Podemos automatizar facilmente a tarefa de construir modelos de aprendizado de máquina, o que inclui treinar e testar o modelo usando o Playground e integrar o arquivo de modelo resultante em nosso projeto iOS.



Dica para novatos : destaque rótulos separados para tarefas de classificação.






Diagrama de blocos geral do Core ML



OK. O que vamos criar?



Neste tutorial, mostrarei como construir um modelo de classificador de imagem usando Core ML, que pode classificar imagens laranja e morango, e adicionar esse modelo ao nosso aplicativo iOS.





Modelo classificador de imagem.



Dica para novatos : a classificação de imagens se refere a problemas de aprendizagem supervisionada em que usamos dados rotulados (em nosso caso, o rótulo é o nome da imagem).








Mínimo exigido:



  • Conhecimento da linguagem Swift
  • IOS Development Basics
  • Compreendendo os conceitos de programação orientada a objetos




Programas de aplicação:



  • Código X 10 ou posterior
  • iOS SDK 11.0+
  • macOS 10.13+




Coleção de dados







Ao coletar dados para classificação de imagens, siga as orientações da Apple.



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




Depois de coletar seu conjunto de dados, divida-o em conjuntos de treinamento e teste e coloque-os nas pastas apropriadas.







NOTA IMPORTANTE: Certifique-se de distribuir as imagens para as pastas apropriadas dentro da pasta de teste. Porque o nome da pasta serve como um rótulo para nossas imagens.






No nosso caso, temos duas pastas, cada uma contendo as imagens correspondentes.



Criação de modelo







Não entrar em pânico! A Apple tornou isso muito mais fácil automatizando os marcos.



Com o Core ML, você pode usar um modelo já treinado para classificar os dados de entrada ou criar o seu próprio. O framework Vision já está trabalhando com o Core ML para aplicar modelos de classificação a imagens e pré-processar essas imagens, e para tornar as tarefas de aprendizado de máquina mais simples e robustas.



Basta seguir estas etapas.



PASSO 1 : Abra seu código X.

PASSO 2 : Crie um Swift Playground limpo.

ETAPA 3 : Remova o código gerado padrão, adicione o seguinte programa e execute playground.



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




Descrição:

aqui abrimos a interface do construtor de modelo padrão fornecido pelo Xcode.



PASSO 4 : Arraste a pasta de amostra de treinamento para a área de treinamento.



Coloque a pasta de amostra de treinamento na área de treinamento indicada pelas linhas pontilhadas.



Dica para novatos : também podemos fornecer um nome arbitrário para nosso modelo clicando na seta para baixo na área do tutorial.




Etapa 5 : o Xcode irá processar automaticamente a imagem e iniciar o processo de aprendizagem. Por padrão, são necessárias 10 iterações para treinar um modelo, dependendo das características do seu Mac e do tamanho do conjunto de dados. Você pode observar o progresso do treinamento na janela do terminal Playground.





Estou esperando enquanto a modelo está sendo treinada.



PASSO 6 : Após terminar o treinamento, você pode testar seu modelo arrastando e soltando a pasta Test na área de teste. O Xcode testará automaticamente seu modelo e exibirá o resultado.





Como você pode ver, nosso modelo classificou as imagens com precisão.



PASSO 7 : Salve seu modelo.









Integração com o aplicativo iOS:



PASSO 1 : Abra seu código-X.

ETAPA 2 : Crie um aplicativo iOS de página única.

PASSO 3 : Abra o navegador do projeto.

PASSO 4 : Arraste o modelo treinado para o navegador do projeto.





Coloque seu modelo no navegador do projeto.



PASSO 5: Abra Main.storyboarde crie uma interface simples como mostrado abaixo, adicione IBOutlets e IBActions para as respectivas visualizações.





Adicione UIImageView, UIButtons e UILabels.



PASSO 6 : Abra o arquivo ViewController.swifte adicione o seguinte código como uma extensão.



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




Descrição: aqui criamos uma extensão para nossa classe ViewController e implementamos UINavigationControllerDelegate e UIImagePickerControllerDelegate para exibir o UIImagePickerView quando o usuário clica no UIButton PickImage. Certifique-se de definir o contexto do delegado.







Etapas relacionadas ao acesso ao modelo Core ML em um aplicativo iOS







PASSO 1 : Certifique-se de ter importado as seguintes bibliotecas.



import CoreML 
 import Vision




PASSO 2 : Crie uma instância de nossa classe Model Core ML.



let modelobj = ImageClassifier()




PASSO 3 : Para forçar o Core ML a fazer a classificação, devemos primeiro fazer uma solicitação do tipo VNCoreMLRequest (VN significa Vision)



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




PASSO 4: certifique-se de cortar a imagem para que seja compatível com o modelo Core ML. ETAPA 5: coloque o código acima em uma função personalizada que retorna um objeto de solicitação.



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




PASSO 6 : Agora precisamos converter nosso UIImage em CIImage (CI: CoreImage) para que ele possa ser usado como entrada para nosso modelo Core ML. Isso pode ser feito facilmente instanciando CIImage passando UIImage no construtor.



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




PASSO 7 : Agora podemos processar o nosso VNCoreMLRequestcriando um manipulador de solicitação e passando ciImage.



let handler = VNImageRequestHandler(ciImage: ciImage)




PASSO 8 : A solicitação pode ser atendida chamando o método perform()e passando-o como um 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")  
       }  
   } 




Descrição : DispatchQueue é um objeto que gerencia a execução de tarefas sequencialmente (ou simultaneamente) no thread principal (ou em segundo plano) de seu aplicativo.



PASSO 10 : Coloque o código acima em uma função personalizada, conforme mostrado abaixo.



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




PASSO 11 : Crie uma função personalizada nomeada handleResult()que tenha VNRequestum objeto de erro e um objeto de erro como parâmetros. Esta função será chamada após a conclusão 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 : Isso é DispatchQueue.main.asyncusado para atualizar objetos UIKit (em nosso caso, é UILabel) usando o UI Thread ou Main Thread, uma vez que todas as tarefas de classificação são realizadas no thread de segundo plano.








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




Tudo está pronto!







Agora inicie seu Simulador e teste seu aplicativo.



Nota : Certifique-se de ter uma foto de laranjas e morangos na biblioteca de fotos do Simulador.






Clique no botão Escolher Imagem





Selecione qualquer imagem





Clique no botão Classificar





Selecione outra imagem e clique em Classificar



Hooray:



Você criou seu primeiro aplicativo iOS usando Core ML.



Ainda:



  • Neomorfismo com SwiftUI. Parte 1
  • Neomorfismo com SwiftUI. Parte 2: O que pode ser feito com acessibilidade?
  • Criação de um aplicativo multi-plataforma Kotlin multi-thread



All Articles