3-Pytorch张量的运算、形状改变、自动微分

3-Pytorch张量的运算、形状改变、自动微分

    • [1 导入必备库](#1 导入必备库)
    • [2 张量的运算](#2 张量的运算)
    • [3 张量的算数运算](#3 张量的算数运算)
    • [4 一个元素的张量可以使用tensor.item()方法转成标量](#4 一个元素的张量可以使用tensor.item()方法转成标量)
    • [5 torch.from_numpy()和tensor.numpy()](#5 torch.from_numpy()和tensor.numpy())
    • [6 张量的变形](#6 张量的变形)
    • [7 张量的自动微分](#7 张量的自动微分)
    • [8 使用with torch.no_grad():包含上下文中使其不再跟踪计算](#8 使用with torch.no_grad():包含上下文中使其不再跟踪计算)
    • [9 使用tensor.detach()分离出张量的值](#9 使用tensor.detach()分离出张量的值)
    • [10 requirs_grad_()方法改变张量的跟踪属性,是否需要追踪计算](#10 requirs_grad_()方法改变张量的跟踪属性,是否需要追踪计算)

1 导入必备库

python 复制代码
import torch
import numpy as np

2 张量的运算

张量的运算规则、切片索引规则与numpy类似,运算中遵循广播原则和同形状同位置元素对齐运算原则

python 复制代码
t1 = torch.randn(2,3)
t2 = torch.ones(2,3)
print('t1=',t1)
print('t1+3=',t1+3)
print('t1+t2=',t1+t2)        #同位置元素相加
print('t1.add(t2)=',t1.add(t2))   #等价t1+t2

print('t1=',t1)
t1.add_(t2)         # add_方法表示就地改变原值,不需要存放在其它变量内
print('t1.add_(t2)=',t1)

输出:

复制代码
t1= tensor([[-1.1872,  1.4624,  0.1379],
        [ 1.0701, -2.6139, -1.2106]])
t1+3= tensor([[1.8128, 4.4624, 3.1379],
        [4.0701, 0.3861, 1.7894]])
t1+t2= tensor([[-0.1872,  2.4624,  1.1379],
        [ 2.0701, -1.6139, -0.2106]])
t1.add(t2)= tensor([[-0.1872,  2.4624,  1.1379],
        [ 2.0701, -1.6139, -0.2106]])
t1= tensor([[-1.1872,  1.4624,  0.1379],
        [ 1.0701, -2.6139, -1.2106]])
t1.add_(t2)= tensor([[-0.1872,  2.4624,  1.1379],
        [ 2.0701, -1.6139, -0.2106]])

3 张量的算数运算

张量的算数运算包括:abs(绝对值)、cunsum(累加)、divide(除)、floor_divide(整除)、mean(均值)、min(最小值)、max(最大值)、multiply(乘)等,矩阵转置常用(tensor.T)和矩阵乘法用(matmul或@)

python 复制代码
print('t1.matmul(t2.T)=',t1.matmul(t2.T))
print('t1 @ (t2.T)=',t1 @ (t2.T))

输出:

复制代码
t1.matmul(t2.T)= tensor([[3.4131, 3.4131],
        [0.2456, 0.2456]])
t1 @ (t2.T)= tensor([[3.4131, 3.4131],
        [0.2456, 0.2456]])

4 一个元素的张量可以使用tensor.item()方法转成标量

python 复制代码
t3 = t1.sum()
print('t3=',t3,type(t3))
print('t3.item()=', t3.item(),type(t3.item()))

输出:

复制代码
t3= tensor(3.6586) <class 'torch.Tensor'>
t3.item()= 3.658644914627075 <class 'float'>

5 torch.from_numpy()和tensor.numpy()

使用torch.from_numpy()方法将ndarray转成张量,使用tensor.numpy()方法得到对应的ndarray数组,它们共用相同内存

python 复制代码
a = np.random.randn(2,3)
print('a= ', a)
t = torch.from_numpy(a)
print('t= ', t)
print('t.numpy()=',t.numpy())

输出:

复制代码
a=  [[-0.17144614  0.03711562 -0.40770295]
 [ 0.64600264 -1.39858095  0.41699902]]
t=  tensor([[-0.1714,  0.0371, -0.4077],
        [ 0.6460, -1.3986,  0.4170]], dtype=torch.float64)
t.numpy()= [[-0.17144614  0.03711562 -0.40770295]
 [ 0.64600264 -1.39858095  0.41699902]]

6 张量的变形

tensor.size()方法和tensor.shape属性返回张量的形状。

改变张量的形状用tensor.view()方法,相当于numpy中的reshape方法

python 复制代码
t = torch.randn(4,6)
print('shape返回张量的形状: t.shape=',t.shape)
t1 = t.view(3,8)
print('view改变形状: t1.shape=',t1.shape)
# 将tensor矩阵展平,-1表示长度自动计算
t1 = t.view(-1,1)
print('view展平: t1.shape=',t1.shape)

# 使用view增加维度,总元素个数不变
t1 = t.view(1,4,6)
print('view增加维度: t1.shape=',t1.shape)

# 当维度为1时,使用torch.squeeze()去掉长度为1的维度,相应的torch.unsqueeze()增加长度为1的维度
print('t1.shape=',t1.shape)
t2 = torch.squeeze(t1)  # 去掉长度为1的维度
print('squeeze去掉1维度: t2.shape=',t2.shape)
t3 = torch.unsqueeze(t2,0)
print('unsqueeze增加1维度: t2.shape=',t3.shape)

输出;

复制代码
shape返回张量的形状: t.shape= torch.Size([4, 6])
view改变形状: t1.shape= torch.Size([3, 8])
view展平: t1.shape= torch.Size([24, 1])
view增加维度: t1.shape= torch.Size([1, 4, 6])
t1.shape= torch.Size([1, 4, 6])
squeeze去掉1维度: t2.shape= torch.Size([4, 6])
unsqueeze增加1维度: t2.shape= torch.Size([1, 4, 6])

7 张量的自动微分

requires_grad属性设置为True时,Pytorch会跟踪此张量所有计算,并可调用backward() 计算所有梯度,梯度将累加到grad属性中。

grad_fn属性指向运算生成此张量的方法。

python 复制代码
t = torch.ones(2,2,requires_grad= True)
print('是否跟踪计算梯度:', t.requires_grad)
print('输出梯度:', t.grad)
print('生成此张量的方法:', t.grad_fn)

y = t + 5
print('y= ', y)
print('y.grad_fn=',y.grad_fn)

z = y * 2
out = z.mean()
print('out=',out)

# 对out微分:d(out)/d(t)
out.backward()
print('t.grad=',t.grad)

输出:

复制代码
是否跟踪计算梯度: True
输出梯度: None
生成此张量的方法: None
y=  tensor([[6., 6.],
        [6., 6.]], grad_fn=<AddBackward0>)
y.grad_fn= <AddBackward0 object at 0x000002A7D34E8248>
out= tensor(12., grad_fn=<MeanBackward0>)
t.grad= tensor([[0.5000, 0.5000],
        [0.5000, 0.5000]])

8 使用with torch.no_grad():包含上下文中使其不再跟踪计算

python 复制代码
print('是否跟踪计算梯度:', t.requires_grad)
print('是否跟踪计算梯度:', (t+2).requires_grad)

with torch.no_grad():
    print('是否跟踪计算梯度:', (t+2).requires_grad)

输出:

复制代码
是否跟踪计算梯度: True
是否跟踪计算梯度: True
是否跟踪计算梯度: False

9 使用tensor.detach()分离出张量的值

python 复制代码
print('是否跟踪计算梯度:', out.requires_grad)
# s1  = out.data()  #获取值
s = out.detach()

print('是否跟踪计算梯度:',s.requires_grad)

输出:

复制代码
是否跟踪计算梯度: True
是否跟踪计算梯度: False

10 requirs_grad_()方法改变张量的跟踪属性,是否需要追踪计算

python 复制代码
print('是否跟踪计算梯度:', t.requires_grad)
t.requires_grad_(False)
print('是否跟踪计算梯度:', t.requires_grad)

输出:

复制代码
是否跟踪计算梯度: True
是否跟踪计算梯度: False
相关推荐
IT_陈寒3 小时前
React 18实战:7个被低估的Hooks技巧让你的开发效率提升50%
前端·人工智能·后端
数据智能老司机4 小时前
精通 Python 设计模式——分布式系统模式
python·设计模式·架构
逛逛GitHub4 小时前
飞书多维表“独立”了!功能强大的超出想象。
人工智能·github·产品
机器之心4 小时前
刚刚,DeepSeek-R1论文登上Nature封面,通讯作者梁文锋
人工智能·openai
数据智能老司机5 小时前
精通 Python 设计模式——并发与异步模式
python·设计模式·编程语言
数据智能老司机5 小时前
精通 Python 设计模式——测试模式
python·设计模式·架构
数据智能老司机5 小时前
精通 Python 设计模式——性能模式
python·设计模式·架构
c8i5 小时前
drf初步梳理
python·django
每日AI新事件5 小时前
python的异步函数
python
这里有鱼汤6 小时前
miniQMT下载历史行情数据太慢怎么办?一招提速10倍!
前端·python