偏導數:就是對函式的兩個未知數求微分
然後得到的函式
例如乙個函式為y=x12+x22+2x1x2
d(y)/d(x1)=2x1+2x2
d(y)/d(x2)=2x2+2x1
學習率:
也稱為迭代的步長,優化函式的梯度是不斷變化的,有時候變化很大,有時候變化很小,所以需要將每次的梯度變化控制在乙個合適的範圍內。
梯度:梯度其實就是函式的變化率,在多元函式中,梯度變為了向量,有了變化的方向。
梯度的方向表示的是函式增加最快的方向。
梯度下降法求解,首先就要求得所給定函式的偏導數,即y對x1和x2的微分函式,規定學習率,給定一組初始值,然後計算梯度函式,使用迭代公式更新迭代一次後的函式未知數的值,然後計算出迭代後的梯度函式,將原梯度函式的值與迭代後的梯度函式的值的差值進行判斷,判斷差值是否收斂,若收斂,就停止演算法,否則,就重複之前的迭代。
1、首先匯入需要的庫並設定字符集
import numpy as np
import matplotlib as mpl
import matplotlib.pyplot as plt
from mpl_toolkits.mplot3d import axes3d
# 設定字符集,防止中文亂碼
mpl.rcparams['font.sans-serif'] = [u'simhei']
mpl.rcparams['axes.unicode_minus'] = false
2、對函式用matlab進行顯示
#定義要求極值的函式表示式
def f2(x1,x2):
return x1**2+2*x2**2-4*x1-2*x1*x2
x1 = np.arange(0,5,0.1)
x2 = np.arange(0,5,0.1)
x1, x2 = np.meshgrid(x1, x2) # 生成xv、yv,將x1、x2變成n*m的矩陣,方便後面繪圖
y = np.array(list(map(lambda t : f2(t[0],t[1]),zip(x1.flatten(),x2.flatten()))))
y.shape = x1.shape
%matplotlib inline
#作圖fig = plt.figure(facecolor='w')
ax = axes3d(fig)
ax.plot_su***ce(x1,x2,y,rstride=1,cstride=1,cmap=plt.cm.jet)
ax.set_title(u'$ y = x1^2 +2x2^2-4x1-2x1x2 $')
plt.show()
顯示為:
3、用梯度下降法求解函式極值,要求對應x1和x2的偏導數
#函式
def f2(x, y):
return x**2+2*y**2-4*x-2*x*y
## 求兩個未知數對於函式的偏導數
def hx1(x, y):
return 2*x-2*y-4
def hx2(x, y):
return -2*x+4*y
4、定義初值和學習率,然後運用陣列儲存梯度下降後所經過的點
#學習率
alpha = 0.1
#儲存梯度下降經過的點
gd_x1 =
gd_x2 =
gd_y =
# 定義y的變化量和迭代次數
y_change = 0-f2(x1,x2)
iter_num = 0
5、判斷前後兩次迭代的y值的差值,如果很小表明函式已經收斂了,就可以得出最後的極小值了,然後用matlab顯示出所經過的點,我的圖上經過的點在背面有點兒看不清晰
while(y_change > 1e-10) :
tmp_x1 = x1 - alpha * hx1(x1,x2)
tmp_x2 = x2 - alpha * hx2(x1,x2)
tmp_y = f2(tmp_x1,tmp_x2)
y_change =f2(x1,x2)-tmp_y
x1 = tmp_x1
x2 = tmp_x2
iter_num =iter_num+1
print(u"最終結果為:(%.5f, %.5f, %.5f)" % (x1, x2, f2(x1,x2)))
print(u"迭代過程中x的取值,迭代次數:%d" % iter_num)
print(gd_x1)#列印出迭代的x1的值
# 作圖
fig = plt.figure(facecolor='w',figsize=(20,18))
ax = axes3d(fig)
ax.plot_su***ce(x1,x2,y,rstride=1,cstride=1,cmap=plt.cm.jet)
ax.plot(gd_x1,gd_x2,gd_y,'ko-')
ax.set_xlabel('x')
ax.set_ylabel('y')
ax.set_zlabel('z')
ax.set_title(u'函式;\n學習率:%.3f; 最終解:(%.3f, %.3f, %.3f);迭代次數:%d' % (alpha, x1, x2, f2(x1,x2), iter_num))
plt.show()
牛頓迭代法是一種線性化方法,基本思想就是將非線性方程f(x)=0逐步歸結為某種線性方程來求解。假設f(x)=0有乙個近似根為xk,那麼f(x)就近似等於f(xk)+f』(xk)(x-xk),令該函式為0,就可以求的迭代公式為
xk+1=xk-f(xk)/f』(xk) (k=0,1,2,…)
然後迭代到前後兩個值的差值非常小時,就可以得到f(x)=0的根。
通俗來講就是,給函式乙個x值,然後求得函式在這個點上的切線與x軸的交點,然後將這個交點的x值做為乙個新的初始值再求切線與x軸的交點,直至前後兩個x值的差值非常小,就可以判斷為這個值為函式等於0時的解。
所以用牛頓法解方程時,要先求得函式的微分方程,寫出迭代公式,然後給定乙個初值,將值帶入到迭代公式中,一直求解,直到達到我們所想要的精度。
牛頓迭代法的python實現**:
方程為y=2x3+5x2-x+6
求解y=0的解
#方程為2*x^3+5*x^2-x+6=0
#設初值
x0=-2.5
#為迭代公式
x1=x0-(2*x0*x0*x0+5*x0*x0-x0+6)/(6*x0*x0+10*x0-1)
while abs(x1-x0)>1e-5:
x0=x1
x1=x0-(2*x0*x0*x0+5*x0*x0-x0+6)/(6*x0*x0+10*x0-1)
print(x1)
梯度下降法和牛頓迭代法都要用到迭代公式,並更新x的值,不同的是牛頓迭代法是只有乙個未知數,而梯度下降法中未知數的個數不止乙個。兩種方法都要求這個函式可以微分。牛頓迭代法,有乙個很大的缺陷就是你得大概清楚方程為0的解在哪個範圍,不然隨便乙個初值,可能要成千上萬次迭代,才能得到最終的值,太過於麻煩。所以可以設定一最大個迭代次數,超過了最大迭代次數,判定牛頓迭代法不可應用於該方程的求解,換為其他的方法。
參考部落格:
梯度下降法和牛頓下降法
泰勒公式可以表示為 f boldsymbol boldsymbol f boldsymbol boldsymbol boldsymbol frac boldsymbol boldsymbol boldsymbol o boldsymbol tag 在 2 中 boldsymbol x 1,x n b...
梯度下降法與牛頓法
梯度下降法,是迭代演算法。在求最值時,常常用到。bp網路中,最小化 誤差cost function,求解對應網路中的weights,即可用梯度下降法來更新weights.梯度下降法基本思想 給定乙個函式 f 假設求 f 最大值 最小值 初始化函式上的乙個點,對該點求導,該點往導數的方向 反方向 移動...
梯度下降法與牛頓法
梯度 f 在 0 處的梯度表示f 在點 0 處函式值變化最快的方向。對於凸函式f 來說,沿著負梯度方向尋找可以找到函式的極小值 k 1 k f k k 表示第 k步迭代,表示修正因子 步長 因為梯度方向變化最快,只在區域性有效 如果對於多維情形,表示為 k 1 k f k 其中 k k1,k2,kn...