[PYTHON] Tiefes Lernen durch Implementierung (Segmentierung) ~ Implementierung von SegNet ~

Umgebung

tensorflow == 2.2.0 keras == 2.3.1 (Standardversion von Google Colab ab 202.6.10)

Code

Sie finden den gesamten Code auf github. https://github.com/milky1210/Segnet Der Code im Artikel ist ein Auszug. Wenn Sie ihn also tatsächlich bearbeiten möchten, laden Sie den Code herunter.

Zusammenfassung der SegNet-Papiere

スクリーンショット 2020-06-09 13.18.49.png

Abstrakt

Bei dem Problem, die Beschriftung dessen, was für jedes Pixel des Bildes reflektiert wird, als SEMANTIC-Segmentierung durch Deep Learning abzuleiten, ist es genau, die Feature-Map wiederherzustellen, deren Auflösung durch Pooling usw. auf die ursprüngliche Dimension verringert wurde. Wir schlagen ein Modell vor, das der Grenzlinie zugeordnet ist. スクリーンショット 2020-06-09 13.29.43.png

Unterschied zu anderen Studien

SegNet führt UpSampling durch, nachdem die Auflösung in der Faltungsschicht und der Pooling-Schicht wie bei einem normalen FCN verringert wurde. Beim Erhöhen der Auflösung wird jedoch eine als Pooling-Index bezeichnete Technik verwendet, um zu verhindern, dass die Grenze unscharf wird. Es gibt. スクリーンショット 2020-06-09 13.34.45.png Hier erben Encode und Decode die Form des VGG16-Modells (ein Modell, das für seine Bildklassifizierung bekannt ist). Pooling indices スクリーンショット 2020-06-09 13.39.25.png Denken Sie, wie in dieser Abbildung gezeigt, daran, wo sich Max befand, als Max Pooling durchgeführt wurde, und übertragen Sie jede Feature-Map während des UpSampling an diese Position.

Leistungsvergleich mit VOC12

Was ist VOC12?

Es handelt sich um einen Datensatz, der Probleme wie Bilderkennung, Bilderkennung und Segmentierung unterstützt, die auch in den Papieren von SegNet zur Leistungsüberprüfung verwendet werden. Sie können es von [hier] herunterladen (http://host.robots.ox.ac.uk/pascal/VOC/voc2012/).

Beim Herunterladen sind JPEGImages / und SegmentationObject / in VOCdevkit / VOC2012 / enthalten, und Training und Überprüfung werden mit JPEGImage als Eingabebild und SegmentationObject als Ausgabebild durchgeführt.

JPEGImages / ~ .jpg und Segmentation Object / ~ .png werden in jedem Verzeichnis unterstützt. 22 Klassen werden klassifiziert, einschließlich Hintergrund und Grenzen.

Implementierung

In diesem Artikel werden nur die Definition des Modells, die Definition der Verlustfunktion und das Training behandelt. Darüber hinaus werden Schulungen und Überprüfungen mit einer Auflösung von 64 x 64 durchgeführt.

Modelldefinition

Zunächst wird SegNet (Encoder-Decoder) ohne Pooling-Index als Vergleichsziel wie folgt als VGG16 modelliert.

def build_FCN():
  ffc = 32
  inputs = layers.Input(shape=(64,64,3))
  for i in range(2):
    x = layers.Conv2D(ffc,kernel_size=3,padding="same")(inputs)
    x = layers.BatchNormalization()(x)
    x = layers.ReLU()(x)
  x = layers.MaxPooling2D((2,2))(x)
  for i in range(2):
    x = layers.Conv2D(ffc*2,kernel_size=3,padding="same")(x)
    x = layers.BatchNormalization()(x)
    x = layers.ReLU()(x)
  x = layers.MaxPooling2D((2,2))(x)
  for i in range(3):
    x = layers.Conv2D(ffc*4,kernel_size=3,padding="same")(x)
    x = layers.BatchNormalization()(x)
    x = layers.ReLU()(x)
  x = layers.MaxPooling2D((2,2))(x)
  for i in range(3):
    x = layers.Conv2D(ffc*8,kernel_size=3,padding="same")(x)
    x = layers.BatchNormalization()(x)
    x = layers.ReLU()(x)
  x = layers.MaxPooling2D((2,2))(x)
  for i in range(3):
    x = layers.Conv2D(ffc*8,kernel_size=3,padding="same")(x)
    x = layers.BatchNormalization()(x)
    x = layers.ReLU()(x)
  x = layers.UpSampling2D((2,2))(x)
  for i in range(3):
    x = layers.Conv2D(ffc*4,kernel_size=3,padding="same")(x)
    x = layers.BatchNormalization()(x)
    x = layers.ReLU()(x)
  x = layers.UpSampling2D((2,2))(x)
  for i in range(3):
    x = layers.Conv2D(ffc*2,kernel_size=3,padding="same")(x)
    x = layers.BatchNormalization()(x)
    x = layers.ReLU()(x)
  x = layers.UpSampling2D((2,2))(x)
  for i in range(2):
    x = layers.Conv2D(ffc*2,kernel_size=3,padding="same")(x)
    x = layers.BatchNormalization()(x)
    x = layers.ReLU()(x)
  x = layers.UpSampling2D((2,2))(x)
  for i in range(2):
    x = layers.Conv2D(ffc,kernel_size=3,padding="same")(x)
    x = layers.BatchNormalization()(x)
    x = layers.ReLU()(x)
  x = layers.Conv2D(22,kernel_size=3,padding="same",activation="softmax")(x)
  return models.Model(inputs,x)

Wenn das vgg16 nachgeahmt wird, hat es eine solche Struktur und wird zu einem Netzwerk mit 24 Faltungsschichten. Beachten Sie, dass MaxPooling2D verwendet wird, um das Bild zu verkleinern, und UpSampling2D, um das Bild zu vergrößern. Schauen wir uns als nächstes den Unterschied zwischen Segnet und diesem Modell an. Zunächst enthält Segnet die Informationen, die ArgMaxPooling2D entsprechen, in dieser Ebene wie folgt, bevor MaxPooling2D ausgeführt wird. Diese Funktion ist nicht in Keras und verwendet die im Tensorflow. Daher muss der ursprüngliche Keras-Layer erstellt werden. Wenn Sie die Funktion wie folgt definieren, handelt es sich um eine Ebene, die auf Keras ausgeführt wird.

class MaxPoolingWithArgmax2D(Layer):
    def __init__(self):
        super(MaxPoolingWithArgmax2D,self).__init__()
    def call(self,inputs):
        output,argmax = tf.nn.max_pool_with_argmax(inputs,ksize=[1,2,2,1],strides=[1,2,2,1],padding='SAME')
        argmax = K.cast(argmax,K.floatx())
        return [output,argmax]
    def compute_output_shape(self,input_shape):
        ratio = (1,2,2,1)
        output_shape = [dim//ratio[idx] if dim is not None else None for idx, dim in enumerate(input_shape)]
        output_shape = tuple(output_shape)
        return [output_shape,output_shape]

Definieren Sie eine Ebene, um beim nächsten Up Sampling an den Ort zurückzukehren, an dem argmax war (dies ist ziemlich lang).

class MaxUnpooling2D(Layer):
    def __init__(self):
        super(MaxUnpooling2D,self).__init__()
    def call(self,inputs,output_shape = None):
        updates, mask = inputs[0],inputs[1]
        with tf.variable_scope(self.name):
            mask = K.cast(mask, 'int32')
            input_shape = tf.shape(updates, out_type='int32')
            #  calculation new shape
            if output_shape is None:
                output_shape = (input_shape[0],input_shape[1]*2,input_shape[2]*2,input_shape[3])
            self.output_shape1 = output_shape
            # calculation indices for batch, height, width and feature maps
            one_like_mask = K.ones_like(mask, dtype='int32')
            batch_shape = K.concatenate([[input_shape[0]], [1 ], [1], [1]],axis=0)
            batch_range = K.reshape(tf.range(output_shape[0], dtype='int32'),shape=batch_shape)
            b = one_like_mask * batch_range
            y = mask // (output_shape[2] * output_shape[3])
            x = (mask // output_shape[3]) % output_shape[2]
            feature_range = tf.range(output_shape[3], dtype='int32')
            f = one_like_mask * feature_range

            # transpose indices & reshape update values to one dimension
            updates_size = tf.size(updates)
            indices = K.transpose(K.reshape(
                K.stack([b, y, x, f]),
                [4, updates_size]))
            values = K.reshape(updates, [updates_size])
            ret = tf.scatter_nd(indices, values, output_shape)
            return ret
    def compute_output_shape(self,input_shape):
        shape = input_shape[1]
        return (shape[0],shape[1]*2,shape[2]*2,shape[3])

Wenn Segnet unter Verwendung der durch diese definierten Ebene definiert wird, ist dies wie folgt.

def build_Segnet():
    ffc = 32
    inputs = layers.Input(shape=(64,64,3))
    for i in range(2):
      x = layers.Conv2D(ffc,kernel_size=3,padding="same")(inputs)
      x = layers.BatchNormalization()(x)
      x = layers.ReLU()(x)
    x,x1 = MaxPoolingWithArgmax2D()(x)
    for i in range(2):
      x = layers.Conv2D(ffc*2,kernel_size=3,padding="same")(x)
      x = layers.BatchNormalization()(x)
      x = layers.ReLU()(x)
    x,x2 = MaxPoolingWithArgmax2D()(x)
    for i in range(3):
      x = layers.Conv2D(ffc*4,kernel_size=3,padding="same")(x)
      x = layers.BatchNormalization()(x)
      x = layers.ReLU()(x)
    x,x3 = MaxPoolingWithArgmax2D()(x)
    for i in range(3):
      x = layers.Conv2D(ffc*8,kernel_size=3,padding="same")(x)
      x = layers.BatchNormalization()(x)
      x = layers.ReLU()(x)
    x,x4 = MaxPoolingWithArgmax2D()(x)
    for i in range(3):
      x = layers.Conv2D(ffc*8,kernel_size=3,padding="same")(x)
      x = layers.BatchNormalization()(x)
      x = layers.ReLU()(x)
    x = layers.Dropout(rate = 0.5)(x)
    x = MaxUnpooling2D()([x,x4])
    for i in range(3):
      x = layers.Conv2D(ffc*4,kernel_size=3,padding="same")(x)
      x = layers.BatchNormalization()(x)
      x = layers.ReLU()(x)
    x = MaxUnpooling2D()([x,x3])
    for i in range(3):
      x = layers.Conv2D(ffc*2,kernel_size=3,padding="same")(x)
      x = layers.BatchNormalization()(x)
      x = layers.ReLU()(x)
    x = MaxUnpooling2D()([x,x2])
    for i in range(2):
      x = layers.Conv2D(ffc,kernel_size=3,padding="same")(x)
      x = layers.BatchNormalization()(x)
      x = layers.ReLU()(x)
    x = MaxUnpooling2D()([x,x1])
    for i in range(2):
      x = layers.Conv2D(ffc,kernel_size=3,padding="same")(x)
      x = layers.BatchNormalization()(x)
      x = layers.ReLU()(x)
    x = layers.Conv2D(22,kernel_size=3,padding="same",activation="softmax")(x)
    return models.Model(inputs,x)

Verlustfunktion und Optimierung

Diesmal verwendete die Verlustfunktion die Kreuzentropie jedes Pixels. Adam (lr = 0,001, beta_1 = 0,9, beta_2 = 0,999) wurde zur Optimierung verwendet.

Ergebnis

Wir haben bestätigt, wie stark sich das Ergebnis je nach Vorhandensein oder Nichtvorhandensein von Würfelpools ändert. Der Trainingsverlust und der Durchschnitt der korrekten Antwortrate bei jedem Pixel wurden grafisch dargestellt. Erstens das Ergebnis des Modells ohne Pooling-Index acc (1).png

loss (1).png

Die Verifizierungsdaten hatten eine korrekte Antwortrate von ca. 78%. Als nächstes werde ich die Ergebnisse von SegNet veröffentlichen.

acc.png loss.png Es war stabil mit einer korrekten Antwortrate von etwa 82%, und wir konnten das Verhalten gemäß dem Papier sehen.

Beispiel für ein Ausgabebild

Eingabe von links, kein Pooling-Index, alle Testdaten mit SegNet, GT

Es wurde festgestellt, dass das Halten des Pooling-Index die Genauigkeit signifikant verbessern kann.

Recommended Posts

Tiefes Lernen durch Implementierung (Segmentierung) ~ Implementierung von SegNet ~
Deep Learning durch Implementierung 1 gelernt (Return Edition)
Tiefes Lernen durch Implementierung gelernt ~ Erkennung von Abnormalitäten (Lernen ohne Lehrer) ~
Tiefes Lernen der Verstärkung 2 Implementierung des Lernens der Verstärkung
Othello-Aus der dritten Zeile von "Implementation Deep Learning" (3)
Othello-Aus der dritten Zeile von "Implementation Deep Learning" (2)
Chainer und Deep Learning durch Funktionsnäherung gelernt
Deep Learning 1 Übung des Deep Learning
Paralleles Lernen von Deep Learning durch Keras und Kubernetes
Deep Learning von Grund auf neu Die Theorie und Implementierung des mit Python erlernten Deep Learning Kapitel 3
Othello ~ Aus der dritten Zeile von "Implementation Deep Learning" (4) [Ende]
Deep Running 2 Tuning von Deep Learning
[Für Anfänger im Deep Learning] Implementierung einer einfachen binären Klassifizierung durch vollständige Kopplung mit Keras
[Deep Learning von Grund auf neu] Implementierung der Momentum-Methode und der AdaGrad-Methode
Rank Learning über ein neuronales Netzwerk (RankNet-Implementierung von Chainer)
Grundlegendes Verständnis der Tiefenschätzung mit einer Monokamera (Deep Learning)
Zusammenfassung der grundlegenden Implementierung von PyTorch
Deep Learning Bilderkennung 2 Modellimplementierung
Versuchen Sie, eine Blackjack-Strategie zu entwickeln, indem Sie das Lernen stärken ((1) Implementierung von Blackjack)
[Lernnotiz] Grundlagen des Unterrichts mit Python
Bedeutung von Deep-Learning-Modellen und -Parametern
Bedingte Verzweigung von Python mit Chemoinfomatik gelernt
Qiskit: Implementierung von Quantum Circuit Learning (QCL)
Produzieren Sie wunderschöne Seekühe durch tiefes Lernen
Implementierung von SVM durch probabilistische Gradientenabstiegsmethode
Versuchen Sie mit Kipoi tiefes Erlernen der Genomik
Algorithmus für maschinelles Lernen (Implementierung einer Klassifizierung mit mehreren Klassen)
Visualisieren Sie die Auswirkungen von Deep Learning / Regularisierung
Objekterkennung durch tiefes Lernen, Keras tief zu verstehen
Emotionale Analyse von Tweets mit Deep Learning
Tiefes Lernen
Lernbericht über das Lesen von "Deep Learning von Grund auf neu"
Deep Learning von Grund auf neu - Kapitel 4 Tipps für die in Python erlernte Theorie und Implementierung von Deep Learning
Python vs Ruby "Deep Learning von Grund auf neu" Kapitel 4 Implementierung der Verlustfunktion
Python vs Ruby "Deep Learning von Grund auf neu" Kapitel 3 Implementierung eines dreischichtigen neuronalen Netzwerks
Erstellen Sie eine Python-Umgebung, um die Theorie und Implementierung von Deep Learning zu erlernen
Python: Deep Learning in der Verarbeitung natürlicher Sprache: Implementierung eines Antwortsatzauswahlsystems
Implementierung eines Modells, das Wechselkurse (Dollar-Yen-Kurs) durch maschinelles Lernen vorhersagt
Die Geschichte des tiefen Lernens mit TPU
Klassifizierung von Gitarrenbildern durch maschinelles Lernen Teil 1
Deep Learning / Fehler-Backpropagation der Sigmoid-Funktion
Ein Memorandum zum Studieren und Implementieren von 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]
Überblick über maschinelle Lerntechniken, die aus Scikit-Learn gelernt wurden
Verbesserung der Leistungsmetrik durch 2-Stufen-Lernmodell
[Übersetzung] scikit-learn 0.18 Einführung in maschinelles Lernen durch Tutorial scikit-learn
Klassifizierung von Gitarrenbildern durch maschinelles Lernen Teil 2
Erstes tiefes Lernen in C # - Einführung in Python implementieren-
Deep Learning Memorandum
Starten Sie Deep Learning
Python Deep Learning
Deep Learning × Python
Aktieninvestitionen durch tiefgreifendes Lernen (Policy Gradient Method) (1)
Erkennung abnormaler Werte durch unbeaufsichtigtes Lernen: Maharanobis-Distanz (Implementierung)
Zählen Sie die Anzahl der Parameter im Deep-Learning-Modell
Übersicht über DNC (Differentiable Neural Computers) + Implementierung durch Chainer