先写一下自己的理解,其实就是说y=f(x),这里的y和x都是向量哈
y对于x的导数J其实是一个雅克比矩阵,而pytorch里其实求的是vector-Jacobian product
即 ,其中是列向量
详解Pytorch 自动微分里的(vector-Jacobian product)
数学,人工智能,经典文学
是Pytorch的重型武器之一,理解它的核心关键在于理解vector-Jacobian product
以三维向量值函数为例:
按Tensor, Element-Wise机制运算,但实际上表示的是:
对 的导数不是 而是一个 矩阵(因为 是向量,不是一维实数):
其中 ,它是关于 的函数,而不仅仅只是关于 ,这儿的
特殊性是由Element-Wise运算机制引起的, 同理 。
而 对每一个分量 的导数(变化率)是, 各个分量函数 对 的偏导数
沿某一方向 的累积, 一般的, 的默认方向是 。
当然,您也可以传入不同的方向进去,就是官方文档声称的可easy feed external gradient。
这儿,
我们可以将其理解为:关于 的偏导数向量在 方向上的投影;
也可以将其理解为:各个分量函数关于 偏导的权重。
一旦确定,关于每个 的权重就都确定了,而且是一样的。
实验一下:
一 ---简单的隐式Jacobian
>>> x = torch.randn(3, requires_grad = True)
>>> x
tensor([-0.9238, 0.4353, -1.3626], requires_grad=True)
>>> y = x**2
>>> y.backward(torch.ones(3))
>>> x.grad
tensor([-1.8476, 0.8706, -2.7252])
>>> x
tensor([-0.9238, 0.4353, -1.3626], requires_grad=True)
>>>
二 ---简单的显示Jacobian验证
>>> x1=torch.tensor(1, requires_grad=True, dtype = torch.float)
>>> x2=torch.tensor(2, requires_grad=True, dtype = torch.float)
>>> x3=torch.tensor(3, requires_grad=True, dtype = torch.float)
>>> y=torch.randn(3) # produce a random vector for vector function define
>>> y[0]=x1**2+2*x2+x3 # define each vector function
>>> y[1]=x1+x2**3+x3**2
>>> y[2]=2*x1+x2**2+x3**3
>>> y.backward(torch.ones(3))
>>> x1.grad
tensor(5.)
>>> x2.grad
tensor(18.)
>>> x3.grad
tensor(34.)
上面代码中 矩阵为:
各分量函数为分别为:
投影方向:
代码结果与分析相互印证
三---投影到不同的方向
先分析:
再代码验证:
>>> x1=torch.tensor(1, requires_grad=True, dtype = torch.float)
>>> x2=torch.tensor(2, requires_grad=True, dtype = torch.float)
>>> x3=torch.tensor(3, requires_grad=True, dtype = torch.float)
>>> y=torch.randn(3)
>>> y[0]=x1**2+2*x2+x3
>>> y[1]=x1+x2**3+x3**2
>>> y[2]=2*x1+x2**2+x3**3
>>> v=torch.tensor([3,2,1],dtype=torch.float)
>>> y.backward(v)
>>> x1.grad
tensor(10.)
>>> x2.grad
tensor(34.)
>>> x3.grad
tensor(42.)
吻合!
总结
- 既然 是权重或向量函数的投影方向,它的大小就必须与向量函数的个数对应
- 如果最后的函数值是标量,则说明“向量函数”只有一个, 可以不传值,默认为