code: def add_training_op(self, clip_gradient=2.0, train_op_name=None):
      assert (
          self._inference_added,
          "Add inference layer by method add_inference_layer before adding training layer",
      )
      self._training_added = True
  
      with tf.compat.v1.device("/gpu:{}".format(self.use_gpu_device)):
          with tf.compat.v1.variable_scope("training", reuse=None):
              if train_op_name:
                  optimizer = tf.compat.v1.train.AdamOptimizer(
                      learning_rate=self.lr, name=train_op_name
                  )
              else:
                  optimizer = tf.compat.v1.train.AdamOptimizer(
                      learning_rate=self.lr
                  )
              if clip_gradient > 0:
                  gvs = optimizer.compute_gradients(self.loss)
                  capped_gvs = [
                      (
                          tf.clip_by_value(
                              grad, -clip_gradient, clip_gradient
                          ),
                          var,
                      )
                      for grad, var in gvs
                      if grad is not None
                  ]
                  self.train_op = optimizer.apply_gradients(capped_gvs)
              else:
                  self.train_op = optimizer.minimize(self.loss)
  
              self.init_op = tf.compat.v1.variables_initializer(
                  tf.compat.v1.global_variables(), name="init"
              )
  
imports: import math
  import random
  import sys
  import numpy
  import tensorflow
  from .sentence_grouper import SentenceGrouper
  from ..tf2contrib import *
label_desc: Use image node_id 9 for calling the NerModel obj's underlying member method code with example usage: obj.add_training_op(clip_gradient, train_op_name) without return types