code: def parse_progress_logs_for_clipped_proportion(exp_dir):
      """Parse progress logs for clipped proportion stats.
  
      e.g. for a line that is parsed from progress.*.log:
      exp/chain/cwrnn_trial2_ld5_sp/log/progress.245.log:component
      name=BLstm1_forward_c type=ClipGradientComponent, dim=512,
      norm-based-clipping=true, clipping-threshold=30,
      clipped-proportion=0.000565527,
      self-repair-clipped-proportion-threshold=0.01, self-repair-target=0,
      self-repair-scale=1
      """
  
      progress_log_files = "%s/log/progress.*.log" % (exp_dir)
      component_names = set([])
      progress_log_lines = common_lib.get_command_stdout(
          'grep -e "{0}" {1}'.format(
              "clipped-proportion", progress_log_files
          ),
          require_zero_status=False,
      )
      parse_regex = re.compile(
          ".*progress\.([0-9]+)\.log:component "
          "name=(.*) type=.* "
          "clipped-proportion=([0-9\.e\-]+)"
      )
  
      cp_per_component_per_iter = {}
  
      max_iteration = 0
      component_names = set([])
      for line in progress_log_lines.split("\n"):
          mat_obj = parse_regex.search(line)
          if mat_obj is None:
              if line.strip() == "":
                  continue
              raise MalformedClippedProportionLineException(line)
          groups = mat_obj.groups()
          iteration = int(groups[0])
          max_iteration = max(max_iteration, iteration)
          name = groups[1]
          clipped_proportion = float(groups[2])
          if clipped_proportion > 1:
              raise MalformedClippedProportionLineException(line)
          if iteration not in cp_per_component_per_iter:
              cp_per_component_per_iter[iteration] = {}
          cp_per_component_per_iter[iteration][
              name
          ] = clipped_proportion
          component_names.add(name)
      component_names = list(component_names)
      component_names.sort()
  
      # re arranging the data into an array
      # and into an cp_per_iter_per_component
      cp_per_iter_per_component = {}
      for component_name in component_names:
          cp_per_iter_per_component[component_name] = []
      data = []
      data.append(["iteration"] + component_names)
      for iter in range(max_iteration + 1):
          if iter not in cp_per_component_per_iter:
              continue
          comp_dict = cp_per_component_per_iter[iter]
          row = [iter]
          for component in component_names:
              try:
                  row.append(comp_dict[component])
                  cp_per_iter_per_component[component].append(
                      [iter, comp_dict[component]]
                  )
              except KeyError:
                  # if clipped proportion is not available for a particular
                  # component it is set to None
                  # this usually happens during layer-wise discriminative
                  # training
                  row.append(None)
          data.append(row)
  
      return {
          "table": data,
          "cp_per_component_per_iter": cp_per_component_per_iter,
          "cp_per_iter_per_component": cp_per_iter_per_component,
      }
  
imports: from __future__ import division
  from __future__ import print_function
  import traceback
  import datetime
  import logging
  import re
  import libs.common
label_desc: Use image node_id 4 for calling a global function with example usage: parse_progress_logs_for_clipped_proportion(exp_dir) and returns: dict