2017-12-16 7 views
0

Ich bin kein Experte in caffe und Python, aber ich versuche Schritt für Schritt zu lernen. Ich bin ein wenig verwirrt, also würde ich es sehr schätzen, wenn Experten meine Fragen sehen.Datenerweiterung für semantische Segmentierung, Ist meine Python-Layer-Definition korrekt?

Ich arbeite an Bildsegmentierung. Ich versuche on-the-fly Datenerweiterung durch Hinzufügen von Python-Schichten zu tun. Für meinen Datensatz würde ich gerne eine Übersetzung von (+ 10, -10) sowohl in der x-Achse als auch in der y-Achse (zusätzlich 4 Übersetzungen) machen, Gaußsches Rauschen hinzufügen und horizontal spiegeln.

Meine Fragen sind:

1) Wie caffe nicht synchronisieren Sie das Bild mit dem Label? Zum Beispiel, wenn ich ein Bild von data Schicht an das Netzwerk und auf der Seite senden, wird label an die SoftmaxWithLoss (zum Beispiel) gesendet. Ich habe (manuell) eine schematische Ansicht der Augmentation und normalen Datenfluss gezeichnet, und ich bin mir nicht sicher, wie viel mein Verständnis ist richtig!

Wie in der Abbildung zu sehen, müssen wir für die Übersetzung Bild und Grundwahrheit in einer Synchronisationsweise übersetzen (oder zum Umdrehen müssen wir auch das Etikett umdrehen); Wenn ich zum Beispiel das Bild um -10 und -10 Pixel in der x-Achse bzw. der y-Achse verschiebe, muss das Grundwahrheitsbild ebenfalls entsprechend verschoben werden. Wie das in der Caffe-Python-Ebene gemacht werden kann. Ist mein Verständnis korrekt (basierend auf der Figur)? Ich habe die Python-Schicht wie folgt geschrieben:

import caffe 
import numpy as np 
from skimage import transform as tf 
from skimage.transform import AffineTransform 

class ShiftLayer(caffe.Layer): 

    def setup(self,bottom,top): 
     assert len(bottom)==2, #requires two inputs bottom(1:image, 2:label) 
     assert len(top)==2  #requires two layer top 

    def reshape(self,bottom,top): 
     top[0].reshape(*bottom[0].data.shape) #HOW CAN WE KNOW LABEL or DATA is GOING TO "bottom[0]" or "bottom[1]"????? 
     top[1].reshape(*bottom[1].data.shape) 

    def forward(self,bottom,top): 
     x_trans=-10 
     y_trans=-10 
     top[0].data[...]=tf.warp(bottom[0].data, AffineTransform(translation=(x_trans,y_trans))) 
     top[1].data[...]=tf.warp(bottom[1].data, AffineTransform(translation=(x_trans,y_trans))) 


    def backward(self,top,propagate_down,bottom): 
     pass 

Und die Schicht Definition:

layer { 
    name: "shift_layer" 
    type: "Python" 
    bottom: "data" 
    bottom: "label" 
    top: "data" 
    top: "label" 
    include { 
    phase: TRAIN 
    } 
    python_param { 
    module: "myshift_layer" 
    layer: "ShiftLayer" 
    } 
} 

2) Wenn ich andere Augmentationstechniken an das Netzwerk am Hinzufügen sollte ich schreiben separate Module für jeden von ihnen ? oder kann ich eine einzelne Python-Ebene einschließlich vieler bottoms und die entsprechende tops schreiben? Wenn ja, wie kann ich wissen, welches Top zu welchem ​​Boden gehört?

3) Im Fall der Gaußschen Rauschaddition haben wir die gleiche Bezeichnung wie Eingangsbild, wie ist die Schichtdefinition für dieses?

Antwort

1

Im Allgemeinen scheint Ihr Verständnis zu stimmen. Aber:

  1. Caffe Blobs (oben, unten) speichert Bilder als (Kanäle * Reihen * Spalten) bilden im Gegensatz zu üblichen Form (Zeilen * Spalten * Kanäle). Bei 1-Kanal-Bildern (wie Etiketten) macht das keinen Unterschied, bei Farbbildern jedoch. Ich habe Zweifel, ob tf.warp in diesem Fall richtig funktioniert.

  2. Ich sehe keinen Grund, separate Schichten für alle Arten von Augmentation (Schicht, Flip usw.) zu machen. Es gibt kein Problem, alle in einer Python-Ebene zu tun. Aber ich verstehe deine Idee nicht, viele Böden und Tops in diesem Fall zu haben. Darüber hinaus macht die Python-Ebene, die Sie gezeigt haben, keine Vergrößerung, weil sie einfach eine Reihe von ähnlich verschobenen Bildern anstelle von Originalbildern erzeugt. Es verbessert den Prozess nicht. Ein häufig verwendeter Ansatz für die On-the-Fly-Augmentation ist eine Transformation, die die Nettoform nicht beeinflusst, sondern zufällige (!) Transformierte Daten an die Stelle der ursprünglichen setzt. Dann verarbeitet das Netz das gleiche Eingangsbild zu verschiedenen Transformationsepochen, es verarbeitet tatsächlich verschiedene Bilder, die durch Zufallsumwandlung aus diesem Eingangsbild erzeugt werden. Sie müssen also Ihr Beispiel mit zufälliger Auswahl von x_trans, y_trans abschließen. Im allgemeinen Fall können Sie auch zufällige Flip und zufällige Gaussian Noise usw. hinzufügenDiese Transformationen können gleichzeitig angewendet werden, oder Sie können eine davon zufällig auswählen. Auf jeden Fall muss die Ebene nur ein Paar Daten + Label als Unterseiten und als Oberseiten haben.

+0

Auch das Anwenden von Transformationen kann zu unscharfen Kanten an den Etiketten führen. Im Fall von Multiklassen-Labels kann dies zu einem Problem werden. –

+0

Ilya Ovodov Vielen Dank für Ihren hilfreichen Kommentar –

Verwandte Themen