我不是主攻人工智能、深度學習方向,可是做爲計算機相關領域的學習者,若是不瞭解下,總以爲已經跟不上時代了,何況,人工智能真的是大勢所趨,學會了,可以嘗試用在不一樣領域。python
本文將使用迴歸的思想來求解二元一次方程的最佳解,理解深度學習的根本思想。網絡
假設,對於二元一次方程:函數
y = a * x + boop
假設咱們可以採集到一組數據(x,y),這些值都是知足以上等式的,可是,現實生活中每每不能這樣順利(若是採集的值是精確值,直接列方程組就能求出a和b),咱們採集到的每組(x,y)都存在必定誤差,因此,現實中採集到的數據應表示爲:學習
y = a * x + b + r人工智能
r表示誤差,這個時候,咱們須要經過這一組數據,來找到一組a和b,使得 y = a * x + b 和理想的狀況越接近。code
爲了方便表示,將r表示爲:get
r = y - (a * x +b)深度學習
由於這個值可能爲負數,因此用r的平方來表示這個誤差,記爲:數學
loss = [ y - (a * x + b)] 2
這裏用loss記,實際上就理解爲模型訓練過程當中的「損失」,咱們須要找到到一組a和b,使得loss最小。
在數學中,咱們會用到極限的思想求解最小值,可是,在深度學習中,是如何找到這個最小loss的呢?
這裏就須要提到梯度降低的思想(這些內容在 《計算方法》 這門學科中有詳細的說明),通俗地理解,在本文的二元一次方程中,就是初始化一個a和b,而後進行必定次數的迭代,在每次迭代中,調整a和b的值。
將loss表示的函數分別對a和b求偏導數:
dei a = 2 * [ y - ( a * x + b ) ] * x
dei b = 2 * [ y - ( a * x + b ) ]
咱們每次調整a和b的值使用以下方法:
new a = a - dei a * learn_rate
new b = b - dei b * learn_rate
實際上,在每輪迭代中,咱們將會用收集到的每組數據都來計算dei a和dei b,最終使用平均值,表示通過這一輪,參數a和b須要被調整的大小。
可是,咱們發現,調整參數的時候,dei a和dei b還分別乘以了一個learn_rate,這個learn_rate在深度學習模型訓練中叫學習率,通常取一個比較小的值,0.00一、0.01等,能夠經過嘗試找到最優的值。若是不乘以learn_rate,對a來講,每次須要調整dei a,這個值是很大的,並且會出現不能收斂的狀況:
從上圖中能夠看到,對同一個loss函數,若是使用0.05的learn_rate,會致使loss在最小值附近波動,不能找到最小值,而使用0.005的學習率,每次調整的範圍更小,且能正確地找到loss的最小值。
經過必定次數的迭代,咱們就能找到一組a和b的值,這組a、b可以使得loss儘量小,甚至爲0,咱們近似認爲這個方程就是理想狀況下的方程:
y = a * x + b
這時,若是給出一個值a1,就能夠根據上式獲得一個y1值,這就是咱們所說的預測值。
這個例子雖然比較簡單,可是包含了深度學習的精髓思想。不管多大的網絡模型、數據量,實際上都是對一組參數不斷地進行調整,使得在這組參數的狀況下,所獲得的一個函數關係,可以讓loss的值儘量小(固然,這種標準能夠根據不一樣需求進行修改),換句話說,就是找到一組參數,使得一個關係式儘量趨近給定的一組數據中的每一個映射關係(數據和標籤的映射),而後再根據這個關係式,對新給定的值,給出相應計算結果,這就是就是預測值。
附,本文涉及的代碼和數據:
import numpy as np ''' y = a*x+b + noise loss = (a*x+b - y)**2 die a = 2(a*x+b-y)*x die b = 2(a*x+b-y) ''' # 計算損失loss,神經網絡模型訓練過程當中,通常會在每一輪都輸出一次,查看訓練效果 def get_loss(a, b, points): sum = 0 for i in points: x = i[0] y = i[1] t = (a * x + b - y) ** 2 sum = sum + t # 由於有多組數據,這裏求平均值,表示當前a,b狀況下,表達式和這組數據的平均誤差 average_loss = sum / float(len(points)) return average_loss # 求梯度,調整a,b的值,這是參數可以被「訓練」的關鍵部分 def step_grad(a, b, learn_rate, points): da_sum, db_sum = 0, 0 for i in points: x = i[0] y = i[1] da_sum = da_sum + 2 * (a * x + b - y) * x db_sum = db_sum + 2 * (a * x + b - y) num = len(points) da = da_sum / float(num) db = db_sum / float(num) # 返回新的a,b return a - learn_rate * da, b - learn_rate * db # totalnum表示總共迭代次數 def loop(a, b, learn_rate, points, totalnum): for i in range(0, totalnum): # 每次迭代都會獲得一組新的a,b,將其做爲下一次迭代的初始值 a, b = step_grad(a, b, learn_rate, points) loss = get_loss(a, b, points) print("after ", totalnum, "times, loss: ", loss) print("a=", a, " b=", b) if __name__ == '__main__': points = np.genfromtxt("data.csv", delimiter=",") # a,b初始化爲0,learn_rate設置爲0.0001,迭代10000次,points理解爲實際狀況中,採集到的數據 loop(0, 0, 0.0001, points, 10000)
csv數據,網盤連接: https://pan.baidu.com/s/1Sknt8dV7kA81IE2ij6bkYw 提取碼: exf2
訓練結果: