wake-up-neo.com

Gegen Klassenungleichgewicht: Beitrag zu Verlust und SGD skalieren

(Ein Update zu dieser Frage wurde hinzugefügt.)

Ich bin ein Doktorand an der Universität von Gent, Belgien; Meine Forschung beschäftigt sich mit der Emotionserkennung mit tiefen Faltungsnetzen. Ich verwende das Caffe Framework, um die CNNs zu implementieren.

Vor kurzem bin ich auf ein Problem mit dem Klassenungleichgewicht gestoßen. Ich benutze 9216 Trainingsbeispiele, ca. 5% sind positiv markiert (1), die restlichen Proben sind negativ markiert (0).

Ich verwende den SigmoidCrossEntropyLoss Layer, um den Verlust zu berechnen. Beim Training nimmt der Verlust ab und die Genauigkeit ist bereits nach wenigen Epochen extrem hoch. Dies ist auf das Ungleichgewicht zurückzuführen: Das Netzwerk sagt einfach immer eine negative (0) voraus. (Präzision und Rückruf sind beide Null, was diese Behauptung bestätigt)

Um dieses Problem zu lösen, möchte ich den Beitrag zum Verlust in Abhängigkeit von der Vorhersage-Wahrheitskombination skalieren (falsche Negative streng bestrafen). Mein Mentor/Coach hat mir auch geraten, beim Backpropagieren einen Skalierungsfaktor zu verwenden durch stochastischen Gradientenabstieg (sgd): Der Faktor würde mit dem Ungleichgewicht in der Charge korrelieren. Eine Charge, die nur negative Proben enthält, würde die Gewichte überhaupt nicht aktualisieren.

Ich habe Caffe nur eine maßgeschneiderte Ebene hinzugefügt: um andere Metriken wie Präzision und Rückruf zu melden. Meine Erfahrung mit Caffe-Code ist begrenzt, aber ich habe viel Erfahrung beim Schreiben von C++ - Code.


Könnte mir jemand helfen oder mich in die richtige Richtung weisen, wie ich den SigmoidCrossEntropyLoss und Sigmoid -Layer an die folgenden Änderungen anpasse:

  1. passen Sie den Beitrag einer Stichprobe zum Gesamtverlust in Abhängigkeit von der Vorhersage-Wahrheits-Kombination an (richtig positiv, falsch positiv, richtig negativ, falsch negativ).
  2. skalieren Sie die Gewichtsaktualisierung, die durch stochastisches Gefälle durchgeführt wird, abhängig vom Ungleichgewicht in der Charge (Negative vs. Positive).

Danke im Voraus!


Aktualisieren

Ich habe denInfogainLossLayer wie von Shaivorgeschlagen eingebaut. Ich habe auch eine weitere benutzerdefinierte Ebene hinzugefügt, die die Infogain-Matrix H basierend auf dem Ungleichgewicht im aktuellen Stapel erstellt.

Derzeit ist die Matrix wie folgt konfiguriert:

H(i, j) = 0          if i != j
H(i, j) = 1 - f(i)   if i == j (with f(i) = the frequency of class i in the batch)

Ich plane, in Zukunft mit verschiedenen Konfigurationen für die Matrix zu experimentieren.

Ich habe dies an einem 10: 1 Ungleichgewicht getestet. Die Ergebnisse haben gezeigt, dass das Netzwerk jetzt nützliche Dinge lernt: (Ergebnisse nach 30 Epochen)

  • Die Genauigkeit beträgt ca. ~ 70% (von ~ 97%);
  • Die Präzision beträgt ca. ~ 20% (von 0%);
  • Rückruf ist ca. ~ 60% (von 0%).

Diese Zahlen wurden nach etwa 20 Epochen erreicht und änderten sich danach nicht wesentlich.

!! Die oben angegebenen Ergebnisse sind lediglich ein Proof-of-Concept. Sie wurden durch Training eines einfachen Netzwerks an einem 10: 1-Datensatz mit Ungleichgewicht erhalten. !!

29
Maarten Bamelis

Warum verwenden Sie nicht den InfogainLoss Layer, um das Ungleichgewicht in Ihrem Trainingsset auszugleichen?

Der Infogain-Verlust wird mithilfe einer Gewichtsmatrix H (in Ihrem Fall 2-mal-2) definiert. Die Bedeutung der Einträge ist

[cost of predicting 1 when gt is 0,    cost of predicting 0 when gt is 0
 cost of predicting 1 when gt is 1,    cost of predicting 0 when gt is 1]

Sie können also die Einträge von H festlegen, um den Unterschied zwischen Fehlern bei der Vorhersage von 0 oder 1 widerzuspiegeln.

Sie finden in diesem Thread , wie Sie die Matrix H für caffe definieren.

In Bezug auf die Beispielgewichte finden Sie diesen Beitrag möglicherweise interessant: Es wird gezeigt, wie die SoftmaxWithLoss - Ebene geändert wird Probengewichte berücksichtigen.


Kürzlich wurde von Tsung-Yi Lin, Ross Girshick, Piotr Dollár, Priya Goyal Fokusverlust für die Erkennung dichter Objekte , (ICCV 2017) .
Die Idee hinter dem Fokusverlust ist, jedem Beispiel ein anderes Gewicht zuzuweisen, basierend auf der relativen Schwierigkeit, dieses Beispiel vorherzusagen (eher basierend auf der Klassengröße usw.). Von der kurzen Zeit an, in der ich mit diesem Verlust experimentieren musste, fühlt es sich besser an als "InfogainLoss" mit Klassengewichten.

20
Shai

In meiner Klassifizierungsaufgabe bin ich auch auf dieses Klassenungleichgewichtsproblem gestoßen. Im Moment verwende ich CrossEntropyLoss mit Gewicht (Dokumentation hier ) und es funktioniert gut. Die Idee ist, Proben in Klassen mit einer geringeren Anzahl von Bildern mehr Verlust zuzufügen.

Gewicht berechnen

das Gewicht für jede Klasse ist umgekehrt proportional zur Bildnummer in dieser Klasse. Hier ist ein Ausschnitt, um das Gewicht für alle Klassen mit numpy zu berechnen.

cls_num = []
# train_labels is a list of class labels for all training samples
# the labels are in range [0, n-1] (n classes in total)
train_labels = np.asarray(train_labels)
num_cls = np.unique(train_labels).size

for i in range(num_cls):
    cls_num.append(len(np.where(train_labels==i)[0]))

cls_num = np.array(cls_num)

cls_num = cls_num.max()/cls_num
x = 1.0/np.sum(cls_num)

# the weight is an array which contains weight to use in CrossEntropyLoss
# for each class.
weight = x*cls_num
0
jdhao