Sie haben Recht, sobald wir die mittleren Feature-Aktivierungen für eine Reihe von Bildern haben, normalisieren wir das Netzwerk nacheinander Schicht für Schicht. Es ist jedoch eine Subtilität beteiligt. Sie können Ebenengewichte nicht unabhängig von den vorherigen Ebenen neu skalieren.
Lassen W.lich und blich seien die Gewichte und Vorspannung der ich-th Faltungsfilter in Schicht l. Der KernelW.lich hat eine 3D-Form mit Abmessungen h × w × c (Höhe, Breite, Kanäle_in), aber zur einfacheren Notation auf der Straße lassen Sie es uns umformen p × c, wo p = h × w.
F.li j≡ m a x ( 0 , W.lich∙P.l - 1j+blich) ist die Aktivierung des ich-th Filter in Schicht l Bei der j-te Position in der Aktivierungskarte. Hier∙ bezeichnet die Faltungsoperation (oder Frobenius-Innenprodukt oder Multiplikationsaddition; ich habe das Symbol aus Babas Antwort übernommen) und P.l - 1j ist das Fenster von h × w × c = p × c Aktivierungen in Schicht l - 1Ausgang, mit dem sich der Filter an der betrachteten Position zusammenfaltet.
Lassen μlich≡E.X., jF.li j=1N.M.l∑X.∑j = 1M.lF.li j=1N.M.l∑X.∑j = 1M.lm a x ( 0 , W.lich∙P.l - 1j+blich)
sei die mittlere Aktivierung der ich-th Filter in Schicht l über alles N. Bilder im Datensatz X. und alles M.lPositionen in der Aktivierungskarte des Filters. Dies ist offensichtlich eine nicht negative Zahl, und sie ist tatsächlich für alle Filter in den VGG-Netzen positiv (wenn mittlere Aktivierungen über einen Datensatz mit angemessener Größe gesammelt werden).
Nehmen wir nun an, wir "normalisieren" die Aktivierungen, indem wir Gewichte und Vorurteile durch dividieren μlich. Dies würde den Mittelwert der Aktivierung gleich 1 machen, wenn die eingehenden Aktivierungen dieselben wären wie die ursprünglichen nicht normalisierten Aktivierungen . Das ist,E.X., jm a x ( 0 , W.lichμlich∙P.l - 1j+blichμlich) = 1, aber nur, wenn die vorherigen Ebenen aktiviert sind P.l - 1j sind die gleichen wie im ursprünglichen nicht normalisierten Netzwerk - dem Netzwerk, das wir berechnet haben μlichDies gilt nur für die erste Conv-Schicht im normalisierten Netzwerk, die Schicht, die sich mit dem Eingabebild faltet. Für andere Schichten führt dies nicht nur zu einer falschen Skalierung, sondern kann auch das Vorzeichen der Faltung umkehren und folglich Aktivierungen nach dem Durchlaufen der ReLU auf Null setzen. Mit anderen Worten, es ändert die Netzwerkausgabe .
Um dies zu beheben, müssen wir eingehende Aktivierungen wiederherstellen. Wir können die eingehenden Werte jedoch nicht selbst ändern. Wir müssen die Normalisierung der vorherigen Ebene mit den Gewichten der aktuellen Ebene rückgängig machen. Beachten Sie, dass ein Gewicht in einem Filter nur mit einem einzelnen Kanal in der vorherigen Ebene interagiert. Also skalieren wir alle Gewichte neuW.lich die mit dem interagieren k-th Kanal in Schicht l - 1 durch Multiplikation mit μl - 1k. Dies hebt die Normalisierung der vorherigen Ebene auf.
Um zu formalisieren, lassen Sie
D.l - 1≡⎡⎣⎢⎢⎢⎢⎢⎢μl - 110⋮00μl - 12………⋱000μl - 1c⎤⎦⎥⎥⎥⎥⎥⎥ sei die Diagonale c × c Matrix mit allen konstruiert c mittlere Aktivierungen aus der Schicht l - 1.
Dann, E.X., jm a x ( 0 , W.lichD.l - 1μlich∙P.l - 1j+blichμlich) = 1. (Aus diesem Grund haben wir die Gewichte in 2D umgestaltet, damit wir der Übersichtlichkeit halber Matrizen anstelle von Tensoren multiplizieren können.)
Beachten Sie auch, dass maximale und durchschnittliche Pooling-Ebenen dieses Schema nicht beeinträchtigen, da sie den Maßstab nicht ändern.
Das Obige sieht wahrscheinlich komplexer aus als im eigentlichen Code. Ich habe ein GitHub-Repo mit einer kurzen Keras-Implementierung gepusht: https://github.com/corleypc/vgg-normalize . Ein Blick auf den Beispielcode wird die Dinge wahrscheinlich weiter erläutern.