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的核心代码。