欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

PyTorch学习笔记(二:Tensor和Variable&&自动微分)

程序员文章站 2022-03-06 21:00:40
...

PyTorch学习笔记(二:Tensor和Variable&&自动微分)

参考博客:https://ptorch.com/docs/3/autograd_tutorial(Pytorch官方中文教程)

                  https://blog.csdn.net/qq_42655135/article/details/90812954?spm=1001.2014.3001.5501

                  https://github.com/L1aoXingyu/code-of-learn-deep-learning-with-pytorch(github项目廖星宇《深度学习入门》)

Tensor和Variable

对于深度学习的环境配置问题:

1、安装nvida cuda

2、cudnn

3、GPU版本的pytorch

Tensor(张量)与Variable(变量)

Tensor:

PyTorch中的Tensor本质上和numpy数组是一样的:Tensor是一个n维数组,并且PyTorch定义了关于Tensor的很多操作。并且Tensor和numpy一样,不知道深度学习、计算图和梯度的概念,它们都是通用的科学计算工具。但是和numpy不同的是,Torch可以利用GPU来加速数值计算。

Variable:

PyTorch的包autograd提供了自动求导的功能。当使用autograd时,定义的前向网络会生成一个计算图:每个节点是一个Tensor,边表示由输入Tensor到输出Tensor的函数。沿着计算图的反向传播可以很容易地计算出梯度。

在实现的时候,用到了Variable对象。Variable对Tensor对象进行封装,只需要Variable::data即可取出Tensor,并且Variable还封装了该Tensor的梯度Variable::grad(是个Variable对象)。现在用Variable作为计算图的节点,则通过反向传播自动求得的导数就保存在Variable对象中了。

Variable提供了和Tensor一样的API,即能在Tensor上执行的操作也可以在Variable上执行。

autograd

autograd包是PyTorch所有神经网络的核心。autograd包为Tensors上的所有操作提供了自动区分。它是一个逐个运行的框架

PyTorch学习笔记(二:Tensor和Variable&&自动微分)

变量&&梯度

autograd.Variable是包的*类。它包含一个Tensor,并支持几乎所有定义的操作。完成计算后,您可以调用.backward()并自动计算所有梯度。

您可以通过.data属性访问原始张量,而将此变量的梯度累加到.grad

如果你想计算导数,你可以在一个Variable中使用.backward()

如果Variable是标量(即它保存一个元素数据),则不需要指定任何参数backward(),但是如果它具有更多元素,则需要指定一个grad_output 作为匹配形状的张量的参数。

'''
torchvision包是服务于Pytorch深度学习框架的,用来生成图片、视频数据集和一些流行的模型类和预训练模型
torchvision 由以下四个模块组成

torchvision.datasets
torchvision.models
torchvision.transforms
torchvision.utils
'''
#变量
import torch
from torch.autograd import Variable

#如果requires_grad=True,在进行反向传播的时候会记录该tensor梯度信息。
x = Variable(torch.ones(2, 2), requires_grad = True)
print(x)

y = x + 2
print(y)
z = y * y * 3
out = z.mean()
print(z)
print(out)

out.backward()
# out是标量,因此不需要为backward()函数指定参数,相当于out.backward(torch.tensor(1))
print(x.grad)#打印梯度d(out)/dx

x = torch.randn(3)
x = Variable(x, requires_grad = True)
y = x * 2
while y.data.norm() < 500:
    y = y * 2
print(y)

gradients = torch.FloatTensor([0.1, 1.0, 0.001])
y.backward(gradients)
print(x.grad)
tensor([[1., 1.],
        [1., 1.]], requires_grad=True)
tensor([[3., 3.],
        [3., 3.]], grad_fn=<AddBackward0>)
tensor([[27., 27.],
        [27., 27.]], grad_fn=<MulBackward0>)
tensor(27., grad_fn=<MeanBackward0>)
tensor([[4.5000, 4.5000],
        [4.5000, 4.5000]])
tensor([525.6600,  38.3866, 294.4510], grad_fn=<MulBackward0>)
tensor([ 25.6000, 256.0000,   0.2560])

 

参考博客:https://blog.csdn.net/a1367666195/article/details/105654101/

leaf Variable、requires_grad、grad_fn的含义以及它们之间的关系

1、requires_grad

requires_grad是pytorch中tensor的一个属性, 如果requires_grad=True,在进行反向传播的时候会记录t该tensor梯度信息。

PyTorch学习笔记(二:Tensor和Variable&&自动微分),   PyTorch学习笔记(二:Tensor和Variable&&自动微分),  PyTorch学习笔记(二:Tensor和Variable&&自动微分), 所以 PyTorch学习笔记(二:Tensor和Variable&&自动微分), requires_grad=True时进行反向传播会记录tensor的梯度信息,方便使用梯度下降法。

import torch
a = torch.tensor([1., 2, 3, 4], requires_grad = True)
b = torch.tensor([1., 2, 3, 4], requires_grad = False)

c = torch.sum(a * 2)
print(c)
c.backward()
print(a.grad)

print("=" * 40)

d = torch.sum(b + a)
d.backward()
print(b.grad)
print(b.requires_grad)
print(d.requires_grad)
#对于d = a + b的情况、对于requires_grad, a为True、b为False、只要有一个为True, d即为True

print("=" * 40)

b.requires_grad_(True)
d = torch.sum(b + a)
d.backward()
print(b.grad)
print(b.requires_grad)
print(d.requires_grad)
tensor(20., grad_fn=<SumBackward0>)
tensor([2., 2., 2., 2.])
========================================
None
False
True
========================================
tensor([1., 1., 1., 1.])
True
True

2、grad_fn

grad_fn也是tensor的一个属性,它记录的是tensor的运算信息。记录grad_fn信息的意义有利于我们使用反向传播算法

import torch
a = torch.tensor([1., 2, 3, 4], requires_grad = True)
b = torch.tensor([1., 2, 3, 4], requires_grad = False)

c = a + b
print(a.grad_fn)
print(b.grad_fn)
print(c)
print(c.data)
print(c.grad_fn)
None
None
tensor([2., 4., 6., 8.], grad_fn=<AddBackward0>)
tensor([2., 4., 6., 8.])
<AddBackward0 object at 0x7fd289ed11d0>

3、Leaf Variable

用pytorch搭建神经网络,数据都是tensor类型的。先前的版本,tensor似乎只包含data信息,不会记录requires_grad、grad_fn信息,转化成variable之后才会有requires_grad和grad_fn属性。现在Variable基本可以被直接用tensor替代了,虽然现在还保留着Variable方法,但基本不需要,直接用tensor就可以了。grad_fn为None的tensor都是leaf variable,反之皆不是。

import torch
a = torch.tensor([1., 2, 3, 4], requires_grad = True)
b = torch.tensor([1., 2, 3, 4], requires_grad = False)
c = a + b
print(a.is_leaf)
print(b.is_leaf)
print(c.is_leaf)

a = torch.tensor([1., 2, 3, 4], requires_grad = False)
b = torch.tensor([1., 2, 3, 4], requires_grad = False)
c = a + b
print(c.is_leaf)
print(c.grad_fn)
True
True
False
True
None

 

上一篇: 每日一题Day32

下一篇: AOP注解开发