從線性迴歸案例理解深度學習思想

我不是主攻人工智能、深度學習方向,可是做爲計算機相關領域的學習者,若是不瞭解下,總以爲已經跟不上時代了,何況,人工智能真的是大勢所趨,學會了,可以嘗試用在不一樣領域。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

訓練結果:

相關文章
相關標籤/搜索