PyTorch官方教程之1:学习tensor

# 《PyTorch官方教程中文版》, 学习tensor
import torch

# Part 1: tensor的创建

# 创建一个全1张量,设置 requires_grad=True 来跟踪与它相关的计算
# 创建一个Tensor时,使用requires_grad参数指定是否记录对其的操作,以便之后利用backward()方法进行梯度求解。
x1 = torch.ones(2, 2, requires_grad=True)
print('x1: ', x1)

# 构造一个5x3矩阵,不初始化。全0,每一次跑的结果都不一样
x2 = torch.empty(5, 3)
print('x2: ', x2)

# 构造一个随机初始化的矩阵, 均值0、方差1的标准正态分布
x3 = torch.rand(5, 2)
print('x3: ', x3)

# 构造一个矩阵全为 0,而且数据类型是 long
x4 = torch.zeros(2, 3, dtype=torch.long)
print('x4: ', x4)

# 默认数据类型是 torch.float32
torch.get_default_dtype()

# 构造一个张量,直接使用数据
x5 = torch.tensor([5.5, 3])
print('x5: ', x5)

# 创建一个 tensor, 基于已经存在的 tensor。
# 全1的5x3矩阵,dtype=torch.float64
x6 = x5.new_ones(5, 3, dtype=torch.double)
print('x6: ', x6)
# 规模与x6一样,override dtype=torch.float32
x7 = torch.randn_like(x6, dtype=torch.float)
print('x7: ', x7)
# 获取它的维度信息
print('size of x7: ', x7.size())

# Part 2: tensor的操作

# 加法
print('x6+x7: ', x6 + x7)
print('x6+x7: ', torch.add(x6, x7))
# 提供一个输出 tensor 作为参数
add_v = torch.empty(5, 3)
torch.add(x6, x7, out=add_v)
print('x6+x7: ', add_v)

# 索引
# 所有行、第2列
print('second column: ', add_v[:, 1])

# Part 3: 关于梯度
# 如果将其属性 .requires_grad 设置为 True,则会开始跟踪针对 tensor的所有操作。完成计算后,您可以调用 .backward() 来自动计算所有梯度。该张量的梯度将累积到.grad 属性中。
# requires_grad: 如果需要为张量计算梯度(求导数),则为True,否则为False(默认)
# x1 = torch.ones(2, 2, requires_grad=True)
y = x1 + 2
print('y: ', y)
# 通过运算得到的Tensor(非自己创建的tensor),会自动被赋值grad_fn属性。该属性表示梯度函数是哪种类型。
# 而自己创建的tensor,.grad_fn为None
print('y.grad_fn: ', y.grad_fn)

# 反向传播求梯度
# y.backward()
# RuntimeError: grad can be implicitly created only for scalar outputs
# backward()没带参数,这与 .backward(torch.Tensor(1.0)) 是相同的,参数默认就是一个标量。
# 但是由于y不是一个标量,而是二维的张量,所以就会报错。
# 返回值不是一个标量,所以需要输入一个大小相同的张量作为参数,这里我们用ones_like函数根据x1生成一个相同规模的全1张量。
y.backward(torch.ones_like(x1))
print('x1.grad: ', x1.grad)

x8 = torch.tensor([2, 3, 4], dtype=torch.float, requires_grad=True)
y1 = x8*x8
print('y1: ', y1)

# 积累非叶子节点的梯度
y1.retain_grad() #modified
#y1.backward(torch.ones_like(x8))
y1.backward(torch.ones_like(x8), retain_graph=True) #modified
print('1st backward ...')
print('x8.grad: ', x8.grad)
print('y1.grad: ', y1.grad)

z = torch.mean(y1)
print('z: ', z)
# z.backward()
# RuntimeError: Trying to backward through the graph a second time
# 程序在试图执行backward的时候,发现计算图的缓冲区已经被释放。在第一次backward()函数中添加参数retain_graph=True,如上
print('2nd backward ...')
z.backward()

print('x8 is leaf: ', x8.is_leaf)
# backward()仅在默认情况下累积叶子节点张量的梯度。
# 积累非叶子节点的梯度, y1.retain_grad()
print('y1 is leaf: ', y1.is_leaf)
print('z is leaf: ', z.is_leaf)

print('x8.grad: ', x8.grad)
print('y1.grad: ', y1.grad)

# .requires_grad属性具有传递性
print(x8.requires_grad) #True
print((x8**2).requires_grad) #True

# 可以通过将代码包裹在 with torch.no_grad(),来停止对从跟踪历史中的 .requires_grad=True 的张量自动求导。
with torch.no_grad():
    print((x8**2).requires_grad) #False
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值