神经网络中,一个小的trick有可能让网络performance变得非常好。对于神经网络的理解,我们不应该停留在对于pytorch、tf等的依赖上,他们经常性的考虑到了我们可能出错的地方,并进行了修正,这样反而对我们调试网络,带来了一定的hidden problem。
对于pytorch等开源框架,很多不可导的函数、表达式都可以被写入模型的forward里,比较常见的是maxpooling 和 Relu。所以先举例这两个。
1.max pooling
源码中有一个max_idx_的变量,这个变量就是记录最大值所在位置的,因为在反向传播中要用到,那么假设前向传播和反向传播的过程就如上图所示。同理 mean pooling
这里还要注意的是,x.min,x.max这类值(网络中间层:x)虽然也可以计算梯度,但是对于整张feature map,相当于只有一个点进行了梯度的回传,网络不可能收敛,所以网络千万不要使用这些参数进行约束
2.Relu
relu在x =0的地方没有导数,但是一般框架把这个点的导数用if -else类型语句写出来了,是0或者1(取决于框架)
3. round,ceil
对于这样子的取整函数,事实上也是不可导的,但是框架会将阶跃函数近似为线性函数,可以去参考2值和3值神经网络的论文,大概意思就是把一个台阶近似为一个滑梯。
4.回归初心
其实有个公式是“万能求导公式”:f′(x)=limΔx0[f(x+Δx)−f(x)]/Δxf′(x)=limΔx0[f(x+Δx)−f(x)]/Δx
我没有验证,我只是猜测,很多不可导的点,可能他都是经过这个计算出来的“导数”,因为不管什么函数只要有值(阶跃函数等等),都可以出来一个导数,只是准确性的问题。
reference:
https://blog.csdn.net/qq_21190081/article/details/72871704
https://www.imooc.com/article/details/id/31069