PyTorch学习笔记(二:Tensor和Variable&&自动微分)
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
上的所有操作提供了自动区分。它是一个逐个运行的框架
变量&&梯度
autograd.Variable
是包的*类。它包含一个Tensor
,并支持几乎所有定义的操作。完成计算后,您可以调用.backward()
并自动计算所有梯度。
您可以通过.dat
a属性访问原始张量,而将此变量的梯度累加到.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梯度信息。
, , , 所以 , 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