• [问题求助] 鲲鹏920跑pytorch cpu训练速度很慢
    如题,pytorch cpu训练很慢,使用的是开源的wenet语音识别框架,搭了一个nvidia/cuda:11.6.1-cudnn8-runtime-ubuntu20.04镜像,但用的是cpu,训练可以正常运行,性能表现是模型前向计算很慢,一个小时的训练数据,batchsize 16, num_worker 4, 模型参数量80M, 需要一个小时才能跑一个batch,16小时跑一个epoch,这是因为什么问题导致的呢,大佬们帮忙看看我仔细分析了下,发现是torch.nn.Conv1d这个函数跑的慢, X86跑了0.016秒,arm跑了0.254秒,这是测试代码: import torch import time  # Create random input input_data = torch.randn(1, 256, 1000)  # Create convolutional layer #conv1d_layer = torch.nn.Conv1d(in_channels=1, out_channels=1, kernel_size=3) #start_time_x86 = time.time() conv1d_layer = torch.nn.Conv1d(             256,             256,             15,             stride=1,             padding=0,             groups=256,             bias=True,         ) # Perform convolution on x86 start_time_x86 = time.time() output_x86 = conv1d_layer(input_data) end_time_x86 = time.time() time_elapsed_x86 = end_time_x86 - start_time_x86 print('Time elapsed on x86:', time_elapsed_x86) print(output_x86) 
  • [问题求助] CANN-6.3使用pytorch框架loss在backward出现问题
    问题显示:  File "/home/ma-user/work/DDA6/src/models.py", line 99, in backward     loss.backward()   File "/home/ma-user/anaconda3/envs/Pytorch-1.8.1/lib/python3.7/site-packages/torch/tensor.py", line 245, in backward     torch.autograd.backward(self, gradient, retain_graph, create_graph, inputs=inputs)   File "/home/ma-user/anaconda3/envs/Pytorch-1.8.1/lib/python3.7/site-packages/torch/autograd/__init__.py", line 147, in backward     allow_unreachable=True, accumulate_grad=True)  # allow_unreachable flag RuntimeError: The size of tensor a (256) must match the size of tensor b (64) at non-singleton dimension 3问题描述:在pytorch框架下的代码,从cuda往cann迁移,在cuda正常运行,而在cann中可以开始训练,但会卡在 loss.backward() 求大佬帮忙
  • [问题求助] Yolov7_for_PyTorch 在Atlas 800 上训练出现RuntimeError: ACL stream synchronize failed, error code:507018
    环境:Atlas800 算力卡910CANN 版本为6.3.RC1 训练容器为:pytorch-modelzoo:23.0.RC1-1.11.0训练代码Yolov7_for_PyTorch下载地址https://gitee.com/ascend/modelzoo-GPL/tree/master/built-in/PyTorch/Official/cv/object_detection/Yolov7_for_PyTorch训练样本coco现象:
  • [ModelArts昇...] 使用torch_npu 训练模型报错 “NPU error code is:500002”
    训练框架版本: Pytorch-1.11 训练硬件: 910B训练insightface 中的 partial_fc 报错:IndexPutTraceback (most recent call last): File "train.py", line 214, in <module> main(parser.parse_args()) File "train.py", line 157, in main loss: torch.Tensor = module_partial_fc(local_embeddings, local_labels, opt) File "/home/ma-user/anaconda3/envs/Pytorch-1.11.0/lib/python3.7/site-packages/torch/nn/modules/module.py", line 1110, in _call_impl return forward_call(*input, **kwargs) File "/cache/development-space/arcface_torch/partial_fc.py", line 213, in forward loss = self.dist_cross_entropy(logits, labels) File "/home/ma-user/anaconda3/envs/Pytorch-1.11.0/lib/python3.7/site-packages/torch/nn/modules/module.py", line 1110, in _call_impl return forward_call(*input, **kwargs) File "/cache/development-space/arcface_torch/partial_fc.py", line 498, in forward return DistCrossEntropyFunc.apply(logit_part, label_part) File "/cache/development-space/arcface_torch/partial_fc.py", line 464, in forward loss[index] = logits[index].gather(1, label[index])RuntimeError: Run:/usr1/workspace/FPTA_Daily_open_pytorchv1.11.0-3.0.tr6/CODE/torch_npu/csrc/framework/OpParamMaker.cpp:136 NPU error,NPU error code is:500002EZ9999: Inner Error, Please contact support engineer!EZ9999 The input dtype of x1 x2 y is equal, please check![FUNC:IndexPutVerify][FILE:matrix_calculation_ops.cc][LINE:4676] TraceBack (most recent call last): Verifying IndexPut failed.[FUNC:InferShapeAndType][FILE:infershape_pass.cc][LINE:135] Call InferShapeAndType for node:IndexPut(IndexPut) failed[FUNC:Infer][FILE:infershape_pass.cc][LINE:117] process pass InferShapePass on node:IndexPut failed, ret:4294967295[FUNC:RunPassesOnNode][FILE:base_pass.cc][LINE:530] build graph failed, graph id:140, ret:1343242270[FUNC:BuildModel][FILE:ge_generator.cc][LINE:1484] [Build][SingleOpModel]call ge interface generator.BuildSingleOpModel failed. ge result = 1343242270[FUNC:ReportCallError][FILE:log_inner.cpp][LINE:161] [Build][Op]Fail to build op model[FUNC:ReportInnerError][FILE:log_inner.cpp][LINE:145] build op model failed, result = 500002[FUNC:ReportInnerError][FILE:log_inner.cpp][LINE:145] build graph failed, graph id:141, ret:1343242270[FUNC:BuildModel][FILE:ge_generator.cc][LINE:1484] build graph failed, graph id:142, ret:1343242270[FUNC:BuildModel][FILE:ge_generator.cc][LINE:1484]
  • [技术干货] 使用Pytorch实现分类器
    用法说明当使用PyTorch实现一个分类器时,通常需要涉及到数据加载、模型定义、损失函数和优化器的选择、训练过程等步骤。本案例采用CIFAR10数据集作为原始图片数据.CIFAR10数据集介绍: 数据集中每张图片的尺寸是3 * 32 * 32, 代表彩色3通道CIFAR10数据集总共有10种不同的分类, 分别是"airplane", "automobile", "bird", "cat", "deer", "dog", "frog", "horse", "ship", "truck".导入必要的库:import torch import torch.nn as nn import torch.optim as optim import torchvision import torchvision.transforms as transforms在代码的开头,我们导入了需要使用的PyTorch模块和库。定义数据预处理变换:transform = transforms.Compose( [transforms.ToTensor(), transforms.Normalize((0.5, 0.5, 0.5), (0.5, 0.5, 0.5))])这里定义了一个数据预处理变换,将输入图像转换为Tensor,并对图像进行归一化处理。加载训练数据集:trainset = torchvision.datasets.CIFAR10(root='./data', train=True, download=True, transform=transform) trainloader = torch.utils.data.DataLoader(trainset, batch_size=4, shuffle=True, num_workers=2)这段代码加载了CIFAR-10数据集,指定了数据集的路径、训练集标志、数据预处理变换等。然后通过数据加载器(DataLoader)将数据集划分为小批量,以便进行训练。定义一个简单的卷积神经网络模型:class Net(nn.Module): def __init__(self): super(Net, self).__init__() # ...(省略了卷积层、池化层、全连接层的定义) def forward(self, x): # ...(定义前向传播过程)这里定义了一个简单的卷积神经网络模型,包括卷积层、池化层和全连接层。forward方法定义了输入如何通过网络层进行前向传播。定义损失函数和优化器:criterion = nn.CrossEntropyLoss() optimizer = optim.SGD(net.parameters(), lr=0.001, momentum=0.9)在这里,我们选择交叉熵损失函数作为分类任务的损失函数,并使用随机梯度下降(SGD)优化器来优化模型参数。学习率设置为0.001,动量设置为0.9。训练网络:for epoch in range(2): # 迭代两次 running_loss = 0.0 for i, data in enumerate(trainloader, 0): inputs, labels = data optimizer.zero_grad() # 梯度清零 outputs = net(inputs) loss = criterion(outputs, labels) loss.backward() optimizer.step() running_loss += loss.item() if i % 2000 == 1999: print(f'[{epoch + 1}, {i + 1:5d}] loss: {running_loss / 2000:.3f}') running_loss = 0.0在这个循环中,我们对数据进行迭代,对每个小批量数据进行如下操作:将输入数据传递给网络,得到预测输出。计算预测输出与真实标签之间的交叉熵损失。调用backward方法计算梯度。调用优化器的step方法更新模型参数。输出当前损失值,并在每2000个小批量数据之后重置损失。保存训练好的模型:PATH = './cifar_net.pth' torch.save(net.state_dict(), PATH)最后,我们保存训练好的模型参数到文件中,以便后续的加载和使用。总之,上述代码展示了一个基本的图像分类器的实现流程,但实际应用中可能需要更多的调整和改进,以获得更好的性能。完整代码import torch import torch.nn as nn import torch.optim as optim import torchvision import torchvision.transforms as transforms # 定义数据预处理变换 transform = transforms.Compose( [transforms.ToTensor(), transforms.Normalize((0.5, 0.5, 0.5), (0.5, 0.5, 0.5))]) # 加载训练数据集 trainset = torchvision.datasets.CIFAR10(root='./data', train=True, download=True, transform=transform) trainloader = torch.utils.data.DataLoader(trainset, batch_size=4, shuffle=True, num_workers=2) # 定义一个简单的卷积神经网络模型 class Net(nn.Module): def __init__(self): super(Net, self).__init__() self.conv1 = nn.Conv2d(3, 6, 5) self.pool = nn.MaxPool2d(2, 2) self.conv2 = nn.Conv2d(6, 16, 5) self.fc1 = nn.Linear(16 * 5 * 5, 120) self.fc2 = nn.Linear(120, 84) self.fc3 = nn.Linear(84, 10) def forward(self, x): x = self.pool(F.relu(self.conv1(x))) x = self.pool(F.relu(self.conv2(x))) x = x.view(-1, 16 * 5 * 5) x = F.relu(self.fc1(x)) x = F.relu(self.fc2(x)) x = self.fc3(x) return x net = Net() # 定义损失函数和优化器 criterion = nn.CrossEntropyLoss() optimizer = optim.SGD(net.parameters(), lr=0.001, momentum=0.9) # 训练网络 for epoch in range(2): # 迭代两次 running_loss = 0.0 for i, data in enumerate(trainloader, 0): inputs, labels = data optimizer.zero_grad() # 梯度清零 outputs = net(inputs) loss = criterion(outputs, labels) loss.backward() optimizer.step() running_loss += loss.item() if i % 2000 == 1999: # 每2000个小批量数据输出一次损失值 print(f'[{epoch + 1}, {i + 1:5d}] loss: {running_loss / 2000:.3f}') running_loss = 0.0 print('Finished Training') # 保存训练好的模型 PATH = './cifar_net.pth' torch.save(net.state_dict(), PATH)
  • [技术干货] 关于torchserve和torchrun的简介【转】
    这两个东西是我最近在github查找大模型时发现的,平时在公司开发时很少使用这两个东西,因为都是在内网.TorchServeTorchServe是一个轻量级的模型服务器,可以轻松地将PyTorch模型部署为RESTful API或TorchServe的自定义格式。它支持多模型管理,自动扩展和生命周期管理,可以快速部署和管理模型。TorchServe还支持模型推理缓存、异步推理和自定义处理程序,可以根据需求自由配置。在使用TorchServe部署模型时,需要编写一个模型描述文件,该文件定义了模型的输入输出规格、预处理和后处理步骤、模型推理的超参数等。TorchServe还支持使用Python的torchscript和ONNX格式导出的模型,方便用户使用各种PyTorch模型。除此之外,TorchServe还提供了易于使用的REST API和管理界面,可以轻松地管理模型服务器。TorchRunTorchRun是一个用于本地或远程服务器上运行PyTorch训练作业的工具。它提供了命令行界面,可以轻松地指定训练参数和模型超参数,并跟踪训练进度和性能。TorchRun还支持分布式训练和自动调优,可以帮助用户快速实现高效的训练过程。在使用TorchRun进行训练时,需要指定训练数据集、优化器、损失函数、学习率等训练参数,以及模型的超参数等。TorchRun支持使用多个GPU和多个节点进行分布式训练,还提供了自动调优的功能,可以根据给定的参数范围和搜索策略,自动搜索最优的超参数组合,从而提高训练效率和模型性能。总之,TorchServe和TorchRun都是与PyTorch深度学习框架相关的工具,可以帮助用户快速部署和管理模型服务器,以及实现高效的训练过程。本文来自博客园,作者:海_纳百川,转载请注明原文链接:https://www.cnblogs.com/chentiao/p/17355955.html,如有侵权联系删除
  • [技术干货] Pytorch的LSTM(RNN)是如何处理Sequence的__关于input中seq_len以及输入格式的总结【转】
    近几天处理了几天卷积LSTM,操作的数据格式太复杂,蓦然回首,突然发现自己不明白LSTM中的输入格式是什么了,于是写一篇文章帮助自己回忆一下,也希望能帮助到一起正在机器学习的伙伴。补充一下,在LSTM之后,GRU和LSTM几乎已经取代了传统的RNN,因此在称呼RNN的时候,大多数情况也是在称呼LSTM,下文中可能会提到RNN,也是在说LSTM按照Pytorch 给的文档里格式写一个LSTM# author: https://www.cnblogs.com/danielkung/lstm = torch.nn.LSTM(input_size, # INT,输入的维度 hidden_size, # INT,隐藏层的维度 num_layers, # INT,LSTM的层数 bias, # BOOL,是否需要wx+b中的b batch_first, # BOOL,输入的数据第一维度为batch,与输出无关 dropout, # BOOL,是否需要dropout bidirectional) # BOOL,是否双向RNN,是的话hidden,output都双倍intput = torch.randn(seq_len, batch, input_size) # 三个参数需要定义output, hidden = lstm(input)Q:在处理了无数次以后,我终于有一次懵圈了,啥是seq_len来着?A:seq_len就是输入的sequence_length(序列长度),既然LSTM是处理序列数据的,那么序列就需要一个长度。虽然LSTM处理的序列长度通常是不固定的,但是Pytorch和TensorFlow的集成实现还是固定了input的序列长度,在处理不固定长度的数据(如机器翻译),通常加入开始和结束符号并采用序列的最大长度MAX_LEN作为seq_len来看几个实际的例子:1. 输入长度不固定,输出长度固定我想做一个语句的情感分析(positve,negtive),或者给一串数字,预测这串数字的下一个数字是什么(例如某串长度为N,预测第N+1数字是什么)。在第一个问题中,假设我们拿到了N条数据,每条包含的字数不定,但是可以知道最长的字数为MAX_LEN。首先我们需要进行word embedding,即把每个词转变为长度固定的矩阵。假如每个word被转化为 [1*128] 的矩阵,那我们得到的数据格式就为:[N, MAX_LEN+2, 128]此时你也许会问,那长度不够MAX_LEN的呢?不够的就被填充到MAX_LEN,并且多的2是开头和结尾的'sos''eos'。然后在LSTM中,我们每次取N条中的batch_size条进行训练,并且input的seq_len就是MAX_LEN+2。代码:# author: https://www.cnblogs.com/danielkung/import torchinput_size = 128 # 输入的维度,就是我们word_embedding的长度hidden_size = 64 # 这里我自己定义的,定义的是lstm的hidden也是输出的维度num_layers = 1 # 先定义一层的LSTMlstm = torch.nn.LSTM(input_size, hidden_size, num_layers)input = getFromDataSet() # 函数没定义,就是从data中取batch条数据,input的shape:[seq_len, batch_size, input_size]=[MAX_LEN+2, batch, 128]output, hidden = lstm(input, hidden=None) # Pytorch的LSTM会自己初始化hidden,因此hidden不写一样output1 = output[-1] # 取最后一层的输出作为最终输出,因为只有一层LSTM,output[-1]==output[0]print(output.shape)# RETURN: [seq_len, batch_size, hidden_size]这里发现如果是做postive或者negtive分析的话,我们只需要一个数值,甚至只需要一个BOOL,因此还需要把输出的output结果取最后一份output[-1],然后通过MLP即可,具体分析如图。代码接上面继续:fc = nn.Linear(hidden_size, 1)last_cell = outpu1t[-1] # shape: [batch_size, hidden_size]# 由图可见, 此时的last_cell就是LSTM的最后一次的输出结果。res = fc(last_cell) # shape: [batch_size, 1]# 由此就得出了所有所有batch的预测结果。Q:可能有人要问,输出了那么多的output,只取最后一个用,这样准确吗?不浪费吗?A:不准,浪费。但是可以这么处理。在早期的sequence_to_sequence模型中,就是把encoder RNN的最后一个cell的输出作为context传给decoder,当然后来还有更好的办法,如attention mechanism。在这里只展示最简单的。2. 输入长度不固定,输出长度不固定如果输出长度不固定,我们只需要把<1>中输出中加入'sos''eos',并且去掉最后的全连接层就好了。3. 特殊情况,seq_len的长度特别大这类问题通常出现在文本翻译或者文本处理,以及音频、视频处理中。我们需要把seq_len设置为一个适当的值,并且通过迭代,传递lstm的hidden_state的方式进行训练。这对模型的设计,网络的深度都有一定的要求,博客中就不在展示。
  • [技术干货] 张量是什么,pytorch为啥不复用numpy中的多维数组,非要自己搞一个
    定义PyTorch 和 NumPy 都是用于科学计算和数据处理的库,但它们的设计和用途略有不同。NumPy 是一个用于数值计算的库,它提供了一个强大的数组对象。ndarray,可以方便地进行数组操作、线性代数运算和数学函数计算等。而 PyTorch 是一个用于深度学习的库,它提供了一个称为张量(Tensor)的对象,可以方便地进行矩阵运算、向量运算和神经网络的前向和反向传播等。区别虽然 PyTorch 的张量和 NumPy 的 ndarray 都是多维数组,但它们在内存管理和计算方式上略有不同。NumPy 的 ndarray 是基于 C 语言编写的,它的内存管理是由操作系统负责的,因此数组的大小和形状在创建后不能更改。而 PyTorch 的张量是基于 Python 语言编写的,它的内存管理是由 PyTorch 自身负责的,因此可以在运行时动态地更改数组的大小和形状。这种灵活性在深度学习中非常重要,因为神经网络的输入和输出往往是不同的大小和形状。此外,PyTorch 的张量还支持 GPU 运算和自动微分。在深度学习中,很多计算都是在 GPU 上进行的,因此 PyTorch 的张量可以在 GPU 上进行矩阵运算和向量运算,从而提高计算效率。另外,自动微分是深度学习中的一个重要功能,它可以自动计算神经网络中每个参数的梯度,从而加快神经网络的训练速度。PyTorch 的张量支持自动微分,因此可以在训练神经网络时自动计算梯度,从而提高训练效率。打印pytorch张量张量的主要属性有以下3个张量的维度(rank,number of dimensions)指的是张量中用来索引元素的索引个数,0维张量就是标量,因为不需要索引,而对于向量(vector)而言,只需要一个索引就可以得到相应元素,后续同理。高维的张量其实就是对低维张量的堆叠。张量的形状(shape,number of rows and columns)指的是张量中每一维度的大小A张量的类型(type,data type of tensor's elements)指的是张量中每个元素的数据类型测试代码如下import torch a = torch.ones(3,4,5, dtype=torch.int32) print(f'ndimension:{a.ndimension()}') print(f'shape:{a.shape}') print(f'dtype:{a.dtype}')总结综上所述,PyTorch 的张量和 NumPy 的 ndarray 虽然都是多维数组,但它们在内存管理和计算方式上略有不同,因此 PyTorch 选择了自己实现张量。
  • [技术干货] Pytorch 梯度下降算法【4/9】动量梯度下降(Momentum Gradient Descent)
    定义在 PyTorch 中,动量梯度下降(Momentum Gradient Descent)是梯度下降算法的一种改进版。与传统的随机梯度下降(SGD)只考虑当前梯度方向不同,动量梯度下降考虑了历史梯度方向,类似于模拟物体滚下斜坡时的惯性效果,使得参数更新更加平滑和稳定。下面我将通过一个简单的线性回归问题来演示如何在 PyTorch 中使用动量梯度下降法。动量梯度下降公式小批量梯度下降于动量梯度下降的区别由于mini-batch每次仅使用数据集中的一部分进行梯度下降,所以每次下降并不是严格按照朝最小方向下降,但是总体下降趋势是朝着最小方向,上图可以明显看出两者之间的区别。对右边的图来说,动量梯度下降法并没有什么用处。梯度批量下降法主要是针对mini-batch梯度下降法进行优化,优化之后左右的摆动减小,从而提高效率。优化前后的对比如下图,可见动量梯度下降法的摆动明显减弱。实战首先,我们需要导入 PyTorch 库并准备数据:import torch import torch.nn as nn import torch.optim as optim import numpy as np # 随机生成一些简单的线性数据 np.random.seed(42) X = np.random.rand(100, 1) # 100个输入样本 y = 2 * X + 1 + 0.1 * np.random.randn(100, 1) # 添加随机噪声的目标输出接下来,我们定义一个简单的线性模型,并使用动量梯度下降法进行优化:# 将数据转换为 PyTorch 张量 X_tensor = torch.tensor(X, dtype=torch.float32) y_tensor = torch.tensor(y, dtype=torch.float32) # 定义线性模型 class LinearModel(nn.Module): def __init__(self): super(LinearModel, self).__init__() self.linear = nn.Linear(1, 1) # 输入特征数为1,输出特征数为1 def forward(self, x): return self.linear(x) # 创建模型实例和优化器 model = LinearModel() criterion = nn.MSELoss() # 使用均方误差损失函数 optimizer = optim.SGD(model.parameters(), lr=0.01, momentum=0.9) # 使用动量梯度下降法 # 进行模型训练 num_epochs = 100 for epoch in range(num_epochs): # 清零梯度 optimizer.zero_grad() # 前向传播 y_pred = model(X_tensor) # 计算损失 loss = criterion(y_pred, y_tensor) # 反向传播 loss.backward() # 更新参数 optimizer.step() if (epoch + 1) % 10 == 0: print(f'Epoch [{epoch+1}/{num_epochs}], Loss: {loss.item():.4f}') # 打印训练后的模型参数 print("训练后的模型参数:", model.state_dict())在上述代码中,我们使用了 torch.optim.SGD 创建了一个动量梯度下降法的优化器,并将其应用于训练过程中。通过在创建优化器时指定 momentum 参数为0.9,我们添加了动量效果。在每次参数更新时,动量梯度下降法会考虑历史梯度方向,并使用动量项来调整参数更新方向,使得更新更加平滑和稳定。动量梯度下降法通常能够加速收敛,并减少参数更新的震荡。
  • [技术干货] Pytorch 梯度下降算法【5/9】超前预测梯度下降(Nesterov Accelerated Gradient)
    定义在 PyTorch 中,超前预测梯度下降算法Nesterov Accelerated Gradient(NAG)是动量梯度下降法(Momentum Gradient Descent)的一种改进版本。NAG 在计算梯度时引入了一个“超前预测”的步骤,以更准确地估计下一步的梯度方向。这有助于改进动量梯度下降法在参数更新时的准确性和收敛速度。案例实战下面我将通过一个简单的线性回归问题来演示如何在 PyTorch 中使用 Nesterov Accelerated Gradient。首先,我们需要导入 PyTorch 库并准备数据:import torch import torch.nn as nn import torch.optim as optim import numpy as np # 随机生成一些简单的线性数据 np.random.seed(42) X = np.random.rand(100, 1) # 100个输入样本 y = 2 * X + 1 + 0.1 * np.random.randn(100, 1) # 添加随机噪声的目标输出接下来,我们定义一个简单的线性模型,并使用 Nesterov Accelerated Gradient 进行优化:# 将数据转换为 PyTorch 张量 X_tensor = torch.tensor(X, dtype=torch.float32) y_tensor = torch.tensor(y, dtype=torch.float32) # 定义线性模型 class LinearModel(nn.Module): def __init__(self): super(LinearModel, self).__init__() self.linear = nn.Linear(1, 1) # 输入特征数为1,输出特征数为1 def forward(self, x): return self.linear(x) # 创建模型实例和优化器 model = LinearModel() criterion = nn.MSELoss() # 使用均方误差损失函数 optimizer = optim.SGD(model.parameters(), lr=0.01, momentum=0.9, nesterov=True) # 使用 NAG # 进行模型训练 num_epochs = 100 for epoch in range(num_epochs): # 清零梯度 optimizer.zero_grad() # 提前根据当前动量的方向进行预测(NAG独有的步骤) with torch.no_grad(): y_pred_ahead = model(X_tensor - optimizer.param_groups[0]['momentum'] * optimizer.state[model.parameters()][0]) # 前向传播 y_pred = model(X_tensor + optimizer.param_groups[0]['momentum'] * (X_tensor - optimizer.param_groups[0]['momentum'] * y_pred_ahead)) # 计算损失 loss = criterion(y_pred, y_tensor) # 反向传播 loss.backward() # 更新参数 optimizer.step() if (epoch + 1) % 10 == 0: print(f'Epoch [{epoch+1}/{num_epochs}], Loss: {loss.item():.4f}') # 打印训练后的模型参数 print("训练后的模型参数:", model.state_dict())在上述代码中,我们使用了 torch.optim.SGD 创建了一个 Nesterov Accelerated Gradient 的优化器,并将其应用于训练过程中。通过在创建优化器时指定 momentum 参数为0.9,并设置 nesterov=True,我们启用了 Nesterov Accelerated Gradient。在每次参数更新时,NAG 首先根据当前动量的方向进行预测,然后利用预测的方向进行参数更新,这有助于更准确地估计下一步的梯度方向,从而改进了动量梯度下降法在参数更新时的准确性和收敛速度。NAG 通常能够加速收敛,并在某些情况下表现更优秀。
  • [技术干货] Pytorch 梯度下降算法【2/9】批量梯度下降(Batch Gradient Descent, BGD)
    在 PyTorch 中,批量梯度下降法(Batch Gradient Descent, BGD)是梯度下降算法的一种变体。与随机梯度下降法(SGD)不同,BGD在每次参数更新时使用整个训练集的梯度来更新模型参数。下面我将通过一个简单的线性回归问题来演示如何在 PyTorch 中使用批量梯度下降法。首先,我们需要导入 PyTorch 库并准备数据:import torch import torch.nn as nn import torch.optim as optim import numpy as np # 随机生成一些简单的线性数据 np.random.seed(42) X = np.random.rand(100, 1) # 100个输入样本 y = 2 * X + 1 + 0.1 * np.random.randn(100, 1) # 添加随机噪声的目标输出接下来,我们定义一个简单的线性模型,并使用批量梯度下降法进行优化:# 将数据转换为 PyTorch 张量 X_tensor = torch.tensor(X, dtype=torch.float32) y_tensor = torch.tensor(y, dtype=torch.float32) # 定义线性模型 class LinearModel(nn.Module): def __init__(self): super(LinearModel, self).__init__() self.linear = nn.Linear(1, 1) # 输入特征数为1,输出特征数为1 def forward(self, x): return self.linear(x) # 创建模型实例和优化器 model = LinearModel() criterion = nn.MSELoss() # 使用均方误差损失函数 optimizer = optim.SGD(model.parameters(), lr=0.01) # 使用批量梯度下降法 # 进行模型训练 num_epochs = 100 batch_size = 10 num_samples = X_tensor.shape[0] for epoch in range(num_epochs): # 将数据切分成小批量 for i in range(0, num_samples, batch_size): start_idx = i end_idx = min(i + batch_size, num_samples) batch_X = X_tensor[start_idx:end_idx] batch_y = y_tensor[start_idx:end_idx] # 清零梯度 optimizer.zero_grad() # 前向传播 y_pred = model(batch_X) # 计算损失 loss = criterion(y_pred, batch_y) # 反向传播 loss.backward() # 更新参数 optimizer.step() if (epoch + 1) % 10 == 0: print(f'Epoch [{epoch+1}/{num_epochs}], Loss: {loss.item():.4f}') # 打印训练后的模型参数 print("训练后的模型参数:", model.state_dict())在上述代码中,我们使用了 torch.optim.SGD 创建了一个批量梯度下降法的优化器,并将其应用于训练过程中。每一轮迭代中,我们将数据切分成小批量,然后使用这些小批量的样本来计算梯度和更新模型参数。通过使用整个训练集的梯度来进行参数更新,BGD通常能够产生相对稳定和收敛较快的训练过程。
  • [技术干货] Pytorch 梯度下降算法【3/9】小批量梯度下降(Mini-Batch Gradient Descent)
    定义在 PyTorch 中,小批量梯度下降法(Mini-Batch Gradient Descent)是梯度下降算法的一种变体。与批量梯度下降法(BGD)使用整个训练集的梯度进行参数更新不同,Mini-Batch Gradient Descent 在每次参数更新时使用一小批样本的梯度来更新模型参数。模型示意图由于mini-batch每次仅使用数据集中的一部分进行梯度下降,所以每次下降并不是严格按照朝最小方向下降,但是总体下降趋势是朝着最小方向,上图可以明显看出两者之间的区别。案例实战下面我将通过一个简单的线性回归问题来演示如何在 PyTorch 中使用小批量梯度下降法。首先,我们需要导入 PyTorch 库并准备数据:import torch import torch.nn as nn import torch.optim as optim import numpy as np # 随机生成一些简单的线性数据 np.random.seed(42) X = np.random.rand(100, 1) # 100个输入样本 y = 2 * X + 1 + 0.1 * np.random.randn(100, 1) # 添加随机噪声的目标输出接下来,我们定义一个简单的线性模型,并使用小批量梯度下降法进行优化:# 将数据转换为 PyTorch 张量 X_tensor = torch.tensor(X, dtype=torch.float32) y_tensor = torch.tensor(y, dtype=torch.float32) # 定义线性模型 class LinearModel(nn.Module): def __init__(self): super(LinearModel, self).__init__() self.linear = nn.Linear(1, 1) # 输入特征数为1,输出特征数为1 def forward(self, x): return self.linear(x) # 创建模型实例和优化器 model = LinearModel() criterion = nn.MSELoss() # 使用均方误差损失函数 optimizer = optim.SGD(model.parameters(), lr=0.01) # 使用小批量梯度下降法 # 进行模型训练 num_epochs = 100 batch_size = 10 for epoch in range(num_epochs): # 将数据切分成小批量 num_samples = X_tensor.shape[0] indices = torch.randperm(num_samples) for i in range(0, num_samples, batch_size): batch_indices = indices[i:i+batch_size] batch_X = X_tensor[batch_indices] batch_y = y_tensor[batch_indices] # 清零梯度 optimizer.zero_grad() # 前向传播 y_pred = model(batch_X) # 计算损失 loss = criterion(y_pred, batch_y) # 反向传播 loss.backward() # 更新参数 optimizer.step() if (epoch + 1) % 10 == 0: print(f'Epoch [{epoch+1}/{num_epochs}], Loss: {loss.item():.4f}') # 打印训练后的模型参数 print("训练后的模型参数:", model.state_dict())在上述代码中,我们使用了 torch.optim.SGD 创建了一个小批量梯度下降法的优化器,并将其应用于训练过程中。每一轮迭代中,我们将数据随机切分成小批量,然后使用这些小批量的样本来计算梯度和更新模型参数。Mini-Batch Gradient Descent 综合了随机梯度下降(SGD)和批量梯度下降(BGD)的优点,既减少了计算成本,又保持了相对稳定和较快的训练过程。
  • [技术干货] Pytorch 梯度下降算法【1/9】随机梯度下降
    在 PyTorch 中,随机梯度下降法(Stochastic Gradient Descent, SGD)是优化神经网络最基础和常见的方法之一。它在每次参数更新时,使用单个样本的梯度来更新模型的参数。下面我将通过一个简单的线性回归问题来演示如何在 PyTorch 中使用随机梯度下降法。假设我们有一个简单的线性回归问题,其中有一组输入和对应的目标输出。我们的目标是通过训练一个线性模型来拟合这些数据。首先,我们需要导入 PyTorch 库并准备数据:import torch import torch.nn as nn import torch.optim as optim import numpy as np # 随机生成一些简单的线性数据 np.random.seed(42) X = np.random.rand(100, 1) # 100个输入样本 y = 2 * X + 1 + 0.1 * np.random.randn(100, 1) # 添加随机噪声的目标输出接下来,我们定义一个简单的线性模型,并使用随机梯度下降法进行优化:# 将数据转换为 PyTorch 张量 X_tensor = torch.tensor(X, dtype=torch.float32) y_tensor = torch.tensor(y, dtype=torch.float32) # 定义线性模型 class LinearModel(nn.Module): def __init__(self): super(LinearModel, self).__init__() self.linear = nn.Linear(1, 1) # 输入特征数为1,输出特征数为1 def forward(self, x): return self.linear(x) # 创建模型实例和优化器 model = LinearModel() criterion = nn.MSELoss() # 使用均方误差损失函数 optimizer = optim.SGD(model.parameters(), lr=0.01) # 使用随机梯度下降法 # 进行模型训练 num_epochs = 100 for epoch in range(num_epochs): # 清零梯度 optimizer.zero_grad() # 前向传播 y_pred = model(X_tensor) # 计算损失 loss = criterion(y_pred, y_tensor) # 反向传播 loss.backward() # 更新参数 optimizer.step() if (epoch + 1) % 10 == 0: print(f'Epoch [{epoch+1}/{num_epochs}], Loss: {loss.item():.4f}') # 打印训练后的模型参数 print("训练后的模型参数:", model.state_dict())在上述代码中,我们使用了 torch.optim.SGD 创建了一个随机梯度下降法的优化器,并将其应用于训练过程中。每一轮迭代中,通过计算损失函数的梯度并使用 optimizer.step() 更新模型的参数。经过多轮迭代后,模型会逐渐拟合数据,并找到较好的线性拟合。
  • [技术干货] Pytorch 中 9 种常见的梯度下降算法
    PyTorch中常见的梯度下降算法主要用于优化神经网络的参数,以下是其中9种常见的梯度下降算法:随机梯度下降法(Stochastic Gradient Descent, SGD):每次更新时使用单个样本的梯度来更新参数。由于随机选择样本,因此收敛过程可能较不稳定,但通常会比其他算法更快。批量梯度下降法(Batch Gradient Descent, BGD):每次更新时使用全部训练集的梯度来更新参数。由于使用全部样本,收敛过程通常较稳定,但计算成本较高。小批量梯度下降法(Mini-Batch Gradient Descent):介于SGD和BGD之间,每次更新时使用一小批样本的梯度来更新参数。既能减少计算成本,又能保持较稳定的收敛。动量梯度下降法(Momentum Gradient Descent):在更新参数时,引入一个动量项,类似于模拟物体滚下斜坡的惯性。可以加速收敛,并减少震荡。Nesterov Accelerated Gradient(NAG):是动量梯度下降法的变种,通过在更新前根据当前动量的方向先进行一次“超前预测”,可以更准确地估计梯度。Adagrad:自适应学习率算法,会根据参数的历史梯度调整学习率,使得稀疏参数的学习率较大,稠密参数的学习率较小。RMSprop:也是自适应学习率算法,对Adagrad做了改进,通过指数加权平均来限制历史梯度的累积。Adadelta:是对RMSprop的改进,解决了RMSprop学习率下降过快的问题。Adam(Adaptive Moment Estimation):结合了动量梯度下降和RMSprop的优点,是目前最为常用的优化算法之一。在PyTorch中,你可以使用torch.optim模块来访问这些优化算法,通过选择不同的优化器,可以灵活地应用在你的神经网络训练中。例如,torch.optim.SGD对应随机梯度下降,torch.optim.Adam对应Adam算法。
  • [技术干货] pytorch实现LSTM自动AI作诗(藏头诗和首句续写)| 第6例
    前言大家好,我是阿光。本专栏整理了《PyTorch深度学习项目实战100例》,内包含了各种不同的深度学习项目,包含项目原理以及源码,每一个项目实例都附带有完整的代码+数据集。正在更新中~ ✨🚨 我的项目环境:平台:Windows10语言环境:python3.7编译器:PyCharmPyTorch版本:1.8.1💥 项目专栏:【PyTorch深度学习项目实战100例】一、LSTM自动AI作诗本项目使用了LSTM作为模型实现AI作诗,作诗模式分为两种,一是根据给定诗句继续生成完整诗句,二是给定诗头生成藏头诗。二、数据集介绍数据来源于chinese-poetry,最全中文诗歌古典文集数据库最全的中华古典文集数据库,包含 5.5 万首唐诗、26 万首宋诗、2.1 万首宋词和其他古典文集。诗 人包括唐宋两朝近 1.4 万古诗人,和两宋时期 1.5 千古词人。实验使用预处理过的二进制文件 tang.npz 作为数据集,含有 57580 首唐诗,每首诗限定在 125 词, 不足 125 词的以空格填充。数据集以 npz 文件形式保存,包含三个部分:data: (57580,125) 的 numpy 数组,总共有 57580 首诗歌,每首诗歌长度为 125 字符 (不足 125 补空格,超过 125 的丢弃),将诗词中的字转化为其在字典中的序号表示ix2word: 序号到字的映射word2ix: 字到序号的映射三、算法流程介绍1.输入数据为input,形状为 124 * 162.输入数据的label为 124 * 16之后需要对输入数据进行嵌入,如果不嵌入那么每个古诗的字应为对应的索引,为了能够进行训练所以需要将其进行嵌入,然后形成连续性变量。之后我们的数据就变成了 124 * 16 * embedding_dim然后将其导入到LSTM模块中,则形成的形状为 124 * 16 * hidden_dim之后将其导入到全连接层,形成分类,变为的形状为 124 * 16 ,vocab_size注意一定要清楚各个位置不同变量的形状,这些在代码中已经注明,一定要弄明白batch_size,time_step,embedding_dim,vocal_size,num_layers,hidden_dim以及input_size在代码中的意义。四、定义网络模型项目中使用的模型是LSTM,在模型中我们定义了三个组件,分别是embedding层,lstm层和全连接层。Embedding层:将每个词生成对应的嵌入向量,就是利用一个连续型向量来表示每个词Lstm层:提取诗句中的语义信息Linear层:将结果映射成vocab_size大小用于分类,即每个字的概率class LSTM(nn.Module): def __init__(self, vocab_size, embedding_dim, hidden_dim): super(LSTM, self).__init__() self.hidden_dim = hidden_dim self.embeddings = nn.Embedding(vocab_size, embedding_dim) self.lstm = nn.LSTM(embedding_dim, hidden_dim, num_layers) self.linear = nn.Linear(hidden_dim, vocab_size) def forward(self, x, hidden=None): time_step, batch_size = x.size() # 124, 16 if hidden is None: h_0 = x.data.new(num_layers, batch_size, self.hidden_dim).fill_(0).float() c_0 = x.data.new(num_layers, batch_size, self.hidden_dim).fill_(0).float() else: h_0, c_0 = hidden embeds = self.embeddings(x) output, (h_n, c_n) = self.lstm(embeds, (h_0, c_0)) output = self.linear(output.reshape(time_step * batch_size, -1)) return output, (h_n, c_n)五、给定首句生成古诗该函数会根据给定的语句生成一段古诗,会根据start_words继续生成下一个字,对于给定的语句生成相应的hidden,然后将最后一个字和对应的hidden将其输入到模型中,生成新的下一个字,然后将新生成的字作为新的输入。此外还可以加入诗句前缀,加入的目的是会影响生成诗句的风格,首先利用prefix_words生成对应的hidden,然后将hidden送入模型生成诗句,此hidden中包含了前缀中的语义信息。start_words:给定的初始语句,基于它生成之后的诗句prefix_words:前缀诗句,该句会影响诗句的风格,因为首先会学习对应的hidden然后将其和开始词送入模型生成对应的诗句六、生成藏头诗生成藏头诗的原理与上述函数同理,只不过是利用给定的藏头字分别作为输入,一旦遇到特殊符号就说明该句生成结束,继续生成下一句藏头诗同理这个函数也会包含诗句前缀,影响诗句的风格七、模型训练对于模型训练最重要的就是模型的输入和输出,针对于写诗这个任务,我们的输入应该是给定一句诗,然后错位1位作为它的标签用于监督,例如:床前明月光疑是地上霜那么我们的输入、输出就应该为:输入数据:床前明月光疑是地上输出数据:前明月光疑是地上霜每个时间步对应的输出应该是他下个时间步对应的字每个时间步的输出应该是vocab_size维度,就是词大小,用于全分类,这样就会根据概率获得该时间步对应的字。由于本项目中采用的是唐诗数据集,数据为data: (57580,125) 的 numpy 数组,也就是每个样本为一句诗,每首诗中含有125个字,相当于不同的时间步,然后将每个字进行embedding进行编码,这里我们将输入作为124,也就是像上面所说,利用前124个字和他对应之后的124个字进行监督。def train(): if use_gpu: device = torch.device("cuda") else: device = torch.device("cpu") # 获取数据 datas = np.load("tang.npz", allow_pickle=True) data = datas['data'] ix2word = datas['ix2word'].item() word2ix = datas['word2ix'].item() data = torch.from_numpy(data) dataloader = DataLoader(data, batch_size=batch_size, shuffle=True) # 定义模型 model = LSTM(len(word2ix), embedding_dim=embedding_dim, hidden_dim=hidden_dim) Configimizer = optim.Adam(model.parameters(), lr=lr) criterion = nn.CrossEntropyLoss() # if model_path: # model.load_state_dict(torch.load(model_path,map_location='cpu')) # 转移到相应计算设备上 model.to(device) loss_meter = meter.AverageValueMeter() # 进行训练 f = open('result.txt', 'w') hidden = None for epoch in range(epochs): loss_meter.reset() for li, data_ in tqdm.tqdm(enumerate(dataloader)): # print(data_.shape) # 16 * 125 batch_size * time_step data_ = data_.long().transpose(1, 0).contiguous() # 125 * 16 time_step * batch_size # 注意这里,也转移到了计算设备上 data_ = data_.to(device) Configimizer.zero_grad() # n个句子,前n-1句作为输入,后n-1句作为输出,二者一一对应 input_, target = data_[:-1, :], data_[1:, :] # 都是124 * 16 output, hidden = model(input_, hidden) # 1984 * 8293 [batch_size * time_step, vocab_size] 124为时间步大小 # print("Here",output.shape) # # 这里为什么view(-1) # output:1984 * 8293 # target.view(-1):1984 # 可以直接放入,因为是交叉熵损失函数,target为标签,而output每个样本的输出为所有样本的类别概率 loss = criterion(output, target.view(-1)) loss.backward() Configimizer.step() loss_meter.add(loss.item()) # 进行可视化 if (1 + li) % plot_every == 0: print("训练损失为%s" % (str(loss_meter.mean))) f.write("训练损失为%s" % (str(loss_meter.mean))) for word in list(u"春江花朝秋月夜"): gen_poetry = ''.join(generate(model, word, ix2word, word2ix)) print(gen_poetry) f.write(gen_poetry) f.write("\n\n\n") f.flush() torch.save(model.state_dict(), '%s_%s.pth' % (model_prefix, epoch))八、生成诗句该函数用于进行测试生成语句,我们会首先加载我们训练好的模型,然后传入续写的诗句或者需要加入的前缀信息,形成诗句。八、完整源码【PyTorch深度学习项目实战100例】—— 使用pytorch实现LSTM自动AI作诗(藏头诗和首句续写)| 第6例_咕 嘟的博客-CSDN博客_pytorch基于 lstm 的自动写诗作者:咕嘟_链接:https://www.jianshu.com/p/ac8c57048ec5来源:简书著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。