import tensorflow as tf

            
            # Select optimizer
            self.optimizer_func = tf.train.AdagradOptimizer
            if self.hparams.grad_strategy == 'sgd':
                self.optimizer_func = tf.train.GradientDescentOptimizer

            self.separate_gradient_update()
        
            tf.summary.scalar('Gradient Norm', self.norm, collections=['train'])
            tf.summary.scalar('Learning Rate', self.ranker_learning_rate, collections=['train'])
            tf.summary.scalar('Final Loss', tf.reduce_mean(self.loss), collections=['train'])
        
            clipped_labels = tf.clip_by_value(reshaped_train_labels, clip_value_min=0, clip_value_max=1)
            pad_removed_train_output = self.remove_padding_for_metric_eval(self.docid_inputs, train_output)
            for metric in self.exp_settings['metrics']:
                for topn in self.exp_settings['metrics_topn']:
                    list_weights = tf.reduce_mean(self.propensity_weights * clipped_labels, axis=1, keep_dims=True)
                    metric_value = utils.make_ranking_metric_fn(metric, topn)(reshaped_train_labels, pad_removed_train_output, None)
                    tf.summary.scalar('%s_%d' % (metric, topn), metric_value, collections=['train'])
                    weighted_metric_value = utils.make_ranking_metric_fn(metric, topn)(reshaped_train_labels, pad_removed_train_output, list_weights)
