import tensorflow as tf

        trainable_vars = tf.trainable_variables()
        if self.config.clip_weight:
            # clip_weight
            tvars = tf.trainable_variables()
            grads = tf.gradients(self.loss, tvars)
            grads, _ = tf.clip_by_global_norm(grads, clip_norm=self.config.max_norm_grad)
            grad_var_pairs = zip(grads, tvars)
            self.train_op = self.optimizer.apply_gradients(grad_var_pairs, name='apply_grad')
        else:
            self.train_op = self.optimizer.minimize(self.loss)

    def _attention(self, output, name='attn', reuse=None):
        with tf.variable_scope(name, reuse=reuse):
            W = tf.get_variable(name="attn_W",
                                shape=[2 * self.config.hidden_size, 2 * self.config.hidden_size],
                                initializer=tf.contrib.layers.xavier_initializer(),
                                # initializer=tf.truncated_normal_initializer(),
                                # initializer=tf.keras.initializers.lecun_normal(),
                                dtype=tf.float32)
            V = tf.get_variable(name="attn_V", shape=[2 * self.config.hidden_size, 1],
                                initializer=tf.contrib.layers.xavier_initializer(),
                                # initializer=tf.truncated_normal_initializer(),
                                # initializer=tf.keras.initializers.lecun_normal(),
                                dtype=tf.float32)
            U = tf.get_variable(name="attn_U",
                                shape=[2 * self.config.hidden_size, 2 * self.config.hidden_size],
                                initializer=tf.contrib.layers.xavier_initializer(),
                                # initializer=tf.truncated_normal_initializer(),
                                # initializer=tf.keras.initializers.lecun_normal(),
                                dtype=tf.float32)
