[SWIFT] [Core ML] Comment convertir YOLO v3 en Core ML

J'ai essayé de convertir YOLO v3 en CoreML, donc j'écrirai la procédure.

YOLO v3 est un algorithme qui détecte les objets. Le moyen le plus simple de faire fonctionner YOLO sur iOS est de télécharger et d'utiliser Apple Official Core ML Models. Cependant, cette fois, j'ai essayé de le convertir manuellement.

Original YOLO v3 est construit sur Darknet, mais cette fois j'utiliserai celui converti en Keras ici.

qqwweee/keras-yolo3 https://github.com/qqwweee/keras-yolo3

procédure

Voici les étapes pour Google Colaboratory.

** 1. Installez et importez les bibliothèques requises **

Notebook


!pip install tensorflow-gpu==1.14.0
!pip install -U coremltools
!pip install keras==2.2.4

** 2. Cloner keras-yolo3 **

Tout d'abord, supprimez-le du référentiel.

Notebook


!git clone https://github.com/qqwweee/keras-yolo3

** 3. Essayez d'exécuter keras-yolo3 **

Tout d'abord, exécutons keras-yolo3 tel qu'il est en Python. Cette zone est la même que la procédure décrite dans README.md sur github.

Tout d'abord, téléchargez le fichier d'informations sur le poids.

Notebook


%cd keras-yolo3
#!wget https://pjreddie.com/media/files/yolov3.weights

Convertir en version keras du modèle yolo.

Notebook


!python convert.py yolov3.cfg yolov3.weights model_data/yolo.h5

Je téléchargerai une image appropriée et la laisserai être déduite. Cette fois, j'ai téléchargé un fichier appelé neco.jpg.

! python yolo_video.py --image --input neco.jpg

#Résultat de sortie
# (416, 416, 3)
# Found 2 boxes for img
# bed 0.66 (11, 481) (656, 660)
# cat 1.00 (98, 17) (624, 637)
# 6.3229040969999915

Il semble que le chat puisse être détecté correctement.

** 4. Convertir en CoreML **

Convertissez à l'aide des outils Core ML. L'image d'entrée est 416 (largeur) x416 (hauteur) x3 (RVB). Définissez également image_scale sur 1 / 255.0 pour la normalisation.

Notebook


from keras.models import load_model
from coremltools.converters import keras as converter
mlmodel = converter.convert(keras_model,
  output_names=['grid1','grid2','grid3'], 
  input_name_shape_dict = {'input1' : [None, 416, 416, 3]},
  image_input_names='input1', 
  image_scale=1/255.0,
)

#production
# 0 : input_1, <keras.engine.input_layer.InputLayer object at 0x7f7e4058fa58>
# 1 : conv2d_1, <keras.layers.convolutional.Conv2D object at 0x7f7e41cffb38>
# 2 : batch_normalization_1, <keras.layers.normalization.BatchNormalization object at 0x7f7e41cc6438>
#~ Abréviation ~
# For large sized arrays, multiarrays of type float32 are more efficient.
# In future, float input/output multiarrays will be produced by default by the converter.
# Please use, either the flag 'use_float_arraytype' during the call to convert or
# the utility 'coremltools.utils.convert_double_to_float_multiarray_type(spec)', post-conversion.

Enregistrez le modèle Core ML converti.

Notebook


coreml_model_path = 'yolo.mlmodel'
mlmodel.save(coreml_model_path)

** 5. Vérifiez l'affichage du résultat de l'inférence **

La conversion vers CoreML a fonctionné, mais lorsque je l'ai copiée dans mon projet Xcode et que j'ai essayé de l'inférer avec Vision Framework, elle a échoué.

En effet, YOLOv3 a trois sorties, 1x1x255x13x13, 1x1x255x26x26, 1x1x255x52x52, mais il ne peut pas être interprété par Vision Framework tel quel. Vous devez décoder la sortie.

Ce blog était facile à comprendre sur la sortie de YOLO v3. Structure du modèle de reconnaissance générale d'objets YOLO v3

Le décodage semble être difficile si vous le faites vous-même, donc cette fois je vais utiliser ce projet.

Ma-Dan/YOLOv3-CoreML https://github.com/Ma-Dan/YOLOv3-CoreML

Ce projet suppose que la sortie CoreML sera 255x13x13, 255x26x26, 255x52x52. Vous devez remodeler la sortie en cette forme.

** 6. Remodeler la sortie **

Modifiez la sortie du modèle comme suit:

1x1x255x13x13 → 255x13x13 1x1x255x26x26 → 255x13x26 1x1x255x52x52 → 255x13x52

Pour ce faire, vous devez ajouter un calque à remodeler avec Core ML Tools. Vous pouvez en savoir plus sur la façon de modifier les couches de votre modèle Core ML avec Core ML Tools ici.

Comment modifier un calque avec Core ML Tools https://qiita.com/TokyoYoshida/items/7aa67dcea059a767b4f2

C'est une couche à remodeler, mais au début cela réduit la dimension [car il y a add_squeeze](https://apple.github.io/coremltools/generated/coremltools.models.neural_network.builder.html#coremltools.models.neural_network J'ai essayé (.builder.NeuralNetworkBuilder.add_squeeze) mais pour une raison quelconque, cela n'a pas fonctionné.

Il y avait aussi add_reshape. Ensuite, la dimension de la première partie 1x1 n'a pas été réduite.

À la suite de diverses enquêtes, il existe add_reshape_static. J'ai pu bien le remodeler en utilisant cela.

Ajoutez-le comme suit.

Notebook


from coremltools.models.neural_network import datatypes

builder.add_reshape_static(name='Reshape1', input_name='grid1', output_name='output1', output_shape=(255,13,13))
builder.add_reshape_static(name='Reshape2', input_name='grid2', output_name='output2', output_shape=(255,26,26))
builder.add_reshape_static(name='Reshape3', input_name='grid3', output_name='output3', output_shape=(255,52,52))

Spécifiez ensuite la forme de la sortie pour l'ensemble du modèle.

Notebook


builder.spec.description.output[0].name = "output1"
builder.spec.description.output[0].type.multiArrayType.shape[0] = 255
builder.spec.description.output[0].type.multiArrayType.shape.append(13)
builder.spec.description.output[0].type.multiArrayType.shape.append(13)

builder.spec.description.output[1].name = "output2"
builder.spec.description.output[1].type.multiArrayType.shape[0] = 255
builder.spec.description.output[1].type.multiArrayType.shape.append(26)
builder.spec.description.output[1].type.multiArrayType.shape.append(26)

builder.spec.description.output[2].name = "output3"
builder.spec.description.output[2].type.multiArrayType.shape[0] = 255
builder.spec.description.output[2].type.multiArrayType.shape.append(52)
builder.spec.description.output[2].type.multiArrayType.shape.append(52)

Enfin, enregistrez le modèle.

Notebook


mlmodel_modified = coremltools.models.MLModel(spec)
mlmodel_modified.save('Yolov3.mlmodel')

** 7. Affichage sur l'application **

Tout ce que vous avez à faire maintenant est de glisser-déposer le modèle Core ML dans le projet YOLO v3-Core ML et de l'exécuter.

Si vous essayez d'afficher le modèle à partir de Xcode, vous pouvez voir qu'il est correctement reconnu.

C'est le résultat de l'exécution.

Vous pouvez le reconnaître correctement.

finalement

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

[Core ML] Comment convertir YOLO v3 en Core ML
Comment modifier un calque avec Core ML Tools
Comment convertir la base Java
Convertir la carte <K, V1> en carte <K, V2> (Convertir la valeur de la carte)
Comment convertir un fichier erb en haml
Comment convertir LocalDate et Timestamp
[Core ML] Convertissez Cycle GAN en Core ML et exécutez-le sur iOS
Comment convertir java.util.Date, java.sql.Date, LocalDate, ZonedDateTime
[Ruby] Comment convertir un fichier CSV en Yaml (Yml)
[Android] Comment convertir une chaîne de caractères en resourceId
Comment installer Titan 2D (v4.2.0) dans un environnement virtuel
Comment convertir un contrat de solidité en une classe de contrat Java
Ruby Comment convertir entre les majuscules et les minuscules
[Rails] Comment convertir l'affichage de l'heure UC en affichage de l'heure japonais
Comment convertir A en A et A en A en utilisant le produit logique et la somme en Java
Comment convertir un fichier en tableau d'octets en Java
Comment écrire un mod de base dans Minecraft Forge 1.15.2
Comment développer OpenSPIFe
Comment appeler AmazonSQSAsync
Comment utiliser Map
Comment écrire des rails
Comment utiliser rbenv
Comment utiliser with_option
Comment utiliser fields_for
Comment utiliser la carte
Comment utiliser collection_select
Comment utiliser Twitter4J
Comment utiliser active_hash! !!
Comment installer Docker
Comment utiliser MapStruct
Comment utiliser TreeSet
Comment désinstaller Rails
Comment installer docker-machine
[Comment utiliser l'étiquette]
Comment faire un pot ombré
Comment écrire docker-compose
Comment utiliser l'identité
Comment utiliser le hachage
Comment écrire Mockito
Comment créer docker-compose
Comment installer MySQL
Comment écrire un fichier de migration
Comment construire android-midi-lib
Comment utiliser Dozer.mapper
Comment utiliser Gradle
Comment utiliser org.immutables
Comment utiliser java.util.stream.Collector
Comment utiliser VisualVM
Comment utiliser Map
Comment repousser la barre oblique \
Comment concaténer des chaînes
Réfléchissez à la façon de diviser MVC en M et V