深度学习19:PyTorch:自动微分模块
发布时间:2026/10/28 1:49:39 锦皓数字建站

目录标题一、概念二、代码三、代码底层涉及内容四、想把其中计算图里面的张量临时拿出来处理五、detach实际应用六、detach vs data 修改数据影响各自原数据的反向传播(但是detach修改微分引擎能发现data却发现不了)一、概念训练神经网络时框架会根据设计好的模型构建一个计算图computational graph来跟踪计算是哪些数据通过哪些操作组合起来产生输出并通过反向传播算法来根据给定参数的损失函数的梯度调整参数模型权重。PyTorch 具有一个内置的微分引擎torch.autograd以支持计算图的梯度自动计算。考虑最简单的单层神经网络具有输入x、参数w、偏置b以及损失函数二、代码importtorch xtorch.tensor(10.0)ytorch.tensor([[3.0]])print(x)print(y)#初始化参数wtorch.rand(1,1,requires_gradTrue)btorch.rand(1,1,requires_gradTrue)#前向传播,得到输出zx*wbprint(z)#查看是否是叶子节点print(x.is_leaf)print(w.is_leaf)print(b.is_leaf)print(y.is_leaf)print(z.is_leaf)#设置损失函数losstorch.nn.MSELoss()loss_valueloss(z,y)print(loss_value)print(loss_value.is_leaf)#反向传播loss_value.backward(retain_graphTrue)print(w.grad)print(b.grad)三、代码底层涉及内容自动微分的关键就是记录节点的数据与运算。数据记录在张量的 data 属性中计算记录在张量的 grad_fn 属性中。计算图根据搭建方式可分为静态图和动态图PyTorch 是动态图机制在计算的过程中逐步搭建计算图同时对每个 Tensor 都存储 grad_fn 供自动微分使用。若设置张量参数 requires_gradTrue则 PyTorch 会追踪所有基于该张量的操作并在反向传播时计算其梯度。依赖于叶子节点的节点requires_grad 默认为 True。当计算到根节点后在根节点调用 backward() 方法即可反向传播计算计算图中所有节点的梯度。非叶子节点的梯度在反向传播之后会被释放掉除非设置参数 retain_graphTrue。而叶子节点的梯度在反向传播之后会保留累积。通常需要使用 optimizer.zero_grad() 清零参数的梯度四、想把其中计算图里面的张量临时拿出来处理前向传播没问题但是反向传播如果某个节点有分支分出来两条路按照全微分公式把两个导数相加有时我们希望将某些计算移动到计算图之外可以使用 Tensor.detach()返回一个新的变量该变量与原变量具有相同的值但丢失计算图中如何计算原变量的信息。换句话说梯度不会在该变量处继续向下传播。代码介绍detachimporttorch xtorch.tensor(2.0,requires_gradTrue)yx.detach()print(x)print(y)print(id(x))print(id(y))print(-------------)#use tensor.untyped_storage() instead of tensor.storage()# print(x.storage().data_ptr())# print(y.storage().data_ptr())#数据共享print(x.untyped_storage().data_ptr())print(y.untyped_storage().data_ptr())tensor(2.,requires_gradTrue)tensor(2.)26547911128002654791113680-------------34084172668803408417266880#分别对x,y进行后续计算z1x**2z2y**2print(z1)print(z2)tensor(4.,grad_fnPowBackward0)tensor(4.)#用sum当损失函数,可以反向传播z1.sum().backward()#z2 报错 element 0 of tensors does not require grad and does not have a grad_fnz2.sum().backward()五、detach实际应用xtorch.ones(2,2,requires_gradTrue)yx*xprint(x)print(y)#分离yuy.detach()tensor([[1.,1.],[1.,1.]],requires_gradTrue)tensor([[1.,1.],[1.,1.]],grad_fnMulBackward0)#让u参与新张量的计算zu*x#反向传播,计算所有梯度z.sum().backward()print(x.grad)print(------------)print(x.gradu)tensor([[1.,1.],[1.,1.]])------------tensor([[True,True],[True,True]])这里u不是3x*2六、detach vs data 修改数据影响各自原数据的反向传播(但是detach修改微分引擎能发现data却发现不了)修改data数据最好只读取不修改自动微分引擎发现不了不会报错修改detach数据最好只读取不修改自动微分引擎会发现会报错
锦
锦皓数字建站
深耕本土企业品牌数字化升级,专注原创端正雅致商务官网,从视觉设计到稳定运维全程保驾护航。