Pytorch入门不脱发(一、数据基本操作)
先来从读Pytorch的官方文档开始
创建Tensor
torch.tensor(data, dtype=None, device=None,requires_grad=False)
data - 可以是list, tuple, numpy array, scalar或其他类型
dtype - 可以返回想要的tensor类型
device - 可以指定返回的设备
requires_grad - 可以指定是否进行记录图的操作,默认为False
需要注意的是,torch.tensor 总是会复制 data, 如果你想避免复制,可以使 torch.Tensor. detach(),如果是从 numpy 中获得数据,那么你可以用 torch.from_numpy(), 注from_numpy() 是共享内存的
>>> torch.tensor([[0.1, 1.2], [2.2, 3.1], [4.9, 5.2]])
tensor([[ 0.1000, 1.2000],
[ 2.2000, 3.1000],
[ 4.9000, 5.2000]])
>>> torch.tensor([0, 1]) # Type inference on data
tensor([ 0, 1])
>>> torch.tensor([[0.11111, 0.222222, 0.3333333]],
dtype=torch.float64,
device=torch.device('cuda:0')) # creates a torch.cuda.DoubleTensor
tensor([[ 0.1111, 0.2222, 0.3333]], dtype=torch.float64, device='cuda:0')
>>> torch.tensor(3.14159) # Create a scalar (zero-dimensional tensor)
tensor(3.1416)
>>> torch.tensor([]) # Create an empty tensor (of size (0,))
tensor([])
基本运算
注意,所有的带_的函数,是原地的操作
x = torch.ones(5, 3,dtype=torch.double)
y = torch.ones(x.size()[0], x.size()[1], dtype=torch.double)
y.add(x)#y还是1的矩阵
y.add_(x)#y成了2的矩阵
backward()函数
- 我们知道,每创建一个tensor,就是在创建一个节点(node),而连接这些节点的编(edge)就是函数,nodes和edges组成了computational graph,当一个节点的x.requires_grad=True,x.grad就是记录了在当前值的梯度大小。
- backward()为梯度求解
- 最后得到的Tensor执行自身的backward()函数,此时之前参与运算并生成当前Tensor的叶子(leaf)Tensor将会保存其梯度在叶子Tensor的grad属性中。backward()函数接受参数,表示在特定位置求梯度值,该参数应和调用backward()函数的Tensor的维度相同,或者是可broadcast的维度。默认为torch.tensor(1),也就是在当前梯度为标量1的位置求叶子Tensor的梯度。
看一下例子:
import torch
x = torch.ones(2,2,requires_grad=True)
y = x + 2
z = y * y * 3
out = z.mean()
out.backward()
print(x.grad)
>>tensor([[4.5000, 4.5000],
[4.5000, 4.5000]])
只有叶子节点(leaf)自动保存梯度在grad属性中,所以上面代码直接print(y.grad)是无法输出的
标量的grad与矢量2020.6.8更新
我们在刚才的例子中,没有求诸如y=2*x的梯度,那是因为2*x就不在是一个标量,而是一个矢量了
我们不允许张量对张量求导 只允许标量对张量求导,求导的结果是和自变量同形的张量。
解决的办法是求一个张量的反向传播的梯度的时候,参数是一个相同形状的张量。
注:参考为D-DL-P书2.3章,讲的挺明白了,以后自己忘记了记得翻