5分钟NLPPython文本生成的BeamSearch解码
贪婪搜索是在每个时间步中选择概率最高的单词,也是我们最常用的一种方法,BeamSearch不取每个标记本身的绝对概率,而是考虑每个标记的所有可能扩展。然后根据其对数概率选择最合适的标记序列。
例如令牌的概率如下所示:
例如,Pancakeslooks时间段1的概率等效于:Pancakeslookssolog(0。2)log(0。7)1。9Pancakeslooksfluffylog(0。2)log(0。3)2。8
所以我们需要定义一个函数来完成整句的概率计算:importtorch。nn。functionalasFdeflogprobabilitysingle(logits,labels):logpF。logsoftmax(logits,dim1)logplabeltorch。gather(logp,2,labels。unsqueeze(2))。squeeze(1)returnlogplabeldefsentencelogprob(model,labels,inputlen0):withtorch。nograd():resultmodel(labels)logprobabilitylogprobabilitysingle(result。logits〔:,:1,:〕,labels〔:,1:〕)sentencelogprobtorch。sum(logprobability〔:,inputlen:〕)returnsentencelogprob。cpu()。numpy()
接下来,可以将其应用于贪婪搜索解码方法生成的输出,并计算生成的序列的对数概率。
在此示例中,我将在村上春木的书中简要介绍:1Q84。inputsentenceAlovestory,amystery,afantasy,anovelofselfdiscovery,adystopiatorivalGeorgeOrwell’s1Q84isHarukiMurakami’smostambitiousundertakingyet:aninstantbestsellerinhisnativeJapan,andatremendousfeatofimaginationfromoneofourmostreveredcontemporarywriters。maxsequence100inputidstokenizer(inputsentence,returntensorspt)〔inputids〕。to(device)outputmodel。generate(inputids,maxlengthmaxsequence,dosampleFalse)greedysearchoutputsentencelogprob(model,output,inputlenlen(inputids〔0〕))print(tokenizer。decode(output〔0〕))
我们可以看到生成的序列的对数概率为52。31。
现在,我们将并比较通过BeamSearch生成的序列的对数概率得分,得分越高潜在结果越好。
我们可以增加ngram惩罚参数norepeatngramsize,这有助于减少输出中的重复生成的序列。beamsearchoutputmodel。generate(inputids,maxlengthmaxsequence,numbeams5,dosampleFalse,norepeatngramsize2)beamsearchlogprobsentencelogprob(model,beamsearchoutput,inputlenlen(inputids〔0〕))print(tokenizer。decode(beamsearchoutput〔0〕))print(flogprob:{beamsearchlogprob:。2f})
输出如下:
分时和连贯性要比贪婪的方法好很多,对吧。
作者:JasonLZP