知识图到文本的生成——拾壹

2021SC@SDUSC

之前的十篇博客,我对train.py中的核心代码和关键代码进行了详细分析,可以得知,它主要是用于对数据集的训练,运行train.py的部分结果如下:

知识图到文本的生成——拾壹接下来我们看对数据集进行评价的代码:eval.py。简单说一下它是用来干嘛的。就是说,我们train完训练集之后,生成文本,也就是generate的过程。在生成之后,需要对生成的文本进行评估,这里也就是eval.py的内容,里面的类、函数和各种操作都是为了对文本进行评估。

首先先看main函数: 

    with open(sys.argv[1]) as f:
      cands = {'generated_description'+str(i):x.strip() for i,x in enumerate(f.readlines())}
    with open(sys.argv[2]) as f:
      refs = {'generated_description'+str(i):[x.strip()] for i,x in enumerate(f.readlines())}
    x = Evaluate()
    x.evaluate(live=True, cand=cands, ref=refs)

cands是sys.argv[1]文件中按行读取的descriptions,大致为:

'generated_description1:text1 generated_description2:text2'

refs类似。

然后初始化x为一个Evaluate类,接下来我将对Evaluate类进行详细分析。

    def __init__(self):
        self.scorers = [
            (Bleu(4), ["Bleu_1", "Bleu_2", "Bleu_3", "Bleu_4"]),
            (Meteor(), "METEOR"),
            (Rouge(), "ROUGE_L")
        ]

这是它的特殊函数__init__,里面的scorers属性是个列表,列表中有三个元素,每个元素是一个元组。Bleu是一种流行的机器翻译评价指标,用于分析候选译文和参考译文中n元组共同出现的程度;Meteor测度基于单精度的加权调和平均数和单字召回率,其目的是解决一些BLEU标准中固有的缺陷,也包括其他指标没有发现一些其他功能,如同义词匹配等。具体对这两个指标的理解我参考了这篇博客:

【NLP】机器翻译常用评价标准 (BLEU & METEOR)_Panonsense-CSDN博客_meteor 机器翻译

 本质上,BLEU是一个 nn-grams精确度的加权几何平均。ROUGE评价方法作为评价自动摘要质量的内部评价方法,这里使用的是Rouge-L,Rouge-L使用了最长公共子序列,一般只考虑召回率。

对Rouge的计算方法,我参考了这篇博客:

自动文摘评测方法:Rouge-1、Rouge-2、Rouge-L、Rouge-S_Jayson365的博客-CSDN博客_rouge

 

根据这三种评测方法,最终得出的分数就是scorers的值。

后面对这个Evaluate类x进行了类函数evaluate()的调用。

def evaluate(self, get_scores=True, live=False, **kwargs):

它是Evaluate的类函数,bool变量get_scores默认为True,为默认得到了scores。

        if live:
            temp_ref = kwargs.pop('ref', {})
            cand = kwargs.pop('cand', {})
        else:
            reference_path = kwargs.pop('ref', '')
            candidate_path = kwargs.pop('cand', '')
            with open(reference_path, 'rb') as f:
                temp_ref = pickle.load(f)
            with open(candidate_path, 'rb') as f:
                cand = pickle.load(f)

如果live为True,那么temp_ref就是传参进来的kwargs的'ref‘所对应的test,cand类似。如果live为False,那么就打开ref和cand的二进制文件,当我们要把对象从磁盘读到内存时,可以先把内容读到一个bytes,然后用pickle.loads()方法反序列化出对象,也可以直接用pickle.load()方法从一个file-like Object中直接反序列化出对象。

        hypo = {}
        ref = {}
        i = 0
        for vid, caption in cand.items():
            hypo[i] = [caption]
            ref[i] = temp_ref[vid]
            i += 1

这里是make directory的过程。cand.items()是一个类似集合的Object,提供cand项的视图。

后面我们会继续分析eval.py的核心代码。

上一篇:Python中常用英文单词大全


下一篇:BaseSerializer部分源码