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.
Nous procéderons dans l'ordre de.
Cette fois, je ne détecterai qu'un seul type de logo giftee pour lequel je travaille.
Utilisez Google Image Search pour collecter des images avec des logos. Cette fois, j'ai collecté environ 40 images.
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.
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.
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.
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é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é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
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é.
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.
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.
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.
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)
Dans certaines images, le logo a été détecté correctement comme indiqué ci-dessous.
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 ...)