pytorch tutorial记录

autograd问题

1. loss.backward(tensor)中的tensor问题

根据tutorial叙述的向量偏导数实际是一个jacobian矩阵,y=f(x),y是m维向量,x是n维向量那么y对x求导数就是m×n的jacobian矩阵

根据链式法则,要求loss对某个参数的偏导就是jacobian矩阵的相乘,backward中输入的tensor就是反向传播过程中第一个偏导数矩阵,至于为什么不默认写成loss.ones_like矩阵,可能是出于其他层面的考虑给出更大的自由度也可能是代码结构的问题

2. 静态图与动态图问题

静态图只关注输入和输出,因此会在计算过程中把中间过程中的内存重复利用,导致中间结果不可见。
同时静态图不可被重复构建,构建完毕后里面的每个tensor的shape等就不能改变否则无法完成整个网络过程,也因为这些特点导致无法使用python原有的控制流逻辑,但是在内存上由于重用中间过程的内存所以内存消耗更小,同时由于静态图无需重复构建反向传播更快

动态图保留python原有的命令式编程特点,因此会消耗更多内存用来保存中间结果。同时由于中间允许使用控制流等会改变执行图结构,所以反向传播的时候必须动态生成DAG,每次调用backward都需要重新构建图。另外注意其为了节省内存,只保留叶子节点的梯度值,为什么不是全部保存一方面可能是为了debug考虑另一方面也可能是中间过程的内存被重复利用算到叶子节点的时候已经没必要再重用所以保留下来了。

3. 梯度消失与梯度爆炸

当小于1的梯度连续相乘时就会造成回传时梯度过小消失
当大于1的梯度连续相乘时就会造成回传时梯度过大模型参数爆炸大Nan
当参数权重过大时也会导致回传时由于loss过大导致模型参数爆炸大Nan

为解决梯度大于小于1的问题,relu使得正区间梯度恒等于1
为解决模型参数过大导致的问题,采用参数正则化惩罚过大参数权值

为解决非线性函数的实际作用区间有限的问题,采用batch normalizationi将非线性函数的输入
归一化到非线性作用区间
但是注意relu并不存在像tanh,sigmoid一样的窄非线性作用区间,但由于relu会有dead neuron的问题,batch normalizatioin能够把一部分输入为0的值拉回来,所以可以保证一定比例的神经元活性

你可能感兴趣的:(deep,learning笔记,神经网络,静态图与动态图,autograd,pytorch)