![](https://img-blog.csdnimg.cn/20190224222400437.png)
# coding=gbk
"""
function : f(x,y,z) = (x+y)z
"""
# first method 解析法
def grad1(x,y,z):
dx = z
dy = z
dz = (x+y)
return (dx,dy,dz)
# second method 数值法
def grad2(x,y,z,epi):
# dx
fx1 = (x+epi+y)*z
fx2 = (x-epi+y)*z
dx = (fx1-fx2)/(2*epi)
# dy
fy1 = (x+y+epi)*z
fy2 = (x+y-epi)*z
dy = (fy1-fy2)/(2*epi)
# dz
fz1 = (x+y)*(z+epi)
fz2 = (x+y)*(z-epi)
dz = (fz1-fz2)/(2*epi)
return (dx,dy,dz)
# third method 反向传播法
def grad3(x,y,z):
# forward
p = x+y;
f = p*z;
# backward
dp = z
dz = p
dx = 1 * dp
dy = 1 * dp
return (dx,dy,dz)
print ("<df/dx,df/dy,df/dz>: %.2f %.2f %.2f"%(grad1(1,2,3)))
print ("<df/dx,df/dy,df/dz>: %.2f %.2f %.2f"%(grad2(1,2,3,1e-5)))
print ("<df/dx,df/dy,df/dz>: %.2f %.2f %.2f"%(grad3(1,2,3)))
三种方法的区别:
数值法,通过对自变量的微小变动,来计算其导数;
解析法,计算出导数的表达式;
梯度下降法,已知当前的导数表达式,并计算出当前的导数;
提问1:为何要用梯度下降法,而不是直接使用解析表达式,使其为0?
答:得到解析表达式很容易,使得导数为0 ,这就变成了一个方程式求解问题,计算机并不擅长,而且非常复杂,计算量大,且不好计算,而且会出现无解;而使用梯度下降法,就非常简单,而且计算机是非常擅长优化的;
提问2:为何不使用数值分析法?
答:在参数比较少的情况下,可以使用,但参数极多的情况下,计算量就非常大的;运行效率极差;
提问3:数值分析法有神经网络训练中是否有其地位呢?
答:当自己写梯度计算时,可以用来检验