2015-11-23 11 views
8

मैं हालिया पेपर "Unsupervised Domain Adaptation by Backpropagation" में Lasagne/Theano ढांचे में प्रस्तावित आर्किटेक्चर का उपयोग करने के लिए उत्सुक हूं।क्या मैं (चुनिंदा) बैकप्रोपैगेशन के दौरान थेनो ग्रैडिएंट को उलटा कर सकता हूं?

enter image description here

(नीचे के साथ तीर:

इस पत्र है कि यह थोड़ा असामान्य बनाता है के बारे में बात यह है कि यह एक 'ढाल उलट परत' है, जो उलट backpropagation दौरान ढाल को शामिल किया गया है छवि के बैकप्रोपैगमेंट हैं जिनके ढाल में उलटा हुआ है)।

लेख में लेखकों का दावा है कि दृष्टिकोण "किसी भी गहरे शिक्षण पैकेज का उपयोग करके कार्यान्वित किया जा सकता है", और वास्तव में वे version made in caffe प्रदान करते हैं।

हालांकि, मैं विभिन्न कारणों से Lasagne/Theano फ्रेमवर्क का उपयोग कर रहा हूं।

क्या Lasagne/Theano में ऐसी ढाल रिवर्सल परत बनाना संभव है? मैंने इस तरह के कोई उदाहरण नहीं देखा है कि कोई इस तरह के ग्रेडियेंट में कस्टम स्केलर ट्रांसफॉर्म लागू कर सकता है। यदि हां, तो क्या मैं Lasagne में एक कस्टम परत बनाकर ऐसा कर सकता हूं?

उत्तर

7

यहां सादा थेनो का उपयोग करके एक स्केच कार्यान्वयन है। इसे आसानी से लासगेन में एकीकृत किया जा सकता है।

आपको एक कस्टम ऑपरेशन बनाने की आवश्यकता है जो आगे के पास में एक पहचान ऑपरेशन के रूप में कार्य करता है लेकिन पिछड़े पास में ढाल को उलट देता है।

यहां एक सुझाव दिया गया है कि इसे कैसे कार्यान्वित किया जा सकता है। यह परीक्षण नहीं किया गया है और मैं 100% निश्चित नहीं हूं कि मैंने सबकुछ सही ढंग से समझा है, लेकिन आप आवश्यकतानुसार सत्यापित और ठीक करने में सक्षम हो सकते हैं।

class ReverseGradient(theano.gof.Op): 
    view_map = {0: [0]} 

    __props__ = ('hp_lambda',) 

    def __init__(self, hp_lambda): 
     super(ReverseGradient, self).__init__() 
     self.hp_lambda = hp_lambda 

    def make_node(self, x): 
     return theano.gof.graph.Apply(self, [x], [x.type.make_variable()]) 

    def perform(self, node, inputs, output_storage): 
     xin, = inputs 
     xout, = output_storage 
     xout[0] = xin 

    def grad(self, input, output_gradients): 
     return [-self.hp_lambda * output_gradients[0]] 

पेपर नोटेशन और नामकरण सम्मेलनों का उपयोग करके, यहां उनके द्वारा प्रस्तावित पूर्ण सामान्य मॉडल का एक सरल थानो कार्यान्वयन है।

import numpy 
import theano 
import theano.tensor as tt 


def g_f(z, theta_f): 
    for w_f, b_f in theta_f: 
     z = tt.tanh(theano.dot(z, w_f) + b_f) 
    return z 


def g_y(z, theta_y): 
    for w_y, b_y in theta_y[:-1]: 
     z = tt.tanh(theano.dot(z, w_y) + b_y) 
    w_y, b_y = theta_y[-1] 
    z = tt.nnet.softmax(theano.dot(z, w_y) + b_y) 
    return z 


def g_d(z, theta_d): 
    for w_d, b_d in theta_d[:-1]: 
     z = tt.tanh(theano.dot(z, w_d) + b_d) 
    w_d, b_d = theta_d[-1] 
    z = tt.nnet.sigmoid(theano.dot(z, w_d) + b_d) 
    return z 


def l_y(z, y): 
    return tt.nnet.categorical_crossentropy(z, y).mean() 


def l_d(z, d): 
    return tt.nnet.binary_crossentropy(z, d).mean() 


def mlp_parameters(input_size, layer_sizes): 
    parameters = [] 
    previous_size = input_size 
    for layer_size in layer_sizes: 
     parameters.append((theano.shared(numpy.random.randn(previous_size, layer_size).astype(theano.config.floatX)), 
          theano.shared(numpy.zeros(layer_size, dtype=theano.config.floatX)))) 
     previous_size = layer_size 
    return parameters, previous_size 


def compile(input_size, f_layer_sizes, y_layer_sizes, d_layer_sizes, hp_lambda, hp_mu): 
    r = ReverseGradient(hp_lambda) 

    theta_f, f_size = mlp_parameters(input_size, f_layer_sizes) 
    theta_y, _ = mlp_parameters(f_size, y_layer_sizes) 
    theta_d, _ = mlp_parameters(f_size, d_layer_sizes) 

    xs = tt.matrix('xs') 
    xs.tag.test_value = numpy.random.randn(9, input_size).astype(theano.config.floatX) 
    xt = tt.matrix('xt') 
    xt.tag.test_value = numpy.random.randn(10, input_size).astype(theano.config.floatX) 
    ys = tt.ivector('ys') 
    ys.tag.test_value = numpy.random.randint(y_layer_sizes[-1], size=9).astype(numpy.int32) 

    fs = g_f(xs, theta_f) 
    e = l_y(g_y(fs, theta_y), ys) + l_d(g_d(r(fs), theta_d), 0) + l_d(g_d(r(g_f(xt, theta_f)), theta_d), 1) 

    updates = [(p, p - hp_mu * theano.grad(e, p)) for theta in theta_f + theta_y + theta_d for p in theta] 
    train = theano.function([xs, xt, ys], outputs=e, updates=updates) 

    return train 


def main(): 
    theano.config.compute_test_value = 'raise' 
    numpy.random.seed(1) 
    compile(input_size=2, f_layer_sizes=[3, 4], y_layer_sizes=[7, 8], d_layer_sizes=[5, 6], hp_lambda=.5, hp_mu=.01) 


main() 

यह untested है, लेकिन निम्नलिखित इस कस्टम सेशन एक Lasagne परत के रूप में इस्तेमाल किया जा करने की अनुमति हो सकता है:

class ReverseGradientLayer(lasagne.layers.Layer): 
    def __init__(self, incoming, hp_lambda, **kwargs): 
     super(ReverseGradientLayer, self).__init__(incoming, **kwargs) 
     self.op = ReverseGradient(hp_lambda) 

    def get_output_for(self, input, **kwargs): 
     return self.op(input) 
+0

यह बहुत अच्छा है, यह मेरी मशीन पर कम से कम संकलित करने के लिए लगता है। मैं इसे लासने प्रारूप में अपनाने और इसे इसके माध्यम से कुछ डेटा चलाने के लिए परिवर्तित करने जा रहा हूं। आपका बहुत बहुत धन्यवाद! –

+0

क्या किसी ने कभी इसका परीक्षण किया? @ बिलकथम, क्या यह आपके लिए काम करता है? – pir

संबंधित मुद्दे

 संबंधित मुद्दे