Pular para o conteúdo principal

Utilizando CoreML para adicionar aprendizagem de máquina e visão computacional no seu aplicativo iOS


Robô olhando para o alto.

Existem algumas tecnologias que surgem e são esquecidas. Outras, surgem e viram moda. Inteligência artificial é um exemplo de tecnologia que está em alta no momento.Dentro da área da inteligência artificial, temos o aprendizado de máquina, que compreende a parte de utilizar técnicas estatísticas para dar a habilidade aos computadores de melhorar sua performance em uma tarefa definida. A Apple não poderia deixar passar este momento e vamos ver como colocar um modelo de aprendizado de máquina em um aplicativo iOS. Falei um monte de palavras difíceis, alguns casos de uso devem simplificar nosso entendimento:
  • Utilizar a camera do seu iPhone para descobrir qual o nome daquela planta que você viu na praça do seu bairro.
  • Utilizar o teclado do seu iPhone para te ajudar a escrever mais rapidamente, recebendo sugestões de próximas palavras de acordo com o que você acabou de escrever.
  • Separar as fotos e vídeos daquela ultima viagem para o litoral e criar montagens a partir dos mesmos.
Fazer isso tudo funcionar é mais simples do que parece. Para tanto, a Apple criou os Modelos de aprendizagem de máquina CoreML, no formato de arquivos .mlmodel. Quando acionados, eles conseguem por exemplo tentar identificar a partir de uma foto de uma fruta se aquela fruta é uma maçã ou uma laranja. Essa é a essência dos modelos. Você vai passar uma ou mais informações para eles e após o processamento, vão te retornar uma ou mais informações. Para efeitos práticos vamos criar um projeto capaz de classificar objetos usando a câmera do telefone, mas as possibilidades são infinitas.

TuriCreate:

Vamos começar, codificando em python. Para o nosso projeto, devemos definir quais objetos queremos que nosso app saiba classificar e pegar um monte de imagens deles. No exemplo, estou detectando celulares, comida, copos, canecas, paisagens, entre outros. A Apple disponibilizou uma biblioteca chamada turicreate que permite a conversão de modelos já existentes de outras plataformas (como tensor flow, do google) para coreML ou a criação dos mesmos. Para o nosso caso, criei o código disponível neste link, que analisa uma série de imagens dentro de pastas nomeadas e gera um modelo que aprende a classificar um objeto novo comparando com o que ele já sabe. Não vou entrar muito em detalhes sobre este processo pois o foco aqui será o aplicativo. Se quiser executar este script ou outro editado com a mesma finalidade, é recomendada a utilização de uma máquina com bastante memória RAM, pois o processo demora um pouco.

Vamos ao app:

Primeiro, crie um projeto novo no Xcode do tipo single view application. Logo após, adicione o arquivo imageClassifier.mlmodel encontrado neste repositório:https://github.com/eduardolomb/ClassificadorML dentro do projeto. Ao clicar nele nos deparamos com esta tela:


Detalhes do modelo CoreML .mlmodel que adicionamos no projeto.

Perceba que em Model Evaluation Parameters temos a definição do modelo: ele recebe uma imagem colorida de resolução 224 x 224 e retorna um dicionário com as probabilidades de previsão e um texto com a previsão de maior probabilidade de acerto.
Nossa interface, será bem simples. Teremos uma UiView para adicionar a imagem da câmera e umUiLabel.




Exemplo de Interface do aplicativo.

Faça a ligação de todos os IBoutlets para a sua ViewController e também realize a conexão entre essa viewController e sua classe. Já no código, precisamos importar os frameworks CoreML e o Vision. Logo após devemos implementar o AVCaptureVideoDataOutputSampleBufferDelegate para capturar imagens da câmera como abaixo:
//MARK: - Camera capture delegatesprivate lazy var captureSession: AVCaptureSession = {
let session = AVCaptureSession()session.sessionPreset = AVCaptureSession.Preset.hd1920x1080
guard let backCamera = AVCaptureDevice.default(.builtInWideAngleCamera, for: .video, position: .back),let input = try? AVCaptureDeviceInput(device: backCamera) else { return session }session.addInput(input)
return session}()
Devemos também implementar o método do vision abaixo. Esse método vai transferindo uma sequencia de imagens para o nosso modelo que fará o reconhecimento de cada uma delas.
func captureOutput(_ output: AVCaptureOutput, didOutput sampleBuffer: CMSampleBuffer, from connection: AVCaptureConnection) {
guard let pixelBuffer = CMSampleBufferGetImageBuffer(sampleBuffer) else {
return
}var requestOptions:[VNImageOption : Any] = [:]if let cameraIntrinsicData = CMGetAttachment(sampleBuffer, kCMSampleBufferAttachmentKey_CameraIntrinsicMatrix, nil) {
requestOptions = [.cameraIntrinsics:cameraIntrinsicData]
}guard let value = CGImagePropertyOrientation(rawValue: 1) else {
return
}let imageRequestHandler = VNImageRequestHandler(cvPixelBuffer: pixelBuffer, orientation:value , options: requestOptions)
do {
try imageRequestHandler.perform(self.requests)
} catch {
print(error)
}
}
Temos que implementar também um método que deverá ser chamado em algum delegate da ViewController para poder carregar o modelo no código. Estamos trabalhando com VNCoreMLModels, ou seja modelos de aprendizagem de máquina voltados para visão computacional. Para modelos que não utilizem uma imagem como entrada podemos criar um MLModel
func setupVision() {
guard let visionModel = try? VNCoreMLModel(for: imageClassifier().model) else {
fatalError("Can't load VisionML model")
}let classificationRequest = VNCoreMLRequest(model: visionModel, completionHandler: handleClassifications)classificationRequest.imageCropAndScaleOption = VNImageCropAndScaleOption.centerCropself.requests = [classificationRequest]
}
O método abaixo deve ser implementado para colher os resultados da saída do modelo VNCoreMLModel e exibir na tela:
func handleClassifications(request: VNRequest, error: Error?) {guard let observations = request.resultselse { print("no results: \(error!)"); return }print(observations)
let classifications = observations[0...4]
.flatMap({ $0 as? VNClassificationObservation })
.filter({ $0.confidence > 0.3 })
.sorted(by: { $0.confidence > $1.confidence })
.map {(prediction: VNClassificationObservation) -> String in
return "\(round(prediction.confidence * 100 * 100)/100)%: \(prediction.identifier)"
}DispatchQueue.main.async {
print(classifications.joined(separator: "###"))
self.uiRecognitionLabel?.text = classifications.joined(separator: "\n")
}
}
Mas aí você deve estar se perguntando…esse modelo pode classificar algo errado? O que acontece nesse caso? Nada. Esses modelos .coreml implementados nos apps são modelos estáticos e seria muito custoso (processamento, bateria) para o aplicativo retreinar o modelo durante seu uso. Mas temos uma forma de contornar esse problema. Podemos colher novas amostras a partir do aplicativo, enviar para um backend e permitir que o backend gere um modelo re-treinado utilizando as novas amostras. Esse modelo então pode ser baixado no celular e recompilado em tempo de execução no aplicativo. Só devemos tomar cuidado porque os modelos gerados geralmente são grandes e pode ser custoso para o usuário baixar um modelo grande na internet movel.

Extras

Comentários

Postagens mais visitadas deste blog

WWDC for First Timers

Pessoa realizando apresentação As you may already have guessed, I've been to WWDC19. There was a ton of releases which in fact did blew minds. (🤯). For the ones who don't know, it is an Apple event which lasts 5 days. If you want to try next year, you should submit your apple ID for the lottery when available. Registry I do recommend getting your badge for it on sunday as if you try to get it on monday you may lose part of the keynote. You don't need to rush for the registry line. It flows particularly well. It is also a great time to meet people, know who are you facing in the subsequent week. Keynote T here are 3 main events in the first day. The first one is the keynote. That's where all the secrets, launches, releases, new products are announced. Information is starting to enter your brain. The second one is the state of the union. This is where all keynote information is detailed for the developers, your brain starts to make a lot of questions on the ...

Desenvolvendo apps acessíveis

Homem digitando com máquina de libras D esenvolver aplicativos para iPhone é algo não trivial, mas também não é um bicho de sete cabeças. Se você já sabe android + kotlin fica ainda mais fácil. O que muitos desenvolvedores esquecem é de contemplar toda uma gama de usuários para seu app. Alguns usuários de iPhone tem baixa visão ou não enxergam, outros tem deficiência auditiva e ainda tem aqueles com deficiência motora. A Apple se preocupa com todos estes usuários de modo que desenvolveu no iOS toda uma solução poderosa de acessibilidade. A configuração fica no aplicativo "configurações" dos aparelhos dentro da seção acessibilidade. A principal opção disponível lá é o voiceOver. Com ela ativa, o device vai passar a falar as opções selecionadas na tela, e o modelo de navegação muda para um que utilize gestos. Os gestos principais são: Toque simples  em qualquer lugar da tela e o VoiceOver vai falar informações sobre os atributos acessíveis do item em destaque. Swipe sim...