[PYTHON] Détection de logo à l'aide de l'API de détection d'objets TensorFlow

introduction

Activer la détection de logo à l'aide de l'API TensorFlow Object Detection annoncée en juillet 2017. Quand j'ai essayé la détection d'objet auparavant, j'ai utilisé les données formées préparées, mais cette fois je commencerai par créer des données d'enseignant Je vais.

procédure

  1. Création de données sur les enseignants
  2. Apprentissage
  3. Test de détection

Nous procéderons dans l'ordre de.

Logo à détecter

Cette fois, je ne détecterai qu'un seul type de logo giftee pour lequel je travaille. gifteelogo.png

Création de données enseignants

Collection d'images

Utilisez Google Image Search pour collecter des images avec des logos. Cette fois, j'ai collecté environ 40 images.

Sélection rectangulaire et étiquetage

L'API de détection d'objets TensorFlow détecte les objets dans l'image, donc Nous avons besoin de données pour apprendre le rectangle contenant l'objet et l'étiquette de l'objet. Cette fois, nous utiliserons labelImg pour créer les données.

labelImg Au début, j'ai essayé de l'exécuter sur mac, mais cela ne fonctionnait pas très bien même si j'essayais de suivre la procédure officielle, alors je l'ai exécuté sur Ubuntu. C'est assez anormal,

J'ai suivi la procédure.

X11 transfert de vagabond à Vagrantfile

Vagrant.configure(VAGRANTFILE_API_VERSION) do |config|
  ...
  config.ssh.forward_x11 = true
  ...
end

Ce sera valide si vous écrivez.

labelImg spécifie le répertoire stocké dans l'image, sélectionne les données du logo dans une forme rectangulaire, Je vais ajouter une étiquette.

labelImg_ss.png

Le fait de placer le nom de l'étiquette par défaut dans Utiliser l'étiquette par défaut facilitera votre travail.

Après avoir sélectionné le rectangle et défini l'étiquette, appuyez sur Enregistrer pour l'enregistrer en tant que données XML.

Conversion en TFRecord

Convertit les images et XML au format TFRecord pour que TensorFlow puisse lire les données. Cette fois, create_pet_tf_record.py dans Tutorial (/blob/master/object_detection/create_pet_tf_record.py) pour créer un script de conversion.

Le correctif principal est que le script d'origine était censé obtenir le nom de l'étiquette à partir du nom du fichier, mais maintenant il renvoie l'étiquette «giftee».

#class_name = get_class_name_from_filename(data['filename'])
class_name = 'giftee'

A part ça, je l'utilise avec presque aucune modification.

Créer labelmap.pbtxt

Puisqu'il n'y a qu'un seul type cette fois, je n'écrirai qu'un seul élément.

item {
  id: 1
  name: 'giftee'
}

Enregistrez-le sous giftee_label_map.pbtxt.

Exécuter le script de conversion

Exécutez le script de conversion.

La plupart des étapes à partir d'ici suivront le Tutoriel.

$ python object_detection/create_giftee_tf_record.py --label_map_path=object_detection/data/giftee_label_map.pbtxt --data_dir=`pwd` --output_dir=`pwd`

Les données d'apprentissage "giftee_train.record" et les données d'évaluation "giftee_val.record" sont créées dans la hiérarchie exécutée.

création de configuration

Créez une configuration pour définir les paramètres du modèle, le taux d'apprentissage pendant la formation, le chemin du fichier tfrecord, le chemin du texte d'étiquette, etc.

Cette fois, j'utiliserai celui du Tutoriel avec quelques modifications.

# Faster R-CNN with Resnet-101 (v1) configured for the Oxford-IIIT Pet Dataset.
# Users should configure the fine_tune_checkpoint field in the train config as
# well as the label_map_path and input_path fields in the train_input_reader and
# eval_input_reader. Search for "PATH_TO_BE_CONFIGURED" to find the fields that
# should be configured.

model {
  faster_rcnn {
    num_classes: 1 
    image_resizer {
      keep_aspect_ratio_resizer {
        min_dimension: 600
        max_dimension: 1024
      }
    }
    feature_extractor {
      type: 'faster_rcnn_resnet101'
      first_stage_features_stride: 16
    }
    first_stage_anchor_generator {
      grid_anchor_generator {
        scales: [0.25, 0.5, 1.0, 2.0]
        aspect_ratios: [0.5, 1.0, 2.0]
        height_stride: 16
        width_stride: 16
      }
    }
    first_stage_box_predictor_conv_hyperparams {
      op: CONV
      regularizer {
        l2_regularizer {
          weight: 0.0
        }
      }
      initializer {
        truncated_normal_initializer {
          stddev: 0.01
        }
      }
    }
    first_stage_nms_score_threshold: 0.0
    first_stage_nms_iou_threshold: 0.7
    first_stage_max_proposals: 300
    first_stage_localization_loss_weight: 2.0
    first_stage_objectness_loss_weight: 1.0
    initial_crop_size: 14
    maxpool_kernel_size: 2
    maxpool_stride: 2
    second_stage_box_predictor {
      mask_rcnn_box_predictor {
        use_dropout: false
        dropout_keep_probability: 1.0
        fc_hyperparams {
          op: FC
          regularizer {
            l2_regularizer {
              weight: 0.0
            }
          }
          initializer {
            variance_scaling_initializer {
              factor: 1.0
              uniform: true
              mode: FAN_AVG
            }
          }
        }
      }
    }
    second_stage_post_processing {
      batch_non_max_suppression {
        score_threshold: 0.0
        iou_threshold: 0.6
        max_detections_per_class: 100
        max_total_detections: 300
      }
      score_converter: SOFTMAX
    }
    second_stage_localization_loss_weight: 2.0
    second_stage_classification_loss_weight: 1.0
  }
}

train_config: {
  batch_size: 1
  optimizer {
    momentum_optimizer: {
      learning_rate: {
        manual_step_learning_rate {
          initial_learning_rate: 0.0003
          schedule {
            step: 0
            learning_rate: .0003
          }
          schedule {
            step: 900000
            learning_rate: .00003
          }
          schedule {
            step: 1200000
            learning_rate: .000003
          }
        }
      }
      momentum_optimizer_value: 0.9
    }
    use_moving_average: false
  }
  gradient_clipping_by_norm: 10.0
  #fine_tune_checkpoint: "PATH_TO_BE_CONFIGURED/model.ckpt"
  from_detection_checkpoint: true
  data_augmentation_options {
    random_horizontal_flip {
    }
  }
}

train_input_reader: {
  tf_record_input_reader {
    input_path: "PATH_TO_BE_CONFIGURED/giftee_train.record"
  }
  label_map_path: "PATH_TO_BE_CONFIGURED/giftee_label_map.pbtxt"
}

eval_config: {
  num_examples: 2000
}

eval_input_reader: {
  tf_record_input_reader {
    input_path: "PATH_TO_BE_CONFIGURED/giftee_train.record"
  }
  label_map_path: "PATH_TO_BE_CONFIGURED/giftee_label_map.pbtxt"
  shuffle: false
  num_readers: 1
}

Les principaux changements sont que class_num est défini sur 1 et le nom du fichier est modifié. Il suffit de commenter fine_tune_checkpoint Autre que cela, l'échantillon est utilisé.

fine_tune_checkpoint est quand il y a déjà des données entraînées Cela semble être à utiliser, mais cette fois, je vais apprendre de 0, donc je commente.

PATH_TO_BE_CONFIGURED utilise cette fois Google Cloud Storage, donc Je l'ai remplacé par ce chemin comme dans le tutoriel.

$ sed -i "s|PATH_TO_BE_CONFIGURED|"gs://${YOUR_GCS_BUCKET}"/data|g" \
    object_detection/samples/configs/faster_rcnn_resnet101_giftee.config

Paramètres de Google Compute Cloud

Google Cloud Storage Importez les fichiers créés jusqu'à présent sur Google Cloud Storage. Le chemin après le téléchargement est le suivant.

+ ${YOUR_GCS_BUCKET}/
  + data/
    - faster_rcnn_resnet101_giftee.config
    - giftee_label_map.pbtxt
    - giftee_train.record
    - giftee_val.record

Google Cloud ML Engine Préparez le fichier à utiliser par Google Cloud ML Engine. Dans la hiérarchie des modèles comme dans le tutoriel

$ python setup.py sdist
$ cd slim && python setup.py sdist

Ensuite, vous avez besoin des fichiers

Est généré.

entraînement

Exécutez une formation à l'aide de Google Cloud ML Engine.

Au début, j'ai essayé de m'entraîner localement sur mac, mais cela a pris trop de temps et j'ai abandonné. Quand je suis passé à ML Enigne, c'était environ 30 fois plus rapide.

La commande exécute ce qui suit en référence au didacticiel.

# From tensorflow/models/
$ gcloud ml-engine jobs submit training `whoami`_object_detection_`date +%s` \
    --job-dir=gs://${YOUR_GCS_BUCKET}/train \
    --packages dist/object_detection-0.1.tar.gz,slim/dist/slim-0.1.tar.gz \
    --module-name object_detection.train \
    --region us-central1 \
    --config object_detection/samples/cloud/cloud.yml \
    -- \
    --train_dir=gs://${YOUR_GCS_BUCKET}/train \
    --pipeline_config_path=gs://${YOUR_GCS_BUCKET}/data/faster_rcnn_resnet101_giftee.config
`whoami`_object_detection_`date +%s`

La partie est le nom du travail.

$ echo `whoami`_object_detection_`date +%s`

Ensuite, vous pouvez voir quel sera le nom.

Pour --job-dir et --train_dir, spécifiez le répertoire dans lequel stocker la progression de l'apprentissage. Les données seront mises à jour à intervalles réguliers.

Pour --packages, spécifiez le fichier tar.gz que vous avez créé précédemment.

Il semble que vous puissiez modifier le nombre de travaux et les spécifications avec --config. Cette fois, j'utiliserai celui par défaut.

L'exécution de cette commande exécutera le travail sur ML Engine. Vous pouvez vérifier l'état de la tâche et les journaux sur ML Engine de GCP.

Temps d'étude

Cette fois, je l'ai déplacé pendant environ 2 heures et je me suis arrêté à 30 000 pas. Les frais GCP étaient d'environ 4000 yens. ..

eval Sur la base des paramètres appris, l'évaluation est effectuée à l'aide d'images qui ne sont pas utilisées pour la formation. Reportez-vous également au didacticiel et exécutez la commande suivante pour exécuter le travail sur ML Enigne.

# From tensorflow/models/
$ gcloud ml-engine jobs submit training `whoami`_object_detection_eval_`date +%s` \
    --job-dir=gs://${YOUR_GCS_BUCKET}/train \
    --packages dist/object_detection-0.1.tar.gz,slim/dist/slim-0.1.tar.gz \
    --module-name object_detection.eval \
    --region us-central1 \
    --scale-tier BASIC_GPU \
    -- \
    --checkpoint_dir=gs://${YOUR_GCS_BUCKET}/train \
    --eval_dir=gs://${YOUR_GCS_BUCKET}/eval \
    --pipeline_config_path=gs://${YOUR_GCS_BUCKET}/data/faster_rcnn_resnet101_giftee.config

tensorborad Si vous utilisez un tensorboard, vous pouvez vérifier graphiquement la transition de la perte. Vous pouvez également voir l'image du résultat du jugement du logo avec les paramètres réellement appris sur l'onglet IMAGES.

Pour démarrer tensorboard, indiquez le chemin de Google Cloud Storage et exécutez-le.

$ tensorboard --logdir=gs://${YOUR_GCS_BUCKET}

Vous pouvez vérifier la transition en accédant à localhost: 6006 avec un navigateur.

TensorBoard.png

Conversion en graphique Tensorflow

Afin d'utiliser les données entraînées pour juger le logo, il est nécessaire de le convertir en un graphique Tensorflow.

Tout d'abord, téléchargez les données localement depuis Google Cloud Storage,

$ gsutil cp gs://${YOUR_GCS_BUCKET}/train/model.ckpt-${CHECKPOINT_NUMBER}.* .

Exécutez le script de conversion.

python object_detection/export_inference_graph.py \
    --input_type image_tensor \
    --pipeline_config_path object_detection/samples/configs/faster_rcnn_resnet101_giftee.config \
    --checkpoint_path model.ckpt-${CHECKPOINT_NUMBER} \
    --inference_graph_path output_inference_graph.pb

Il semble que CHECKPOINT_NUMBER devrait être celui avec le plus grand nombre dans les données d'apprentissage.

Converti lors de l'exécution de ce script

Est sortie.

Jugement du logo

Je vais enfin porter un jugement sur le logo.

Le script python pour le jugement sera exécuté sur Jupyter sur la base de ce tutoriel.

Vous pouvez procéder presque selon le tutoriel, mais je corrigerai la partie du graphique Tensorflow et le chemin des données d'étiquette.

# What model to download.
#MODEL_NAME = 'ssd_mobilenet_v1_coco_11_06_2017'
#MODEL_FILE = MODEL_NAME + '.tar.gz'
#DOWNLOAD_BASE = 'http://download.tensorflow.org/models/object_detection/'

# Path to frozen detection graph. This is the actual model that is used for the object detection.
PATH_TO_CKPT = 'data/output_inference_graph.pb'

# List of the strings that is used to add correct label for each box.
PATH_TO_LABELS = 'data/giftee_label_map.pbtxt'

NUM_CLASSES = 1

De plus, je ne téléchargerai pas le modèle, je vais donc le commenter.

#opener = urllib.request.URLopener()
#opener.retrieve(DOWNLOAD_BASE + MODEL_FILE, MODEL_FILE)
#tar_file = tarfile.open(MODEL_FILE)
#for file in tar_file.getmembers():
#   file_name = os.path.basename(file.name)
#  if 'frozen_inference_graph.pb' in file_name:
#        tar_file.extract(file, os.getcwd())

Enfin, modifiez le chemin de l'image et exécutez. Les noms de fichiers utilisés pour le jugement doivent être image1.jpg et image2.jpg.

# For the sake of simplicity we will use only 2 images:
# image1.jpg
# image2.jpg
# If you want to test the code with your images, just add path to the images to the TEST_IMAGE_PATHS.
PATH_TO_TEST_IMAGES_DIR = 'gifteeimages'
TEST_IMAGE_PATHS = [ os.path.join(PATH_TO_TEST_IMAGES_DIR, 'image{}.jpg'.format(i)) for i in range(1, 3) ]

# Size, in inches, of the output images.
IMAGE_SIZE = (12, 8)

Résultat d'exécution

Dans certaines images, le logo a été détecté correctement comme indiqué ci-dessous.

jupyter_image1.png

jupyter_image2.png

finalement

Après avoir étudié pendant environ 2 heures, j'ai pu porter un jugement avec plus de précision que prévu. Cette fois, il semble que les données sur les enseignants soient également petites, environ 40, donc Je pense que la précision sera encore améliorée si la quantité de données sur les enseignants est augmentée et le temps d'apprentissage est allongé. (Les frais d'utilisation de GCP constituent un goulot d'étranglement ...)

Recommended Posts

Détection de logo à l'aide de l'API de détection d'objets TensorFlow
[Pour les débutants] J'ai essayé d'utiliser l'API Tensorflow Object Detection
Détection générale des objets à l'aide du modèle pré-entraîné de Google (via TensorFlow Hub)
[Pour ceux qui veulent utiliser TPU] J'ai essayé d'utiliser l'API de détection d'objets Tensorflow 2
Détection d'objets à l'aide de Jetson Nano (YOLOv3) - (1) Paramètres Jetson Nano-
Essayez la reconnaissance d'objets en temps réel avec YOLOv2 (TensorFlow)
API Tensorflow: tf.truncated_normal
API Tensorflow: FLAGS
API Tensorflow: tf.reverse
Mémo de l'API TensorFlow
J'ai essayé la détection d'objets en utilisant Python et OpenCV
Essayons la détection d'objets en temps réel en utilisant Faster R-CNN
Trouvez une approximation polynomiale à l'aide de l'API de bas niveau de TensorFlow 2.x
[TF] À propos de l'API Tensorflow
Mémo de l'API TensorFlow (Python)
[Résumé] Modèle de détection d'objets utilisant Transformer "Détection d'objets de bout en bout avec des transformateurs"
J'ai essayé la nouvelle API de détection d'objets de tensorflow sur macOS Sierra
2020/02 Python 3.7 + TensorFlow 2.1 + Keras 2.3.1 + YOLOv3 Détection d'objets avec la dernière version
Analyse d'image avec l'API Object Detection à essayer en 1 heure
Détection d'expression à l'aide de Yolov5
Tester l'API CloudStack à l'aide du simulateur
Reconnaissance de l'âge à l'aide de l'API de Pepper
Détection de caractéristiques à l'aide d'opencv (détection de coin)
Essayez d'utiliser l'API Twitter
Mettre en ligne des vidéos à l'aide de l'API YouTube
Essayez d'utiliser l'API Twitter
Essayez d'utiliser l'API PeeringDB 2.0
Utilisez configparser lors de l'utilisation de l'API
J'ai essayé d'utiliser magenta / TensorFlow