11.22 深度学习-pytorch自动微分

自动微分模块torch.autograd负责自动计算张量操作的梯度,具有自动求导功能。自动微分模块是构成神经网络训练的必要模块,可以实现网络权重参数的更新,使得反向传播算法的实现变得简单而高效

import torch

1. **张量**

Torch中一切皆为张量,属性requires_grad决定是否对其进行梯度计算。默认是 False,如需计算梯度则设置为True。

2. **计算图**:

torch.autograd通过创建一个动态计算图来跟踪张量的操作,每个张量是计算图中的一个节点,节点之间的操作构成图的边。

3. **反向传播**

使用tensor.backward()方法执行反向传播,从而计算张量的梯度。这个过程会自动计算每个张量对损失函数的梯度。

4. **梯度**

计算得到的梯度通过tensor.grad访问,这些梯度用于优化模型参数,以最小化损失函数。

张量的梯度计算 导数值

使用tensor.backward() 求tensor的导数值 会先求 tensor的导函数 然后带入值 这个tensor 是关于另一个tensor的表达式 原来的tensor是一组数据浮点型 这个tensor是一个函数

创建 原来的tensor时 要设置 requires_grad=True 表示这个tensor要被用于求导 设置了之后 tensor每次参加运算都会被求导一次 吃性能

调用backward 后 原来的tensor 就有个grad属性 这个属性是 导数值

一个 标量映射成另一个标量 对这个映射的结果做反向传播 结果在原来 标量里面

def demo1():

t1= torch.tensor(7.0, requires_grad=True, dtype=torch.float32)

t2= t1**2 + 2 * t1 + 7

t2.backward()

print(t1.grad)

向量的梯度计算

映射的结果必须是一个标量才行 对映射进行一下处理让他为标量 比如求和 或者平均值

def demo2():

torch.manual_seed(666)

t1=torch.rand(20,4, requires_grad=True, dtype=torch.float32)

t2= t1**2 + 2 * t1 + 7

t2=t2.sum()

t2.backward()

print(t1.grad) # 返回的是原向量每一个元素的梯度 是一个跟原来向量size一样的tensor

多标量梯度计算 就是映射式子里面有两个未知数 两个变量tensor 就是求了一个偏导

两个变量就都有了grad

def demo3():

t1= torch.tensor(7.0, requires_grad=True, dtype=torch.float32)

t2= torch.tensor(5.0, requires_grad=True, dtype=torch.float32)

t3= t1**2 + 2 * t1 + 7+t2**2

t3.backward()

print(t1.grad)

print(t2.grad)

多向量也差不多不过要先 变为标量

理解 一个tensor 代表一个W tensor里面代表这个W的取值情况 ,然后当这些W取值的时候 Y应该也有个对应的值组成了一个数据集 有x和y的 这样就可以 算梯度了

y.backward()的时候 相当于把y 表达式的 导函数求出来存在y的一个属性里面 然后再把y表达式中的变量的值传进来计算导数 再返回给 变量的grad属性里面

def demo4():

torch.manual_seed(666)

t1=torch.rand(20,4, requires_grad=True, dtype=torch.float32)

torch.manual_seed(3)

t2=torch.rand(20,4, requires_grad=True, dtype=torch.float32)

t3= t1**2 + 2 * t1 + 7+t2**2

t3=t3.sum()

t3.backward()

print(t1.grad)

print(t2.grad)

梯度的上下文控制

梯度计算的上下文控制和设置对于管理计算图、内存消耗、以及计算效率至关重要。下面我们学习下Torch中与梯度计算相关的一些主要设置方式。

映射函数y的requires_grad默认为ture 不用的话占性能 可以手动关了

def demo4():

x=torch.rand(20,4, requires_grad=True, dtype=torch.float32)

使用with语法 torch.no_grad() 关闭梯度 with torch.no_grad(): 局部作用 再with里面所有的torch都没有requires_grad

with torch.no_grad():

y = x**2 + 2 * x + 3 # 没有梯度的y

print(y.requires_grad) # False

或者装饰器也可以

@torch.no_grad()

def test():

y = x**2 + 2 * x + 3 # 没有梯度的y

return y

全局设置 设置了之后后面代码全部都没有梯度了

torch.set_grad_enabled(False)

累积梯度 多次backward 的时候每次给变量返回的导数值 会累加起来 而不是覆盖 因为不管你怎么变y的表达式 都会给y里面的变量 返回个梯度 让他存起来

def demo5():

torch.manual_seed(666)

t1=torch.rand(20,4, requires_grad=True, dtype=torch.float32)

for x in range(3):

t2= t1**2 + 2 * t1 + 7

t2=t2.sum()

t2.backward()

print(t1.grad)

梯度清空 每次backward 把梯度清空了 tensor.grad.zero_()

def demo6():

torch.manual_seed(666)

t1=torch.rand(20,4, requires_grad=True, dtype=torch.float32)

for x in range(3):

t2= t1**2 + 2 * t1 + 7

t2=t2.sum()

if t1.grad != None:

t1.grad.zero_()

t2.backward()

print(t1.grad)

梯度更新 手动

def demo7():

定义初始W 学习率和 训练轮次

torch.manual_seed(666)

w1=torch.rand(3,3,3,requires_grad=True)

torch.manual_seed(6)

w2=torch.rand(3,3,3,requires_grad=True)

print(w1,w2)

lr=0.1

turn=100

开始训练 假设 均方差公式

for x in range(turn):

y=w1**2+w2**2+2*w1+2*w2+100

清空梯度

if w1.grad!=None:

w1.grad.zero_()

if w2.grad!=None:

w2.grad.zero_()

计算梯度

y=y.mean()

y.backward()

得到当前梯度

梯度更新 使用tensor.data

w1.data=w1.data-lr*w1.grad

w2.data=w1.data-lr*w2.grad

得到训练完后的 w值 可以保存 这个时候w有requires_grad=Ture 保存的时候 去掉用detach 下次使用 load出来

print(w1,w2)

torch.save(w1.detach(),"assets/w/w1.plt")

torch.save(w2.detach(),"assets/w/w2.plt")

注意事项

当requires_grad=True时,在调用numpy转换为ndarray时报错

使用detach()方法创建张量的叶子节点即可 tensor.detach().numpy()

detach() 就是原来 requires_grad=Flase的tensor 和原来的tensor 浅拷贝 改一个两个都变

def test():

torch.manual_seed(666)

w1=torch.rand(3,3,3,requires_grad=True)

print(w1)

w2=w1.detach()

print(w2)

w2[:,:,1]=100

print(w1)

print(w2)

if name=="main":

demo1()

demo2()

demo3()

demo4()

demo5()

demo6()

demo7()

test()

相关推荐
scan72411 分钟前
LILAC采样算法
人工智能·算法·机器学习
leaf_leaves_leaf14 分钟前
win11用一条命令给anaconda环境安装GPU版本pytorch,并检查是否为GPU版本
人工智能·pytorch·python
夜雨飘零119 分钟前
基于Pytorch实现的说话人日志(说话人分离)
人工智能·pytorch·python·声纹识别·说话人分离·说话人日志
爱喝热水的呀哈喽34 分钟前
《机器学习》支持向量机
人工智能·决策树·机器学习
minstbe38 分钟前
AI开发:使用支持向量机(SVM)进行文本情感分析训练 - Python
人工智能·python·支持向量机
月眠老师41 分钟前
AI在生活各处的利与弊
人工智能
四口鲸鱼爱吃盐1 小时前
Pytorch | 从零构建MobileNet对CIFAR10进行分类
人工智能·pytorch·分类
苏言の狗1 小时前
Pytorch中关于Tensor的操作
人工智能·pytorch·python·深度学习·机器学习
bastgia2 小时前
Tokenformer: 下一代Transformer架构
人工智能·机器学习·llm
菜狗woc2 小时前
opencv-python的简单练习
人工智能·python·opencv