2021SC@SDUSC
?本文将针对vertorize.py中pad_list pad seqentmat三部分函数进行重点分析
? ? lens = [len(x) for x in l] ? ? m = max(lens) ? ? return torch.stack([self.pad(torch.tensor(x),m,ent) for x in l],0), torch.LongTensor(lens)
首先获取最大长度m,调用stack函数沿着一个新维度对输入张量序列进行连接,在这里是对每一个x维度调用了pad函数,然后在0维度上,和lens生成的张量拼接
def pad(self,tensor, length,ent=1): ?return torch.cat([tensor, tensor.new(length - tensor.size(0), *tensor.size()[1:]).fill_(ent)])
?在pad函数中调用tensor.new创建了一个新的张量该张量从第二维度开始,形成 tensor,新张量和指针的列表,通过ent调用fill_函数后使用cat函数合并。
?for l in entseq: ? ? ? ? l = l.tolist() ? ? ? if self.enteos in l: ? ? ? ? l = l[:l.index(self.enteos)] ? ? ? tmp = [] ? ? ? while self.entspl in l: ? ? ? ? tmp.append(l[:l.index(self.entspl)]) ? ? ? ? l = l[l.index(self.entspl)+1:] ? ? ? if l: ? ? ? ? tmp.append(l) ? ? ? lens.append(len(tmp)) ? ? ? m = max([len(x) for x in tmp]) ? ? ? sms.append(m) ? ? ? tmp = [x +([0]*(m-len(x))) for x in tmp] ? ? ? newents.append(tmp)
将entseq 中每个元素遍历,并转换为列表l,判断enteos是否在l中,如果存在,则截取其前半部分内容给l,设置一个tmp空列表,进入内层循环while,该循环不断地向tmp中追加截取entspl前半部部分类额表,并让列表扩容;if语句实现向tmp中追加最后一个元素,并且追加lens的长度,加上tep长,m变为tmp中元素最大长度。在sms中追加m值,并为tmp中空出的部分补上0,追加tmp给newents。
? ? sm = max(lens) ? ? pm = max(sms) ? ? for i in range(len(newents)): ? ? ? tmp = torch.LongTensor(newents[i]).transpose(0,1) ? ? ? tmp = self.pad(tmp,pm,ent=0) ? ? ? tmp = tmp.transpose(0,1) ? ? ? tmp = self.pad(tmp,sm,ent=0) ? ? ? newents[i] = tmp ? ? newents = torch.stack(newents,0).cuda() ? ? lens = torch.LongTensor(lens).cuda() ? ? return newents,lens
重新获取最大长度,分别为sm和pm,遍历每一个newents中的元素,将每个元素0和1维度进行转置赋值给tmp,接着调用pad函数,将tmp pm合并为新的张量,再次进行转置,再次将tmp和sm合并为新的张量,沿着0维度将新的向量按序拼接获得newents,获得长度lens,并返回最终结果。
if __name__=="__main__": ? args = arg.pargs() ? ? ds = dataset(args) ? ds.getBatch()?
这部分代码对主函数分配迭代训练数据集并抽取出迭代数据。
|