当前位置: 首页 > news >正文

Pytorch实现transformer语言模型

转载自:| 03_language_model/02_Transformer语言模型.ipynb | 从头训练Transformer语言模型 |Open In Colab |

Transformer语言模型

本节训练一个 sequence-to-sequence 模型,使用pytorch的
nn.Transformer <https://pytorch.org/docs/master/nn.html?highlight=nn%20transformer#torch.nn.Transformer> module.

PyTorch 1.2 基于论文 Attention is All YouNeed <https://arxiv.org/pdf/1706.03762.pdf> 实现了一个 Transformer 模型, nn.Transformer 模块依赖于 attention 机制实现表达输入和输出文本的关系。

定义模型

基于 nn.TransformerEncoder 模型训练语言模型。

语言模型任务是为句子后跟随单词输出一个似然概率,表征这个单词可能出现的概率。

首先做 embedding,再做 positional encoding, 表征单词位置关系。nn.TransformerEncoder 由多层nn.TransformerEncoderLayer <https://pytorch.org/docs/master/nn.html?highlight=transformerencoderlayer#torch.nn.TransformerEncoderLayer>组成,对于语言模型任务,每个未来可能出现的单词都需要 mask 并预测其概率,为了得到实际的预测单词,nn.TransformerEncoder模型的输出后需要接一个 log-Softmax 函数。

import math
import torch
import torch.nn as nn
import torch.nn.functional as Fclass TransformerModel(nn.Module):def __init__(self, ntoken, ninp, nhead, nhid, nlayers, dropout=0.5):super(TransformerModel, self).__init__()from torch.nn import TransformerEncoder, TransformerEncoderLayerself.model_type = 'Transformer'self.src_mask = Noneself.pos_encoder = PositionalEncoding(ninp, dropout)encoder_layers = TransformerEncoderLayer(ninp, nhead, nhid, dropout)self.transformer_encoder = TransformerEncoder(encoder_layers, nlayers)self.encoder = nn.Embedding(ntoken, ninp)self.ninp = ninpself.decoder = nn.Linear(ninp, ntoken)self.init_weights()def _generate_square_subsequent_mask(self, sz):mask = (torch.triu(torch.ones(sz, sz)) == 1).transpose(0, 1)mask = mask.float().masked_fill(mask == 0, float('-inf')).masked_fill(mask == 1, float(0.0))return maskdef init_weights(self):initrange = 0.1self.encoder.weight.data.uniform_(-initrange, initrange)self.decoder.bias.data.zero_()self.decoder.weight.data.uniform_(-initrange, initrange)def forward(self, src):if self.src_mask is None or self.src_mask.size(0) != len(src):device = src.devicemask = self._generate_square_subsequent_mask(len(src)).to(device)self.src_mask = masksrc = self.encoder(src) * math.sqrt(self.ninp)src = self.pos_encoder(src)output = self.transformer_encoder(src, self.src_mask)output = self.decoder(output)return output

PositionalEncoding 模块包括 relative 和 absolute 位置编码,positional encodings 与 embeddings 的维度是一样的,这样两者可以相加。

class PositionalEncoding(nn.Module):def __init__(self, d_model, dropout=0.1, max_len=5000):super(PositionalEncoding, self).__init__()self.dropout = nn.Dropout(p=dropout)pe = torch.zeros(max_len, d_model)position = torch.arange(0, max_len, dtype=torch.float).unsqueeze(1)div_term = torch.exp(torch.arange(0, d_model, 2).float() * (-math.log(10000.0) / d_model))pe[:, 0::2] = torch.sin(position * div_term)pe[:, 1::2] = torch.cos(position * div_term)pe = pe.unsqueeze(0).transpose(0, 1)self.register_buffer('pe', pe)def forward(self, x):x = x + self.pe[:x.size(0), :]return self.dropout(x)

加载数据

模型训练过程使用来自 torchtext 的Wikitext-2数据集。vocab 基于 train 数据集构建。batchify()函数将数据集排列成列,在将数据划分为大小为`batch_size``的批次后,删除所有剩余的标记。

例如,将字母表作为序列(总长度为26),批量大小为4,我们将字母表分成4个长度为6的序列:
在这里插入图片描述

import os
import torchtext
from torchtext.data.utils import get_tokenizerdevice = torch.device("cuda" if torch.cuda.is_available() else "cpu")TEXT = torchtext.legacy.data.Field(init_token='<sos>',eos_token='<eos>',lower=True)
train_txt, val_txt, test_txt = torchtext.legacy.datasets.language_modeling.WikiText2.splits(TEXT)
TEXT.build_vocab(train_txt)TEXT
len(train_txt.examples[0].text)
# 2088628
def batchify(data, bsz):data = TEXT.numericalize([data.examples[0].text])# Divide the dataset into bsz parts.nbatch = data.size(0) // bsz# Trim off any extra elements that wouldn't cleanly fit (remainders).data = data.narrow(0, 0, nbatch * bsz)# Evenly divide the data across the bsz batches.data = data.view(bsz, -1).t().contiguous()return data.to(device)batch_size = 20
eval_batch_size = 10
train_data = batchify(train_txt, batch_size)
val_data = batchify(val_txt, eval_batch_size)
test_data = batchify(test_txt, eval_batch_size)print(train_data.shape)
print(val_data.shape)
# torch.Size([104431, 20])
# torch.Size([21764, 10])

定义生成target文本

bptt = 35
def get_batch(source, i):seq_len = min(bptt, len(source) - 1 - i)data = source[i:i+seq_len]target = source[i+1:i+1+seq_len].view(-1)return data, target

试一下模型效果

设置超参:

ntokens = len(TEXT.vocab.stoi)  # the size of vocabulary
emsize = 200  # embedding dimension
nhid = 200  # the dimension of the feedforward network model in nn.TransformerEncoder
nlayers = 2  # the number of nn.TransformerEncoderLayer in nn.TransformerEncoder
nhead = 2  # the number of heads in the multiheadattention models
dropout = 0.2  # the dropout value
model = TransformerModel(ntokens, emsize, nhead, nhid,nlayers, dropout).to(device)

运行模型

import time
criterion = nn.CrossEntropyLoss()
lr = 5.0  # learning rate
optimizer = torch.optim.SGD(model.parameters(), lr=lr)
scheduler = torch.optim.lr_scheduler.StepLR(optimizer, 1.0, gamma=0.95)def train():model.train()  # Turn on the train modetotal_loss = 0.start_time = time.time()ntokens = len(TEXT.vocab.stoi)for batch, i in enumerate(range(0, train_data.size(0) - 1, bptt)):data, targets = get_batch(train_data, i)optimizer.zero_grad()output = model(data)loss = criterion(output.view(-1, ntokens), targets)loss.backward()torch.nn.utils.clip_grad_norm_(model.parameters(), 0.5)optimizer.step()total_loss += loss.item()log_interval = 200if batch % log_interval == 0 and batch > 0:cur_loss = total_loss / log_intervalelapsed = time.time() - start_timeprint('| epoch {:3d} | {:5d}/{:5d} batches | ''lr {:02.2f} | ms/batch {:5.2f} | ''loss {:5.2f} | ppl {:8.2f}'.format(epoch, batch, len(train_data) // bptt, scheduler.get_lr()[0],elapsed * 1000 / log_interval,cur_loss, math.exp(cur_loss)))total_loss = 0start_time = time.time()def evaluate(eval_model, data_source):eval_model.eval()  # Turn on the evaluation modetotal_loss = 0.ntokens = len(TEXT.vocab.stoi)with torch.no_grad():for i in range(0, data_source.size(0) - 1, bptt):data, targets = get_batch(data_source, i)output = eval_model(data)output_flat = output.view(-1, ntokens)total_loss += len(data) * criterion(output_flat, targets).item()return total_loss / (len(data_source) - 1)

在validation loss最优时保存模型,在每个epoch结束时调整learning rate。

best_val_loss = float("inf")
epochs = 10  # The number of epochs
best_model = None
MODEL_PATH = 'transformer_lm.pth'
for epoch in range(1, epochs + 1):epoch_start_time = time.time()train()val_loss = evaluate(model, val_data)print('-' * 89)print('| end of epoch {:3d} | time: {:5.2f}s | valid loss {:5.2f} | ''valid ppl {:8.2f}'.format(epoch, (time.time() - epoch_start_time),val_loss, math.exp(val_loss)))print('-' * 100)if val_loss < best_val_loss:best_val_loss = val_lossbest_model = modeltorch.save(best_model.state_dict(), MODEL_PATH)scheduler.step()best_model.load_state_dict(torch.load(MODEL_PATH))

在这里插入图片描述
Evaluate the model with the test dataset

Apply the best model to check the result with the test dataset.

test_loss = evaluate(best_model, test_data)
print('=' * 89)
print('| End of training | test loss {:5.2f} | test ppl {:8.2f}'.format(test_loss, math.exp(test_loss)))
print('=' * 89)
import os
os.remove('transformer_lm.pth')

相关文章:

Pytorch实现transformer语言模型

转载自&#xff1a;| 03_language_model/02_Transformer语言模型.ipynb | 从头训练Transformer语言模型 |Open In Colab | Transformer语言模型 本节训练一个 sequence-to-sequence 模型&#xff0c;使用pytorch的 nn.Transformer <https://pytorch.org/docs/master/nn.ht…...

Java后台生成指定路径下创建指定名称的文件

1.Java后台生成指定路径下创建指定名称的CSV文件 /*** <生成csv文件>* param filePath 文件路径名称* param fileName 文件名称* param colNameList 标题数据信息* param dataList CSV的文件数据* return filePathfileName* throws*/public static File genera…...

sqlcoder70b模型,如果需要训练或者微调需要什么样的GPU机器

要训练或微调 SQLCoder-70B 这样的大规模模型&#xff0c;需要高性能 GPU 资源。以下是硬件资源的推荐配置&#xff0c;特别是针对内存需求较大的模型&#xff1a; 1. GPU 显存要求 至少 8 张 A100 80GB GPUs&#xff1a;70B 参数模型在微调时需要高显存&#xff0c;80GB A10…...

【Python实战案例】爬虫项目实例(附赠源码)

文章目录 声明安装必要的库项目结构技术细节小结 声明 请您遵守网站的robots文件规定&#xff0c;本文目的只是做学习交流使用&#xff0c;包括多个模块&#xff0c;例如数据存储、日志记录、错误处理、多线程或异步请求 安装必要的库 pip install requests beautifulsoup4 sq…...

PDF多功能工具箱 PDF Shaper v14.6

如今对PDF处理的软件很多都是只是单一的功能。PDF Shaper给你完全不同的体验&#xff0c;因为PDF Shaper是一款免费的PDF工具集合的软件。有了PDF Shaper&#xff0c;你以后再也不用下载其他处理PDF的软件了。PDF Shaper的功能有&#xff1a;合并&#xff0c;分割&#xff0c;加…...

Jupyter Notebook添加kernel的解决方案

大家好,我是爱编程的喵喵。双985硕士毕业,现担任全栈工程师一职,热衷于将数据思维应用到工作与生活中。从事机器学习以及相关的前后端开发工作。曾在阿里云、科大讯飞、CCF等比赛获得多次Top名次。现为CSDN博客专家、人工智能领域优质创作者。喜欢通过博客创作的方式对所学的…...

Linux 无名管道

无名管道&#xff08;unnamed pipe&#xff09;是一种进程间通信的方式&#xff0c;通常用于父子进程之间的通信。下面是使用无名管道的基本步骤&#xff1a; pipe 调用的返回值如下&#xff1a; 成功时&#xff1a;pipe 调用成功时返回 0。失败时&#xff1a;如果 pipe 调用…...

Java项目实战II基于Spring Boot的药店管理系统的设计与实现(开发文档+数据库+源码)

目录 一、前言 二、技术介绍 三、系统实现 四、文档参考 五、核心代码 六、源码获取 全栈码农以及毕业设计实战开发&#xff0c;CSDN平台Java领域新星创作者&#xff0c;专注于大学生项目实战开发、讲解和毕业答疑辅导。 一、前言 随着医疗行业的快速发展和人们对健康需…...

前端拖拽库方案之react-beautiful-dnd

近期&#xff0c;知名 React 拖拽库 react-beautiful-dnd 宣布了项目弃用的决定&#xff0c;未来将不再维护。这一决定源于其存在的缺陷与局限性&#xff0c;促使作者转向开发一个更加现代化的拖拽解决方案——Pragmatic drag and drop&#xff08;下面会介绍&#xff09;&…...

【题解】CF2033G

题目 CF2033G 分析 一道很显然是树形dp的题&#xff0c;但非常恶心QwQ。   先不管复杂度&#xff0c;找找递推关系&#xff0c;一种很直接的想法如下&#xff08;我觉得是错误的&#xff09;&#xff1a; d p [ i ] [ k ] m a x ( d p [ f a i ] [ k − 1 ] , d p [ s o …...

【error】 react 控制台报错Invalid hook call

目录 事件起因解决办法结束语 事件起因 我的前端react ant-design-pro项目能正常启动 但是网页这边就是一片空白&#xff0c;然后在浏览器的控制台报错&#xff1a; index.js:1 Warning: Invalid hook call. Hooks can only be called inside of the body of a function co…...

SDL基本使用

#include <stdio.h>#include <SDL.h>#undef main int main() {printf("Hello World!\n");SDL_Window *window NULL; // 声明窗口SDL_Init(SDL_INIT_VIDEO); // 初始化SDL// 创建SDL Windowwindow SDL_CreateWindow("Basic Window"…...

大模型的temperature参数

目录 模型的temperature参数 一、定义与作用 二、工作原理 三、举例说明 四、应用场景与调整策略 五、注意事项 模型的temperature参数 是人工智能领域中,特别是在生成式模型中使用的一个重要概念。它主要用于控制生成结果的多样性和随机性。以下是对该参数的详细解释和…...

软件项目功能复用指南,复用方案,评估方案(word原件)

6 复用原则 6.1 单一职责原则 SRP &#xff08;Single Responsibility Principle&#xff09; 6.2 开放封闭原则 OCP &#xff08;Open Closed Principle&#xff09; 6.3 Liskov 替换原则 LSP &#xff08;Liskov Subtitle Principle&#xff09; 6.4 接口隔离原则 ISP &a…...

leetcode 3255 长度为 K 的子数组的能量值 II 中等

给你一个长度为 n 的整数数组 nums 和一个正整数 k 。 一个数组的 能量值 定义为&#xff1a; 如果 所有 元素都是依次 连续 且 上升 的&#xff0c;那么能量值为 最大 的元素。否则为 -1 。 你需要求出 nums 中所有长度为 k 的 子数组 的能量值。 请你返回一个长度为 n …...

CCS下载安装(以12.3.0版本为例)

Code Composer Studio 是一个集成开发环境 (IDE)&#xff0c;简称CCS软件。支持 TI 的微控制器和嵌入式处理器产品的开发。Code Composer Studio 包含一整套用于开发和调试嵌入式应用程序的工具。 CCS9.3.0及以上版本不需要License文件&#xff0c;但是CCS旧版本比如CCS5.5.0需…...

C++STL容器详解——list

目录 一.list 1.list的介绍 2.为什么会有list? 二.list的常见接口 1.list的构造函数 2.list的遍历 3.迭代器类型 4.list的头插头删和尾插尾删 5.list任意位置的插入和删除 6.list的sort()及reverse() 7.迭代器失效 三.整体代码 一.list 1.list的介绍 list的文档说…...

linux tar 打包为多个文件

将目录打包成多个大小为 80MB 的文件&#xff0c;可以使用以下命令&#xff1a; tar -cf - my_folder | split -b 80m - my_folder.tar.解释&#xff1a; tar -cf - my_folder 将 my_folder 目录打包成一个 tar 文件并通过管道 (|) 输出到标准输出。 split -b 80m - my_fold…...

json字符串与python字典的区别与联系

json字符串与python中自带的字典类型外表长的很像&#xff0c;很容易区分不清楚&#xff0c;它们之间有着本质的区别&#xff0c;可以通过内置的json模块来互相转换。 文章目录 1、Python字典2、JSON数据格式3、JSON与python字典的区别4、JSON与python字典相互转换4.1 json字符…...

数据结构-链表【chapter1】【c语言版】

目录 1 链表的优势&#xff1a; 2 链表的组成: 3.一般使用结构体的形式来实现链表&#xff1a; 4.单向链表实现(创建&#xff0c;遍历&#xff0c;释放)&#xff1a; 4.1代码关键点备注&#xff1a; 5.查找节点&#xff1a; 5.1.按值查找节点 5.2.按位置查找节点 5.3 …...

CTF show Web 红包题第六弹

提示 1.不是SQL注入 2.需要找关键源码 思路 进入页面发现是一个登录框&#xff0c;很难让人不联想到SQL注入&#xff0c;但提示都说了不是SQL注入&#xff0c;所以就不往这方面想了 ​ 先查看一下网页源码&#xff0c;发现一段JavaScript代码&#xff0c;有一个关键类ctfs…...

Cesium1.95中高性能加载1500个点

一、基本方式&#xff1a; 图标使用.png比.svg性能要好 <template><div id"cesiumContainer"></div><div class"toolbar"><button id"resetButton">重新生成点</button><span id"countDisplay&qu…...

Python实现prophet 理论及参数优化

文章目录 Prophet理论及模型参数介绍Python代码完整实现prophet 添加外部数据进行模型优化 之前初步学习prophet的时候&#xff0c;写过一篇简单实现&#xff0c;后期随着对该模型的深入研究&#xff0c;本次记录涉及到prophet 的公式以及参数调优&#xff0c;从公式可以更直观…...

宇树科技,改名了!

提到国内具身智能和机器人领域的代表企业&#xff0c;那宇树科技&#xff08;Unitree&#xff09;必须名列其榜。 最近&#xff0c;宇树科技的一项新变动消息在业界引发了不少关注和讨论&#xff0c;即&#xff1a; 宇树向其合作伙伴发布了一封公司名称变更函称&#xff0c;因…...

【网络安全】开源系统getshell漏洞挖掘

审计过程&#xff1a; 在入口文件admin/index.php中&#xff1a; 用户可以通过m,c,a等参数控制加载的文件和方法&#xff0c;在app/system/entrance.php中存在重点代码&#xff1a; 当M_TYPE system并且M_MODULE include时&#xff0c;会设置常量PATH_OWN_FILE为PATH_APP.M_T…...

群晖NAS如何在虚拟机创建飞牛NAS

套件中心下载安装Virtual Machine Manager 创建虚拟机 配置虚拟机 飞牛官网下载 https://iso.liveupdate.fnnas.com/x86_64/trim/fnos-0.9.2-863.iso 群晖NAS如何在虚拟机创建飞牛NAS - 个人信息分享...

elementUI点击浏览table所选行数据查看文档

项目场景&#xff1a; table按照要求特定的数据变成按钮可以点击 解决方案&#xff1a; <el-table-columnprop"mlname"label"名称"align"center"width"180"><template slot-scope"scope"><el-buttonv-if&qu…...

SQL Server 触发器调用存储过程实现发送 HTTP 请求

文章目录 需求分析解决第 1 步:前置条件,启用 OLE 自动化方式 1:使用 SQL 实现启用 OLE 自动化方式 2:Sql Server 2005启动OLE自动化方式 3:Sql Server 2008启动OLE自动化第 2 步:创建存储过程第 3 步:创建触发器扩展 - 如何调试?第 1 步:登录 SQL Server 2008第 2 步…...

鸿蒙(HarmonyOS5)实现跳一跳小游戏

下面我将介绍如何使用鸿蒙的ArkUI框架&#xff0c;实现一个简单的跳一跳小游戏。 1. 项目结构 src/main/ets/ ├── MainAbility │ ├── pages │ │ ├── Index.ets // 主页面 │ │ └── GamePage.ets // 游戏页面 │ └── model │ …...

Python 高级应用10:在python 大型项目中 FastAPI 和 Django 的相互配合

无论是python&#xff0c;或者java 的大型项目中&#xff0c;都会涉及到 自身平台微服务之间的相互调用&#xff0c;以及和第三发平台的 接口对接&#xff0c;那在python 中是怎么实现的呢&#xff1f; 在 Python Web 开发中&#xff0c;FastAPI 和 Django 是两个重要但定位不…...