'initialize_training_ops.
Initialize all ops used for training. Because a network can have
multiple optimizers, an id \'i\' is allocated to differentiate them.
This is meant to be used by `Trainer` when initializing all train ops.
Arguments:
i: `int`. This optimizer training process ID.
session: `tf.Session`. The session used to train the network.
tensorboard_verbose: `int`. Logs verbose. Supports:
0 - Loss, Accuracy.
1 - Loss, Accuracy, Gradients.
2 - Loss, Accuracy, Gradients, Weights.
3 - Loss, Accuracy, Gradients, Weights, Activations, Sparsity..
clip_gradients: `float`. Option for clipping gradients.'

def initialize_training_ops(self, i, session, tensorboard_verbose, clip_gradients):

    self.session = session
    self.val_loss_T = tf.Variable(0.0, name='val_loss', trainable=False)
    self.val_acc_T = tf.Variable(0.0, name='val_acc', trainable=False)
    self.validation_monitors_T = [tf.Variable(0.0, name=('%s_T' % v.name.rsplit(':', 1)[0]), trainable=False) for v in self.validation_monitors]
    self.val_loss_P = tf.placeholder(dtype=tf.float32, name=('placeholder/%s' % self.val_loss_T.name.rsplit(':')[0]))
    self.val_acc_P = tf.placeholder(dtype=tf.float32, name=('placeholder/%s' % self.val_acc_T.name.rsplit(':')[0]))
    self.val_monitors_P = [tf.placeholder(dtype=tf.float32, name=('placeholder/%s' % v.name.rsplit(':')[0])) for v in self.validation_monitors_T]
    self.val_loss_assign = tf.assign(self.val_loss_T, self.val_loss_P, name=('assign/%s' % self.val_loss_T.name.rsplit(':')[0]))
    self.val_acc_assign = tf.assign(self.val_acc_T, self.val_acc_P, name=('assign/%s' % self.val_acc_T.name.rsplit(':')[0]))
    self.val_monitors_assign = [tf.assign(vmt, vmp, name=('assign/%s' % vmt.name.rsplit(':')[0])) for (vmt, vmp) in zip(self.validation_monitors_T, self.val_monitors_P)]
    if (self.metric is not None):
        self.acc_averages = tf.train.ExponentialMovingAverage(0.9, self.training_steps, name='moving_avg')
        acc_avg_op = self.acc_averages.apply([self.metric])
    else:
        acc_avg_op = tf.no_op()
    with tf.name_scope(self.name):
        lss = ([self.loss] + tf.get_collection(tf.GraphKeys.REGULARIZATION_LOSSES))
        total_loss = tf.add_n(lss, name='Total_Loss')
        loss_avg_op = summaries.add_loss_summaries(total_loss, self.loss, regul_losses_collection_key=tf.GraphKeys.REGULARIZATION_LOSSES, name_prefix=self.scope_name, summaries_collection_key=(self.name + '_training_summaries'), exp_moving_avg=0.9, ema_num_updates=self.training_steps)
        with tf.control_dependencies([loss_avg_op, acc_avg_op]):
            self.grad = tf.gradients(total_loss, self.train_vars)
            if (clip_gradients > 0.0):
                (self.grad, self.grad_norm) = tf.clip_by_global_norm(self.grad, clip_gradients)
        self.grad = list(zip(self.grad, self.train_vars))
        self.apply_grad = self.optimizer.apply_gradients(grads_and_vars=self.grad, global_step=self.training_steps, name=('apply_grad_op_' + str(i)))
        self.create_summaries(tensorboard_verbose)
        if (self.ema > 0.0):
            var_averages = tf.train.ExponentialMovingAverage(self.ema, self.training_steps)
            var_averages_op = var_averages.apply(self.train_vars)
            with tf.control_dependencies([var_averages_op]):
                with tf.control_dependencies([self.apply_grad]):
                    self.train = tf.no_op(name=('train_op_' + str(i)))
        else:
            with tf.control_dependencies([self.apply_grad]):
                self.train = tf.no_op(name=('train_op_' + str(i)))
