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

  • 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()

你可能感兴趣的:(笔记,pytorch,深度学习,机器学习)