使用深度学习模型创作动漫故事,比较LSTM和GPT2的文本生成方法(下)

本文涉及的产品
模型训练 PAI-DLC,5000CU*H 3个月
模型在线服务 PAI-EAS,A10/V100等 500元 1个月
交互式建模 PAI-DSW,5000CU*H 3个月
简介: 使用深度学习模型创作动漫故事,比较LSTM和GPT2的文本生成方法

在上面的例子中,我给出的最大长度为100,输入文本为“In the”,这就是我们得到的输出

In the days attempt it 's . although it has , however ! what they  believe that humans of these problems . it seems and if will really make anything . as she must never overcome allowances with jousuke s , in  order her home at him without it all in the world : in the hospital she  makes him from himself by demons and carnage . a member and an idol team the power for to any means but the two come into its world for what if  this remains was to wait in and is n't going ! on an

这在语法上似乎是正确的,但却毫无意义。LSTM虽然更善于捕捉长期依赖比基本RNN但他们只能看到几步(字)或向前迈了几步,如果我们使用双向RNNs捕获文本的上下文因此生成很长的句子时,我们看到他们毫无意义。

GPT2方式

一点点的理论

Transformers在捕获所提供的文本片段的上下文方面做得更好。他们只使用注意力层(不使用RNN),这让他们更好地理解文本的上下文,因为他们可以看到尽可能多的时间步回(取决于注意力)。注意力有不同的类型,但GPT2所使用的注意力,是语言建模中最好的模型之一,被称为隐藏的自我注意。

GPT2没有同时使用transformer 编码器和解码器堆栈,而是使用了一个高栈的transformer 解码器。根据堆叠的解码器数量,GPT2转换器有4种变体。

640.png

每个解码器单元主要由2层组成:

  • Masked 的自我关注
  • 前馈神经网络

在每一步之后还有一个层规范化步骤和一个残差连接。

640.png

直观地说,自注意分数给了我们当前时间步长的单词应该给予其他单词的重要性或注意(过去的时间步或者未来的时间步取决于注意力)。

然而,在隐藏的自注意中,我们并不关心下一个或未来的单词。因此,transformer 解码器仅关注当前和过去的单词以及将来的单词。盖。

这里有一个关于这个想法的漂亮的表述……

640.png

在上面的示例中,当前单词是“ it”,并且您可以看到单词“ a”和“ robot”具有很高的注意力得分。这是因为“ it”被用来指“robot”,“ a”也被指。

您必须已经注意到上面输入文本开头的<s>标记。<s>仅用于标记输入字符串的开头。传统上,使用<| endoftext |>代替<s>令牌。

您还必须注意的另一件事是,这与传统语言建模相似,在传统语言建模中,可以看到当前令牌和过去令牌,并预测下一个令牌。然后,将该预测令牌添加到输入中,然后再次预测下一个令牌。

代码

我已经将GPT2与Hugging Face库中的线性模型一起用于文本生成。在这4个变体中,我使用了GPT2 small(具有117M个参数)。

我已经在Google Colab上训练了模型,训练中的主要问题是弄清楚批大小和最大序列长度,以便在GPU上进行训练时不会出现内存不足的情况,批大小为10,最大序列长度为 300终于可以工作了。

因此,我也删除了带有300个以上单词的提要,以便当我们生成提要直到300时,它实际上是完整的。

创建数据集

为了进行微调,首要任务是获取所需格式的数据,Pytorch中的数据加载器使我们可以非常轻松地做到这一点。

步骤如下:

  1. 使用上面定义的clean_function清理数据。
  2. 每个提要后都添加<| endoftext |>标记。
  3. 使用HuggingFace的GPT2Tokenizer对每个大纲进行标记。
  4. 为标记化单词创建一个遮罩(注意:此遮罩与我们讨论的被遮罩的自我注意不同,这是用于遮罩下一个将要看到的填充标记)。
  5. 使用<| pad |>标记填充长度小于最大长度(此处为300)的序列。
  6. 将令牌ID和掩码转换为张量并返回它们。
importtorchfromconfigimporttokenizerfromutilsimportclean_synopsisfromconfigimportmax_seq_lenclassAnimeDataset():
def__init__(self,data):
self.eos_tok='<|endoftext|>'synopsis=clean_synopsis(data)
synopsis=synopsis.apply(lambdax: str(x) +self.eos_tok)
self.synopsis=synopsis.tolist()
self.pad_tok=tokenizer.encode(['<|pad|>'])
def__getitem__(self,item):
synopsis=self.synopsis[item]
tokens=tokenizer.encode(synopsis)
mask= [1]*len(tokens)
max_len=max_seq_lenifmax_len>len(tokens):
padding_len=max_len-len(tokens)
tokens=tokens+self.pad_tok*padding_lenmask=mask+ [0]*padding_lenelse:
tokens=tokens[:max_len]
mask=mask[:max_len]
iftokens[-1]!=tokenizer.encode(self.eos_tok)[0]:
tokens[-1] =tokenizer.encode(self.eos_tok)[0]
return {'ids':torch.tensor(tokens,dtype=torch.long),
'mask': torch.tensor(mask,dtype=torch.long),
'og_synpsis':synopsis}
def__len__(self):
returnlen(self.synopsis)

模型架构

在这里,我们不需要明确地创建模型架构,因为Hugging Face库会为我们解决这个问题。我们只需要导入带有语言模型的预训练GPT2模型即可。

这个模型中的LM头是一个线性层,它输出每个词汇标记的分数(在softmax之前)。

Hugging Face提供的带有LM头的GPT2Model的有趣之处在于,我们可以在此处直接传递标签(我们的输入令牌),并且标签在内部向右移动一级,模型与预测得分一起返回损失 也一样 实际上,它也返回模型中每一层的隐藏状态以及注意力得分,但我们对此并不感兴趣。

我们可以导入模型和令牌生成器,并在配置类中定义所有超参数,如下所示:

importtransformersbatch_size=10model_path='gpt2_epoch5.bin'max_seq_len=300epochs=5data_path='Data/eda-data.csv'tokenizer=transformers.GPT2Tokenizer.from_pretrained('gpt2')
model=transformers.GPT2LMHeadModel.from_pretrained('gpt2')

训练函数

步骤:

  • 训练功能从dataloader获取ID和掩码。
  • 通过模型传递ID和掩码。

该模型输出一个元组:-(损失,预测分数,每个被屏蔽的关注层的键和值对列表,每个层的隐藏状态列表,注意力分数)我们仅对该元组中的前2个项目感兴趣。

  • 执行向后传播并更新参数。
  • 返回该时期的平均损失。

fromtqdmimporttqdmimporttorchfromutilsimportAverageMeterimportnumpyasnpdeftrain_fn(model,dataloader,optimizer,scheduler,device):
model.train()
tk0=tqdm(dataloader, total=len(dataloader), leave=True, position=0)
train_loss=AverageMeter()
losses= []
forbi,dinenumerate(tk0):
ids=d['ids'].to(device,dtype=torch.long)
mask=d['mask'].to(device,dtype=torch.long)
loss,out=model(input_ids=ids, labels=ids, attention_mask=mask)[:2]
train_loss.update(loss.item())    
loss.backward()
losses.append(loss.item())
optimizer.step()
scheduler.step()
model.zero_grad()
tk0.set_postfix(loss=train_loss.avg)
returnnp.mean(losses)

执行训练

步骤:

  1. 读取数据。
  2. 创建dataloader对象。
  3. 定义优化程序,我正在使用AdamW(具有权重衰减的Adam)。学习率是0.0001,体重衰减是0.003。
  4. 定义学习率计划。我使用线性学习率,可以从Hugging Face的模型进行预热。预热步骤为10(基本上,这意味着对于前10个训练步骤,学习率将线性增加,然后线性降低)。
  5. 运行训练功能。我已经训练了5个轮次。
  6. 保存损失最小的模型。
  7. 在每个轮次后清空GPU缓存,以防止OOM错误。
importpandasaspdfromtransformersimportAdamWfromdatasetimportAnimeDatasetfromconfigimportmodel,epochs,batch_size,data_path,model_pathfromengineimporttrain_fnfromtransformersimportget_linear_schedule_with_warmupimporttorchdefrun():
data=pd.read_csv(data_path)
dataset=AnimeDataset(data=data)
dataloader=torch.utils.data.DataLoader(dataset,batch_size=batch_size,shuffle=True)
device='cuda'model.to(device)
optimizer=AdamW(model.parameters(),lr=0.0001,weight_decay=0.003)    
scheduler=get_linear_schedule_with_warmup(optimizer,
num_warmup_steps=10,num_training_steps=int(len(data)/batch_size*epochs))
best_loss=111111forepochinrange(epochs):
loss=train_fn(model,dataloader,optimizer,scheduler,device)
ifloss<best_loss:
best_loss=losstorch.save(model.state_dict(),model_path)
torch.cuda.empty_cache

生成动漫文字

在生成步骤中,我使用了top-k采样(如LSTM方式)以及top-p采样。在top-p采样中,我们提供了一个累积概率,即p,则所选的顶级词汇标记必须具有p的总和概率。

我们可以结合使用top-k和top-p方法,首先以最高的概率分数选择top-k令牌,然后为这k个令牌计算归一化分数。这样,k个令牌的这些分数之和为1,我们也可以说概率质量只是在k个令牌之间重新分配。

接下来的top-p采样是在这k个分数上完成的,然后最后从选定的标记中,我们仅使用概率进行采样以获取最终的输出标记。

我们不必编写所有代码,Hugging Face可以通过其generate方法来处理所有事情。

步骤:

  • 获取输入文本并对其进行编码(标记+填充)以获取ID。
  • 使用generate函数传递ID。在generate方法中传递编码的<| pad |>令牌非常重要,这样才能区分它。
  • 解码输出并返回。
  • 将输出保存在文本文件中。
importtorchfromconfigimportmodel,tokenizer,model_pathdefgenerate_text(input_text,device='cuda',max_len=300):
pad_tok=tokenizer.encode(['<|pad|>'])[0]
model.load_state_dict(torch.load(model_path))
model.to(device)
model.eval()
input_ids=tokenizer.encode(input_text)
ids=torch.tensor(input_ids,dtype=torch.long).to(device).unsqueeze(0)
sample_out=model.generate(ids, min_length=30,max_length=max_len, pad_token_id=pad_tok,
top_k=1000,
top_p=0.95, early_stopping=True,
do_sample=True, num_beams=5,
no_repeat_ngram_size=2,num_return_sequences=1,
temperature=0.6)
out=tokenizer.decode(sample_out[0],skip_special_tokens=True)
returnouttorch.random.seed=55input_texts= ['After years','When the night','This is the story', 'Spike was','In the year',
'A shinigami','During the war','A young man']
forinput_textininput_texts:
generated_anime=generate_text(input_text,device='cpu')
print(generated_anime,'\n\n')
#savingfile=open('Generated Anime Examples.txt','a')
file.write(f'{generated_anime}\n\n')
file.close()

你可能已经注意到generate方法有很多参数。可以对其进行调整以获得最佳的输出。

对于输入文本“In the year”,这是我们得到的输出…。

In the year 2060, mankind has colonized the solar system, and is now on  the verge of colonizing other planets. In order to defend themselves  against this new threat, the Earth Federation has established a special  unit known as the Planetary Defense Force, or PDF. The unit is composed  of the elite Earth Defense Forces, who are tasked with protecting the  planet from any alien lifeforms that might threaten the safety of Earth. However, when a mysterious alien ship crashes in the middle of their  patrol, they are forced to use their special mobile suits to fend off  the alien threat.

LSTM和GPT2生成的提要之间的差异非常大!该模型不仅能够很好地捕获长期依赖关系,而且上下文始终保持不变。比如这个

A shinigami (death god) who is a descendant of the legendary warrior  Shigamis father, is sent to Earth to fight against the evil organization known as the Dark Clan. However, his mission is to steal the sacred  sword, the Sword of Light, which is said to grant immortality to those  who wield it.

希望您喜欢这篇文章。

目录
相关文章
|
9天前
长上下文能力只是吹牛?最强GPT-4o正确率仅55.8%,开源模型不如瞎蒙
【8月更文挑战第10天】新研究NoCha挑战显示,即使是顶级的大型语言模型GPT-4o,在处理长篇幅文本时正确率仅55.8%,低于人类直观水平。该挑战基于近作英文小说,检验模型对整本书信息的理解与推理能力。结果显示,模型在全局推理上的表现不佳,倾向于依赖局部信息而非整体上下文,尤其是在复杂推理需求高的科幻小说上表现更弱。这一发现揭示了当前模型在处理长上下文任务上的局限性。论文链接: [https://arxiv.org/pdf/2406.16264](https://arxiv.org/pdf/2406.16264)。
103 65
|
4天前
|
机器学习/深度学习 数据可视化 网络架构
增强深度学习模型的可解释性和泛化能力的方法研究
【8月更文第15天】在深度学习领域,模型的准确率和预测能力是衡量模型好坏的重要指标。然而,随着模型复杂度的增加,它们往往变得越来越难以理解,这限制了模型在某些关键领域的应用,例如医疗诊断、金融风险评估等。本文将探讨如何通过几种方法来增强深度学习模型的可解释性,同时保持或提高模型的泛化能力。
20 2
|
16天前
|
人工智能 自然语言处理
公理训练让LLM学会因果推理:6700万参数模型比肩万亿参数级GPT-4
【8月更文挑战第3天】新论文提出“公理训练”法,使仅有6700万参数的语言模型掌握因果推理,性能媲美万亿级GPT-4。研究通过大量合成数据示例教授模型因果公理,实现有效推理并泛化至复杂图结构。尽管面临合成数据需求大及复杂关系处理限制,此法仍为语言模型的因果理解开辟新途径。[链接: https://arxiv.org/pdf/2407.07612]
28 1
|
1月前
|
人工智能 知识图谱
LeCun谢赛宁首发全新视觉多模态模型,等效1000张A100干翻GPT-4V
【7月更文挑战第7天】LeCun与谢赛宁团队推出 Cambrian-1,一款视觉多模态大语言模型,挑战GPT-4V。该模型以视觉为中心,利用20多种视觉编码器强化表示学习,实现SOTA性能,同时开源权重、代码及工具,促进领域发展。尽管面临资源需求与数据隐私的讨论,但其创新如空间视觉聚合器(SVA)降低了计算需求。[论文链接: https://arxiv.org/abs/2406.16860]
34 1
|
6天前
|
人工智能
ECCV 2024:让GPT-4图像理解更易出错,全新策略增强VLP模型对抗迁移性
【8月更文挑战第13天】在AI领域,视觉语言预训练(VLP)模型展现出了强大的图像与文本理解能力,但也易受多模态对抗样本攻击。为此,研究者提出了Cross-Clean-Adversarial Regional Diversification (CCAR-Div)策略,通过增强对抗样本多样性以提升VLP模型的对抗迁移性。此策略在对抗轨迹交集区域采样,增加样本多样性,并利用模态交互作用。经Flickr30K和MSCOCO数据集验证,CCAR-Div能有效提高跨模型与跨任务场景下的对抗迁移性,如使用ALBEF生成的对抗样本攻击TCL时,成功率高达95.58%。
95 60
|
5天前
|
人工智能 安全 测试技术
Google DeepMind推出大模型 Gemini (vs GPT4):规模最大、能力最强的人工智能模型
Google DeepMind推出大模型 Gemini (vs GPT4):规模最大、能力最强的人工智能模型
16 4
|
1月前
|
机器学习/深度学习 编解码 监控
算法金 | 深度学习图像增强方法总结
**图像增强技术概括** 图像增强聚焦于提升视觉效果和细节,广泛应用于医学、遥感等领域。空间域增强包括直方图均衡化(增强对比度)、对比度拉伸、灰度变换、平滑滤波(均值、中值)和锐化滤波(拉普拉斯、高通)。频率域增强利用傅里叶变换、小波变换,通过高频和低频滤波增强图像特征。现代方法涉及超分辨率重建、深度学习去噪(如CNN、Autoencoder)、图像修复(如GAN)和GANs驱动的多种图像处理任务。
52 14
算法金 | 深度学习图像增强方法总结
|
13天前
|
机器学习/深度学习
【机器学习】面试题:LSTM长短期记忆网络的理解?LSTM是怎么解决梯度消失的问题的?还有哪些其它的解决梯度消失或梯度爆炸的方法?
长短时记忆网络(LSTM)的基本概念、解决梯度消失问题的机制,以及介绍了包括梯度裁剪、改变激活函数、残差结构和Batch Normalization在内的其他方法来解决梯度消失或梯度爆炸问题。
26 2
|
13天前
|
人工智能 测试技术
ACL 2024:对25个开闭源模型数学评测,GPT-3.5-Turbo才勉强及格
【8月更文挑战第6天】在ACL 2024会议上,研究人员提出GSM-Plus对抗性基准,旨在评估大型语言模型(LLMs)如GPT-3.5-Turbo在数学推理上的鲁棒性。通过对25个模型和4种提示技术的测试,结果显示模型们虽能在标准GSM8K数据集上取得好成绩,但在遇到问题变异时表现欠佳,提示技术提升作用有限,揭示了LLMs在数学理解深度上的局限。论文详述了这一发现及其对未来研究的意义。
27 2
|
1月前
|
测试技术
8B尺寸达到GPT-4级性能!北大等提出医疗专家模型训练方法
【7月更文挑战第8天】北京大学等研究者提出的新方法缓解了大模型如Llama-3-8B在持续预训练时的“稳定性差距”,通过多轮次训练、高质量子语料库选择和数据混合策略,提升性能和效率。在医疗领域,他们将OpenLlama-3B性能提升至40.7%,并创建的Llama-3-Physician模型达到GPT-4级别。尽管取得突破,该方法在其他模型和领域的适用性仍需探索,且持续预训练仍资源密集。[链接: https://arxiv.org/abs/2406.14833]
62 25