2015-10-20 18 views
8

Ich möchte GoogLeNet Feinabstimmung für Multi-Label-Klassifizierung mit Caffe tun. Ich habe es bereits auf eine Single-Label-Klassifizierung abgestimmt, aber ich kann noch nicht auf Multi-Label umsteigen.Multi-Label-Klassifizierung mit Caffe

Die wichtigsten Schritte, die ich tue, die unterschiedlich sind:

erstellen LMDB für Data & Ground Truth

Ich Modifizieren Sie den Code here und here ein LMDB mit der Daten und das andere mit Grundwahrheit zu schaffen .

Ersetzen SoftmaxWithLoss mit SigmoidCrossEntropyLoss

die train_val.prototxt Aktualisieren, Ersetzen I SoftmaxWithLoss Schichten SigmoidCrossEntropyLoss, und stellen Sie die Datenschichten, so dass beide DB geladen. Ich habe die Lernratenparameter so eingestellt, wie ich es bei dem Ein-Label-Klassifikationsproblem getan habe.

Diese Schritte scheint zu funktionieren. Der Datenfluss und es ist möglich, solver.step (1) durchzuführen. Um zu überprüfen, ob die Daten und Beschriftungen richtig geladen sind, habe ich den Verlust explizit mit der Formel berechnet und habe das gleiche Ergebnis wie Caffe erhalten.

Problem

Das Netzwerk konvergiert nicht. Wenn Sie mehrere Hundert Iterationen ausführen, wird jede der verschiedenen Klassen um die Klassenpopulation herum gemittelt. Das heißt, wenn Klasse a 0,35 1 und 0,65 0 in der Population hat, konvergiert das Netzwerk für jede Beobachtung zu einer Wahrscheinlichkeit von 0,35, unabhängig von der wahren Bezeichnung.

Mögliche Fehler 1

Ich vermute, das Problem ist, weil ich nicht die Bilder richtig in caffe in einer Art und Weise zu laden, dass GoogLeNet Modell vortrainierter von ihnen lernen können. Meine bisherigen Erfahrungen sind convert_imageset was perfekt funktioniert. Im Moment bin shelhamer Code verwende die Bilder in die LMDB zu speichern:

im = np.array(Image.open(os.path.join(data_dir,in_))) 
im = im[:,:,::-1] 
im = im.transpose((2,0,1)) 
im_dat = caffe.io.array_to_datum(im) 
in_txn.put('{:0>10d}'.format(in_idx), im_dat.SerializeToString()) 

ich normalisieren den Mittelwert in der Datenschicht, wenn das Bild geladen ist. Scheint das richtig? Gibt es einen anderen Weg, das zu tun?

Mögliche Fehler 2

Es könnte auch sein, dass der train_val.prototxt falsch definiert wurde. Gibt es noch etwas anderes als das Umschalten von SoftmaxWithLoss -> SigmoidCrossEntropyLoss?

Jede Hilfe wird sehr geschätzt! Danke!

+2

es wie Ihr Netz mit einer „alles 1“ Vorhersage stecken scheint. Das kann passieren, wenn Ihre Gradienten zu hoch sind und die Parameter in bedeutungslose Regionen treiben. Können Sie eine Grafik des Trainingsverlustes gegen die Iterationszahl aufzeichnen? Ich würde versuchen, die Lernrate um ein oder zwei * Größenordnungen * zu reduzieren und neu zu trainieren, um zu sehen, ob das Modell wieder festsitzt. – Shai

+1

Wenn Ihr Netzwerk nicht konvergiert, sollten Sie die Lernrate überprüfen. Im Allgemeinen sollten Sie für die Feinabstimmung eine niedrigere Lernrate (oder eine hohe Lernrate und einen schnellen Abfall) haben. Wenn der Zugverlust über Epochen zunimmt, ist dies ein Hinweis darauf, dass Ihre Lernrate zu hoch ist. – user3334059

+0

Haben Sie dieses Problem gesehen? https://github.com/BVLC/caffe/issues/2407 – ginge

Antwort

0

In GoogLeNet Eingangsdaten sollte durch Mittelabzug:

... 
im = im.transpose((2,0,1)) 
mean = np.array((104,117,123)) 
im -= mean 
im_dat = caffe.io.array_to_datum(im) 
...