2017-12-22 22 views
1

TensorFlow에서 GRU의 사용자 정의 구현을 실험했습니다. 교육을 받으면 고유 TensorFlow GRUcell과 같은 기능을 수행하지 않습니다. 나는 이유를 알아 내려고 애 쓰고 있었고 간단히 할 수 없었습니다. 모든 입력을 부탁드립니다.GRU의 사용자 정의 구현이 수행되지 않습니다.

기본 구현 :

encoder = tf.nn.rnn_cell.GRUCell(feature_no,activation = tf.nn.tanh) 
encoding = tf.nn.dynamic_rnn(encoder,inputs,dtype=tf.float32)[1] 

내 구현 :

class GRU: 
    def __init__(self, hid_dim, vec_dim, 
       name = None): 
     self.hid_dim = hid_dim     #Dimension of the hidden layer 
     self.vec_dim = vec_dim     #Dimension of the input layer 
     ## Declare the variables 
     ## Update gate 
     self.W_ux = tf.get_variable(name = name + ".GRU.W_ux", 
            shape = [vec_dim, hid_dim], 
            initializer = tf.random_normal_initializer()) 
     self.W_uh = tf.get_variable(name = name + ".GRU.W_uh", 
            shape = [hid_dim, hid_dim], 
            initializer = tf.random_normal_initializer()) 
     self.b_u = tf.get_variable(name = name + ".GRU.g_u", 
            shape = [hid_dim], 
            initializer = tf.random_normal_initializer()) 
     ## Forget gate 
     self.W_rx = tf.get_variable(name = name + ".GRUt.W_rx", 
            shape = [vec_dim, hid_dim], 
            initializer = tf.random_normal_initializer()) 
     self.W_rh = tf.get_variable(name = name + ".GRU.W_rh", 
            shape = [hid_dim, hid_dim], 
            initializer = tf.random_normal_initializer()) 
     self.b_r = tf.get_variable(name = name + ".GRU.b_r", 
            shape = [hid_dim], 
            initializer = tf.random_normal_initializer()) 
     ## Update function 
     self.W_hx = tf.get_variable(name = name + ".GRU.W_hx", 
            shape = [vec_dim, hid_dim], 
            initializer = tf.random_normal_initializer()) 
     self.W_hh = tf.get_variable(name = name + ".GRU.W_hh", 
            shape = [hid_dim, hid_dim], 
            initializer = tf.random_normal_initializer()) 
     self.b_h = tf.get_variable(name = name + ".GRU.b_h", 
            shape = [hid_dim], 
            initializer = tf.random_normal_initializer()) 

    def update_state(self, x, h): 
     u = tf.sigmoid(tf.matmul(x, self.W_ux) + tf.matmul(h, self.W_uh) + 
         self.b_u) 

     ## 'Forget' gate 
     r = tf.sigmoid(tf.matmul(x, self.W_rx) + tf.matmul(h, self.W_rh) + self.b_r) 

     ## Hidden state 
     hp = tf.tanh(tf.matmul(x, self.W_hx) + r*tf.matmul(h, self.W_hh) 
         + self.b_h) 
     return (1 - u) * hp + u * h 

    def get_states(self, x): 
     init = tf.reshape(tf.tile(tf.zeros_like(x[:,0,0]),[self.hid_dim]), 
              shape = [-1,self.hid_dim]) 
     x_t = tf.transpose(x,perm=[1,0,2]) 
     self.h_set = tf.transpose(tf.scan(lambda h, x: self.update_state(x, h), 
              x_t, init), perm = [1,0,2]) 
     self.h = self.h_set[:,-1] 

    def __call__(self, x): 
     self.get_states(x) 
     return self.h 

encoder = GRU(feature_no,vec_dim,name='encoder') 
encoding = encoder(sent) 

답변

0

문제를 발견. RNN이 초기화에 악명 높게 민감하다는 것을 알고 있지만 tf.glorot_uniform_initializer() 대신 tf.random_normal_initializer()을 사용했습니다. 나는 스왑을 만들었고 이제는 똑같이 수행합니다.