深度学习导论(2)深度学习案例:回归问题
深度學(xué)習(xí)導(dǎo)論(2)深度學(xué)習(xí)案例:回歸問題
- 問題分析
- 優(yōu)化方法
- 代碼
- 采樣數(shù)據(jù)
- 計算誤差
- 計算梯度
- 梯度更新
- main函數(shù)
- 結(jié)果輸出
這篇文章將介紹深度學(xué)習(xí)的小案例:回歸問題的問題分析、優(yōu)化以及實現(xiàn)代碼。
問題分析
如果只采樣兩個點則會存在較大偏差(如藍色線),為減小估計偏差,可通過采樣多組樣本點:
{(x(1),y(1)),(x(2),y(2)),...,(x(n),y(n))}\{(x^{(1)},y^{(1)}),(x^{(2)},y^{(2)}),...,(x^{(n)},y^{(n)})\}{(x(1),y(1)),(x(2),y(2)),...,(x(n),y(n))}
然后找出一條“最好”的直線,使得它盡可能地讓所有采樣點到該直線的誤差(Error,或損失Loss)之和最小。
如:求出當前模型的所有采樣點上的預(yù)測值wx(i)+bwx^{(i)}+bwx(i)+b與真實值y(i)y^{(i)}y(i)之間差的平方和作為總誤差L:
L=1n∑i=1n(wx(i)+b?y(i))2L=\frac{1}{n}\sum_{i=1}^{n}(wx^{(i)}+b-y^{(i)})^{2}L=n1?i=1∑n?(wx(i)+b?y(i))2
即:均方差誤差(Mean Squared Error,MSE)
優(yōu)化方法
- 最簡單的方法:暴力搜索,隨機試驗
- 常用方法:梯度下降方法(Gradient Descent)
(a)函數(shù)導(dǎo)數(shù)為0的點即為f(x)的駐點(函數(shù)取得極大、極小值時對應(yīng)的自變量點)
(b)函數(shù)的梯度(Gradient)定義為對各個自變量的偏導(dǎo)數(shù)(Partial Derivative)組成的向量
圖中xy平面的紅色箭頭的長度表示梯度向量的模,箭頭的方向表示梯度向量的方向。可以看到,箭頭的方向總是指向當前位置函數(shù)值增速最大的方向,函數(shù)曲面越陡峭,箭頭的長度也就越長,梯度的模也越大。
函數(shù)在各處的梯度方向▽f總是指向函數(shù)值增大的方向,那么梯度的反方向-▽f應(yīng)指向函數(shù)值減少的方向。
按照:
x′=x?η??fx'=x-\eta\cdot\nabla{f}x′=x?η??f
迭代更新x,就能獲得越來越小的函數(shù)值。
代碼
采樣數(shù)據(jù)
import numpy as np# 采樣數(shù)據(jù)data = [] # 保存樣本集的列表for i in range(100): # 循環(huán)采樣100個點x = np.random.uniform(-10., 10.) # 隨機采樣輸入xeps = np.random.normal(0., 0.1) # 采樣高斯噪聲y = 1.477 * x + 0.089 +eps # 得到模型的輸出data.append([x, y]) # 保存樣本點data = np.array(data) # 轉(zhuǎn)換為2D Numpy數(shù)組計算誤差
# 計算誤差def mse(b, w, points):# 根據(jù)當前的 w,b參數(shù)計算均方差損失totalError = 0for i in range(0, len(points)): # 循環(huán)迭代所有點x = points[i, 0] # 獲得 i號點的輸入 xy = points[i, 1] # 獲得 i號點的輸出 y# 計算差的平方,并累加totalError += (y - (w * x + b)) ** 2# 將累加的誤差求平均,得到均方差return totalError / float(len(points))計算梯度
# 計算梯度 # b_current:當前 b的值 # w_current:當前 w的值 # points:樣本點集合 # lr:學(xué)習(xí)率def step_gradient(b_current, w_current, points, lr):# 計算誤差函數(shù)在所有點上的導(dǎo)數(shù),并更新 w,bb_gradient = 0w_gradient = 0M = float(len(points)) # 總樣本數(shù)for i in range(0, len(points)):x = points[i, 0]y = points[i, 1]# 誤差函數(shù)對 b的導(dǎo)數(shù):grand_b = 2(wx+b-y)b_gradient += (2/M) * ((w_current * x +b_current) - y)# 誤差函數(shù)對 w的導(dǎo)數(shù):grand_w = 2(wx+b-y)*xw_gradient += (2/M) * x * ((w_current * x +b_current) - y)# 根據(jù)梯度下降算法更新 w,b,其中l(wèi)r為學(xué)習(xí)率new_b = b_current - (lr * b_gradient)new_w = w_current - (lr * w_gradient)return [new_b, new_w]梯度更新
# 梯度更新def gradient_descent(points, starting_b, starting_w, lr, num_iterations):# 循環(huán)更新 w,b多次b = starting_b # b的初始值w = starting_w # w的初始值# 根據(jù)梯度下降算法更新多次for step in range(num_iterations):# 計算梯度并更新一次b, w = step_gradient(b, w, np.array(points), lr)loss = mse(b, w, points) # 計算當前的均方差,用于監(jiān)控訓(xùn)練進度if step%50 == 0: # 打印誤差和實時的 w,b值print(f"iteration:{step}, loss:{loss}, w:{w}, b:{b}")return [b, w] # 返回最后一次的 w,bmain函數(shù)
# main函數(shù) if __name__ == '__main__':# 加載訓(xùn)練集數(shù)據(jù),這些數(shù)據(jù)是通過真實模型添加觀測誤差采樣得到的lr = 0.01 # 學(xué)習(xí)率initial_b = 0 # 初始化 b為 0initial_w = 0 # 初始化 w為 0num_iterations = 1000# 訓(xùn)練優(yōu)化1000次,返回最優(yōu) w*,b*和訓(xùn)練 Loss的下降過程[b, w] = gradient_descent(data, initial_b, initial_w, lr, num_iterations)losses = gradient_descent(data, initial_b, initial_w, lr, num_iterations)loss = mse(b, w, data) # 計算最優(yōu)數(shù)值解 w,b上的均方差print(f'Final loss:{loss}, w:{w}, b:{b}')結(jié)果輸出
結(jié)果輸出如下圖所示:
在上述迭代過程中,迭代次數(shù)與均方差誤差MSE之間的關(guān)系如下圖:
由上圖可以看出,雖然我們迭代了1000次,但是在100輪左右就已經(jīng)收斂了,設(shè)在第n輪收斂,則我們只需要記錄第n輪時的w和b的值就行,就是我們要求的w和b的值。有了w和b的值后,模型 y=wx+by=wx+by=wx+b就有了。
總結(jié)
以上是生活随笔為你收集整理的深度学习导论(2)深度学习案例:回归问题的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 最受欢迎的豪华中大型SUV 新款宝马X5
- 下一篇: 深度学习导论(3)PyTorch基础