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
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.
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