J'écrirai comment convertir Cycle GAN en Core ML.
Le contenu est fondamentalement le même que celui du prochain article, mais à partir du 1er novembre 2020, la conversion de modèle peut être effectuée avec Core ML Tools au lieu de tf-coreml, donc j'écrirai la différence dans cette partie.
Convertir Cycle GAN en modèle mobile (CoreML) https://qiita.com/john-rocky/items/3fbdb0892b639187c234
En conclusion, vous pouvez convertir chaque version de bibliothèque sans aucun problème en procédant comme suit.
tensorflow==2.2.0
keras==2.2.4
coremltools==4.0
J'écrirai la procédure dans Google Colaboratory.
** 1. Ouvrez le didacticiel TensorFlow **
Ouvrez le tutoriel à partir de cette page https://colab.research.google.com/github/tensorflow/docs/blob/master/site/en/tutorials/generative/cyclegan.ipynb
** 2. Faites correspondre chaque version de bibliothèque avec Core ML Tools 4.0 **
Désinstallez le tensorflow et les keras d'origine de Colab, puis réinstallez la version appropriée. Installez également Core ML Tools 4.0. Vous devrez peut-être redémarrer l'environnement d'exécution de Google Colab.
Notebook
!pip uninstall -y tensorflow
!pip uninstall -y keras
!pip install tensorflow==2.2.0
!pip install keras==2.2.4
!pip install -U coremltools==4.0
** 3. Effectuez l'apprentissage selon le tutoriel **
Vous pouvez apprendre Cycle GAN simplement en exécutant le didacticiel de haut en bas, alors continuez tel quel.
** 4. Enregistrez le modèle et convertissez-le en Core ML **
Enregistrez le modèle TensorFlow.
Notebook
generator_g.save('./savedmodel')
Convertissez en Core ML. Les arguments sont beaucoup plus simples que tf-coreml.
Notebook
import coremltools as ct
input_name = generator_g.inputs[0].name.split(':')[0]
print(input_name) #Check input_name.
keras_output_node_name = generator_g.outputs[0].name.split(':')[0]
graph_output_node_name = keras_output_node_name.split('/')[-1]
mlmodel = ct.converters.convert('./savedmodel/',
inputs=[ct.ImageType(bias=[-1,-1,-1], scale=2/255,shape=(1, 256, 256, 3,))],
output_names=[graph_output_node_name],
)
Enregistrez le modèle Core ML converti.
Notebook
mlmodel.save('./cyclegan.mlmodel')
** 5. Charger et afficher le modèle Core ML dans le projet Xcode **
Créez un projet dans Xcode.
Créez une application qui convertit les images de la caméra avec Cycle GAN.
Créez un écran simple avec un seul UIImageView et UIButton sur le Main.storyboard et connectez-le au contrôleur de vue. UIImage se connecte en tant que référence et UIButton se connecte en tant qu'action.
Cette fois, laissez le Vision Framework déduire, mais le résultat de l'inférence sera renvoyé en tant que type Multi Array. Vous devez le convertir en UIImage, mais c'est facile avec Core ML Helper. Pour cela, copiez le code source de CoreMLHelper.
En particulier
https: // github.com / hollance / CoreMLHelpers / tree / master / CoreMLHelpers
J'ai copié tout le code source ci-dessous dans mon projet.
Voici une référence pour savoir comment utiliser Core ML Helper.
Conversion de MultiArray vers Image CoreMLHelper https://qiita.com/john-rocky/items/bfa631aba3e7aabc2a66
J'écrirai le processus dans le contrôleur de vue. Je capture une image de caméra, je la transmets à Vision Framework, je la convertis en UIImage et je la colle dans une UIImageView.
Cette fois, j'ai interrompu le processus de transmission de l'image de la caméra à Vision Framework et d'extraction de l'IUImage du résultat de l'inférence dans une classe appelée CycleGanConverter
.
ViewController.swift
import UIKit
import Vision
class ViewController: UIViewController, UIImagePickerControllerDelegate & UINavigationControllerDelegate {
@IBOutlet weak var imageView: UIImageView!
//Convertisseur Cycle GAN
let converter = CycleGanConverter()
override func viewDidLoad() {
super.viewDidLoad()
}
@IBAction func tappedCamera(_ sender: Any) {
//Démarrez l'appareil photo lorsque vous appuyez sur le bouton de l'appareil photo
if UIImagePickerController.isSourceTypeAvailable(UIImagePickerController.SourceType.camera) {
let picker = UIImagePickerController()
picker.modalPresentationStyle = UIModalPresentationStyle.fullScreen
picker.delegate = self
picker.sourceType = UIImagePickerController.SourceType.camera
self.present(picker, animated: true, completion: nil)
}
}
func imagePickerController(_ picker: UIImagePickerController, didFinishPickingMediaWithInfo info: [UIImagePickerController.InfoKey : Any]) {
defer {
picker.dismiss(animated: true, completion: nil)
}
guard let image = info[UIImagePickerController.InfoKey(rawValue: UIImagePickerController.InfoKey.originalImage.rawValue)] as? UIImage else {return}
//L'image prise par la caméra est entrée dans l'image variable
//Conversion à la taille d'image à transmettre à Cycle GAN(Utiliser l'extension d'assistance CoreML)
let resized = image.resized(to: CGSize(width: 256, height: 256))
//Converti car il doit être passé en tant que type cgImage
guard let cgImage = resized.cgImage else {return}
//Passer au convertisseur
converter.convert(image: cgImage) {
images in
//Le convertisseur renvoie le résultat dans le tableau d'images si la conversion réussit
guard images.count > 0 else {return}
let image = images.first!
DispatchQueue.main.async {
//Coller dans UIImageView
self.imageView.image = image
}
}
}
}
class CycleGanConverter {
func convert(image: CGImage, completion: @escaping (_ images: [UIImage]) -> Void) {
//Configurer le cadre de vision
let handler = VNImageRequestHandler(cgImage: image,options: [:])
let model = try! VNCoreMLModel(for: cyclegan().model)
let request = VNCoreMLRequest(model: model, completionHandler: {
[weak self](request: VNRequest, error: Error?) in
//Puisque le résultat de l'inférence est renvoyé à la demande de variable, convertissez-le avec la méthode perseImage.
guard let images = self?.parseImage(request: request) else {return}
completion(images)
})
try? handler.perform([request])
}
func parseImage(request: VNRequest) -> [UIImage] {
guard let results = request.results as? [VNCoreMLFeatureValueObservation] else {return []}
//featureValue de chaque élément dans le tableau de résultats.Étant donné que l'image convertie est incluse dans multiArrayValue, convertissez-la en UIImage
return results.compactMap {
$0.featureValue.multiArrayValue?
.image(min: -1, max: 1, channel: nil, axes: (3,2,1))? //Une méthode de Core ML Helper qui se convertit en UIImage
.rotated(by: 90) //Faire pivoter pour afficher l'écran
.withHorizontallyFlippedOrientation() //Inverser pour l'affichage à l'écran
}
}
}
<Après la conversion>
Cette fois, en raison de contraintes de temps, le nombre de formations a été considérablement réduit par rapport à celui spécifié dans le tutoriel, les résultats de conversion sont donc raisonnables.
Si vous vous entraînez conformément au didacticiel, vous devriez obtenir de meilleurs résultats de conversion.
Note publie régulièrement sur le développement iOS, alors suivez-nous. https://note.com/tokyoyoshida
Il est également publié sur Twitter. https://twitter.com/jugemjugemjugem
Recommended Posts