code: def _generate_config(self):
      configs = []
      name = self.name
      input_dim = self.descriptors["input"]["dim"]
      input_descriptor = self.descriptors["input"]["final-string"]
      output_dim = self.config["dim"]
      bottleneck_dim = self.config["bottleneck-dim"]
      bypass_scale = self.config["bypass-scale"]
      dropout_proportion = self.config["dropout-proportion"]
      time_stride = self.config["time-stride"]
      context = self.config["context"]
      if time_stride != 0 and context != "none":
          time_offsets1 = "{0},0".format(-time_stride)
          if context == "default":
              time_offsets2 = "0,{0}".format(time_stride)
          elif context == "shift-left":
              time_offsets2 = "{0},0".format(-time_stride)
          else:
              assert context == "left-only"
              time_offsets2 = "0"
      else:
          time_offsets1 = "0"
          time_offsets2 = "0"
      l2_regularize = self.config["l2-regularize"]
      max_change = self.config["max-change"]
      self_repair_scale = self.config["self-repair-scale"]
  
      # The first linear layer, from input-dim (spliced x2) to bottleneck-dim
      configs.append(
          "component name={0}.linear type=TdnnComponent input-dim={1} "
          "output-dim={2} l2-regularize={3} max-change={4} use-bias=false "
          "time-offsets={5} orthonormal-constraint=-1.0".format(
              name,
              input_dim,
              bottleneck_dim,
              l2_regularize,
              max_change,
              time_offsets1,
          )
      )
      configs.append(
          "component-node name={0}.linear component={0}.linear "
          "input={1}".format(name, input_descriptor)
      )
  
      # The affine layer, from bottleneck-dim (spliced x2) to output-dim
      configs.append(
          "component name={0}.affine type=TdnnComponent "
          "input-dim={1} output-dim={2} l2-regularize={3} max-change={4} "
          "time-offsets={5}".format(
              name,
              bottleneck_dim,
              output_dim,
              l2_regularize,
              max_change,
              time_offsets2,
          )
      )
      configs.append(
          "component-node name={0}.affine component={0}.affine "
          "input={0}.linear".format(name)
      )
  
      # The ReLU layer
      configs.append(
          "component name={0}.relu type=RectifiedLinearComponent dim={1} "
          "self-repair-scale={2}".format(
              name, output_dim, self_repair_scale
          )
      )
      configs.append(
          "component-node name={0}.relu component={0}.relu "
          "input={0}.affine".format(name)
      )
  
      # The BatchNorm layer
      configs.append(
          "component name={0}.batchnorm type=BatchNormComponent "
          "dim={1}".format(name, output_dim)
      )
      configs.append(
          "component-node name={0}.batchnorm component={0}.batchnorm "
          "input={0}.relu".format(name)
      )
  
      if dropout_proportion != -1:
          # This is not normal dropout.  It's dropout where the mask is shared
          # across time, and (thanks to continuous=true), instead of a
          # zero-or-one scale, it's a continuously varying scale whose
          # expected value is 1, drawn from a uniform distribution over an
          # interval of a size that varies with dropout-proportion.
          configs.append(
              "component name={0}.dropout type=GeneralDropoutComponent "
              "dim={1} dropout-proportion={2} continuous=true".format(
                  name, output_dim, dropout_proportion
              )
          )
          configs.append(
              "component-node name={0}.dropout component={0}.dropout "
              "input={0}.batchnorm".format(name)
          )
          cur_component_type = "dropout"
      else:
          cur_component_type = "batchnorm"
  
      if bypass_scale != 0.0:
          # Add a NoOpComponent to cache the weighted sum of the input and the
          # output.  We could easily have the output of the component be a
          # Descriptor like 'Append(Scale(0.66, tdnn1.batchnorm), tdnn2.batchnorm)',
          # but if we did that and you used many of this component in sequence,
          # the weighted sums would have more and more terms as you went deeper
          # in the network.
          configs.append(
              "component name={0}.noop type=NoOpComponent "
              "dim={1}".format(name, output_dim)
          )
          configs.append(
              "component-node name={0}.noop component={0}.noop "
              "input=Sum(Scale({1}, {2}), {0}.{3})".format(
                  name,
                  bypass_scale,
                  input_descriptor,
                  cur_component_type,
              )
          )
  
      return configs
  
imports: from __future__ import print_function
  import math
  import re
  import sys
  from libs.nnet3.xconfig.basic_layers import XconfigLayerBase
label_desc: Use image node_id 8 for calling the XconfigTdnnfLayer obj's underlying member method code with example usage: obj._generate_config() and returns: configs