pytorch求导

这篇具有很好参考价值的文章主要介绍了pytorch求导。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

pytorch求导的初步认识

requires_grad

tensor(data, dtype=None, device=None, requires_grad=False)

requires_grad是torch.tensor类的一个属性。如果设置为True,它会告诉PyTorch跟踪对该张量的操作,允许在反向传播期间计算梯度。

x.requires_grad    判断一个tensor是否可以求导,返回布尔值

叶子变量-leaf variable

  • 对于requires_grad=False 的张量,我们约定俗成地把它们归为叶子张量。
  • 对于requires_grad为True的张量,如果他们是由用户创建的,则它们是叶张量。

pytorch求导,pytorch使用,pytorch,人工智能,python

 如果某一个叶子变量,开始时不可导的,后面想设置它可导,该怎么办?

x.requires_grad_(True/False)   设置tensor的可导与不可导

注意:这种方法只适用于设置叶子变量,否则会出现如下错误

pytorch求导,pytorch使用,pytorch,人工智能,python

x = torch.tensor(2.0, requires_grad=True)
y = torch.pow(x, 2)
z = torch.add(y, 3)
z.backward()
print(x.grad)
print(y.grad)
tensor(4.)
None
  1. 创建一个浮点型张量x,其值为2.0,并设置requires_grad=True,使PyTorch可以跟踪x的计算历史并允许计算它的梯度。

  2. 创建一个新张量y,y是x的平方。

  3. 创建一个新张量z,z是y和3的和。

  4. 调用z.backward()进行反向传播,计算z关于x的梯度。

  5. 打印x的梯度,应该是2*x=4.0。

  6. 试图打印y的梯度。但是,PyTorch默认只计算并保留叶子节点的梯度非叶子节点的梯度在计算过程中会被释放掉,因此y的梯度应该为None。

保留中间变量的梯度

tensor.retain_grad()

pytorch求导,pytorch使用,pytorch,人工智能,python

 retain_grad()和retain_graph是用来处理两个不同的情况

  1. retain_grad(): 用于保留非叶子节点的梯度。如果你想在反向传播结束后查看或使用非叶子节点的梯度,你应该在非叶子节点上调用.retain_grad()

  2. retain_graph: 当你调用.backward()时,PyTorch会自动清除计算图以释放内存。这意味着你不能在同一个计算图上多次调用.backward()。但是,如果你需要多次调用.backward()(例如在某些特定的优化算法中),你可以在调用.backward()时设置retain_graph=True保留计算图

.grad

通过tensor的grad属性查看所求得的梯度值。

.grad_fn

在PyTorch中,.grad_fn属性是一个引用到创建该Tensor的Function对象。也就是说,这个属性可以告诉你这个张量是如何生成的。对于由用户直接创建的张量,它的.grad_fnNone。对于由某个操作创建的张量,.grad_fn将引用到一个与这个操作相关的对象

import torch

x = torch.tensor([1.0, 2.0], requires_grad=True)
y = x * 2
z = y.mean()

print(x.grad_fn)
print(y.grad_fn)
print(z.grad_fn)

pytorch求导,pytorch使用,pytorch,人工智能,python

这里,x是由用户直接创建的,所以x.grad_fnNoney是通过乘法操作创建的,所以y.grad_fn是一个MulBackward0对象,这表明y是通过乘法操作创建的。z是通过求平均数操作创建的,所以z.grad_fn是一个MeanBackward0对象。

pytorch求导,pytorch使用,pytorch,人工智能,python

 pytorch自动求导实现神经网络

numpy手动实现

import numpy as np
import matplotlib.pyplot as plt

N, D_in, H, D_out = 64, 1000, 100, 10  # 64个训练数据(只是一个batch),输入是1000维,hidden是100维,输出是10维

'''随机创建一些训练数据'''
X = np.random.randn(N, D_in)
y = np.random.randn(N, D_out)

W1 = np.random.randn(D_in, H)  # 1000维转成100维
W2 = np.random.randn(H, D_out)  # 100维转成10维

learning_rate = 1e-6

all_loss = []

epoch = 500

for t in range(500):  # 做500次迭代
    '''前向传播(forward pass)'''
    h = X.dot(W1)  # N * H
    h_relu = np.maximum(h, 0)  # 激活函数,N * H
    y_hat = h_relu.dot(W2)  # N * D_out

    '''计算损失函数(compute loss)'''
    loss = np.square(y_hat - y).sum()  # 均方误差,忽略了÷N
    print("Epoch:{}   Loss:{}".format(t, loss))  # 打印每个迭代的损失
    all_loss.append(loss)

    '''后向传播(backward pass)'''
    # 计算梯度(此处没用torch,用最普通的链式求导,最终要得到 d{loss}/dX)
    grad_y_hat = 2.0 * (y_hat - y)  # d{loss}/d{y_hat},N * D_out
    grad_W2 = h_relu.T.dot(grad_y_hat)  # 看前向传播中的第三个式子,d{loss}/d{W2},H * D_out

    grad_h_relu = grad_y_hat.dot(W2.T)  # 看前向传播中的第三个式子,d{loss}/d{h_relu},N * H
    grad_h = grad_h_relu.copy()  # 这是h>0时的情况,d{h_relu}/d{h}=1
    grad_h[h < 0] = 0  # d{loss}/d{h}
    grad_W1 = X.T.dot(grad_h)  # 看前向传播中的第一个式子,d{loss}/d{W1}

    '''参数更新(update weights of W1 and W2)'''
    W1 -= learning_rate * grad_W1
    W2 -= learning_rate * grad_W2

plt.plot(all_loss)
plt.xlabel("epoch")
plt.ylabel("Loss")
plt.show()

pytorch自动实现

import torch

N, D_in, H, D_out = 64, 1000, 100, 10  # 64个训练数据(只是一个batch),输入是1000维,hidden是100维,输出是10维

'''随机创建一些训练数据'''
X = torch.randn(N, D_in)
y = torch.randn(N, D_out)

W1 = torch.randn(D_in, H, requires_grad=True)  # 1000维转成100维
W2 = torch.randn(H, D_out, requires_grad=True)  # 100维转成10维

learning_rate = 1e-6

for t in range(500):  # 做500次迭代
    '''前向传播(forward pass)'''
    y_hat = X.mm(W1).clamp(min=0).mm(W2)  # N * D_out

    '''计算损失函数(compute loss)'''
    loss = (y_hat - y).pow(2).sum()  # 均方误差,忽略了÷N,loss就是一个计算图(computation graph)
    print("Epoch:{}   Loss:{}".format(t, loss.item()))  # 打印每个迭代的损失

    '''后向传播(backward pass)'''
    loss.backward()

    '''参数更新(update weights of W1 and W2)'''
    with torch.no_grad():
        W1 -= learning_rate * W1.grad
        W2 -= learning_rate * W2.grad
        W1.grad.zero_()
        W2.grad.zero_()

pytorch手动实现

import torch
import matplotlib.pyplot as plt

N, D_in, H, D_out = 64, 1000, 100, 10  # 64个训练数据(只是一个batch),输入是1000维,hidden是100维,输出是10维

'''随机创建一些训练数据'''
X = torch.randn(N, D_in)
y = torch.randn(N, D_out)

W1 = torch.randn(D_in, H)  # 1000维转成100维
W2 = torch.randn(H, D_out)  # 100维转成10维

learning_rate = 1e-6

all_loss = []

for t in range(500):  # 做500次迭代
    '''前向传播(forward pass)'''
    h = X.mm(W1)  # N * H
    h_relu = h.clamp(min=0)  # 激活函数,N * H
    y_hat = h_relu.mm(W2)  # N * D_out

    '''计算损失函数(compute loss)'''
    loss = (y_hat - y).pow(2).sum().item()  # 均方误差,忽略了÷N
    print("Epoch:{}   Loss:{}".format(t, loss))  # 打印每个迭代的损失
    all_loss.append(loss)

    '''后向传播(backward pass)'''
    # 计算梯度(此处没用torch,用最普通的链式求导,最终要得到 d{loss}/dX)
    grad_y_hat = 2.0 * (y_hat - y)  # d{loss}/d{y_hat},N * D_out
    grad_W2 = h_relu.t().mm(grad_y_hat)  # 看前向传播中的第三个式子,d{loss}/d{W2},H * D_out

    grad_h_relu = grad_y_hat.mm(W2.t())  # 看前向传播中的第三个式子,d{loss}/d{h_relu},N * H
    grad_h = grad_h_relu.clone()  # 这是h>0时的情况,d{h_relu}/d{h}=1
    grad_h[h < 0] = 0  # d{loss}/d{h}
    grad_W1 = X.t().mm(grad_h)  # 看前向传播中的第一个式子,d{loss}/d{W1}

    '''参数更新(update weights of W1 and W2)'''
    W1 -= learning_rate * grad_W1
    W2 -= learning_rate * grad_W2

plt.plot(all_loss)
plt.xlabel("epoch")
plt.ylabel("Loss")
plt.show()

torch.nn实现

import torch
import torch.nn as nn  # 各种定义 neural network 的方法

N, D_in, H, D_out = 64, 1000, 100, 10  # 64个训练数据(只是一个batch),输入是1000维,hidden是100维,输出是10维

'''随机创建一些训练数据'''
X = torch.randn(N, D_in)
y = torch.randn(N, D_out)

model = torch.nn.Sequential(
    torch.nn.Linear(D_in, H, bias=True),  # W1 * X + b,默认True
    torch.nn.ReLU(),
    torch.nn.Linear(H, D_out)
)

# model = model.cuda()  #这是使用GPU的情况

loss_fn = nn.MSELoss(reduction='sum')

learning_rate = 1e-4

for t in range(500):  # 做500次迭代
    '''前向传播(forward pass)'''
    y_hat = model(X)  # model(X) = model.forward(X), N * D_out

    '''计算损失函数(compute loss)'''
    loss = loss_fn(y_hat, y)  # 均方误差,忽略了÷N,loss就是一个计算图(computation graph)
    print("Epoch:{}   Loss:{}".format(t, loss.item()))  # 打印每个迭代的损失

    '''后向传播(backward pass)'''
    loss.backward()

    '''参数更新(update weights of W1 and W2)'''
    with torch.no_grad():
        for param in model.parameters():
            param -= learning_rate * param.grad  # 模型中所有的参数更新

    model.zero_grad()

torch.nn的继承类文章来源地址https://www.toymoban.com/news/detail-633456.html

import torch
import torch.nn as nn  # 各种定义 neural network 的方法
from torchsummary import summary
# pip install torchsummary
N, D_in, H, D_out = 64, 1000, 100, 10  # 64个训练数据(只是一个batch),输入是1000维,hidden是100维,输出是10维

'''随机创建一些训练数据'''
X = torch.randn(N, D_in)
y = torch.randn(N, D_out)

'''定义两层网络'''


class TwoLayerNet(torch.nn.Module):
    def __init__(self, D_in, H, D_out):
        super(TwoLayerNet, self).__init__()
        # 定义模型结构
        self.linear1 = torch.nn.Linear(D_in, H, bias=False)
        self.linear2 = torch.nn.Linear(H, D_out, bias=False)

    def forward(self, x):
        y_hat = self.linear2(self.linear1(X).clamp(min=0))
        return y_hat


model = TwoLayerNet(D_in, H, D_out)

loss_fn = nn.MSELoss(reduction='sum')
learning_rate = 1e-4
optimizer = torch.optim.Adam(model.parameters(), lr=learning_rate)

for t in range(500):  # 做500次迭代
    '''前向传播(forward pass)'''
    y_hat = model(X)  # model.forward(), N * D_out

    '''计算损失函数(compute loss)'''
    loss = loss_fn(y_hat, y)  # 均方误差,忽略了÷N,loss就是一个计算图(computation graph)
    print("Epoch:{}   Loss:{}".format(t, loss.item()))  # 打印每个迭代的损失

    optimizer.zero_grad()  # 求导之前把 gradient 清空
    '''后向传播(backward pass)'''
    loss.backward()

    '''参数更新(update weights of W1 and W2)'''
    optimizer.step()  # 一步把所有参数全更新


print(summary(model, (64, 1000)))

到了这里,关于pytorch求导的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 人工智能之配置环境教程二:在Anaconda中创建虚拟环境安装GPU版本的Pytorch及torchvision并在VsCode中使用虚拟环境

    孟莉苹,女,西安工程大学电子信息学院,2021级硕士研究生,张宏伟人工智能课题组。 研究方向:机器视觉与人工智能。 电子邮件:2425613875@qq.com 本教程提供需要安装的CUDA11.3、Pytorch1.10.0、torchvision0.11.0的安装包,在下述百度网盘链接中自取! 链接:https://pan.baidu.com/s/18m

    2024年02月02日
    浏览(68)
  • 【Python/人工智能】TensorFlow 框架原理及使用教程

    TensorFlow 是一款由 Google 开源的人工智能框架,是目前应用最广泛的深度学习框架之一。它可以在各种硬件平台上运行,包括单个 CPU、CPU 集群、GPU,甚至是分布式环境下的 CPU 和 GPU 组合。 除了深度学习领域,TensorFlow 还支持其他机器学习算法和模型,如 决策树 、 SVM 、 k-m

    2024年04月28日
    浏览(45)
  • 【人工智能】使用Python构建神经网络模型预测房价

    目录 一 、实验目的 二 、实验内容 三 、实验原理 四 、实验过程 数据处理 1.1数据读入 1.2缺失值处理 1.3数据归一化 1.4数据集乱序 1.6数据集分批次 模型设计与配置 2.1 构建前向网络结构,定义假设空间 2.2初始化参数w和b,使用标准正态分布随机生成 训练网络 3.1外层循环

    2024年02月03日
    浏览(43)
  • 《人工智能专栏》必读150篇 | 专栏介绍 & 专栏目录 & Python与PyTorch | 机器与深度学习 | 目标检测 | YOLOv5及改进 | YOLOv8及改进 | 关键知识点 | 工具

    各位读者们好,本专栏最近刚推出,限于个人能力有限,不免会有诸多错误,敬请私信反馈给我,接受善意的提示,后期我会改正,谢谢,感谢。 第一步 :[ 购买点击跳转 ] 第二步 : 代码函数调用关系图(全网最详尽-重要) 因文档特殊,不能在博客正确显示,请移步以下链接

    2024年02月02日
    浏览(71)
  • 人工智能(pytorch)搭建模型9-pytorch搭建一个ELMo模型,实现训练过程

    大家好,我是微学AI,今天给大家介绍一下人工智能(pytorch)搭建模型9-pytorch搭建一个ELMo模型,实现训练过程,本文将介绍如何使用PyTorch搭建ELMo模型,包括ELMo模型的原理、数据样例、模型训练、损失值和准确率的打印以及预测。文章将提供完整的代码实现。 ELMo模型简介 数据

    2024年02月07日
    浏览(63)
  • 人工智能学习07--pytorch15(前接pytorch10)--目标检测:FPN结构详解

    backbone:骨干网络,例如cnn的一系列。(特征提取) (a)特征图像金字塔 检测不同尺寸目标。 首先将图片缩放到不同尺度,针对每个尺度图片都一次通过算法进行预测。 但是这样一来,生成多少个尺度就要预测多少次,训练效率很低。 (b)单一特征图 faster rcnn所采用的一种方式

    2023年04月12日
    浏览(70)
  • 人工智能:Pytorch,TensorFlow,MXNET,PaddlePaddle 啥区别?

    学习人工智能的时候碰到各种深度神经网络框架:pytorch,TensorFlow,MXNET,PaddlePaddle,他们有什么区别? PyTorch、TensorFlow、MXNet和PaddlePaddle都是深度学习领域的开源框架,它们各自具有不同的特点和优势。以下是它们之间的主要区别: PyTorch是一个开源的Python机器学习库,它基

    2024年04月16日
    浏览(66)
  • 入门人工智能 —— 学习 python 使用 IDE :vscode 完成编程 (2)

    在上一篇文章中,介绍了如何入门人工智能编程,并开始了学习 Python 编程语言的基础知识。本文是系列文章的第二部分,我们将继续探讨 Python 编程,但这次我们将使用 Visual Studio Code(简称 VSCode)作为我们的集成开发环境(IDE)。VSCode 是一个功能强大的文本编辑器,它可以

    2024年02月09日
    浏览(59)
  • 人工智能学习07--pytorch14--ResNet网络/BN/迁移学习详解+pytorch搭建

    亮点:网络结构特别深 (突变点是因为学习率除0.1?) 梯度消失 :假设每一层的误差梯度是一个小于1的数,则在反向传播过程中,每向前传播一层,都要乘以一个小于1的误差梯度。当网络越来越深的时候,相乘的这些小于1的系数越多,就越趋近于0,这样梯度就会越来越小

    2023年04月11日
    浏览(144)
  • AI写作革命:PyTorch如何助力人工智能走向深度创新

    身为专注于人工智能研究的学者,我十分热衷于分析\\\"AI写稿\\\"与\\\"PyTorch\\\"这两项领先技术。面对日益精进的人工智能科技,\\\"AI写作\\\"已不再是天方夜谭;而\\\"PyTorch\\\"如璀璨明珠般耀眼,作为深度学习领域的尖端工具,正有力地推进着人工智能化进程。于此篇文章中,我将详细解析\\\"

    2024年04月13日
    浏览(51)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包