【问题标题】:Implement Theano operation in Tensorflow在 TensorFlow 中实现 Theano 操作
【发布时间】:2017-12-19 08:44:27
【问题描述】:

在此paper on domain adaptation 之后,我正在尝试在 Tensorflow 中实现以下梯度反转层(为带有 Theano 后端的 Keras 编写,如在此 Keras issue 中找到),因为我的模型在 Theano 上运行不佳。

class GradientReversalLayer(Layer):
    """ Reverse a gradient
    <feedforward> return input x
    <backward> return -lambda * delta
    """
    def __init__(self, hp_lambda, **kwargs):
        super(GradientReversalLayer, self).__init__(**kwargs)
        self.hp_lambda = hp_lambda
        self.gr_op = ReverseGradient(self.hp_lambda)

    def build(self, input_shape):
        self.trainable_weights = []

    def call(self, x, mask=None):
        return self.gr_op(x)

    def get_output_shape_for(self, input_shape):
        return input_shape

    def get_config(self):
        config = {"name": self.__class__.__name__,
                         "lambda": self.hp_lambda}
        base_config = super(GradientReversalLayer, self).get_config()
        return dict(list(base_config.items()) + list(config.items()))

层执行这个操作:

 import theano
    from keras.engine import Layer

    class ReverseGradient(theano.Op):
        """ theano operation to reverse the gradients
        Introduced in http://arxiv.org/pdf/1409.7495.pdf
        """

        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):
            assert hasattr(self, '_props'), "Your version of theano is too old to support __props__."
            x = theano.tensor.as_tensor_variable(x)
            return theano.Apply(self, [x], [x.type()])

        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]]

        def infer_shape(self, node, i0_shapes):
            return i0_shapes

为什么不能这样用?

如果我使用 tf 后端运行我的模型并使用 Theano 编写的此函数,我会收到以下错误:

theano.tensor.var.AsTensorError: ('Cannot convert Tensor("concatenate_1/concat:0", shape=(?, ?, 128), dtype=float32) to TensorType', <class 'tensorflow.python.framework.ops.Tensor'>)

这样调用之后:

lstm_concat = concatenate([hidden_out_1, hidden_out_2])
lstm_concat = FlipGradientKeras.GradientReversalLayer(0.31)(lstm_concat)

如何将此操作转换为 TF operation

关于adding a new operation 的文档只建议用C++ 实现它。

ops codes 显示了一般框架,但我想确保我正在实现的所有东西都与 Theano 操作一样。

我认为它会是这样的:

def ReverseGradient(input_tensor, hp_lambda):

    with ops.name_scope(name, "ReverseGradient", [input_tensor, hp_lambda]) as name:
        input_tensor = ops.convert_to_tensor(input_tensor, name="input_tensor")

但我真的不确定其余的。

提前致谢!

【问题讨论】:

    标签: python tensorflow deep-learning keras theano


    【解决方案1】:

    我通过扩展 here 所做的工作解决了这个问题。

    这是工作代码:

    import tensorflow as tf
    from keras.engine import Layer
    import keras.backend as K
    
    def reverse_gradient(X, hp_lambda):
        '''Flips the sign of the incoming gradient during training.'''
        try:
            reverse_gradient.num_calls += 1
        except AttributeError:
            reverse_gradient.num_calls = 1
    
        grad_name = "GradientReversal%d" % reverse_gradient.num_calls
    
        @tf.RegisterGradient(grad_name)
        def _flip_gradients(op, grad):
            return [tf.negative(grad) * hp_lambda]
    
        g = K.get_session().graph
        with g.gradient_override_map({'Identity': grad_name}):
            y = tf.identity(X)
    
        return y
    
    class GradientReversal(Layer):
        '''Flip the sign of gradient during training.'''
        def __init__(self, hp_lambda, **kwargs):
            super(GradientReversal, self).__init__(**kwargs)
            self.supports_masking = False
            self.hp_lambda = hp_lambda
    
        def build(self, input_shape):
            self.trainable_weights = []
    
        def call(self, x, mask=None):
            return reverse_gradient(x, self.hp_lambda)
    
        def get_output_shape_for(self, input_shape):
            return input_shape
    
        def get_config(self):
            config = {}
            base_config = super(GradientReversal, self).get_config()
            return dict(list(base_config.items()) + list(config.items()))
    

    【讨论】:

      猜你喜欢
      • 2018-06-28
      • 1970-01-01
      • 2016-10-18
      • 1970-01-01
      • 2018-01-28
      • 2016-04-07
      • 2017-04-10
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多