2021SC@SDUSC
本文将针对vectorize中的rev_ents函数和reverse函数进行分析
重点在于对reverse函数的分析和理解
vocab = self.NERD.vocab
es = []
for e in batch:
s = [vocab.itos[y].split(">")[0]+"_"+str(i)+">"for i,y in enumerate(e)
if vocab.itos[y] not in ['<pad>','<eos>']]
es.append(s)
return es
首先传入我们的批数据batch,获取当前向量实例为vocab。同时,初始化一个空的集合便于后续的添加与结果返回,在这里表示为es=[],创建一个空列表。
遍历批数据batch中的每个元素e,创建一个新的向量s ,s的值为向量实例在y方向上的投影按>分割后第一位值与字符串_和字符串>的拼接,
enumerate函数将可迭代对象其组成一个索引序列,利用它可以同时获得索引和值,因此我们获得每个元素e的索引值i和y值,如果voab迭代器y值不在我们的划分内,则在es中加上s值
ents = ents[0][0]
vocab = self.TGT.vocab
ss = []
在反转reverse函数中,我们新初始化一个二维数组ents,空列表ss[],vocab表示传入vocab对象实例。
for i,x in enumerate(preds):
s = ' '.join([vocab.itos[y]if y<len(vocab.itos) else "COPY"
同样使用enumerate遍历preds,获取每个元素值x和索引值i,并将空字符串’ ‘与vocab.itos[y]拼接起来(将其转换为字符串类型),如果我们vocab在y上的值大于等于itos容量时,需要对它进行一个复制转存。
for j,y in enumerate(x)])
if "<eos>" in s:s = s.split("<eos>")[0]
elif s[-1] not in ".?!":
lastidx = [i for i,x in enumerate(s) if x in ".?!"]
if lastidx:
lastidx = max(lastidx)
s = s[:lastidx+1]
ss.append(s)
该层循环是上层循环的一个内嵌循环,对获得的x进行二次遍历,获得对应的y值和索引值j。如果s中包含我们的划分,我们就根据’<eos>'值进行划分,并获得首位的投影,再次赋值给s
同时需要对s的末尾值进行一个判断,如果s数组不以.?!结束,则需启用依次遍历找到.?!所在的索引i,并赋值给lastidx,表示最后一个元素的索引值。
如果lastidx存在,返回最大的lastidx值,这时s的存储范围扩大到lastidx+1
最后再最初的空序列ss中追加上s