把多元函数的输入看成是状态s,把函数结果看成输出状态s',用numpy表达即为输入输入一些数组,函数本身就是改变状态的机器。
拟求极值得函数是(x-1.3)**2+(y+2.5)**3+3
初始状态为(x,y) = (2.7,2.0),取一个比较靠近极值的点,如果对极值点一无所知,取随机点的话np.random.randn(2)会收敛的很慢。
梯度下降法求极值:
sn = s + deltas(s)
deltas(s) = delta * (-g(s)) #取负梯度
代码如下:
import numpy as np
import matplotlib.pyplot as plt
delta = 0.01
s = np.array((2.7,2.0))
sl = [s]
def z(s):
return (s[0]-1.3)**2+(s[1]+2.5)**3+3
def g(s):
sx = np.array((s[0]+delta,s[1]))
sy = np.array((s[0],s[1]+delta))
return np.array(((z(sx)-z(s))/delta,(z(sy)-z(s))/delta))
def deltas(s):
return delta * (-g(s))
while True:
sn = s + deltas(s)
if np.linalg.norm(sn-s) < 0.00001:break
else:
s = sn
sl.append(s)
print('start parameters :%s ,z is %s \nend parameters :%s ,z is %s'%(sl[0],z(sl[0]),sl[-1],z(sl[-1])))
plt.plot(*zip(*sl))
plt.scatter(*sl[-1])
plt.show()
运行结果为:
start parameters :[2.7 2. ] ,z is 96.085
end parameters :[ 1.295 -2.48697771] ,z is 3.0000272083227912

梯度下降划过的曲线表明函数收敛于1.295,-2.48697771点