NDArray自动求导

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)>
时间: 2024-11-04 19:00:55

NDArray自动求导的相关文章

『PyTorch』第三弹_自动求导

torch.autograd 包提供Tensor所有操作的自动求导方法. 数据结构介绍 autograd.Variable 这是这个包中最核心的类. 它包装了一个Tensor,并且几乎支持所有的定义在其上的操作.一旦完成了你的运算,你可以调用 .backward()来自动计算出所有的梯度,Variable有三个属性: 访问原始的tensor使用属性.data: 关于这一Variable的梯度则集中于 .grad: .creator反映了创建者,标识了是否由用户使用.Variable直接创建(No

PyTorch 1.0 中文文档:自动求导机制

译者:冯宝宝 本说明将概述autograd(自动求导)如何工作并记录每一步操作.了解这些并不是绝对必要的,但我们建议您熟悉它,因为它将帮助你编写更高效,更清晰的程序,并可以帮助您进行调试. 反向排除子图 每个张量都有一个标志:requires_grad,允许从梯度计算中细致地排除子图,并可以提高效率. requires_grad 只要有单个输入进行梯度计算操作,则其输出也需要梯度计算.相反,只有当所有输入都不需要计算梯度时,输出才不需要梯度计算.如果其中所有的张量都不需要进行梯度计算,后向计算不

第一章基本操作-自动求导

使用目标对象的.backward()进行反向梯度求导 import torch x = torch.randn(3, 4, requires_grad=True) print(x) b = torch.randn(3, 4, requires_grad=True) t = x + b y = t.sum() y.backward() print(b.grad) x = torch.rand(1) b = torch.rand(1, requires_grad=True) w = torch.ra

PyTorch学习之自动求导机制-Volatile标志

修改官方文档的错误 运行官方文档中的代码可能会报错(维度不一致): Traceback (most recent call last): File "<stdin>", line 1, in <module> File "e:\Anaconda3\lib\site-packages\torch\nn\modules\module.py", line 489, in __call__ result = self.forward(*input,

PyTorch入门学习(二):Autogard之自动求梯度

autograd包是PyTorch中神经网络的核心部分,简单学习一下. autograd提供了所有张量操作的自动求微分功能. 它的灵活性体现在可以通过代码的运行来决定反向传播的过程, 这样就使得每一次的迭代都可以是不一样的. Variable类 autograd.Variable是这个包中的核心类. 它封装了Tensor,并且支持了几乎所有Tensor的操作. 一旦你完成张量计算之后就可以调用.backward()函数,它会帮你把所有的梯度计算好. 通过Variable的.data属性可以获取到

matlab求导

在matlab中求导要进行符号运算. >>syms x; >>y = x^cos(x); >>ydot = diff(y, x, 1);%对x求一阶导数 ydot =   x^(cos(x) - 1)*cos(x) - x^cos(x)*log(x)*sin(x) >> y2dot = diff(y, x, 2)%求二阶导数,求n阶导数同理. y2dot =   cos(x)*(x^(cos(x) - 2)*(cos(x) - 1) - x^(cos(x)

[转载]机器学习中常用的矩阵求导公式

原文地址:机器学习中常用的矩阵求导公式作者:MachineLearner 矩阵求导好像读书的时候都没学过,因为讲矩阵的课程上不讲求导,讲求导的课又不提矩阵.如果从事机器学习方面的工作,那就一定会遇到矩阵求导的东西.维基百科上:http://en.wikipedia.org/wiki/Matrix_calculus , 根据Y与X的不同类型(实值,向量,矩阵),给出了具体的求导公式,以及一堆相关的公式,查起来都费劲. 其实在实际的机器学习工作中,最常用到的就是实值函数y对向量X的求导,定义如下(其

矩阵求导

Y = A * X --> DY/DX = A'Y = X * A --> DY/DX = AY = A' * X * B --> DY/DX = A * B'Y = A' * X' * B --> DY/DX = B * A' 于是把以前学过的矩阵求导部分整理一下: 1. 矩阵Y对标量x求导: 相当于每个元素求导数后转置一下,注意M×N矩阵求导后变成N×M了 Y = [y(ij)] --> dY/dx = [dy(ji)/dx] 2. 标量y对列向量X求导: 注意与上面不同

对任意函数求导的sas模拟

*模拟求导 步长一定要比阈值小,才能得出准确的结果; data Derivation (keep=interval slope); * function y = 1/x only concern about x>0; deltaX = 1e-6; *割线变为切线时x1减小的步长; x0 = 2; y0 = 0; %function(y0,x0);*需要求导的点; put y0; slope = 0; *需要求得的斜率,即倒数; interval = 5; *x0与x1的在x轴的间距,也是判定停止