PyTorch 是一个开源深度学习框架
PyTorch 是动态图框架,TensorFlow 1.x 是静态图框架
静态图和动态图的区别
简介
静态图(Static Graph)是在运行前就把整个模型结构“画死”的图;动态图(Dynamic Graph)是在运行时一边运行一边“画图”的模型结构。
区别展示
你可以把模型比作“做饭的菜谱”,来看这两种图的区别:
类别 | 类比 | 特点 |
---|---|---|
静态图 | 提前写好菜谱 | 执行前构建好计算图,运行时按图执行,优化快但不灵活 |
动态图 | 边做边调整 | 每一步运行时动态创建计算图,调试更方便,更灵活 |
📦 举例对比
静态图 严格按菜谱执行的新手厨师
# TensorFlow 1.x 静态图版:做面包 + 炖汤加盐(先写流程图)
import tensorflow as tf
tf.compat.v1.disable_eager_execution() # 兼容 TF 1.x 风格
# Step 1: 构建菜谱图(只写,不执行)
flour = tf.compat.v1.placeholder(tf.float32, name="flour")
salt = tf.compat.v1.placeholder(tf.float32, name="salt")
bread = flour * 2 # 面包 = 面粉 * 2
soup = salt + 2 # 汤 = 盐 + 2
final_score = bread + soup # 总分 = 面包 + 汤
# Step 2: 开始下厨(运行图)
with tf.compat.v1.Session() as sess:
result = sess.run(final_score, feed_dict={
flour: 300.0,
salt: 5.0
})
print("总分值:", result) # 输出 600 + 7 = 607
动态图 边做边走的灵活厨子
# PyTorch 动态图版:做面包 + 炖汤加盐,边做边写步骤
import torch
# Step 1: 准备材料(定义变量)
flour = torch.tensor(300.0, requires_grad=True) # 面粉,单位克
salt = torch.tensor(5.0, requires_grad=True) # 盐,单位克
# Step 2: 动态进行计算(做菜)
# 做面包:面粉翻倍
bread = flour * 2
# 炖汤:加一点盐
soup = salt + 2
# 总菜品分值 = 面包量 + 汤咸度(举例)
final_score = bread + soup
# Step 3: 模拟反向传播(计算各食材对最终分值的影响)
final_score.backward()
# Step 4: 打印结果
print("总分值:", final_score.item()) # 输出面包 + 汤的“总分”
print("面粉的贡献(梯度):", flour.grad) # 面粉对总分的影响:2
print("盐的贡献(梯度):", salt.grad) # 盐对总分的影响:1
PyTorch的基本概念
Tensor = 张量
Tensor 是 PyTorch 中存储数据的基本单位,类似于“高级的多维数组”。
常见Tensor
import torch
a=torch.Tensor([[1,2],[3,4]])
print(a)
print(a.type())
''' 几种特殊的tensor'''
a = torch.ones(2,2)
print(a)
print(a.type())
a = torch.eye(2,2)
print(a)
print(a.type())
a = torch.zeros(2,2)
print(a)
print(a.type())
print(''' 随机 ''')
a = torch.rand(2,2)
print(a)
print(a.type())
''' 正态分布
mean : 均值
std : 标准差
'''
print(''' 正态分布 ''')
a = torch.normal(mean=torch.rand(5),std=torch.rand(5))
print(a)
print(a.type())
print(''' 均匀 ''')
a = torch.Tensor(2,2).uniform_(-1,1)
print(a)
print(a.type())
print(''' 序列 ''')
a = torch.arange(0,10,1)
print(a)
print(a.type())
print(''' 序列: 等间隔的 n 个数字 ''')
a =torch.linspace(2,10,3)
print(a)
print(a.type())
Tensor的属性
类型(
dtype
)、所存储设备名称(device
)、内存布局的对象(layout
)
稀疏的张量
当前非 0 元素 个数 越少越稀疏
import torch
dev = torch.device("cpu")
dev = torch.device("cuda:0")
a = torch.tensor([2,2],device=dev,dtype=torch.float32)
print(a)
###############################
#坐标
i = torch.tensor([[0,1,2],[0,1,2]])
#坐标值
v = torch.tensor([1,2,3])
x = torch.sparse_coo_tensor(i,v,(4,4))
print(x)
x = torch.sparse_coo_tensor(i,v,(4,4)).to_dense()
print(x)
x = torch.sparse_coo_tensor(i,v,(4,4),
device=dev,
dtype=torch.float32).to_dense()
print(x)
算数运算
import torch
a = torch.rand(2,3)
b = torch.rand(2,3)
b = 3.0
''' 加法 add '''
print(f"a + b = {a+b}")
print(f"torch.add(a,b) = {torch.add(a,b)}")
print(f"a = {a}")
print(f"a.add_(b)={a.add_(b)}")
print(f"a = {a}")
''' 减法 sub '''
print("=== sub ====")
print(f"a - b = {a-b}")
print(f"torch.sub(a,b) = {torch.sub(a,b)}")
print(f"a = {a}")
print(f"a.sub_(b)={a.sub_(b)}")
print(f"a = {a}")
''' 乘法 mul '''
print("=== 乘法 mul ===")
print(f"a * b = {a*b}")
print(f"torch.mul(a,b) = {torch.mul(a,b)}")
print(f"a = {a}")
print(f"a.mul_(b)={a.mul_(b)}")
print(f"a = {a}")
''' 除法 div'''
print("=== 除法 div ===")
print(f"a / b = {a/b}")
print(f"torch.div(a,b) = {torch.div(a,b)}")
print(f"a = {a}")
print(f"a.div_(b)={a.div_(b)}")
print(f"a = {a}")
''' 取整/取余运算 '''
print("=== 取整/取余运算 ===")
a = torch.tensor([1.2,2.5,3.7])
print(f"向下取整 {a.floor()}")
print(f"向上取整 {a.ceil()}")
print(f"四舍五入 {a.round()}")
print(f"取余 {a%2}")
print(f"裁剪到[0,3] {a.clamp(0,3)}")
print(f"只取小数部分 {a.frac()}")
''' 矩阵乘法 matmul '''
print("=== 矩阵乘法 matmul ===")
a = torch.ones(2,1)
b = torch.ones(1,2)
print(f"a @ b = {a @ b}")
print(f"torch.matmul(a,b) = {torch.matmul(a,b)}")
print(f"torch.mm(a,b) = {torch.mm(a,b)}")
print(f"a.mm={a.mm(b)}")
''' 高维tensor '''
print("=== 高维tensor ===")
a = torch.ones(1,2,3,4)
b = torch.ones(1,2,4,3)
print(f"a.matmul(b) = {a.matmul(b)}")
print(f"{a.matmul(b).shape}")
''' pow '''
print("=== pow ===")
a = torch.tensor([1,2])
print(f"a.pow(2) = {a.pow(3)}")
print(f"a**3 = {a**3}")
print(f"a.pow_(2) = {a.pow_(3)}")
print(f"a.pow = {a.pow}")
''' 指数运算 exp '''
print("=== 指数运算 exp ===")
a = torch.tensor([1,2],dtype=torch.float32)
print(f"a.exp() = {a.exp()}")
print(f"a = {a}")
print(f"a.exp_() = {a.exp_()}")
print(f"a = {a}")
''' 对数运算 log '''
print("=== 对数运算 log ===")
a = torch.tensor([1,2],dtype=torch.float32)
print(f"torch.log(a) = {torch.log(a)}")
print(f"a.log() = {a.log()}")
print(f"a = {a}")
print(f"a.log_() = {a.log_()}")
print(f"a = {a}")
''' sqrt 开根号 :如果值为负数,则运算结果nan'''
print("=== sqrt ===")
a = torch.tensor([1,2],dtype=torch.float32)
print(f"torch.sqrt(a) = {torch.sqrt(a)}")
print(f"a.sqrt() = {a.sqrt()}")
print(f"a = {a}")
print(f"a.sqrt_() = {a.sqrt_()}")
print(f"a = {a}")
in-place
就地操作,直接修改原来变量,不使用临时变量。如:
add_
、sun_
、mul_
等
广播机制
当两个张量的形状不一样时,PyTorch 会“自动扩展它们”,让它们能正常进行运算。
满足条件:其中有一个值为1,或者值相等
例子
import torch
x = torch.tensor([10, 20, 30]) # shape = [3]
y = torch.tensor(2) # shape = []
z = x + y
print(z) # 输出:[12, 22, 32]
比较运算
'''比较运算'''
a = torch.rand([2,3])
b = torch.rand([2,3])
print(a)
print(b)
# 比较两个张量中元素是否相等,返回布尔值张量
print(torch.eq(a,b))
# 比较两个张量中所有元素是否不相等,返回布尔值张量
print(torch.equal(a,b))
# 比较两个张量中元素是否不等于,返回布尔值张量
print(torch.ne(a,b))
# 比较两个张量中元素是否大等于,返回布尔值张量
print(torch.ge(a,b))
# 比较两个张量中元素是否小于等于,返回布尔值张量
print(torch.gt(a,b))
# 比较两个张量中元素是否小于,返回布尔值张量
print(torch.le(a,b))
# 比较两个张量中元素是否大于,返回布尔值张量
print(torch.lt(a,b))
排序
'''排序
dim: 指定排序的维度,默认为0
descending: 是否降序排序,默认为False
k: 指定返回前k个元素,默认为None
'''
print("=== 排序 ===")
a = torch.tensor([1, 4, 2, 4,8, 5])
print(a.shape)
print(a.sort())
print(torch.sort(a,dim=0,descending=True))
a= torch.tensor([[1, 4, 2, 4,8, 5],[1, 4, 2, 4,8, 5]])
print(a)
print(a.sort(dim=1,descending=False))
print(a.sort(dim=1,k=1,descending=False))
####三角函数