def __call__(self, x, state_prev, scope=None):
with tf.variable_scope(scope or type(self).__name__):
h_prev, c_prev = state_prev
# Check if the input size exist.
input_size = x.shape.with_rank(2)[1].value
if input_size is None:
raise ValueError("Expecting input_size to be set.")
### get weights for concated tensor.
W_shape = (input_size, self.output_size)
U_shape = (self.output_size, self.output_size)
b_shape = (self.output_size,)
Wi = tf.get_variable(name='Wi', shape=W_shape)
Wj = tf.get_variable(name='Wj', shape=W_shape)
Wf = tf.get_variable(name='Wf', shape=W_shape)
Wo = tf.get_variable(name='Wo', shape=W_shape)
Ui = tf.get_variable(name='Ui', shape=U_shape,
initializer=TFCommon.Initializer.random_orthogonal_initializer())
Uj = tf.get_variable(name='Uj', shape=U_shape,
initializer=TFCommon.Initializer.random_orthogonal_initializer())
Uf = tf.get_variable(name='Uf', shape=U_shape,
initializer=TFCommon.Initializer.random_orthogonal_initializer())
Uo = tf.get_variable(name='Uo', shape=U_shape,
initializer=TFCommon.Initializer.random_orthogonal_initializer())
bi = tf.get_variable(name='bi', shape=b_shape,
initializer=tf.constant_initializer(0.0))
bj = tf.get_variable(name='bj', shape=b_shape,
initializer=tf.constant_initializer(0.0))
bf = tf.get_variable(name='bf', shape=b_shape,
initializer=tf.constant_initializer(self.__forget_bias)) # forget gate bias := 1
bo = tf.get_variable(name='bo', shape=b_shape,
initializer=tf.constant_initializer(0.0))
### calculate gates and input's info
i = tf.tanh(tf.matmul(x, Wi) + tf.matmul(h_prev, Ui) + bi)
j = self.__gate_activation(tf.matmul(x, Wj) + tf.matmul(h_prev, Uj) + bj)
f = self.__gate_activation(tf.matmul(x, Wf) + tf.matmul(h_prev, Uf) + bf)
o = tf.tanh(tf.matmul(x, Wo) + tf.matmul(h_prev, Uo) + bo)
### calculate candidate
new_c = f * c_prev + i * j
### final cal
new_h = o * tf.tanh(new_c)
return new_h, LSTMStateTuple(new_h, new_c)
评论列表
文章目录