自动求梯度 讨论区


#21

如果是在pytorch里,会这么解释:对应x作为scalar, 不需要头梯度;对于x作为1d,2d array, 就必须要加;如果加,关于系数,没有要求,只要维度数正确就行


#23

开始我也有和你一样的疑惑,不过跑了代码以后发现,头梯度指的就是系数。 可以跑跑代码,加深记忆。赞同@astonzhang 的观点。


#24

以结果来看头梯度并没有替换x的值,而是在

dz/dy

之前的一个梯度(系数)


#25

当y是一个更大的z函数的一部分,并且我们希望求得dz/dx保存在x.grad中时,我们可以传入头梯度dz/dy的值作为backward()方法的输入参数,系统会自动应用链式法则进行计算。

我认为这边应该说是,当 z 是一个更大的函数 w 的自变量时,我们想利用链式法则,把 dw/dz 延续下去(求得 dw/dx = dw/dz * dz/dy * dy/dx),那么就可以将 dw/dz 的值作为头梯度传入 backward() 中,然后 x.grad 会求得 dw/dx 的值。


#26

关于头梯度与链式法则,其实没有必然联系,原文放在一起讲解,反而容易让新手迷糊。我整理了这块内容的学习笔记,记录在个人博客上了,http://www.cnblogs.com/yjmyzz/p/7783286.html,有需要的可以参考。


#27

跑代码的总结和小问题
1.一定要先为待求导的变量分配存储导数的空间x.attach_grad(),再定义求导函数with ag.record(),不然会报错。我以为定义导函数与为变量的导数分配的顺序先后都没有关系,只要在backward()之前定义就好了。没想到不是的。
2.我将ag.record()里的函数改写了一下,改成z = 2*x*x结果正确,改成y = x * x, z = 2 * y结果就不正确了(x.grad == 4 * x结果为1)。暂时还没有想明白是为什么。那么这里的函数到底要按照什么规则写呢?
3.开始以为with ag.record():是可以重复使用的,后来发现不是,对于同一个变量每次的新数据,都要重新分配存储导数的空间x.attach_grad(),再定义求导函数with ag.record(),再求导数backward()这一系列的程序。
4.尝试学习率0.001, 0.003, 0.006, 0.01, 随着学习率的增长,算法收敛的速度变快,学习率为0.01的时候,在epoch=1的时候算法就收敛了,达到误差率的最小值了。


#28

非常简洁明了,赞!


#29

这个文档写的好,补充一点,dz/dy时,如果z=yx,y=x2,最好将z完全表述为y的表达式再使用链式法则,即z=y*y/2,这样的求导才是全面的,且容易理解


#30

请问一下,在with ag.record(): , nd的哪些操作可以求反向梯度呢?
例如:nd.sum()可以,但是nd.floor()不可以求导。有api可以解释吗?


#31

目前还没有统一标在文档里, floor其实应该可以求导才对,这个我们应该会加的


#32

应该是这样,感觉这种问题应该及时修复,论坛还是蛮有用的:grinning:


#33

round的op的grad修好了 https://github.com/apache/incubator-mxnet/pull/9040, nightly里有


#34

使用autograd.record()和之前的bind相比性能怎么样呢

我看介绍说每次都在后端实时创建计算图


#35

outputs1= [net(X) for X in data]
with autograd.record():
outputs2 = [net(X) for X in data]
为什么output1与output2不同,课程例子中的训练精度是用的output2来计算,而测试精度用的是output1来计算,我的项目中两个精度相差很大,是什么原因?该如何解决?谢谢老师!


#36

正常来说,像教程一样定义符号xyz,清晰明了,没有问题
但若出现

x = nd.array([[1, 2], [3, 4]])
x.attach_grad()
with ag.record():
    x = x * 2  #注意这里
    z = x * x
z.backward()

这时求x.grad还会是原来的x吗?

之所以产生这样的问题是因为,我用RNNCell写了一段程序,其中

# 这里data是sequence输入
for item in data:
    hidden_state, state = RNNCell(item, state)

output = self.FCLayer(hidden_state)
# 后面再output与label做loss,求导 

这里用RNNCell不断覆盖state和hidden_state,是否会对求导产生歧义?


#37

x = x * 2会返回一个新的tensor,并把这个tensor保存在叫做x的变量上

with autograd.record() 里的代码会被默认标记为训练模式,这会影响dropout和batchnorm之类的operator的行为


#38

关于第二点,我测试时可以通过的

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

x = nd.array([[1, 2], [3, 4]])

x.attach_grad()

with ag.record():
    y = x*x 
    z = 2 * y 

z.backward()

print x.grad

#39

是求a的平方和再求根 得出的数乘以系数,直到1000的意思吧


#40

请问一下文章中有写到,‘如果z不是一个标量,那么z.backward()等价于nd.sum(z).backward().’。
那么什么时候是标量,什么时候是向量呢。而且在线性回归的实现中,loss为一个10*1的ndarray,为什么对param的求导是一个只有一个元素的ndarray。
而且文章中w是一个二维的ndarray,这种一对多的求导又是什么意思?


#41

继承 autograd.Function 如何写 softmaxentropy loss?

如果返回两个 ndarray:

class SoftmaxCE(ag.Function):
    name = 'SoftmaxCE'
    def forward(self, pred, label):
        logy = mx.nd.log_softmax(pred, axis=1)
        loss = -mx.nd.pick(logy, label, axis=1)
        self.save_for_backward(pred, mx.nd.exp(logy))
        return loss
    def backward(self, gy):
        v, y = self.saved_tensors
        return y - v, mx.nd.ones(y.shape[0], ctx=y.context)

运行报错如下:

Traceback (most recent call last):
  File "_ctypes/callbacks.c", line 259, in 'converting callback result'
TypeError: an integer is required (got type NoneType)
Exception ignored in: <function Function.__call__.<locals>.backward_entry at 0x7f1dfd7ec7b8>
terminate called after throwing an instance of 'dmlc::Error'
  what():  [18:08:32] src/c_api/c_api_function.cc:111: Check failed: reinterpret_cast<CustomFunctionBwdFunc>( params.info->callbacks[kCustomFunctionBackward])( inputs.size(), outputs.size(), const_cast<NDArrayHandle*>(ptrs.data()), reinterpret_cast<const int*>(req.data()), ctx.is_train, params.info->contexts[kCustomFunctionBackward])

Stack trace returned 7 entries:
[bt] (0) /leuvenfs/tools/Anacoda3/envs/python36/lib/python3.6/site-packages/mxnet/libmxnet.so(+0x2ab998) [0x7f1e255c5998]
[bt] (1) /leuvenfs/tools/Anacoda3/envs/python36/lib/python3.6/site-packages/mxnet/libmxnet.so(+0x2abda8) [0x7f1e255c5da8]
[bt] (2) /leuvenfs/tools/Anacoda3/envs/python36/lib/python3.6/site-packages/mxnet/libmxnet.so(+0x23fb367) [0x7f1e27715367]
[bt] (3) /leuvenfs/tools/Anacoda3/envs/python36/lib/python3.6/site-packages/mxnet/libmxnet.so(+0x3cbf26) [0x7f1e256e5f26]
[bt] (4) /leuvenfs/tools/Anacoda3/envs/python36/bin/../lib/libstdc++.so.6(+0xafc5c) [0x7f1e1177ec5c]
[bt] (5) /lib/x86_64-linux-gnu/libpthread.so.0(+0x76ba) [0x7f1e53b946ba]
[bt] (6) /lib/x86_64-linux-gnu/libc.so.6(clone+0x6d) [0x7f1e538ca41d]


Aborted (core dumped)