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