[PYTHON] Objekterkennung durch tiefes Lernen, Keras tief zu verstehen

Für wen

Für diejenigen, die bereits tiefes Lernen verstehen und den Mechanismus von der Bildklassifizierung bis zur Objekterkennung beherrschen möchten

Da es viele Formeln gibt, gehen Sie wie folgt vor, wenn Sie den Code überprüfen möchten

[Spezifisches Implementierungsbeispiel](http://qiita.com/GushiSnow/private/8c946208de0d6a4e31e7#%E5%85%B7%E4%BD%93%E7%9A%84%E3%81%AA%E5%AE % 9F% E8% A3% 85% E4% BE% 8B)

Bonus

Übersetzte ein Buch über Keras. Es deckt ein breites Spektrum von Bildidentifikation, Bilderzeugung, Verarbeitung natürlicher Sprache, Zeitreihenvorhersage und Verstärkungslernen ab. [Intuitives Deep Learning-Rezept zur Gestaltung von Ideen mit Python x Keras](https://www.amazon.co.jp/Deep-Learning-%E2%80%95Python%C3%97Keras%E3%81%A7% E3% 82% A2% E3% 82% A4% E3% 83% 87% E3% 82% A2% E3% 82% 92% E5% BD% A2% E3% 81% AB% E3% 81% 99% E3% 82% 8B% E3% 83% AC% E3% 82% B7% E3% 83% 94-Antonio-Gulli / dp / 4873118263 / ref = sr_1_1? S = Bücher & dh = UTF8 & qid = 1530227887 & sr = 1-1 & Schlüsselwörter =% E7% 9B % B4% E6% 84% 9F + Deep + Learning)

Zweck

Ich habe es geschrieben, weil ich die Technologie zur Objekterkennung systematisch zusammenfassen und die Codebasis verstehen wollte.

Dieser Artikel wird unter Bezugnahme auf das Kapitel zur Objekterkennung in der Bilderkennung erstellt, das ein gutes Buch ist.

[Bilderkennung](https://www.amazon.co.jp/%E7%94%BB%E5%83%8F%E8%AA%8D%E8%AD%98-%E6%A9%9F%E6 % A2% B0% E5% AD% A6% E7% BF% 92% E3% 83% 97% E3% 83% AD% E3% 83% 95% E3% 82% A7% E3% 83% 83% E3% 82 % B7% E3% 83% A7% E3% 83% 8A% E3% 83% AB% E3% 82% B7% E3% 83% AA% E3% 83% BC% E3% 82% BA-% E5% 8E% 9F% E7% 94% B0-% E9% 81% 94% E4% B9% 9F / dp / 4061529129 "Bilderkennung")

Screen Shot 2017-06-22 at 9.37.01.png

Gesamtbild

Screen Shot 2017-06-22 at 9.59.59.png

Es ist grob in drei Phasen unterteilt.

1: Extraktion von Objektbereichskandidaten

Es ist eine Methode, um Flächenkandidaten eines Objekts aus dem Bild zu extrahieren. Es ist der Teil, der Genauigkeit und Geschwindigkeit beeinflusst. Wie in der Abbildung gezeigt, gibt es eine Methode, um ein kleines Fenster (Begrenzungsrahmen) vorzubereiten und Flächenkandidaten zu extrahieren, während eine bestimmte Anzahl von Pixeln verschoben wird. Wenn dies für jedes Pixel verschoben wird, muss die Bildgröße W * H ausgewertet werden. Um diese Berechnungskosten zu reduzieren, ist es daher üblich, die Kandidaten durch ein Verfahren einzugrenzen, das die Bildqualität des Objekts bewertet.

2: Objekterkennung von Objektbereichskandidaten

Sie müssen wissen, was Sie in den Kandidaten sehen. Dies kann mit einem allgemeinen überwachten Klassifizierungsproblem gelöst werden. Wichtig hierbei ist die Auswahl der Lehrerdaten. Negative Beispiele (falsche Daten) sind Klassifizierer, die nur einfache Probleme lösen können, es sei denn, Sie wählen Beispiele aus, die schwer zu klassifizieren sind, und die Leistung ist nicht praktikabel. Daher ist es wichtig, es als negatives Beispiel auszuwählen, das schwer zu klassifizieren ist. In dieser Abbildung ist der Teil, in dem das gesamte Bild der Kuh aufgenommen wurde, als negatives Beispiel geeignet.

3: Grenzen Sie den Erkennungsbereich ein

Selbst wenn nur ein Zielobjekt vorhanden ist, werden mehrere Bereiche angezeigt. Der geeignete Erkennungsbereich wird durch Auswahl des Teils bestimmt, in dem die Erkennungsbewertung nur der Maximalwert ist.

Jede Methode

Extraktion von Objektbereichskandidaten Objekterkennung von Objektbereichskandidaten Eingrenzen des Erkennungsbereichs
Schiebefenstermethode(Ineffizient aber einfach) HOG-Funktionen+Lineare SVM NMS(IoU wird verwendet)
Selektive Suchmethode(Effizient) DPM(Betrachten Sie die Verformung des Objekts)
Zweigbegrenzungsmethode(Effizient) Schwein Features+ LatentSVM(Berücksichtigung der Filterposition)
attentional cascade(Schnelle Objekterkennung, erfordert jedoch einen Klassifikator) Exampler-SVM(Klassifizieren Sie einzelne Objekte)
Rechteckige Merkmale+ Adaboost(Hohe Klassifizierungsleistung bei geringen Kosten)

Screen Shot 2017-06-22 at 10.26.32.png

Der Weg, gute negative Fälle bei der Objekterkennung von Objektbereichskandidaten zu sammeln, besteht darin, die negativen Fälle zu speichern, die der Klassifizierer als Cache falsch klassifiziert hat, und effizient zu sammeln und zu lernen, indem die negativen Fallkandidaten entfernt werden, die klassifiziert werden könnten. Ich kann.

Objekterkennung durch tiefes Lernen

Die Objekterkennung durch tiefes Lernen hat den Vorteil, dass CNN-Merkmale, die qualitativ hochwertige Merkmale extrahieren können, im Vergleich zu dem obigen Verfahren verwendet werden können. Lassen Sie uns tatsächlich den Fluss der Objekterkennung durch tiefes Lernen sehen.

Von nun an wird das kleine Fenster als Begrenzungsrahmen bezeichnet.

R-CNN (Region)

Screen Shot 2017-06-22 at 10.55.35.png

Es ist eine Methode zum Zurückziehen des Begrenzungsrahmens, aber des vorgeschlagenen Begrenzungsrahmens

\vec{r} = (r_x, r_y, r_w, r_h)^T

Echter Begrenzungsrahmen

\vec{g} = (g_x, g_y, g_w, g_h)^T

Der Modellparameter W, um den wahren Begrenzungsrahmen zu erhalten, wird unten gelöst.

\vec{W} = argmin_{\vec{w}}\sum^{N}_{n=1}({\vec{t}_n - \vec{W}^Tf(\vec{r}_n)})^2 + \lambda\|\vec{W}\|^2_{F}

Wert für die Zielregression hier

\vec{t} = (t_x, t_y, t_w, t_h)^T

t verwendet den zuvor definierten wahren Begrenzungsrahmen g und den vorgeschlagenen Begrenzungsrahmen r

t_x = (g_x - r_x) / r_w,
t_y = (g_y - r_y) / r_h,
t_w = log(g_w / r_w),
t_h = log(g_h / r_h),

Definieren Sie wie oben. Der Grund für das oben Gesagte wird wie folgt angenommen. Der Grund für die Vermutung ist, dass ich nicht untersucht habe, dass es nicht in dem Buch war. Wenn Sie interessiert sind, überprüfen Sie es bitte.

Da es verschiedene Arten von Begrenzungsrahmengrößen gibt, wird die Mittelposition durch das Verhältnis des Breitenwerts zum Differenzwert berechnet. Der Breitenwert wird als Verhältnis zum wahren Wert berechnet. Da der Wert jedoch extrem klein oder groß sein kann, wird der Effekt durch den Logarithmus verringert.

Es scheint, dass wir für das Obige entwickeln, ohne den Wert direkt zu verwenden.

Fast R-CNN

R-CNN musste CNN für jeden Objektbereich ausführen. Schnelles R-CNN unterscheidet sich darin, dass die CNN-Funktion das gesamte Bild verwendet. Da der CNN-Merkmalsbetrag zu diesem Zeitpunkt für jeden zugeschnittenen Bildbereich unterschiedlich ist, ist er insofern unterschiedlich, als er durch RoI-Pooling in einen Merkmalsbetrag fester Länge konvertiert werden muss.

Screen Shot 2017-06-22 at 11.24.35.png

Auf Seite 10 unten erfahren Sie, was RoI-Pooling ist.

Artikeleinführung: Schnelles R-CNN und schnelleres R-CNN

Lernmethode

Nehmen Sie eine Methode zur Optimierung des Multitasking-Verlusts für das gleichzeitige Lernen der Klassenerkennung und kehren Sie zum Begrenzungsrahmen zurück.

Angenommen, jeder richtige Begrenzungsrahmen erhält die richtige Position t und Bezeichnung u, die bei der Berechnung durch R-CNN verwendet wurden. Der Multitasking-Verlust wird durch die folgende Formel ausgedrückt.

Wahrscheinlichkeit nach dem Unterricht

\vec{p} = (p^0, p^1,... p^N_c)^T

Relative Position und Größe des Begrenzungsrahmens

\vec{v} = (v_x, v_y, v_w, v_h)^T

basierend auf dem oben genannten

J(\vec{p}, u, \vec{v}, \vec{t}) = J_{cls}(\vec{p}, u) + \lambda[u >= 1]J_{loc}(\vec{v}, \vec{t})

J_cls ist der Verlust der Klassenerkennung und J_loc ist der Verlust der Bounding-Box-Regression.

J_cls wird als negativer Logarithmus der posterioren Wahrscheinlichkeit p ^ u für die wahre Klasse u berechnet.

J_{cls}(\vec{p}, u) = -\log{p^u} 

J_loc ist

J_{loc} = \sum_{i \in { \{x,y,w,h} \}}smooth_{L1}(t_i - v_i)
smooth_{L1}(x) = \left\{
\begin{array}{ll}
0.5x^2 & if (|x| < 1) \\
|x| - 0.5 &otherwise
\end{array}
\right.

Die Glättungsfunktion korrigiert die relative Positionsdifferenz so, dass sie groß wird, wenn sie kleiner als 1 ist, und ansonsten wird sie vom Medianwert von 0,5 subtrahiert, damit sie nicht zu einem extrem großen Wert wird.

Effizienz der Berechnung

Da die vollständige Kombination für jedes Bild verarbeitet wird, arbeitet der Mini-Batch mit einem Bild, sodass die Feature-Map effizient verwendet werden kann. Insbesondere wird N (die Anzahl der Bilder) verringert und R (die Anzahl der Begrenzungsrahmen) wird erhöht.

Faster R-CNN

In Fast R-CNN war es erforderlich, den Objektbereichskandidaten in einem anderen Modul zu berechnen (selektive Erkennungsmethode). Schnelleres R-CNN verwendet eine Methode zum Erstellen eines Regionsnetzwerks, das die Objektregion aus einer Feature-Map namens RPN schätzt und in Fast R-CNN integriert.

Screen Shot 2017-06-22 at 12.10.38.png

Wir schlagen einen Begrenzungsrahmen mit einer Punktzahl von RPN vor. Die RPN besteht aus einem Teil, der die Parameter des Begrenzungsrahmens lernt, und einem separaten Netzwerk, das das Vorhandensein oder Fehlen eines Objekts vorhersagt, und dies wird kombiniert, um die RPN zu realisieren.

Bereiten Sie K Ankerkästen vor, deren Form im Voraus festgelegt wurde. Bereiten Sie einen Standard-Begrenzungsrahmen vor, der auf dem lokalen Bereich der Eingabe zentriert ist (dies wird durch Berechnung der Kante usw. abgeleitet). Dieser Bereich ist ein Hyperparameterelement. Die Begrenzungsrahmenvorhersage gibt einen 4k-dimensionalen Vektor aus, der die relative Position und das Seitenverhältnis von jedem Ankerkasten enthält. (x, y, w, h) * k

[Seitenverhältnis](https://ja.wikipedia.org/wiki/%E3%82%A2%E3%82%B9%E3%83%9A%E3%82%AF%E3%83%88%E6% AF% 94)

Da das Klassifizierungsnetzwerk das Vorhandensein oder Fehlen eines Objekts in zwei Klassen beurteilt, gibt es einen 2k-dimensionalen Vektor aus. (Ja, nein) * k

Leitet den optimalen Begrenzungsrahmen ab, indem der Multitasking-Verlust ähnlich wie bei Fast R-CNN minimiert wird. Wenn Sie abwechselnd RPN und Fast R-CNN lernen, lernen Sie das gesamte Netzwerk von Faster R-CNN. Lernen Sie zuerst nur mit RPN, damit der optimale Begrenzungsrahmen abgeleitet werden kann, und lernen Sie dann R-CNN und dann Fast R-CNN.

YOLO (You only look once)

Bisher ging es darum, einen guten Begrenzungsrahmen zu finden, aber es gibt Versuche, Objekte direkt zu erkennen. Das ist YOLO.

Screen Shot 2017-06-22 at 12.43.34.png

YOLO-Verfahren

1: Teilen Sie das Eingabebild in S * S-Bereiche 2: Abgeleitet die Klassenwahrscheinlichkeit von Objekten in der Region 3: Berechnen Sie die Parameter (x, y, h, w) und die Zuverlässigkeit von B-Begrenzungsrahmen (Hyperparameter).

Grad der Zuverlässigkeit

q = P_r(Obj) \times IoU^{truth}_{pred}
IoU^{truth}_{pred}

Ist der Grad der Übereinstimmung zwischen der Vorhersage und dem richtigen Begrenzungsrahmen. Das Produkt aus der Objektklassenwahrscheinlichkeit und der Zuverlässigkeit jedes Begrenzungsrahmens wird zur Objekterkennung verwendet.


P_r(C_i|Obj) \times P_r(Obj) \times IoU^{truth}_{pred}

Das YOLO-Netzwerk ist wie folgt.

Screen Shot 2017-06-22 at 12.57.23.png

Die Ausgabe ist die Anzahl der Begrenzungsrahmen und die Anzahl der Klassen, einschließlich des Bildbereichs, unterteilt in S * S, (x, y, h, w) und Zuverlässigkeit.

Die Zuverlässigkeit wird durch die folgende Formel ausgedrückt. Messen Sie die Übereinstimmung des Begrenzungsrahmens.

IoU = \frac{area(R_p \bigcap R_g)}{area(R_p \bigcup R_g)}

Screen Shot 2017-06-22 at 13.02.20.png

SSD

Ich werde auch auf SSD eingehen, die nicht im Buch enthalten war, aber als Methode nützlich ist.

・ Geschwindigkeitsvergleich

Screen Shot 2017-06-30 at 10.53.05.png

・ Genauigkeitsvergleich

Der Unterschied zwischen SSD512 und SSD300 ist die Größe des Eingabebildes

Screen Shot 2017-06-30 at 10.54.04.png

Vorteil

Grund für den Vorteil

Modellvergleich

Screen Shot 2017-06-26 at 10.19.02.png

Die obige Abbildung vergleicht das End-to-End-Modell YOLO und SSD. Bei SSD werden mehrere Feature-Maps mit unterschiedlichen Seitenverhältnissen erstellt und in die endgültige Ebene eingegeben, sodass sie auch bei unterschiedlichen Bildauflösungen angewendet werden können.

Über die Ausgabeebene

Screen Shot 2017-06-26 at 10.17.24.png

Die Bedeutung von 8732 in der Abbildung ist die Anzahl der Begrenzungsrahmen. Wenn die Anzahl groß ist, erhöht sich die Genauigkeit, aber die Geschwindigkeit nimmt ab, sodass ein Kompromiss entsteht.

Die Ausgabeschicht hat die Anzahl der Klassen C und den Versatz (x, y, h, w) und die Anzahl der ihnen zugeordneten Begrenzungsrahmen k. Da sie für jede Feature-Map vorbereitet werden müssen, beträgt die Größe der Feature-Map m * n. In diesem Fall ist das Folgende die Größe der Ausgabeebene.


(c+4)kmn

Die Verlustfunktion findet zwei Punkte: die Abweichung der Position des Objekts und die Abweichung der Klassifizierung der Klasse. N ist die Anzahl der übereinstimmenden Standardbegrenzungsrahmen (0 wird auf 0 gesetzt, da der Verlust gegen unendlich abweicht). α steuert die Bedeutung der Identifizierung von Hyperparameterklassen oder der Offset-Regression) Wobei x 1 ist, wenn die Box der wahren Daten j und die Box der vorhergesagten Daten i übereinstimmen, 0, wenn sie nicht übereinstimmen (p ist die Klasse)

x^p_{ij} = {1, 0} 

L(x,c,l,g) = 1/N(L_{conf}(x, c) + \alpha L_{loc}(x,l,g))

Verlustfunktion auf Position

l ist die vorhergesagte Position

L_{loc}(x,l,g) = \sum^N_{i \in Pos}\sum_{m \in {cx, cy, w, h}} x^k_{ij} {\rm smooth_{L1}}(l^m_i-\hat{g}^m_j)
smooth_{L1}(x) = \left\{
\begin{array}{ll}
0.5x^2 & if (|x| < 1) \\
|x| - 0.5 &otherwise
\end{array}
\right.

Der Standardbegrenzungsrahmen wird durch d dargestellt, der wahre Begrenzungsrahmen wird durch g dargestellt und der wahre Wert wird auf die Skala des Begrenzungsrahmens normiert.


\hat{g}^{cx}_j = (g^{cx}_j - d^{cx}_i) / d^{w}_i,
\hat{g}^{cy}_j = (g^{cy}_j - d^{cy}_i) / d^{h}_i,
\hat{g}^{w}_j = \log(g^{w}_j / d^{w}_i),
\hat{g}^{h}_j = \log(g^{h}_j / d^{h}_i),

Verlustfunktion für die Klasse

Der erste Term repräsentiert die Vorhersagen für jede Klasse und der zweite Term repräsentiert die Hintergrundvorhersagen.

L_{conf}(x, c) = -\sum^N_{i \in Pos}x^p_{ij}\log(\hat{c}^p_i) -\sum^N_{i \in Neg}x^p_{ij}\log(\hat{c}^0_i)

Die Klassifizierung ist eine Softmax-Funktion

\hat{c}^p_i = \frac{\exp(c^p_i)}{\sum_p{\exp(c^p_i)}}

Choosing scales and aspect ratios for default boxes

Da die Feature-Maps mehrskalig sind, gibt jede Feature-Map dem zu erkennenden Objekt eine Rolle. Je größer m, desto kleiner der Maßstab. Dies bedeutet, dass das Objekt umso kleiner erkannt wird, je tiefer das Modell ist.

s_k = s_{min} + \frac{s_{max} - s_{min}}{m-1}(k-1)

Stellen Sie das Seitenverhältnis des standardmäßig vorbereiteten Begrenzungsrahmens wie folgt ein


a_r = {1, 2, 3, 1/2, 1/3}

Berechnen Sie jeweils die Breite und Höhe und bereiten Sie einen Begrenzungsrahmen vor.

Breite


w^a_k = s_k \sqrt{a_r}

Höhe


h^a_k = s_k / \sqrt{a_r}

Wenn das Seitenverhältnis 1 ist, bereiten Sie einen Begrenzungsrahmen vor, auf den die folgende Skala angewendet wird.


s_k' = \sqrt{s_ks_k+1}

Hard negative mining

Da viele negative Begrenzungsrahmen angezeigt werden, sortieren Sie sie in der Reihenfolge ihrer Zuverlässigkeit, nehmen Sie sie von oben auf und ändern Sie sie so, dass das Verhältnis 3: 1 beträgt (negatives Beispiel: positives Beispiel).

Data augmentation

Spezifisches Implementierungsbeispiel

Sie können Leute sagen hören, dass sie die abstrakten Konzepte und Methoden verstehen und wie sie implementiert werden. Implementieren Sie mit Keras v2.0 anhand des folgenden Codes.

A port of SSD: Single Shot MultiBox Detector to Keras framework.

Da der ursprüngliche Code nicht mit der Keras 2.0-Serie kompatibel ist, verweise ich auf den Code, der durch Pull-Anfrage korrigiert wurde. Beschrieb die Umgebungsbereitstellung durch Docker.

https://github.com/SnowMasaya/ssd_keras

Modell verstehen

Tensorflow verfügt über ein Visualisierungstool namens Tensorboard, das zur Visualisierung verwendet wird.

Stellen Sie das Tensorboard-Modell grafisch dar, um das Gesamtbild zu erhalten.

CNN-Schicht

Screen Shot 2017-06-26 at 14.33.10.png

Der Teil, in dem die Feature-Map vereint ist

--Offset (Position): mbox_loc

Screen Shot 2017-06-26 at 14.33.44.png

Letzte Schicht

Wird mithilfe der kombinierten Feature-Map vorhergesagt

Screen Shot 2017-06-26 at 14.37.28.png

Den spezifischen Code verstehen

Nachdem Sie das konzeptionelle Diagramm verstanden haben, verstehen Sie die spezifische Verarbeitung.

Modellbeschreibung

ssd_v2.py

Screen Shot 2017-06-26 at 10.19.02.png

In ssd werden verschiedene Ebenen der Feature-Map kombiniert und ausgegeben.

Das Folgende ist der Prozess der Verkettung der Versatz- bzw. Klassenidentifikationsschichten. Da die 0. Dimension die Dimension von Daten ist, nimmt die Dimension der Merkmalsmenge der 1. Dimension zu.

        mbox_loc = concatenate([conv4_3_norm_mbox_loc_flat,
                                fc7_mbox_loc_flat,
                                conv6_2_mbox_loc_flat,
                                conv7_2_mbox_loc_flat,
                                conv8_2_mbox_loc_flat,
                                pool6_mbox_loc_flat],
                               axis=1, name='mbox_loc')
        mbox_conf = concatenate([conv4_3_norm_mbox_conf_flat,
                                 fc7_mbox_conf_flat,
                                 conv6_2_mbox_conf_flat,
                                 conv7_2_mbox_conf_flat,
                                 conv8_2_mbox_conf_flat,
                                 pool6_mbox_conf_flat],
                                axis=1, name='mbox_conf')
num_boxes = mbox_loc._keras_shape[-1] // 4

Die Anzahl der Felder kann ermittelt werden, indem der Merkmalsbetrag der Position (alle verkettet) durch 4 geteilt wird. Verwenden Sie also diesen Wert.

Die unten verketteten Dimensionen werden in die Versatzdimension und die Klassenidentifikationsdimension geändert.

Num_boxes-Dimension: 7308 Dimension von mbox_loc: 29232 (7308 * 4) Dimension von mbox_conf: 153468 (7308 * Anzahl der Klassen (21))

        mbox_loc = Reshape((num_boxes, 4),
                           name='mbox_loc_final')(mbox_loc)
        mbox_conf = Reshape((num_boxes, num_classes),
                            name='mbox_conf_logits')(mbox_conf)

In der Ausgabeebene ist dies ein Prozess, der Offset, Klassenidentifikation und Begrenzungsrahmen (x, y, h, w und Varianz von jeweils 4 Koordinaten) verkettet. Da die 0. Dimension die Dimension von Daten und die 1. Dimension die Dimension der Anzahl der Begrenzungsrahmen ist, nimmt die Dimension des Merkmalsbetrags der 2. Dimension zu.

    predictions = concatenate([mbox_loc,
                               mbox_conf,
                               mbox_priorbox],
                              axis=2,
                              name='predictions')

Beschreibung der für SSD erforderlichen Verarbeitung

ssd_utils.py konfiguriert den Begrenzungsrahmen.

Methodenliste

--decode_boxes: Konvertieren von Positionsvorhersagen in übereinstimmende Begrenzungsrahmenwerte.

Als Argumente werden vier Positionsversätze, ein Begrenzungsrahmenversatz und eine Begrenzungsrahmenverteilung verwendet. Der Grund für die Verwendung der Verteilung ist, dass der Wert nicht eindeutig bestimmt wird, sodass Vorhersagen mit einem bestimmten Bereich möglich sind.

1: Ermitteln Sie die mittlere Position, Breite und Höhe aus den Versatzinformationen des Begrenzungsrahmens. 2: Um die zu decodierende Grenzbox zu erhalten, werden die Mittelposition, Breite und Höhe der decodierten Grenzbox unter Verwendung der obigen Werte und der Dispersion erhalten. Da der vorhergesagte Wert klein ist, wird er durch exp in einen Wert von ausreichender Größe umgewandelt. Es ist zu beachten, dass die Dispersion berücksichtigt wird. Der vorhergesagte Mittelpunkt, die Breite und die Höhe werden unter Berücksichtigung der Wahrscheinlichkeit berücksichtigt, um Abweichungen der Werte aufgrund der Streuung zu berücksichtigen. 3: Konvertieren Sie von der Mittelposition für minimale und maximale Offsets 4: Kombinieren Sie die erhaltenen Werte zu einem Vektor 5: Geben Sie nur den Bereich 0 oder mehr und 1 oder weniger vom konvertierten Wert zurück.


    def decode_boxes(self, mbox_loc, mbox_priorbox, variances):
        prior_width = mbox_priorbox[:, 2] - mbox_priorbox[:, 0]
        prior_height = mbox_priorbox[:, 3] - mbox_priorbox[:, 1]
        prior_center_x = 0.5 * (mbox_priorbox[:, 2] + mbox_priorbox[:, 0])
        prior_center_y = 0.5 * (mbox_priorbox[:, 3] + mbox_priorbox[:, 1])

        decode_bbox_center_x = mbox_loc[:, 0] * prior_width * variances[:, 0]
        decode_bbox_center_x += prior_center_x
        decode_bbox_center_y = mbox_loc[:, 1] * prior_width * variances[:, 1]
        decode_bbox_center_y += prior_center_y
        decode_bbox_width = np.exp(mbox_loc[:, 2] * variances[:, 2])
        decode_bbox_width *= prior_width
        decode_bbox_height = np.exp(mbox_loc[:, 3] * variances[:, 3])
        decode_bbox_height *= prior_height

        decode_bbox_xmin = decode_bbox_center_x - 0.5 * decode_bbox_width
        decode_bbox_ymin = decode_bbox_center_y - 0.5 * decode_bbox_height
        decode_bbox_xmax = decode_bbox_center_x + 0.5 * decode_bbox_width
        decode_bbox_ymax = decode_bbox_center_y + 0.5 * decode_bbox_height

        decode_bbox = np.concatenate((decode_bbox_xmin[:, None],
                                      decode_bbox_ymin[:, None],
                                      decode_bbox_xmax[:, None],
                                      decode_bbox_ymax[:, None]), axis=-1)
       
        decode_bbox = np.minimum(np.maximum(decode_bbox, 0.0), 1.0)

        return decode_bbox

Detection_out: Gibt das vorhergesagte Ergebnis zurück

1: Holen Sie sich Position, Varianz, Begrenzungsrahmen und Vertrauen aus vorhergesagten Werten 2: Konvertieren Sie den Positionswert in einen Begrenzungsrahmen 3: Wenn die Sicherheit der Klasse über einem bestimmten Niveau liegt, ermitteln Sie den Wert des Begrenzungsrahmens. 4: Geben Sie die Top 200 Ergebnisse zurück


    def detection_out(self, predictions, background_label_id=0, keep_top_k=200,
                      confidence_threshold=0.01):

        mbox_loc = predictions[:, :, :4]
        variances = predictions[:, :, -4:]
        mbox_priorbox = predictions[:, :, -8:-4]
        mbox_conf = predictions[:, :, 4:-8]
        results = []
        for i in range(len(mbox_loc)):
            results.append([])
            
            decode_bbox = self.decode_boxes(mbox_loc[i],
                                            mbox_priorbox[i], variances[i])
            
            for c in range(self.num_classes):
                if c == background_label_id:
                    continue
                c_confs = mbox_conf[i, :, c]
                c_confs_m = c_confs > confidence_threshold
                if len(c_confs[c_confs_m]) > 0:
                    boxes_to_process = decode_bbox[c_confs_m]
                    confs_to_process = c_confs[c_confs_m]
                    feed_dict = {self.boxes: boxes_to_process,
                                 self.scores: confs_to_process}
                    idx = self.sess.run(self.nms, feed_dict=feed_dict)
                    good_boxes = boxes_to_process[idx]
                    confs = confs_to_process[idx][:, None]
                    labels = c * np.ones((len(idx), 1))
                    c_pred = np.concatenate((labels, confs, good_boxes),
                                            axis=1)
                    results[-1].extend(c_pred)
            
            if len(results[-1]) > 0:
                results[-1] = np.array(results[-1])
                argsort = np.argsort(results[-1][:, 1])[::-1]
                results[-1] = results[-1][argsort]
                results[-1] = results[-1][:keep_top_k]
        return results

ssd_layers.py legt die Klasse von PriorBox fest, die die Größe des Begrenzungsrahmens bestimmt. Die schwarzen und roten Linien in der Abbildung.

Screen Shot 2017-06-26 at 17.00.25.png

1: Ermitteln Sie die Breite und Höhe der Feature-Map 2: Ermitteln Sie die Breite und Höhe des Eingabebildes 3: Fügen Sie die Größe des Begrenzungsrahmens dem Seitenverhältnis hinzu 4: Die Verarbeitung hängt davon ab, ob das Seitenverhältnis 1 beträgt oder nicht. 5: Definition der Mittelposition der Box 6: Minimale und maximale Begrenzungsrahmeneinstellungen 7: Verteilungseinstellung 8: Begrenzungsrahmen und Verteilung festlegen und im Tensorflow-Format zurückgeben


class PriorBox(Layer):
    
    #Kürzung

    def call(self, x, mask=None):
        if hasattr(x, '_keras_shape'):
            input_shape = x._keras_shape
        elif hasattr(K, 'int_shape'):
            input_shape = K.int_shape(x)

        layer_width = input_shape[self.waxis]
        layer_height = input_shape[self.haxis]
         
        img_width = self.img_size[0]
        img_height = self.img_size[1]
        # define prior boxes shapes
        box_widths = []
        box_heights = []

        for ar in self.aspect_ratios:
            if ar == 1 and len(box_widths) == 0:
                box_widths.append(self.min_size)
                box_heights.append(self.min_size)
            elif ar == 1 and len(box_widths) > 0:
                box_widths.append(np.sqrt(self.min_size * self.max_size))
                box_heights.append(np.sqrt(self.min_size * self.max_size))
            elif ar != 1:
                box_widths.append(self.min_size * np.sqrt(ar))
                box_heights.append(self.min_size / np.sqrt(ar))
        box_widths = 0.5 * np.array(box_widths)
        box_heights = 0.5 * np.array(box_heights)

        #Ermitteln Sie die Schrittweite, indem Sie die Bildgröße durch die Feature-Größe dividieren
        step_x = img_width / layer_width
        step_y = img_height / layer_height
        #Linspace-Verarbeitung
        #     https://docs.scipy.org/doc/numpy/reference/generated/numpy.linspace.html
        # np.linspace(2.0, 3.0, num=5)
        #   -> array([ 2.  ,  2.25,  2.5 ,  2.75,  3.  ])
        #Holen Sie sich vertikale und horizontale Arrays für die Anzahl der Features für jede Schrittweite
        linx = np.linspace(0.5 * step_x, img_width - 0.5 * step_x,
                           layer_width)
        liny = np.linspace(0.5 * step_y, img_height - 0.5 * step_y,
                           layer_height)
        #Verarbeitung von Meshgrid
        #     https://docs.scipy.org/doc/numpy/reference/generated/numpy.meshgrid.html
        # xv, yv = np.meshgrid(x, y)
        # xv
        # -> array([[ 0. ,  0.5,  1. ],
        #          [ 0. ,  0.5,  1. ]])
        # yv
        # -> array([[ 0.,  0.,  0.],
        #          [ 1.,  1.,  1.]])
        #Passen Sie das zuvor erstellte Feature-Array an
        centers_x, centers_y = np.meshgrid(linx, liny)
        centers_x = centers_x.reshape(-1, 1)
        centers_y = centers_y.reshape(-1, 1)

        num_priors_ = len(self.aspect_ratios)
        prior_boxes = np.concatenate((centers_x, centers_y), axis=1)
        prior_boxes = np.tile(prior_boxes, (1, 2 * num_priors_))
        prior_boxes[:, ::4] -= box_widths
        prior_boxes[:, 1::4] -= box_heights
        prior_boxes[:, 2::4] += box_widths
        prior_boxes[:, 3::4] += box_heights
        prior_boxes[:, ::2] /= img_width
        prior_boxes[:, 1::2] /= img_height
        prior_boxes = prior_boxes.reshape(-1, 4)
        if self.clip:
            prior_boxes = np.minimum(np.maximum(prior_boxes, 0.0), 1.0)
        num_boxes = len(prior_boxes)
        if len(self.variances) == 1:
            variances = np.ones((num_boxes, 4)) * self.variances[0]
        elif len(self.variances) == 4:
            variances = np.tile(self.variances, (num_boxes, 1))
        else:
            raise Exception('Must provide one or four variances.')
        prior_boxes = np.concatenate((prior_boxes, variances), axis=1)
        prior_boxes_tensor = K.expand_dims(K.variable(prior_boxes), 0)
        if K.backend() == 'tensorflow':
            pattern = [tf.shape(x)[0], 1, 1]
            prior_boxes_tensor = tf.tile(prior_boxes_tensor, pattern)
        return prior_boxes_tensor

Lernen

Der Lernprozess wird mit SSD_training.ipynb durchgeführt.

Da der Lernprozess von "model.fit_generator" ausgeführt wird, wird der Generatorprozess einschließlich der Datenerweiterung von "Generator" ausgeführt. Lehrerdaten (Beschriftungen, Versätze, Begrenzungsrahmen) Es wird in assign_boxes von ssd_utils.py gesetzt.

ssd_utils.py legt den Begrenzungsrahmen fest.

Der Begrenzungsrahmen hat für jeden Versatz einen Versatzwert und einen Verteilungswert

priors[i] = [xmin, ymin, xmax, ymax, varxc, varyc, varw, varh].

Methodenliste

--assign_boxes: Weisen Sie während des Lernens nur Prioritätsfelder zu --encode_box: Der Prozess des Änderns des Begrenzungsrahmens in einen tiefen Lernraum, der von "assign_boxes" aufgerufen wird --iou: Berechnen Sie die Anzahl der von encode_box aufgerufenen Bounding-Box-Schnittpunkte

iou

Screen Shot 2017-06-27 at 13.42.35.png

1: Ermitteln Sie die Koordinaten oben links und unten rechts mithilfe des True-Felds und des vorhergesagten Felds. 2: Berechnen Sie den Bereich der Überlappung zwischen der wahren Box und der vorhergesagten Box basierend auf den erhaltenen Koordinaten. 3: Berechnen Sie die vorhergesagte Boxfläche. 4: Berechnen Sie die Fläche der True Box. 5: Subtrahieren Sie den inneren Bereich von der Gesamtfläche der wahren Box und der vorhergesagten Box. 6: Teilen Sie die Fläche des überlappenden Teils durch den Wert 5 (die Fläche des nicht überlappenden Teils).

Die Bedeutung von 6 ist, dass je größer die Fläche des überlappenden Teils ist, desto kleiner die Fläche des nicht überlappenden Teils ist und es ein Index ist, um zu verstehen, wie nahe die vorhergesagte Box an der wahren Box liegt.

        inter_upleft = np.maximum(self.priors[:, :2], box[:2])
        inter_botright = np.minimum(self.priors[:, 2:4], box[2:])
        inter_wh = inter_botright - inter_upleft
        inter_wh = np.maximum(inter_wh, 0)
        inter = inter_wh[:, 0] * inter_wh[:, 1]
        # compute union
        area_pred = (box[2] - box[0]) * (box[3] - box[1])
        area_gt = (self.priors[:, 2] - self.priors[:, 0])
        area_gt *= (self.priors[:, 3] - self.priors[:, 1])
        union = area_pred + area_gt - inter
        # compute iou
        iou = inter / union
        return iou

encode_box

1: Spielen Sie unter den von "iou" erworbenen Feldern den Begrenzungsrahmen mit einem Schnittverhältnis von 0,5 oder weniger. 2: Ermitteln Sie die Mittelposition und Breite der True Box Ermitteln Sie die Mittelposition und Breite der vorhergesagten Box, die die 3: 1-Bedingung erfüllt 4: Bereiten Sie eine Encode-Box zum Lernen und Verwenden vor 5: Zeichnen Sie die Mittelposition der wahren Box und die Mittelposition der vorhergesagten Box (Sie können sehen, wie groß der Unterschied ist). Teilen Sie den Wert 6: 5 durch die Breite des vorhergesagten Felds (Sie können das Verhältnis sehen). Teilen Sie den 7: 6-Wert durch die vorhergesagte Box-Varianz 8: Teilen Sie die Breite der codierten Box durch die Breite der wahren Box und die Breite der vorhergesagten Box, um den Logarithmus zu erhalten. 9: Teilen Sie die Breite der codierten Box durch die vorhergesagte Breite der Box

Die Verarbeitung 8 und 9 ist ein Umwandlungsprozess für die Verlustfunktion in Bezug auf die Position.

        iou = self.iou(box)
        encoded_box = np.zeros((self.num_priors, 4 + return_iou))
        assign_mask = iou > self.overlap_threshold
        if not assign_mask.any():
            assign_mask[iou.argmax()] = True
        if return_iou:
            encoded_box[:, -1][assign_mask] = iou[assign_mask]
        assigned_priors = self.priors[assign_mask]
        box_center = 0.5 * (box[:2] + box[2:])
        box_wh = box[2:] - box[:2]
        assigned_priors_center = 0.5 * (assigned_priors[:, :2] +
                                        assigned_priors[:, 2:4])
        assigned_priors_wh = (assigned_priors[:, 2:4] -
                              assigned_priors[:, :2])
        # we encode variance
        encoded_box[:, :2][assign_mask] = box_center - assigned_priors_center
        encoded_box[:, :2][assign_mask] /= assigned_priors_wh
        encoded_box[:, :2][assign_mask] /= assigned_priors[:, -4:-2]
        encoded_box[:, 2:4][assign_mask] = np.log(box_wh /
                                                  assigned_priors_wh)
        encoded_box[:, 2:4][assign_mask] /= assigned_priors[:, -2:]
        return encoded_box.ravel()

assign_boxes

1: Bereiten Sie einen Begrenzungsrahmen und Zuweisungen vor, die mit der Anzahl der Klassen, dem Versatz und der Varianz initialisiert wurden. 2: Bereiten Sie eine codierte True Box vor 3: Holen Sie sich nur den Maximalwert der True Box und der vorhergesagten Box 4: Holen Sie sich nur den Index des Maximalwerts der wahren Box und der vorhergesagten Box Wählen Sie nur solche mit einem Verhältnis von 5: 0 oder mehr aus 6: Ersetzen Sie den Versatz des Felds, das den zuzuweisenden Versatz codiert, der die obigen Bedingungen erfüllt. 7: Klassenzuordnung 8: Bereiten Sie positive Proben im Voraus vor, um mit positiven und negativen Proben zu studieren

        # 
        assignment = np.zeros((self.num_priors, 4 + self.num_classes + 8))
        assignment[:, 4] = 1.0
        if len(boxes) == 0:
            return assignment
        encoded_boxes = np.apply_along_axis(self.encode_box, 1, boxes[:, :4])
        encoded_boxes = encoded_boxes.reshape(-1, self.num_priors, 5)
        best_iou = encoded_boxes[:, :, -1].max(axis=0)
        best_iou_idx = encoded_boxes[:, :, -1].argmax(axis=0)
        best_iou_mask = best_iou > 0
        best_iou_idx = best_iou_idx[best_iou_mask]
        assign_num = len(best_iou_idx)
        encoded_boxes = encoded_boxes[:, best_iou_mask, :]
        #Weisen Sie codierte Koordinaten zu
        assignment[:, :4][best_iou_mask] = encoded_boxes[best_iou_idx,
                                                         np.arange(assign_num),
                                                         :4]
        assignment[:, 4][best_iou_mask] = 0
        #Klassenzuordnung
        assignment[:, 5:-8][best_iou_mask] = boxes[best_iou_idx, 4:]
        #Zuordnung positiver Stichproben zum Lernen
        assignment[:, -8][best_iou_mask] = 1
        return assignment

ssd_training.py

Die Verlustfunktion zur Positions- und Klassenidentifikation ist in ssd_training.py eingestellt. Die erste Werteinstellung bestimmt die Anzahl der Klassen, das Verhältnis der Klassenverlustfunktion zur Positionsverlustfunktion und das Verhältnis der negativen Beispiele.

class MultiboxLoss(object):

    def __init__(self, num_classes, alpha=1.0, neg_pos_ratio=3.0,
                 background_label_id=0, negatives_for_hard=100.0):
        self.num_classes = num_classes
        self.alpha = alpha
        self.neg_pos_ratio = neg_pos_ratio
        if background_label_id != 0:
            raise Exception('Only 0 as background label id is supported')
        self.background_label_id = background_label_id
        self.negatives_for_hard = negatives_for_hard

Unten ist die Funktion l1_smooth aufgeführt, die in der Positionsverlustfunktion verwendet wird.


    def _l1_smooth_loss(self, y_true, y_pred):
        abs_loss = tf.abs(y_true - y_pred)
        sq_loss = 0.5 * (y_true - y_pred)**2
        l1_loss = tf.where(tf.less(abs_loss, 1.0), sq_loss, abs_loss - 0.5)
        return tf.reduce_sum(l1_loss, -1)

Unten ist die Funktion soft_max aufgeführt, die in der Klassenverlustfunktion verwendet wird.


    def _softmax_loss(self, y_true, y_pred):
        y_pred = tf.maximum(tf.minimum(y_pred, 1 - 1e-15), 1e-15)
        softmax_loss = -tf.reduce_sum(y_true * tf.log(y_pred),
                                      axis=-1)
        return softmax_loss

Der Mehrfachverlust wird berechnet, indem die Positionsverlustfunktion und die Klassenidentifikationsverlustfunktion unten hinzugefügt werden.

1: Berechnen Sie die Identifikation und den Positionsverlust 2: Berechnen Sie den positiven Verlust 3: Berechnen Sie den Verlust negativer Fälle und erhalten Sie nur solche mit hoher Sicherheit 4: Berechnen Sie den Gesamtverlust von negativen und positiven Fällen


    def compute_loss(self, y_true, y_pred):
        batch_size = tf.shape(y_true)[0]
        num_boxes = tf.to_float(tf.shape(y_true)[1])

        #Berechnen Sie den Verlust aller Boxen
        conf_loss = self._softmax_loss(y_true[:, :, 4:-8],
                                       y_pred[:, :, 4:-8])
        loc_loss = self._l1_smooth_loss(y_true[:, :, :4],
                                        y_pred[:, :, :4])

        #Berechnen Sie den positiven Verlust
        num_pos = tf.reduce_sum(y_true[:, :, -8], axis=-1)
        pos_loc_loss = tf.reduce_sum(loc_loss * y_true[:, :, -8],
                                     axis=1)
        pos_conf_loss = tf.reduce_sum(conf_loss * y_true[:, :, -8],
                                      axis=1)

        #Berechnen Sie negative Verluste und erhalten Sie nur solche mit hohem Vertrauen
        #Ermitteln Sie die Anzahl der negativen Fälle
        num_neg = tf.minimum(self.neg_pos_ratio * num_pos,
                             num_boxes - num_pos)
        # 
        pos_num_neg_mask = tf.greater(num_neg, 0)
        has_min = tf.to_float(tf.reduce_any(pos_num_neg_mask))
        num_neg = tf.concat(axis=0, values=[num_neg,
                                [(1 - has_min) * self.negatives_for_hard]])
        num_neg_batch = tf.reduce_min(tf.boolean_mask(num_neg,
                                                      tf.greater(num_neg, 0)))
        num_neg_batch = tf.to_int32(num_neg_batch)
        confs_start = 4 + self.background_label_id + 1
        confs_end = confs_start + self.num_classes - 1
        max_confs = tf.reduce_max(y_pred[:, :, confs_start:confs_end],
                                  axis=2)
        _, indices = tf.nn.top_k(max_confs * (1 - y_true[:, :, -8]),
                                 k=num_neg_batch)
        batch_idx = tf.expand_dims(tf.range(0, batch_size), 1)
        batch_idx = tf.tile(batch_idx, (1, num_neg_batch))
        full_indices = (tf.reshape(batch_idx, [-1]) * tf.to_int32(num_boxes) +
                        tf.reshape(indices, [-1]))
        neg_conf_loss = tf.gather(tf.reshape(conf_loss, [-1]),
                                  full_indices)
        neg_conf_loss = tf.reshape(neg_conf_loss,
                                   [batch_size, num_neg_batch])
        neg_conf_loss = tf.reduce_sum(neg_conf_loss, axis=1)

        # loss is sum of positives and negatives
        total_loss = pos_conf_loss + neg_conf_loss
        total_loss /= (num_pos + tf.to_float(num_neg_batch))
        num_pos = tf.where(tf.not_equal(num_pos, 0), num_pos,
                            tf.ones_like(num_pos))
        total_loss += (self.alpha * pos_loc_loss) / num_pos
        return total_loss

Trainingsdaten

Bilddaten Etikettendaten: Versatz und Klassenbeschreibung

Etikettendaten werden in XML im folgenden Format beschrieben. Sie können die Klassenbezeichnung und den Versatz sehen.

<annotation>
        <folder>VOC2007</folder>
        <filename>000032.jpg</filename>
        <source>
                <database>The VOC2007 Database</database>
                <annotation>PASCAL VOC2007</annotation>
                <image>flickr</image>
                <flickrid>311023000</flickrid>
        </source>
        <owner>
                <flickrid>-hi-no-to-ri-mo-rt-al-</flickrid>
                <name>?</name>
        </owner>
        <size>
                <width>500</width>
                <height>281</height>
                <depth>3</depth>
        </size>
        <segmented>1</segmented>
        <object>
                <name>aeroplane</name>
                <pose>Frontal</pose>
                <truncated>0</truncated>
                <difficult>0</difficult>
                <bndbox>
                        <xmin>104</xmin>
                        <ymin>78</ymin>
                        <xmax>375</xmax>
                        <ymax>183</ymax>
                </bndbox>
        </object>
        <object>
                <name>aeroplane</name>
                <pose>Left</pose>
                <truncated>0</truncated>
                <difficult>0</difficult>
                <bndbox>
                        <xmin>133</xmin>
                        <ymin>88</ymin>
                        <xmax>197</xmax>
                        <ymax>123</ymax>
                </bndbox>
        </object>
        <object>
                <name>person</name>
                <pose>Rear</pose>
                <truncated>0</truncated>
                <difficult>0</difficult>
                <bndbox>
                        <xmin>195</xmin>
                        <ymin>180</ymin>
                        <xmax>213</xmax>
                        <ymax>229</ymax>
                </bndbox>
        </object>
        <object>
                <name>person</name>
                <pose>Rear</pose>
                <truncated>0</truncated>
                <difficult>0</difficult>
                <bndbox>
                        <xmin>26</xmin>
                        <ymin>189</ymin>
                        <xmax>44</xmax>
                        <ymax>238</ymax>
                </bndbox>
        </object>
</annotation>

Da auch ein Bild mehrere Offsets haben kann, gibt es so viele Etikettendatenformate wie Begrenzungsrahmen. Der Begrenzungsrahmen ist als "prior_boxes_ssd300.pkl" definiert. prior_box_variance repräsentiert die Bounding-Box-Varianz.

[xmin, ymin, xmax, ymax, binary_class_label[Hängt von der Anzahl der Klassen ab],  prior_box_xmin, prior_box_ymin, prior_box_xmax, prior_box_ymax, prior_box_variance_xmin, prior_box_variance_ymin, prior_box_variance_xmax, prior_box_variance_ymax,]
[xmin, ymin, xmax, ymax, binary_class_label[Hängt von der Anzahl der Klassen ab],  prior_box_xmin, prior_box_ymin, prior_box_xmax, prior_box_ymax, prior_box_variance_xmin, prior_box_variance_ymin, prior_box_variance_xmax, prior_box_variance_ymax,]

:

So bereiten Sie Ihre eigenen Trainingsdaten vor

Ich denke, es gibt eine Bitte, Trainingsdaten selbst vorzubereiten und zu kommentieren. Wenn Sie das folgende Tool verwenden, können Sie die mit Anmerkungen versehenen Daten im selben XML-Format wie dieses Mal vorbereiten. Es wird daher empfohlen.

https://github.com/tzutalin/labelImg

Ich bin jedoch süchtig nach der Installation, daher werde ich Ihnen den Fall mitteilen, von dem ich in meiner Umgebung abhängig war.

OS: macOS Sierra 10.12.5 (16F73)

Bitte richten Sie die virtuelle Umgebung von Python ein! !! Es kann verschiedene Dinge geben, aber wenn Sie dies nicht tun, wird es katastrophal sein, wenn Sie süchtig werden.

SIP herunterladen und installieren

https://riverbankcomputing.com/software/sip/download

cd  {download folder}/SIP

python configure.py
make
make install

Laden Sie PyQt5 herunter und installieren Sie es

Ich habe PyQt5 installiert, weil ich es in einer Python3-Umgebung versucht habe. Die neueste Version 5.8 wird aufgrund eines Fehlers nicht gestartet. Geben Sie daher die vorherige Version explizit an und laden Sie sie herunter.

pip install PyQt5==5.7.1

Installation von libxml

Da die libxml-Verarbeitung ausgeführt wird, installieren Sie sie unten. (Für Mac)

brew install libxml2

Beim Speichern einer Datei mit einem japanischen Namen werden verstümmelte Zeichen angezeigt, sodass dies behoben wurde. Bitte überprüfen und beheben Sie Folgendes, bis die Pull-Anforderung zusammengeführt wird.

https://github.com/SnowMasaya/labelImg/commit/066eb78704fb0bc551dbb5aebccd8804dae3ed9e

Geschultes Modell

Caffe bietet eine Reihe von ausgebildeten Modellen an. Wenn Sie das trainierte Modell mit Keras verwenden möchten, benötigen Sie einen Konverter.

Screenshot from 2017-07-18 08:47:54.png

Sie können das trainierte Modell von Caffe unten erhalten.

https://github.com/weiliu89/caffe/tree/ssd

Verwenden Sie für die Konvertierung Folgendes.

deploy.prototxt
*.caffemodel

deploy.protxt muss die Eingabeebene wie folgt konvertieren. Der * Teil hängt vom Modell ab.

Vor der Konvertierung

input: "data"
input_shape {
  dim: *
  dim: *
  dim: *
  dim: *
}

Nach der Konvertierung

layer {
  name: "input_1"
  type: "Input"
  top: "data"
  input_param {
    # These dimensions are purely for sake of example;
    # see infer.py for how to reshape the net to the given input size.
    shape { dim: * dim: * dim: * dim: * }
  }
}

Referenz

Creating object detection network using SSD

SSD: Single Shot MultiBox Detector (ECCV2016)

SSD: Single-Shot-MultiBox-Detektor Testen Sie die Hochgeschwindigkeits-Demo zur Objekterkennung in Echtzeit mit Keras

Irasutoya

A port of SSD: Single Shot MultiBox Detector to Keras framework.

Liu, Wei, et al. "Ssd: Single shot multibox detector." European conference on computer vision. Springer, Cham, 2016.

SSD: Single-Shot-MultiBox-Detektor Testen Sie die Hochgeschwindigkeits-Demo zur Objekterkennung in Echtzeit mit Keras

Lernen wir den Objekterkennungsalgorithmus (SSD: Single Shot MultiBox Detector)

SSD: Single Shot MultiBox Detector

Recommended Posts

Objekterkennung durch tiefes Lernen, Keras tief zu verstehen
Paralleles Lernen von Deep Learning durch Keras und Kubernetes
[Erkennung von Abnormalitäten] Erkennen Sie Bildverzerrungen durch Fernunterricht
Klassifizieren Sie Anime-Gesichter durch Fortsetzung / Deep Learning mit Keras
Grundlegendes Verständnis der Tiefenschätzung mit einer Monokamera (Deep Learning)
Deep Learning durch Implementierung 1 gelernt (Return Edition)
Tiefes Lernen
Deep Learning 2 durch Implementierung gelernt (Bildklassifizierung)
Produzieren Sie wunderschöne Seekühe durch tiefes Lernen
[Deep Learning] Nogisaka Gesichtserkennung ~ Für Anfänger ~
Chainer und Deep Learning durch Funktionsnäherung gelernt
Deep Learning Memorandum
Starten Sie Deep Learning
Grundlegendes Verständnis der Stereo-Tiefenschätzung (Deep Learning)
99,78% Genauigkeit bei tiefem Lernen durch Erkennen von handgeschriebenem Hiragana
Videorahmeninterpolation durch tiefes Lernen Teil 1 [Python]
Python Deep Learning
Ich habe versucht, das Objekterkennungs-Tutorial mit dem neuesten Deep-Learning-Algorithmus auszuführen
Deep Learning × Python
Tiefes Lernen durch Implementierung (Segmentierung) ~ Implementierung von SegNet ~
[Für Anfänger im Deep Learning] Implementierung einer einfachen binären Klassifizierung durch vollständige Kopplung mit Keras
Deep Learning of Object Detection 7 Artikel zum Lesen und Zusammenfassen von Punkten [Road to Efficient Det]
Aktieninvestitionen durch tiefgreifendes Lernen (Policy Gradient Method) (1)
Erkennung abnormaler Werte durch unbeaufsichtigtes Lernen: Maharanobis-Distanz (Implementierung)
Abnormalitätserkennung von Zeitreihendaten durch LSTM (Keras)
Deep Learning Bildanalyse beginnend mit Kaggle und Keras
Techniken zum Verständnis der Grundlagen von Deep-Learning-Entscheidungen
Erkennung abnormaler Werte durch unbeaufsichtigtes Lernen: Maharanobis-Distanz (Theorie)
Erstes tiefes Lernen ~ Kampf ~
Python: Deep Learning-Praxis
Deep Learning / Aktivierungsfunktionen
Deep Learning von Grund auf neu
Deep Learning 1 Übung des Deep Learning
Machine Sommelier von Keras-
Erstes tiefes Lernen ~ Lösung ~
[AI] Deep Metric Learning
Ich habe versucht, tief zu lernen
Python: Deep Learning Tuning
Deep Learning Großtechnologie
Deep Learning / Softmax-Funktion
Anwendung der affinen Umwandlung durch Tensor - von der Basis- zur Objekterkennung -
Ich habe versucht, die Erkennung von Anomalien durch spärliches Strukturlernen zu implementieren
"Lernen Sie, während Sie machen! Entwicklung tiefes Lernen von PyTorch" auf Colaboratory.
Erstellen Sie eine KI, die Zuckerbergs Gesicht mit tiefem Lernen identifiziert learning (Datenlernen)
Selbstgesteuertes Lied durch tiefes Lernen (gestapelte LSTM-Ausgabe) [DW Tag 6]
Abnormalitätserkennung durch Auto-Encoder mit Keras [Implementierungsbeispiel für Anfänger]