2017-07-14 9 views
0

これに続いて、Tensorflowのグラデーションリバーサル(TheKeras issueにあるTheanoバックエンドのKeras用に書かれた)のレイヤーを実装しようとしています。私のモデルはTheano 。Tensorflowで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 opのすべてを実装していることを確認したいと思います。

私はそれがのライン上のものになるだろうと仮定します:

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") 

しかし、私は本当に、残りについてはよく分かりません。

ありがとうございます!

答えて

2

私は仕事を拡張して問題を解決しました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())) 
関連する問題