“基于通用知识的推理问题”源代码分析-模型算法剩余部分

2021SC@SDUSC

有赖于之前数周的描述,我已经将DrFact模型与其他模型之间的联系阐述的比较详尽,因此我将在接下来的源代码分析中描述模型算法的剩余部分内容。由于fact2fact_index.py文件和index_corpus.py文件存在一个流程上的先后关系,因此在这次的源代码分析中,我将会把重心放在fact2fact_index.py文件和index_corpus.py文件上。接下里就直接进入分析环节。

一、fact2fact_index.py文件源码分析

1.1 调用模块

首先,fact2fact_index.py文件调用了这些python模块。其中有许多老熟人,如tqdm,absl,tensorflow.compat.v1等等。此外,还调用了DrKit模型中定义好的search_utils,正是之前我分析过的内容,那么在接下来的分析过程中,我们就不会再因为这个search_utils而感到头疼了。这正是我决定先对这些内容进行分析的一大原因。

import collections
import gc
import json
import os

from random import randint
from time import sleep
from tqdm import tqdm
from absl import app
from absl import flags
from language.labs.drkit import search_utils
import scipy.sparse as sp
import tensorflow.compat.v1 as tf

1.2 flags参数

接下来依旧是对flags定义参数的介绍。在fact2fact_index.py文件中,一共设置了9个参数。这些参数有三个参数有明确的缺省值,即num_shards的缺省值为1,max_follow的缺省值为1000,max_sleep的缺省值为-1。在此以外的变量均缺省值为None。

FLAGS = flags.FLAGS

flags.DEFINE_string("corpus_file", None, "Path to corpus.")

flags.DEFINE_string("fact2fact_index_dir", None, "Path to output files.")

flags.DEFINE_boolean("do_preprocess", None,
                     "Whether to run paragraph preprocessing.")

flags.DEFINE_boolean("do_combine", None,
                     "Whether to combine all shards into one.")

flags.DEFINE_integer("num_shards", 1,
                     "Number of shards to store mention embeddings in.")

flags.DEFINE_integer("max_follow", 1000, "Maximum of the following facts.")

flags.DEFINE_integer("my_shard", None,
                     "Shard number for this process to run over.")

flags.DEFINE_integer("shards_to_combine", None,
                     "Max number of shards to combine.")

flags.DEFINE_integer("max_sleep", -1,
                     "Max sleep random rate (1-100).")

 1.3 do_preprocess()函数

接下来进入对函数的分析,首先分析的对象是do_preprocess()函数。望文生义,do_preprocess()函数的功能是预处理数据,而查看了其中的注释后可以证实这一点。

在函数的定义中,首先通过_load_lines()函数(这个函数就是个很简单的读取,就不赘述了),获取flags参数corpus_file指向的文件中的每一行本文内容代表的数据,存放于lines列表中,然后构建一个表示实体频率的0字典entity_freq。

接下来,遍历lines列表,将其中内容使用json.loads()进行加载,存放于orig_para中,然后将其加入facts列表,再对其中mentions值遍历存于集合cecept_set中,以实现去重的效果,完成集合的存取之后,再将concept_set集合装入fact2entity_set列表中。完成这一系列操作之后,对concept_set遍历,将其中值作为索引,为该索引下的entity_freq列表的值+1。

之后,将entity_freq中的键值对根据翻转键序排序,再放入most_frequent_concepts集合中。

再将facts的长度保存于num_facts,如果num_shards参数大于等于2,则将num_facts与之相除,得到的值存于平均值num_facts_per_shard中,此时检测my_shard参数是否在0与num_shards之间,不是则报错。之后将my_shard与刚刚求出的平均值num_facts_per_shard相乘后加上平均值num_facts_per_shard的结果存于end_fact_index。

最后将num_facts中内容切片后形成indices列表,遍历其中内容切分整合成为一个矩阵之后,通过tensorflow的gfile处理储存于参数fact2fact_index_dir的位置。

def do_preprocess():
  """Loads and processes the data."""
  lines = _load_lines()
  fact2entity_set = []
  facts = []
  entity_freq = collections.defaultdict(lambda: 0)
  for line in tqdm(lines, desc="Reading corpus lines of shard_%d"%FLAGS.my_shard):
    orig_para = json.loads(line.strip())
    facts.append(orig_para)
    concept_set = set([m["kb_id"] for m in orig_para["mentions"]])
    fact2entity_set.append(concept_set)
    for c in concept_set:
      entity_freq[c] += 1
  k = 100  # For avoiding the bridge concepts being too common.
  most_frequent_concepts = set([
      c for c, _ in sorted(
          entity_freq.items(), key=lambda x: x[1], reverse=True)[:k]
  ])
  num_facts = len(facts)
  start_fact_index, end_fact_index = 0, None
  if FLAGS.num_shards >= 2:
    num_facts_per_shard = int(num_facts / FLAGS.num_shards)
    assert FLAGS.my_shard >= 0 and FLAGS.my_shard <= FLAGS.num_shards
    start_fact_index = int(FLAGS.my_shard * num_facts_per_shard)
    end_fact_index = int(start_fact_index + num_facts_per_shard)
    tf.logging.info("batch_mode! num_facts_per_shard: %d start:end=[%d:%d]",
                    num_facts_per_shard, start_fact_index, end_fact_index)

  rows, cols, vals = [], [], []
  indices = list(range(num_facts))
  for fact_i in tqdm(indices[start_fact_index: end_fact_index],
                     desc="Processing Fact2Fact (%d/%d)" %
            
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值