[PYTHON] Logoerkennung mit der TensorFlow-Objekterkennungs-API

Einführung

Aktivieren Sie die Logoerkennung mithilfe der im Juli 2017 angekündigten TensorFlow-Objekterkennungs-API. Als ich zuvor versucht habe, Objekte zu erkennen habe ich die vorbereiteten trainierten Daten verwendet, aber dieses Mal beginne ich mit der Erstellung von Lehrerdaten Ich werde.

Verfahren

  1. Erstellung von Lehrerdaten
  2. Lernen
  3. Erkennungstest

Wir werden in der Reihenfolge von fortfahren.

Logo zu erkennen

Dieses Mal werde ich nur eine Art von fünfzehn Logos erkennen, für die ich arbeite. gifteelogo.png

Erstellung von Lehrerdaten

Bildersammlung

Verwenden Sie die Google Bildsuche, um Bilder mit Logos zu sammeln. Dieses Mal habe ich ungefähr 40 Bilder gesammelt.

Rechteckige Auswahl und Kennzeichnung

Die TensorFlow-Objekterkennungs-API erkennt also Objekte im Bild Wir benötigen Daten, um das Rechteck mit dem Objekt und der Beschriftung des Objekts zu lernen. Dieses Mal verwenden wir labelImg, um die Daten zu erstellen.

labelImg Zuerst habe ich versucht, es auf einem Mac auszuführen, aber es hat nicht sehr gut funktioniert, selbst wenn ich versucht habe, das offizielle Verfahren zu befolgen, also habe ich es auf Ubuntu ausgeführt. Es ist ziemlich anomal,

Ich habe das Verfahren übernommen.

X11 Übertragung von Vagrant auf Vagrantfile

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

Es ist gültig, wenn Sie schreiben.

labelImg gibt das im Bild gespeicherte Verzeichnis an, wählt die Logodaten in rechteckiger Form aus, Ich werde ein Etikett hinzufügen.

labelImg_ss.png

Wenn Sie den Standardetikettennamen in "Standardetikett verwenden" einfügen, wird Ihre Arbeit erheblich vereinfacht.

Nachdem Sie das Rechteck ausgewählt und die Beschriftung festgelegt haben, drücken Sie Speichern, um es als XML-Daten zu speichern.

Umstellung auf TFRecord

Konvertiert Bilder und XML in das TFRecord-Format, damit TensorFlow die Daten lesen kann. Diesmal create_pet_tf_record.py in Tutorial (/blob/master/object_detection/create_pet_tf_record.py), um ein Konvertierungsskript zu erstellen.

Die Hauptkorrektur besteht darin, dass das ursprüngliche Skript den Labelnamen aus dem Dateinamen abrufen sollte, jetzt aber das Label "giftee" zurückgibt.

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

Davon abgesehen benutze ich es fast ohne Modifikation.

Erstellen Sie labelmap.pbtxt

Da es diesmal nur einen Typ gibt, werde ich nur einen Artikel schreiben.

item {
  id: 1
  name: 'giftee'
}

Speichern Sie es als giftee_label_map.pbtxt.

Konvertierungsskript ausführen

Führen Sie das Konvertierungsskript aus.

Die meisten Schritte von hier folgen dem Tutorial.

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

Die Trainingsdaten "giftee_train.record" und die Auswertungsdaten "giftee_val.record" werden in der ausgeführten Hierarchie erstellt.

Konfigurationserstellung

Erstellen Sie eine Konfiguration, die Modellparameter, Lernrate während des Trainings, tfrecord-Dateipfad, Beschriftungstextpfad usw. festlegt.

Dieses Mal werde ich einen Teil von [Tutorial] verwenden (https://github.com/tensorflow/models/blob/master/object_detection/samples/configs/faster_rcnn_resnet101_pets.config).

# 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
}

Die wichtigsten Änderungen sind, dass class_num auf 1 gesetzt und der Dateiname geändert wird. Kommentieren Sie einfach fine_tune_checkpoint aus Ansonsten wird die Probe verwendet.

fine_tune_checkpoint ist, wenn bereits trainierte Daten vorhanden sind Es scheint für den Gebrauch zu sein, aber dieses Mal werde ich von 0 lernen, also kommentiere ich aus.

PATH_TO_BE_CONFIGURED verwendet diesmal also Google Cloud Storage Ich habe es wie im Tutorial durch diesen Pfad ersetzt.

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

Google Compute Cloud-Einstellungen

Google Cloud Storage Laden Sie die bisher erstellten Dateien in Google Cloud Storage hoch. Der Pfad nach dem Hochladen lautet wie folgt.

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

Google Cloud ML Engine Bereiten Sie die Datei vor, die von Google Cloud ML Engine verwendet werden soll. In der Modellhierarchie wie im Tutorial

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

Dann brauchen Sie die Dateien

Wird generiert.

Ausbildung

Führen Sie das Training mit der Google Cloud ML Engine durch.

Zuerst habe ich versucht, lokal auf dem Mac zu trainieren, aber es hat zu lange gedauert und ich habe aufgegeben. Als ich zu ML Enigne wechselte, war es ungefähr 30 Mal schneller.

Der Befehl führt Folgendes unter Bezugnahme auf das Lernprogramm aus.

# 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`

Der Teil ist der Name des Jobs.

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

Dann können Sie sehen, wie der Name lautet.

Geben Sie für --job-dir und --train_dir das Verzeichnis an, in dem der Lernfortschritt gespeichert werden soll. Die Daten werden in regelmäßigen Abständen aktualisiert.

Geben Sie für --packages die zuvor erstellte Datei tar.gz an.

Es scheint, dass Sie die Anzahl der Jobs und Spezifikationen mit --config ändern können. Dieses Mal werde ich die Standardeinstellung verwenden.

Durch Ausführen dieses Befehls wird der Job auf der ML Engine ausgeführt. Sie können den Auftragsstatus und die Protokolle mit der ML Engine von GCP überprüfen.

Lernzeit

Diesmal habe ich es für ca. 2 Stunden bewegt und bei 30.000 Schritten angehalten. Die GCP-Gebühr betrug ungefähr 4000 Yen. ..

eval Basierend auf den erlernten Parametern wird die Auswertung anhand von Bildern durchgeführt, die nicht für das Training verwendet werden. Lesen Sie auch das Lernprogramm und führen Sie den folgenden Befehl aus, um den Job auf ML Enigne auszuführen.

# 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 Wenn Sie Tensorboard verwenden, können Sie den Verlustübergang grafisch überprüfen. Sie können auch das Bild des Ergebnisses der Logo-Beurteilung mit den tatsächlich gelernten Parametern auf der Registerkarte BILDER sehen.

Geben Sie zum Starten von Tensorboard den Pfad von Google Cloud Storage an und führen Sie ihn aus.

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

Sie können den Übergang überprüfen, indem Sie mit einem Browser auf localhost: 6006 zugreifen.

TensorBoard.png

Konvertierung in Tensorflow Graph

Um die trainierten Daten zur Beurteilung des Logos zu verwenden, muss es in ein Tensorflow-Diagramm konvertiert werden.

Laden Sie zunächst die Daten lokal aus Google Cloud Storage herunter.

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

Führen Sie das Konvertierungsskript aus.

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

Es scheint, dass CHECKPOINT_NUMBER diejenige mit der größten Anzahl in den Trainingsdaten sein sollte.

Konvertiert beim Ausführen dieses Skripts

Wird ausgegeben.

Logo Beurteilung

Ich werde endlich ein Logo-Urteil fällen.

Das Python-Skript zur Beurteilung wird auf Jupyter basierend auf [diesem Tutorial] ausgeführt (https://github.com/tensorflow/models/blob/master/object_detection/object_detection_tutorial.ipynb).

Sie können fast gemäß dem Tutorial fortfahren, aber ich werde den Teil des Tensorflow-Diagramms und den Etikettendatenpfad korrigieren.

# 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

Außerdem werde ich das Modell nicht herunterladen, also werde ich es auskommentieren.

#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())

Ändern Sie abschließend den Bildpfad und führen Sie ihn aus. Die zur Beurteilung verwendeten Dateinamen sollten image1.jpg und image2.jpg sein.

# 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)

Ausführungsergebnis

In einigen Bildern wurde das Logo wie unten gezeigt korrekt erkannt.

jupyter_image1.png

jupyter_image2.png

Schließlich

Nachdem ich ungefähr 2 Stunden studiert hatte, konnte ich ein Urteil mit höherer Genauigkeit fällen, als ich erwartet hatte. Dieses Mal scheinen die Lehrerdaten ebenfalls klein zu sein, also ungefähr 40 Ich denke, dass die Genauigkeit weiter verbessert wird, wenn die Menge der Lehrerdaten erhöht und die Lernzeit verlängert wird. (Die GCP-Nutzungsgebühr ist ein Engpass ...)

Recommended Posts

Logoerkennung mit der TensorFlow-Objekterkennungs-API
[Für Anfänger] Ich habe versucht, die Tensorflow-Objekterkennungs-API zu verwenden
Allgemeine Objekterkennung mit dem von Google vorab trainierten Modell (über TensorFlow Hub)
[Für diejenigen, die TPU verwenden möchten] Ich habe versucht, die Tensorflow Object Detection API 2 zu verwenden
Objekterkennung mit Jetson Nano (YOLOv3) - (1) Jetson Nano-Einstellungen-
Versuchen Sie die Objekterkennung in Echtzeit mit YOLOv2 (TensorFlow).
Tensorflow-API: tf.truncated_normal
Tensorflow API: FLAGGEN
Tensorflow-API: tf.reverse
TensorFlow API-Memo
Ich habe versucht, Objekte mit Python und OpenCV zu erkennen
Versuchen wir die Echtzeit-Objekterkennung mit Faster R-CNN
Finden Sie eine Polynomnäherung mit der Low-Level-API von TensorFlow 2.x.
[TF] Informationen zur Tensorflow-API
TensorFlow API-Memo (Python)
[Zusammenfassung] Objekterkennungsmodell "End-to-End-Objekterkennung mit Transformatoren" mit Transformer
Ich habe die neue Objekterkennungs-API von tensorflow unter macOS Sierra ausprobiert
2020/02 Python 3.7 + TensorFlow 2.1 + Keras 2.3.1 + YOLOv3 Objekterkennung mit der neuesten Version
Bildanalyse mit Objekterkennungs-API zum Ausprobieren in 1 Stunde
Expressionsnachweis mit Yolov5
Testen Sie die CloudStack-API mit Simulator
Alterserkennung mit Peppers API
Feature-Erkennung mit opencv (Eckenerkennung)
Versuchen Sie es mit der Twitter-API
Laden Sie Videos mit der YouTube-API hoch
Versuchen Sie es mit der Twitter-API
Versuchen Sie es mit der PeeringDB 2.0-API
Verwenden Sie configparser, wenn Sie die API verwenden
Ich habe versucht, Magenta / TensorFlow zu verwenden