# encoding:utf-8
"""
function : f(x,y,z) = (x+y)z
"""
def fun(x,y,z):
return (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 (": %.2f %.2f %.2f"%(grad1(1,2,3)))
print (": %.2f %.2f %.2f"%(grad2(1,2,3,1e-5)))
print (": %.2f %.2f %.2f"%(grad3(1,2,3)))
# 初始值
x0=1;y0=2;z0=3;f0=fun(x0,y0,z0)
计算梯度是为了下降
t0=grad1(x0,y0,z0)
print(t0,f0)
# 第一次迭代:根据初始梯度计算迭代点坐标,并求函数值
x1=x0-t0[0];y1=y0-t0[1];z1=z0-t0[2];f1=fun(x1,y1,z1)
t1=grad1(x1,y1,z1)
print(t1,f1)
# 第二次迭代:根据第一次的坐标,计算迭代点做表,并求函数值
x2=x1-t1[0];y2=y1-t1[1];z2=z1-t1[2];f2=fun(x2,y2,z2)
t2=grad1(x2,y2,z2)
print(t2,f2)
# 以此类推,,,,迭代n次之后,求出函数值序列的最小值,就是最优值,最优值所使用的坐标就是最优坐标。
# 值得一提的是:1.理论上梯度下降法无法保证绝对最优,只能保证局部最优;
# 2.要适度设置学习速率,若学习速率过大,可能导致无法收敛的结局。但是学习速率过小运算速度会非诚的慢。
# 3.如果是求最大值,可以通过加一个负号把它变成求最小值问题。得到最优解后,再求反即是最优解。
def fun1(x,y):
return x**2+y**2
print('--'*10)
def grad4(x,y):
dx=2*x
dy=2*y
return(dx,dy)
def die_one(x,y,apha):
#梯度
t=grad4(x,y)
# 下降
x=x-apha*t[0];y=y-apha*t[1]
return fun1(x,y),(x,y)
算法
def die_(x,y,num,apha):
li=[]
for i in range(num):
resu=die_one(x,y,apha)
li+=[resu[0]]
x,y=resu[1]
return round(min(li),2),resu[1]
r=die_(100,100,10000,0.01)
print(r[0],r[1])
https://blog.csdn.net/li_wen01/article/details/73222657