2017-10-18 2 views
0

Ich schreibe eine Caffe Python-Schicht, die die Eingabe zwischen [0 255] entlang bestimmter Achse (Code angehängt) und die Weiterleitung funktioniert gut. Ist der Rückwärtsdurchlauf für eine solche Schicht erforderlich? Wenn ja, wie kann ich es umsetzen?Caffe Python-Layer-Backword-Pass-Implementierung

caffe_root = 'caffe_root'   
import sys 
sys.path.insert(0, caffe_root + 'python') 
import caffe 
import numpy as np 

class scale_layer(caffe.Layer): 

    def setup(self, bottom, top): 
    assert len(bottom)==1 and len(top)==1, "scale_layer expects a single input and a single output" 

    def reshape(self, bottom, top): 
    top[0].reshape(*bottom[0].data.shape) 

    def forward(self, bottom, top): 
    in_ = np.array(bottom[0].data) 
    x_min = in_.min(axis=(0, 1), keepdims=True) 
    x_max = in_.max(axis=(0, 1), keepdims=True) 
    top[0].data[...] = np.around(255*((in_-x_min)/(x_max-x_min))) 

    def backward(self, top, propagate_down, bottom): 
    # backward pass is not implemented! 
    ??????????????????????????? 
    pass 
+0

warum np.around? Wie planen Sie das zu differenzieren? – Shai

+0

Denkst du an eine Problemumgehung für die np.around? – Mak

+0

ignorieren Sie es vollständig? – Shai

Antwort

1

Ihre Funktion ist ganz einfach, wenn Sie bereit sind, die np.around zu ignorieren: null

enter image description here

Für x=x_min und für x=x_max das Derivat, für alle anderen x das Derivat 255/(x_max-x_min) ist.

Dies kann durch

def forward(self, bottom, top): 
    in_ = bottom[0].data 
    self.x_min = in_.min(axis=(0, 1), keepdims=True) # cache min/max for backward 
    self.x_max = in_.max(axis=(0, 1), keepdims=True) 
    top[0].data[...] = 255*((in_-self.x_min)/(self.x_max-self.x_min))) 

def backward(self, top, propagate_down, bottom): 
    in_ = bottom[0].data 
    b, c = in_.shape[:2] 
    diff = np.tile(255/(self.x_max-self.x_min), (b, c, 1, 1)) 
    diff[ in_ == self.x_min ] = 0 
    diff[ in_ == self.x_max ] = 0 
    bottom[0].diff[...] = diff * top[0].diff 

Vergessen Sie nicht, diese numberically zu testen, implementiert werden. Dies kann beispielsweise unter Verwendung von test_gradient_for_python_layer erfolgen.

+0

Danke für Ihre Wiederholung. 1. Ich habe die letzte Zeile nicht erhalten: bottom [0] .diff [...] = diff * top [0] .diff sollte es nicht sein: top [0] .diff [...] ] = diff * unten [0] .diff. Eine andere Frage ist, wie man den "test_gradient_for_python_layer" ausführt? Sollte es ausgeführt werden, wenn ich das Training mache? Könnten Sie bitte einige Schritte dafür tun? – Mak

+0

@Mak top [0] .diff hält die obere Schicht diff, müssen Sie damit multiplizieren, so dass Gradienten weiterhin durch Ihre Schicht propagieren – Shai

+0

@Mak sollten Sie ein Exple in der PR haben, wie Sie die Gradienten Test-Dienstprogramm – Shai