code: def parse_rnnlm_prob_logs(exp_dir, key="objf"):
      train_prob_files = "%s/log/train.*.*.log" % (exp_dir)
      valid_prob_files = "%s/log/compute_prob.*.log" % (exp_dir)
      train_prob_strings = common_lib.get_command_stdout(
          "grep -e {0} {1}".format(key, train_prob_files)
      )
      valid_prob_strings = common_lib.get_command_stdout(
          "grep -e {0} {1}".format(key, valid_prob_files)
      )
  
      # LOG
      # (rnnlm-train[5.3.36~8-2ec51]:PrintStatsOverall():rnnlm-core-training.cc:118)
      # Overall objf is (-4.426 + -0.008287) = -4.435 over 4.503e+06 words (weighted)
      # in 1117 minibatches; exact = (-4.426 + 0) = -4.426
  
      # LOG
      # (rnnlm-compute-prob[5.3.36~8-2ec51]:PrintStatsOverall():rnnlm-core-training.cc:118)
      # Overall objf is (-4.677 + -0.002067) = -4.679 over 1.08e+05 words (weighted)
      # in 27 minibatches; exact = (-4.677 + 0.002667) = -4.674
  
      parse_regex_train = re.compile(
          ".*train\.([0-9]+).1.log:LOG "
          ".rnnlm-train.*:PrintStatsOverall..:"
          "rnnlm.*training.cc:[0-9]+. Overall ([a-zA-Z\-]+) is "
          ".*exact = \(.+\) = ([0-9.\-\+e]+)"
      )
  
      parse_regex_valid = re.compile(
          ".*compute_prob\.([0-9]+).log:LOG "
          ".rnnlm.*compute-prob.*:PrintStatsOverall..:"
          "rnnlm.*training.cc:[0-9]+. Overall ([a-zA-Z\-]+) is "
          ".*exact = \(.+\) = ([0-9.\-\+e]+)"
      )
  
      train_objf = {}
      valid_objf = {}
  
      for line in train_prob_strings.split("\n"):
          mat_obj = parse_regex_train.search(line)
          if mat_obj is not None:
              groups = mat_obj.groups()
              if groups[1] == key:
                  train_objf[int(groups[0])] = groups[2]
      if not train_objf:
          raise KaldiLogParseException(
              "Could not find any lines with {k} in "
              " {l}".format(k=key, l=train_prob_files)
          )
  
      for line in valid_prob_strings.split("\n"):
          mat_obj = parse_regex_valid.search(line)
          if mat_obj is not None:
              groups = mat_obj.groups()
              if groups[1] == key:
                  valid_objf[int(groups[0])] = groups[2]
  
      if not valid_objf:
          raise KaldiLogParseException(
              "Could not find any lines with {k} in "
              " {l}".format(k=key, l=valid_prob_files)
          )
  
      iters = list(
          set(valid_objf.keys()).intersection(list(train_objf.keys()))
      )
      if not iters:
          raise KaldiLogParseException(
              "Could not any common iterations with"
              " key {k} in both {tl} and {vl}".format(
                  k=key, tl=train_prob_files, vl=valid_prob_files
              )
          )
      iters.sort()
      return [
          (int(x), float(train_objf[x]), float(valid_objf[x]))
          for x in iters
      ]
  
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 8 for calling a global function with example usage: parse_rnnlm_prob_logs(exp_dir, key) and returns: unknown