2017-10-18 6 views
0

J'écris une couche caffe python qui revend l'entrée entre [0 255] le long d'un axe spécifique (code attaché) et la passe avant fonctionne bien. Le passage vers l'arrière est-il requis pour une telle couche? si oui, comment puis-je l'implémenter?Caffe python backword passe la mise en œuvre

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

pourquoi np.around? Comment envisagez-vous de différencier cela? – Shai

+0

Pensez-vous à une solution de contournement pour faire le np.around? – Mak

+0

l'ignore complètement? – Shai

Répondre

1

Votre fonction est assez simple, si vous êtes prêt à ignorer le np.around:

enter image description here

Pour x=x_min et x=x_max le dérivé est égal à zéro, pour tous les autres x le dérivé est 255/(x_max-x_min).

Cela peut être mis en œuvre par

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 

Ne pas oublier de tester cette numberically. Cela peut être fait, par exemple, en utilisant test_gradient_for_python_layer.

+0

Merci pour votre rediffusion. 1. Je n'ai pas obtenu la dernière ligne: bottom [0] .diff [...] = diff * top [0] .diff ne devrait-il pas être: top [0] .diff [... ] = diff * bottom [0] .diff. Une autre question est comment exécuter le "test_gradient_for_python_layer"? devrait-il être exécuté quand je cours la formation? Pourriez-vous s'il vous plaît fournir quelques étapes pour le faire. – Mak

+0

@Mak top [0] .diff contient la couche supérieure diff, vous devez la multiplier pour que les dégradés continuent à se propager à travers votre couche – Shai

+0

@Mak vous devriez avoir une exple dans le PR comment utiliser l'utilitaire de test de gradient – Shai