NDArray自动求导

简介: NDArray可以很方便的求解导数,比如下面的例子:(代码主要参考自https://zh.gluon.ai/chapter_crashcourse/autograd.html)  用代码实现如下: 1 import mxnet.

NDArray可以很方便的求解导数,比如下面的例子:(代码主要参考自https://zh.gluon.ai/chapter_crashcourse/autograd.html

 用代码实现如下:

 1 import mxnet.ndarray as nd
 2 import mxnet.autograd as ag
 3 x = nd.array([[1,2],[3,4]])
 4 print(x)
 5 x.attach_grad() #附加导数存放的空间
 6 with ag.record():
 7     y = 2*x**2
 8 y.backward() #求导
 9 z = x.grad #将导数结果(也是一个矩阵)赋值给z
10 print(z) #打印结果
[[ 1.  2.]
 [ 3.  4.]]
<NDArray 2x2 @cpu(0)>

[[  4.   8.]
 [ 12.  16.]]
<NDArray 2x2 @cpu(0)>

 

对控制流求导

NDArray还能对诸如if的控制分支进行求导,比如下面这段代码:

1 def f(a):
2     if nd.sum(a).asscalar()<15: #如果矩阵a的元数和<15
3         b = a*2 #则所有元素*2
4     else:
5         b = a 
6     return b

数学公式等价于:

这样就转换成本文最开头示例一样,变成单一函数求导,显然导数值就是x前的常数项,验证一下:

import mxnet.ndarray as nd
import mxnet.autograd as ag

def f(a):
    if nd.sum(a).asscalar()<15: #如果矩阵a的元数和<15
        b = a*2 #则所有元素平方
    else:
        b = a 
    return b

#注:1+2+3+4<15,所以进入b=a*2的分支
x = nd.array([[1,2],[3,4]])
print("x1=")
print(x)
x.attach_grad()
with ag.record():
    y = f(x)
print("y1=")
print(y)
y.backward() #dy/dx = y/x 即:2
print("x1.grad=")
print(x.grad)


x = x*2
print("x2=")
print(x)
x.attach_grad()
with ag.record():
    y = f(x)
print("y2=")
print(y)
y.backward()
print("x2.grad=")
print(x.grad)
x1=
[[ 1.  2.]
 [ 3.  4.]]
<NDArray 2x2 @cpu(0)>

y1= [[ 2. 4.] [ 6. 8.]] <NDArray 2x2 @cpu(0)>
x1.grad= [[ 2. 2.] [ 2. 2.]] <NDArray 2x2 @cpu(0)>
x2= [[ 2. 4.] [ 6. 8.]] <NDArray 2x2 @cpu(0)>
y2= [[ 2. 4.] [ 6. 8.]] <NDArray 2x2 @cpu(0)>
x2.grad= [[ 1. 1.] [ 1. 1.]] <NDArray 2x2 @cpu(0)>

 

头梯度

原文上讲得很含糊,其实所谓头梯度,就是一个求导结果前的乘法系数,见下面代码:

 1 import mxnet.ndarray as nd
 2 import mxnet.autograd as ag
 3 
 4 x = nd.array([[1,2],[3,4]])
 5 print("x=")
 6 print(x)
 7 
 8 x.attach_grad()
 9 with ag.record():
10     y = 2*x*x
11 
12 head = nd.array([[10, 1.], [.1, .01]]) #所谓的"头梯度"
13 print("head=")
14 print(head)
15 y.backward(head_gradient) #用头梯度求导
16 
17 print("x.grad=")
18 print(x.grad) #打印结果
x=
[[ 1.  2.]
 [ 3.  4.]]
<NDArray 2x2 @cpu(0)>

head= [[ 10. 1. ] [ 0.1 0.01]] <NDArray 2x2 @cpu(0)>
x.grad= [[ 40. 8. ] [ 1.20000005 0.16 ]] <NDArray 2x2 @cpu(0)>

对比本文最开头的求导结果,上面的代码仅仅多了一个head矩阵,最终的结果,其实就是在常规求导结果的基础上,再乘上head矩阵(指:数乘而非叉乘)

 

链式法则

先复习下数学

注:最后一行中所有变量x,y,z都是向量(即:矩形),为了不让公式看上去很凌乱,就统一省掉了变量上的箭头。NDArray对复合函数求导时,已经自动应用了链式法则,见下面的示例代码:

 1 import mxnet.ndarray as nd
 2 import mxnet.autograd as ag
 3 
 4 x = nd.array([[1,2],[3,4]])
 5 print("x=")
 6 print(x)
 7 
 8 x.attach_grad()
 9 with ag.record():
10     y = x**2
11     z = y**2 + y
12 
13 z.backward()
14 
15 print("x.grad=")
16 print(x.grad) #打印结果
17 
18 print("w=")
19 w = 4*x**3 + 2*x
20 print(w) # 验证结果
x=
[[ 1.  2.]
 [ 3.  4.]]
<NDArray 2x2 @cpu(0)>

x.grad= [[ 6. 36.] [ 114. 264.]] <NDArray 2x2 @cpu(0)>
w= [[ 6. 36.] [ 114. 264.]] <NDArray 2x2 @cpu(0)>

 

目录
相关文章
|
23天前
|
存储 机器学习/深度学习 PyTorch
Pytorch-张量形状操作
PyTorch中,张量形状操作至关重要,如reshape用于改变维度而不变元素,transpose/permute用于维度交换,view改形状需内存连续,squeeze移除单维度,unsqueeze添加维度。这些函数帮助数据适应神经网络层间的转换。例如,reshape能调整数据适配层的输入,transpose用于矩阵转置或多维排列,而squeeze和unsqueeze则用于处理单维度。理解并熟练运用这些工具是深度学习中必要的技能。
|
2月前
|
机器学习/深度学习 存储 算法
PyTorch 中的自动求导
PyTorch 中的自动求导
19 0
|
2月前
|
机器学习/深度学习 PyTorch 算法框架/工具
pytorch中非标量调用backward()的时候为什么要先进行sum操作
在《动手学深度学习》第二版教程中,当y为非标量的时候,调用backward()函数时,为什么先要求和呢(即y.sum().backward()),估计很多读者有点懵,今天小编给大家说说我的理解。
199 3
|
8月前
|
PyTorch Serverless 算法框架/工具
Pytorch与autograd自动求导
Pytorch与autograd自动求导
53 0
|
PyTorch 算法框架/工具
torch,如何将两个二维张量,按照第一维度,合并
在这个例子中,torch.cat() 函数的第一个参数是一个列表,包含要拼接的张量 x 和 y,第二个参数是拼接的维度,即第一维度。拼接后的张量 z 的形状为 (6, 4),因为两个原始张量的第一维度都是 3,拼接后就变成了 6。
641 0
|
机器学习/深度学习 算法 数据可视化
梯度下降法的三种形式BGD、SGD以及MBGD
有上述的两种梯度下降法可以看出,其各自均有优缺点,那么能不能在两种方法的性能之间取得一个折衷呢?即,算法的训练过程比较快,而且也要保证最终参数训练的准确率,而这正是小批量梯度下降法(Mini-batch Gradient Descent,简称MBGD)的初衷。
梯度下降法的三种形式BGD、SGD以及MBGD
|
存储 PyTorch 算法框架/工具
pytorch 如何按行计算tensor张量的二范数
在 PyTorch 中,可以使用 torch.norm(input, dim=1) 函数来按行计算张量的二范数。具体来说,input 是一个张量,dim=1 表示按照行的方向计算二范数。
558 0
|
PyTorch 算法框架/工具 索引
pytorch中,假设已经有了一个张量a,现在还有一个张量B,张量B为一维的张量,如何利用B张量的元素作为索引去检索a张量的元素?
可以使用PyTorch的索引操作符[]和张量的gather()方法来利用张量B的元素作为索引来检索张量a的元素。
188 0
|
机器学习/深度学习 PyTorch 算法框架/工具
【26】pytorch中的grad求导说明以及利用backward获取梯度信息
【26】pytorch中的grad求导说明以及利用backward获取梯度信息
324 0
【26】pytorch中的grad求导说明以及利用backward获取梯度信息
|
Python
Numpy向量和矩阵操作
NumPy是Python的一个扩展程序库,支持大量的维度数组与矩阵运算,此外也针对数组运算提供大量的数学函数库。本文介绍Numpy的向量和矩阵操作。
108 0