• [开发环境] Notebook中使用Ascend 910B4训练模型npu AI core占用为0%
    在ModelArt的notebook创建了基于Ascend 910B4的环境,运行代码时在npu上的计算非常慢,显示npu AI core占用率为0%,但是如下的代码中torch.npu.is_available()的输出为Trueprint("torch.npu.is_available(): ",torch.npu.is_available()) torch.npu.set_device('npu:0') torch_npu.npu.set_device('npu:0') device = torch.device('npu:0' if torch.npu.is_available() else 'cpu') print("devise:----------", device)另外,我运行下面这个简单的测试脚本用了二十多秒:import torch  import torch_npu  device = torch.device('npu:0' if torch.npu.is_available() else 'cpu')  torch.npu.set_device(device)  #创建一个简单的张量并在NPU上进行计算  a = torch.randn(1000, 1000, device=device)  print(a)  b = torch.randn(1000, 1000, device=device)  print(b)  c = a + b  print(c)求助怎么解决训练模型时npu AI core占用0%的问题
  • [问题求助] mindspore如何使用优化器进行参数更新和梯度清零
    mindspore如何使用优化器进行参数更新和梯度清零,Adam和optimizer都找不到相关功能和范例
  • [问题求助] arm架构BC-Linux,启动ascend-pytorch镜像失败
    arm架构BC-Linux,启动ascend-pytorch镜像失败# docker run -it -e ASCEND_VISIBLE_DEVICES=0 ascendhub.huawei.com/public-ascendhub/ascend-pytorch:23.0.0-A2-1.11.0-centos7  /bin/bash standard_init_linux.go:219: exec user process caused "exec format error" libcontainer: container start initialization failed: standard_init_linux.go:219: exec user process caused "exec format error"
  • [技术干货] Open-Sora 文生视频
    Open-Sora(Gradio版本)文生视频不久前,OpenAI Sora以其惊人的视频生成效果迅速走红,在众多文本转视频模型中脱颖而出,成为全球关注的焦点。继两周前推出用于训练和推理过程的Sora Replication,成本降低46%。之后,Colossal-AI团队又推出了新的开源解决方案“Open-Sora 1.0”,涵盖了整个训练过程,包括数据处理、所有训练细节和模型检查点,与世界各地的AI爱好者携手推进视频创作的新时代。详细内容请参考:https://hpc-ai.com/blog/open-sora-v1.0可以点击我发布的Notebook在AI Gallery中一键运行!
  • [问题求助] 鲲鹏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通常能够产生相对稳定和收敛较快的训练过程。