torch.autograd在写求导代码时,参与计算的非torch.Tensor类型的数值返回梯度只能为None,不可训练参数梯度可以不是None

这篇博客探讨了在PyTorch中使用torch.autograd进行反向传播时,非Variable类型参数和不可训练参数的梯度处理。通过一个自定义的多元函数示例,展示了非Tensor类型参数(如常数a)在backward函数中必须返回None,以及不可训练参数(如x)在反向传播后查询梯度会得到None。同时,博客指出保存中间计算时,所有变量必须为Tensor类型,否则会导致错误。
摘要由CSDN通过智能技术生成
  • torch.autograd在写求导代码时,参与计算的非torch.Tensor类型的数值返回梯度只能为None,并且不可训练参数的梯度可以不为None,但是反向传播后查询其梯度时只有None与之对应,也就是说网络中的一些参数原先可训练但是后来令其不训练之后,可以不改变自己定义的求导函数(backward)中不可训练的参数返回值为None

下面给出例子,其中x为不可求导参数,a为非torch.Tensor的参数
其中:

  1. x可以返回梯度,但是在i.backward()之后,x的梯度查询为None,
  2. a对应的梯度只能为None,如果修改之后会出现以下报错:

Traceback (most recent call last):
File “test.py”, line 41, in
i.backward()
File “/home/skt1faker/anaconda3/lib/python3.8/site-packages/torch/_tensor.py”, line 255, in backward
torch.autograd.backward(self, gradient, retain_graph, create_graph, inputs=inputs)
File “/home/skt1faker/anaconda3/lib/python3.8/site-packages/torch/autograd/init.py”, line 147, in backward
Variable._execution_engine.run_backward(
RuntimeError: function funcBackward returned a gradient different than None at position 4, but the corresponding forward input was not a Variable

大概意思就是参数a不是Variable数据类型的数据!

import torch
from torch.autograd import Function as Function
import math

class func(Function):	# 这是一个多元函数,拥有混合计算

	def __init__(self):
		Function.__init__(self)	
		self.a = 100

	@staticmethod
	def	forward(ctx,x,y,z,const):	# const*xye^z
		
		ctx.save_for_backward(x,y,torch.tensor(math.exp(z)),torch.tensor(const))	# 注意这里只能存储torch.Tensor
		# ctx.save_for_backward(x,y,math.exp(z),torch.tensor(const))	# 注意这里math.exp返回值为float,这里会报错为有变量不是torch.tensor
		"""
		ctx.save_for_backward(x)	
		ctx.save_for_backward(y)	
		ctx.save_for_backward(math.exp(z))	
		ctx.save_for_backward(torch.tensor(const))	
		
		"""		# 注意ctx中的变量只能一次性储存完,如果这样存储的话 只能存储最后一个torch.tensor(const)
		return x*y*math.exp(z)*const

	@staticmethod
	def	backward(ctx, output_grad):

		x,y,ez,const = ctx.saved_tensors			# 后面必须为","
		x_grad = y*ez*const
		y_grad = x*ez*const
		z_grad = x*y*ez*const
		return x_grad*output_grad, y_grad*output_grad, z_grad*output_grad,None # 常数没有导数,设为None


x = torch.tensor(10.)
y = torch.tensor(2., requires_grad = True)
z = torch.tensor(5., requires_grad = True)
a = 10
h = func.apply(x,y,z,a)	# 
i = 10 * h
i.backward()

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值