![v2-cff86b32219cf1fd551edf7f99883e47_1440w.jpg?source=172ae18b](http://img-02.proxy.5ce.com/view/image?&type=2&guid=79c523fa-e32e-eb11-8da9-e4434bdf6706&url=https://pic1.zhimg.com/v2-cff86b32219cf1fd551edf7f99883e47_1440w.jpg?source=172ae18b)
Pytorch中是根据前向传播生成计算图的,如果最终生成的函数是标量,那么这是一般情况下的backward反向传播,但是事实上backward中有个retain_graph和create_graph参数,这2个参数有什么用其实其他地方已经有些比较好的介绍了,这里再详细记录下,首先是一般的情况:
import
实际运算:
![v2-37bee3f9ddf70234742f6e5df7a6d1d8_b.jpg](http://img-03.proxy.5ce.com/view/image?&type=2&guid=79c523fa-e32e-eb11-8da9-e4434bdf6706&url=https://pic1.zhimg.com/v2-37bee3f9ddf70234742f6e5df7a6d1d8_b.jpg)
这里z是一个scalar,比较简单
接下来稍微改变一下上面的函数:
x
可以看到,提示标量输出才能反向求导。
解决方法:为backward添加一个tensor参数:
z
![v2-da9dc1094a72e7efe269b281785ae057_b.jpg](http://img-02.proxy.5ce.com/view/image?&type=2&guid=79c523fa-e32e-eb11-8da9-e4434bdf6706&url=https://pic4.zhimg.com/v2-da9dc1094a72e7efe269b281785ae057_b.jpg)
至于为什么添加张量[1,1,1],其实添加的这个tensor是待求得x得梯度的系数,所以如果我改变一下[10,10,10]
z
。。。
最后一个稍微复杂点的:
先看下我先定义的函数的手算:
![v2-486af65c4b623476a4cf4e5f1ba3ad9d_b.jpg](http://img-02.proxy.5ce.com/view/image?&type=2&guid=79c523fa-e32e-eb11-8da9-e4434bdf6706&url=https://pic2.zhimg.com/v2-486af65c4b623476a4cf4e5f1ba3ad9d_b.jpg)
雅可比矩阵也算好了
看下代码运行:
x
为什么是这样呢?前面没有交叉项的时候其实是雅可比矩阵的正对角线,传入的系数是分别对应x1,x2,x3 3个梯度的系数,且只需要一步求导即可,这里一步求导是求不了的,分为3次,每一次求一列,如第一次传入[1,0,0],那么另外2列系数为0,相当于暂时忽略掉,同样的第二次传入[0,1,0],那么另2列为0被忽略掉。
这么处理可能就是为了要处理高维下的求导吧!!!
接下来有2个地方要注意:
1.create_graph = True or retain_graph = True,该2个参数默认都为False,随便修改哪个都行,而且除了最后一次不要设置之外,前面的反向求导都要设置一下,不设置应该就会忘记了前面的求导结果,即清楚了前面的反向传播计算图
2.每次求导前,要清零,不然会在前面的求导结果上迭代,这里就是
![v2-7b8bcfa7b775176c108c6262d8923143_b.png](http://img-02.proxy.5ce.com/view/image?&type=2&guid=79c523fa-e32e-eb11-8da9-e4434bdf6706&url=https://pic4.zhimg.com/v2-7b8bcfa7b775176c108c6262d8923143_b.png)
终于写完了,