日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程语言 > python >内容正文

python

梯度、梯度法、python实现神经网络的梯度计算

發布時間:2025/3/12 python 20 豆豆
生活随笔 收集整理的這篇文章主要介紹了 梯度、梯度法、python实现神经网络的梯度计算 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

【機器學習】梯度、梯度法、python實現神經網絡的梯度計算

    • 一、python實現求導的代碼:
    • 二、what is 梯度
    • 三、使用梯度法尋找神經網絡的最優參數
    • 四、神經網絡的梯度計算

一、python實現求導的代碼:

導數含義也就是:變量x一個微小的變化將導致f(x)的值在多大程度上變化。

def numerical_diff(f, x):h = 1e-4return (f(x+h) - f(x-h)) / (2*h)

偏導數怎么求,對哪個變量求偏導,就把其他變量固定為某個值,然后就像求一元函數導數那樣對這個變量求導。

舉個例子,對x0^ 2+x1 ^2=y這個二元函數,求x0=3,x1=4時,對x0的偏導數。

代碼如下:

def numerical_diff(f, x):h = 1e-4return (f(x+h) - f(x-h)) / (2*h)def func_1(x):return x[0]**2+x[1]**2# 求x0=3,x1=4時,x0的偏導數def func_temp1(x0):return x0**2+4**2if __name__ == '__main__':res = numerical_diff(func_temp1,3.0)print(res)

輸出:

6.00000000000378

二、what is 梯度

由全部變量的偏導數匯總而成的向量叫梯度。

求梯度代碼如下:

函數 _numerical_gradient_no_batch 的參數f為函數,x為Numpy數組。

grad = np.zeros_like(x)生成一個形狀和x相同,所有元素均為0的數組,梯度就存到這里面。

這里面fxh1計算的時候,如果在這(x[0],x[1])這一點對x[0]求編導,變的是x[0],x[1]不變。而且對x[1]求偏導的時候,變的是x[1],x[0]不變。所以,要用tmp_val存變化前的數,并且,在求完偏導后把一切恢復。

下面代碼是對x0 ^ 2+x1 ^ 2=y這個二元函數,求點(3,4)處的梯度。

import sys, os sys.path.append(os.pardir) # 為了導入父目錄的文件而進行的設定 import numpy as npdef _numerical_gradient_no_batch(f, x):h = 1e-4 # 0.0001grad = np.zeros_like(x)for idx in range(x.size):tmp_val = x[idx]x[idx] = float(tmp_val) + hfxh1 = f(x) # f(x+h)x[idx] = tmp_val - hfxh2 = f(x) # f(x-h)grad[idx] = (fxh1 - fxh2) / (2 * h)x[idx] = tmp_val # 還原值return graddef func_1(x):return x[0]**2+x[1]**2if __name__ == '__main__':#求點(3,4)處的梯度res = _numerical_gradient_no_batch(func_1, np.array([3.0, 4.0]))print(res)

結果:

[6. 8.]

用python畫很多點的梯度向量,那么就發現一個很神奇的結果:梯度指向函數最小值,離最小值越遠,箭頭越大。

嚴格來講,梯度指示的方向是各點處函數值減小最多的方向。無法保證梯度所指方向就是函數最小值。

雖然梯度的方向不一定指向最小值,但是沿著它的方向能夠最大限度減小函數的值,這就是梯度法

三、使用梯度法尋找神經網絡的最優參數

通過不斷地沿著梯度方向前進,逐漸減小函數值的過程就是梯度法。

梯度法的數學表示:

η表示更新量,在神經網絡的學習中,稱為學習率( learningrate)。學習率決定在一次學習中,應該學習多少,以及在多大程度上更新參數。

這個數學表示是什么意思,其實就是沿著梯度走,如上圖,(x0,x1)取(0,2)時,梯度是(0,4)。這里的x0-η乘f在x0處的偏導,表示沿那個梯度方向走的一小步。學習率小的話,每次走的步子會很小,學習率大的話,步子就大。

用python實現梯度法的代碼如下:

f是要進行最優化的函數, init_x是初始值, lr是學習率, step_num是梯度法的重復次數。

gradient_descent函數里面調用了numerical_gradient函數,用來求函數的梯度。gradient_descent函數里面會一直循環step_num次梯度法,每一次都用梯度乘以學習率得到新值,并更新。最后如果梯度法進行的順利,將走到最小值的位置。

def gradient_descent(f, init_x, lr=0.01, step_num=100):x = init_xx_history = []for i in range(step_num):x_history.append( x.copy() )grad = numerical_gradient(f, x)x -= lr * gradreturn x, np.array(x_history)

下面這個例子,用了梯度法求f(x0,x1)=x0^ 2+x1 ^2的最小值。最終結果接近(0,0),說明我們的結果基本正確,因為最小值確實是在(0,0)點取到。

import numpy as np import matplotlib.pylab as plt from gradient_2d import numerical_gradientdef gradient_descent(f, init_x, lr=0.01, step_num=100):x = init_xx_history = []for i in range(step_num):x_history.append( x.copy() )grad = numerical_gradient(f, x)x -= lr * gradreturn x, np.array(x_history)def function_2(x):return x[0]**2 + x[1]**2init_x = np.array([-3.0, 4.0]) lr = 0.1 step_num = 20 x, x_history = gradient_descent(function_2, init_x, lr=lr, step_num=step_num) print(x)plt.plot( [-5, 5], [0,0], '--b') plt.plot( [0,0], [-5, 5], '--b') plt.plot(x_history[:,0], x_history[:,1], 'o')plt.xlim(-3.5, 3.5) plt.ylim(-4.5, 4.5) plt.xlabel("X0") plt.ylabel("X1") plt.show()

輸出:

[-0.03458765 0.04611686]

學習率取的過大或者過小都無法得到好結果。

對上面代碼進行修改:

學習率過大的話,結果會發散成一個很大的值。

lr = 10 step_num = 100 x, x_history = gradient_descent(function_2, init_x, lr=lr, step_num=step_num) print(x)

結果:

[-2.58983747e+13 -1.29524862e+12]

學習率過小,基本上沒怎么更新就結束了。

lr = 1e-10 step_num = 100 x, x_history = gradient_descent(function_2, init_x, lr=lr, step_num=step_num) print(x)

結果:

[-2.99999994 3.99999992]

四、神經網絡的梯度計算

神經網絡的學習中的梯度,指的是損失函數關于權重參數的梯度。

假設,有一個形狀為2*3的權重W的神經網絡,損失函數是L,下面是該網絡權重和梯度的數學表示。

下面是一個例子,首先要實現一個simpleNet類,這個網絡的權重矩陣是2*3的。

最后輸出的dw如下,這個是梯度。

[[ 0.12894287 0.31807705 -0.44701992][ 0.19341431 0.47711557 -0.67052988]]

比如,如果w11增加h,那么損失函數的值會增加0.47h。從減小損失函數值的觀點看,w11應該向負方向更新。

import sys, os sys.path.append(os.pardir) # 為了導入父目錄中的文件而進行的設定 import numpy as np from common.functions import softmax, cross_entropy_error from common.gradient import numerical_gradientclass simpleNet:def __init__(self):self.W = np.random.randn(2,3)def predict(self, x):return np.dot(x, self.W)def loss(self, x, t):z = self.predict(x)y = softmax(z)loss = cross_entropy_error(y, t)return lossnet = simpleNet() print(net.W) # 權重參數x = np.array([0.6, 0.9])#輸入數據 p = net.predict(x) #由輸入經過神經網絡得到的輸出預測值 print(p) print(np.argmax(p))#最大值的索引t = np.array([0, 0, 1]) # 正確解標簽 print(net.loss(x, t)) #輸出損失函數的值def f(W):return net.loss(x, t) # f = lambda w: net.loss(x, t)dW = numerical_gradient(f, net.W)#求梯度print(dW)

輸出:

[[-0.66110535 -2.3121261 0.61870626][-0.43594672 1.66798289 -1.09922476]] [-0.78901526 0.11390894 -0.61807852] 1 1.366622688011303 [[ 0.12894287 0.31807705 -0.44701992][ 0.19341431 0.47711557 -0.67052988]]

總結

以上是生活随笔為你收集整理的梯度、梯度法、python实现神经网络的梯度计算的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。