【深度學習DL】二、梯度下降

一氢伟、平方平均誤差

除了對數(shù)損失函數(shù)之外榜轿,還有很多其他誤差函數(shù)都可以應(yīng)用在神經(jīng)網(wǎng)絡(luò)中幽歼。平方平均誤差就是其中一個。從名字可以看出谬盐,它表示預測值和標簽值的差的平方的平均值甸私。

二、學習權(quán)重

你了解了如何使用感知器來構(gòu)建 AND 和 XOR 運算飞傀,但它們的權(quán)重都是人為設(shè)定的皇型。如果你要進行一個運算,例如預測大學錄取結(jié)果砸烦,但你不知道正確的權(quán)重是什么弃鸦,該怎么辦?你要從樣本中學習權(quán)重外冀,然后用這些權(quán)重來做預測寡键。

要了解我們將如何找到這些權(quán)重,可以從我們的目標開始考慮雪隧。我們想讓網(wǎng)絡(luò)做出的預測與真實值盡可能接近西轩。為了能夠衡量,我們需要有一個指標來了解預測有多差脑沿,也就是誤差(error)藕畔。一個普遍的指標是誤差平方和 sum of the squared errors (SSE)

{E = \frac{1}{2}\sum_\mu \sum_j \left[ y^{\mu}_j - \hat{y} ^{\mu} _j \right]^2}

這里 {\hat y }預測值{ y}真實值庄拇。一個是所有輸出單元 j 的和注服,另一個是所有數(shù)據(jù)點{ \mu}的和。這里看上去很復雜措近,但你一旦理解了這些符號之后溶弟,你就能明白這是怎么回事了。

首先是內(nèi)部這個對 {j }的求和瞭郑。變量 {j}代表網(wǎng)絡(luò)輸出單元辜御。所以這個內(nèi)部的求和是指對于每一個輸出單元,計算預測值 {\hat y }與真實值 {y }之間的差的平方,再求和。

另一個對 {\mu}的求和是針對所有的數(shù)據(jù)點唯咬。也就是說,對每一個數(shù)據(jù)點寄疏,計算其對應(yīng)輸出單元的方差和,然后把每個數(shù)據(jù)點的方差和加在一起。這就是你整個輸出的總誤差。

SSE 是一個很好的選擇有幾個原因:誤差的平方總是正的剖效,對大誤差的懲罰大于小誤差。同時,它對數(shù)學運算也更友好贱鄙。

回想神經(jīng)網(wǎng)絡(luò)的輸出劝贸,也就是預測值,取決于權(quán)重
{\hat{y}^{\mu}_j = f \left( \sum_i{ w_{ij} x^{\mu}_i }\right) }

相應(yīng)的逗宁,誤差也取決于權(quán)重
{E = \frac{1}{2}\sum_\mu \sum_j \left[ y^{\mu}_j - f \left( \sum_i{ w_{ij} x^{\mu}_i }\right) \right]^2}
我們想讓網(wǎng)絡(luò)預測的誤差盡可能小,權(quán)重是讓我們能夠?qū)崿F(xiàn)這個目標的調(diào)節(jié)旋鈕梦湘。我們的目的是尋找權(quán)重 {w_{ij}}使得誤差平方 {E} 最小瞎颗。通常來說神經(jīng)網(wǎng)絡(luò)通過梯度下降來實現(xiàn)這一點。

三捌议、梯度下降

用梯度下降哼拔,我們通過多個小步驟來實現(xiàn)目標。在這個例子中瓣颅,我們希望一步一步改變權(quán)重來減小誤差倦逐。借用前面的比喻,誤差就像是山宫补,我們希望走到山下檬姥。下山最快的路應(yīng)該是最陡峭的那個方向,因此我們也應(yīng)該尋找能夠使誤差最小化的方向粉怕。我們可以通過計算誤差平方的梯度來找到這個方向健民。

梯度改變率或者斜度的另一個稱呼。如果你需要回顧這個概念贫贝,可以看下可汗學院對這個問題的講解秉犹。

要計算變化率,我們要轉(zhuǎn)向微積分稚晚,具體來說是導數(shù)崇堵。一個函數(shù) {f(x)}的導函數(shù){f'(x)} 給到你的是{f(x)}{x}這一點的斜率。例如 {x^2} 客燕,{x^2}的導數(shù)是 {f'(x) = 2x}鸳劳。所以,在{x = 2}這個點斜率 {f'(2) = 4}幸逆。畫出圖來就是:

梯度示例.png

梯度就是對多變量函數(shù)導數(shù)的泛化棍辕。我們可以用微積分來尋找誤差函數(shù)中任意一點的梯度,它與輸入權(quán)重有關(guān)还绘,下一節(jié)你可以看到如何推導梯度下降的步驟楚昭。

下面我畫了一個擁有兩個輸入的神經(jīng)網(wǎng)絡(luò)誤差示例,相應(yīng)的拍顷,它有兩個權(quán)重抚太。你可以將其看成一個地形圖,同一條線代表相同的誤差,較深的線對應(yīng)較大的誤差尿贫。

每一步电媳,你計算誤差和梯度,然后用它們來決定如何改變權(quán)重庆亡。重復這個過程直到你最終找到接近誤差函數(shù)最小值的權(quán)重匾乓,即中間的黑點。

梯度下降到最小誤差

注意事項

因為權(quán)重會走向梯度帶它去的位置又谋,它們有可能停留在誤差小拼缝,但不是最小的地方。這個點被稱作局部最低點彰亥。如果權(quán)重初始值有錯咧七,梯度下降可能會使得權(quán)重陷入局部最優(yōu),例如下圖所示任斋。

梯度下降引向局部最低點

有方法可以避免這一點继阻,被稱作 momentum.

四、梯度下降的實現(xiàn)

簡單神經(jīng)網(wǎng)絡(luò)輸出結(jié)果的過程
1.誤差平方和 :The sum of the squared errors(SSE)

{E = \frac{1}{2}\sum_\mu \sum_j \left[ y^{\mu}_j - \hat{y} ^{\mu} _j \right]^2}
{\hat{y}^{\mu}_j = f \left( \sum_i{ w_{ij} x^{\mu}_i }\right) }
{E = \frac{1}{2}\sum_\mu \sum_j \left[ y^{\mu}_j - f \left( \sum_i{ w_{ij} x^{\mu}_i }\right) \right]^2}

  • {\mu}表示全體數(shù)據(jù)
  • {x}表示輸入值
  • {y}表示目標值

誤差平方和用于衡量預測效果废酷,值越高瘟檩,預測效果越差;值越低锦积,預測效果越好芒帕。從上面的公式可以看出權(quán)重{w}是誤差函數(shù)的參數(shù),因此丰介,權(quán)重可以當作控制旋鈕用來調(diào)整預測值背蟆,從而最終影響整體誤差。我們的目標是求取能使誤差最小化的權(quán)重值哮幢。

2.計算梯度下降值

{\Delta w = - gradient}

3.更新權(quán)重

{w_i = w_i +\Delta w}
{\Delta w }

權(quán)重delta w計算

權(quán)重delta w計算_多輸出單元

用梯度下降來更新權(quán)重的算法概述:
權(quán)重步長設(shè)定為 0:{ \Delta w_i = 0}
對訓練數(shù)據(jù)中的每一條記錄:
通過網(wǎng)絡(luò)做正向傳播带膀,計算輸出 { \hat y = f(\sum_i w_i x_i) }
計算輸出單元的誤差項(error term) { \delta = (y - \hat y) * f'(\sum_i w_i x_i)}
更新權(quán)重步長{ \Delta w_i = \Delta w_i + \delta x_i}
更新權(quán)重 { w_i = w_i + \eta \Delta w_i / m}。其中 { \eta} 是學習率橙垢,{ m} 是數(shù)據(jù)點個數(shù)垛叨。這里我們對權(quán)重步長做了平均,為的是降低訓練數(shù)據(jù)中大的變化柜某。
重復 { e} 代表{ (epoch)}嗽元。

五、梯度下降:代碼

一個權(quán)重的更新可以這樣計算:

{\Delta w_i = \eta \, \delta x_i}
?
這里 error term {\delta}是指

{\delta = (y - \hat y) f'(h) = (y - \hat y) f'(\sum w_i x_i)}
記住喂击,上面公式中 {(y - \hat y)}是輸出誤差剂癌,激活函數(shù){ f(h)}的導函數(shù)是{f'(h)} ,我們把這個導函數(shù)稱做輸出的梯度翰绊。

# Defining the sigmoid function for activations 
# 定義 sigmoid 激活函數(shù)
def sigmoid(x):
    return 1/(1+np.exp(-x))

# Derivative of the sigmoid function
# 激活函數(shù)的導數(shù)
def sigmoid_prime(x):
    return sigmoid(x) * (1 - sigmoid(x))

# Input data
# 輸入數(shù)據(jù)
x = np.array([0.1, 0.3])
# Target
# 目標
y = 0.2
# Input to output weights
# 輸入到輸出的權(quán)重
weights = np.array([-0.8, 0.5])

# The learning rate, eta in the weight step equation
# 權(quán)重更新的學習率
learnrate = 0.5

# the linear combination performed by the node (h in f(h) and f'(h))
# 輸入和權(quán)重的線性組合
h = x[0]*weights[0] + x[1]*weights[1]
# or h = np.dot(x, weights)

# The neural network output (y-hat)
# 神經(jīng)網(wǎng)絡(luò)輸出
nn_output = sigmoid(h)

# output error (y - y-hat)
# 輸出誤差
error = y - nn_output

# output gradient (f'(h))
# 輸出梯度
output_grad = sigmoid_prime(h)

# error term (lowercase delta)
error_term = error * output_grad

# Gradient descent step 
# 梯度下降一步
del_w = [ learnrate * error_term * x[0],
          learnrate * error_term * x[1]]
# or del_w = learnrate * error_term * x

六佩谷、反向傳播

如何讓多層神經(jīng)網(wǎng)絡(luò)學習呢旁壮?我們已了解了使用梯度下降來更新權(quán)重,反向傳播算法則是它的一個延伸谐檀。以一個兩層神經(jīng)網(wǎng)絡(luò)為例抡谐,可以使用鏈式法則計算輸入層-隱藏層權(quán)重的誤差

要使用梯度下降法更新隱藏層的權(quán)重桐猬,你需要知道各隱藏層節(jié)點的誤差最終輸出的影響麦撵。每層的輸出是由兩層間的權(quán)重決定的,兩層之間產(chǎn)生的誤差溃肪,按權(quán)重縮放后在網(wǎng)絡(luò)中向前傳播厦坛。既然我們知道輸出誤差,便可以用權(quán)重來反向傳播到隱藏層乍惊。

例如,輸出層每個輸出節(jié)點{k}的誤差是 {\delta^o_k}? 放仗,隱藏節(jié)點 {j}的誤差即為輸出誤差乘以輸出層-隱藏層間的權(quán)重矩陣(以及梯度)润绎。

隱藏節(jié)點 j 的誤差

然后,梯度下降與之前相同诞挨,只是用新的誤差:


隱藏節(jié)點 j 的梯度下降

其中 {w_{ij}}是輸入和隱藏層之間的權(quán)重莉撇, {x_{i}}是輸入值。這個形式可以表示任意層數(shù)惶傻。權(quán)重更新步長等于步長乘以輸出層誤差再乘以該層的輸入值棍郎。

反向傳播_隱藏節(jié)點的權(quán)重

現(xiàn)在,你有了輸出誤差银室,{\delta_{output}}涂佃,便可以反向傳播這些誤差了。{V_{in}} 是該層的輸入蜈敢,比如經(jīng)過隱藏層激活函數(shù)的輸出值辜荠。

范例

反向傳播步驟:

  • 計算網(wǎng)絡(luò)輸出誤差
  • 計算輸出層誤差項
  • 用反向傳播計算隱藏層誤差項
  • 計算反向傳播誤差的權(quán)重更新步長

實現(xiàn)反向傳播

現(xiàn)在我們知道輸出層的誤差是
{\delta_k = (y_k - \hat y_k) f'(a_k)}

隱藏層誤差是

{\delta_j = \sum[w_{jk}\delta_k]f'(h_j)}

現(xiàn)在我們只考慮一個簡單神經(jīng)網(wǎng)絡(luò),它只有一個隱藏層和一個輸出節(jié)點抓狭。這是通過反向傳播更新權(quán)重的算法概述:

  • 把每一層權(quán)重更新的初始步長設(shè)置為 0
    • 輸入到隱藏層的權(quán)重更新是 {\Delta w_{ij} }
    • 隱藏層到輸出層的權(quán)重更新是 {\Delta W_j = 0}
  • 對訓練數(shù)據(jù)當中的每一個點
    • 讓它正向通過網(wǎng)絡(luò)伯病,計算輸出 {\hat y}
    • 計算輸出節(jié)點的誤差梯度 {\delta^o = (y - \hat y) f'(z)}這里 {z = \sum_j W_j a_j}是輸出節(jié)點的輸入。
    • 誤差傳播到隱藏層 {\delta^h_j = \delta^o W_j f'(h_j)}
    • 更新權(quán)重步長:
      • {\Delta W_j = \Delta W_j + \delta^o a_j}
      • {\Delta w_{ij} = \Delta w_{ij} + \delta^h_j a_i}
  • 更新權(quán)重, 其中 {\eta} 是學習率否过,{ m } 是數(shù)據(jù)點的數(shù)量:
    • {W_j = W_j + \eta \Delta W_j / m}
    • {w_{ij} = w_{ij} + \eta \Delta w_{ij} / m}
  • 重復這個過程 {e}代午笛。
import numpy as np
from data_prep import features, targets, features_test, targets_test

np.random.seed(21)

def sigmoid(x):
    """
    Calculate sigmoid
    """
    return 1 / (1 + np.exp(-x))


# Hyperparameters
n_hidden = 2  # number of hidden units
epochs = 900
learnrate = 0.005

n_records, n_features = features.shape
last_loss = None
# Initialize weights
weights_input_hidden = np.random.normal(scale=1 / n_features ** .5,
                                        size=(n_features, n_hidden))
weights_hidden_output = np.random.normal(scale=1 / n_features ** .5,
                                         size=n_hidden)

for e in range(epochs):
    del_w_input_hidden = np.zeros(weights_input_hidden.shape)
    del_w_hidden_output = np.zeros(weights_hidden_output.shape)
    for x, y in zip(features.values, targets):
        ## Forward pass ##
        # TODO: Calculate the output
        #(輸入層輸入)*(輸入層到隱藏層的權(quán)重)
        hidden_input = np.dot(x, weights_input_hidden)
        #通過隱藏層的激活函數(shù)計算(隱藏層輸出)
        hidden_output = sigmoid(hidden_input)

        #將隱藏層的輸出,作為(輸出層的輸入)*(隱藏層到輸出層的權(quán)重)苗桂,并通過輸出層的激活函數(shù)求得
        #輸出層的輸出
        output = sigmoid(np.dot(hidden_output,
                                weights_hidden_output))

        ## Backward pass ##
        # TODO: Calculate the network's prediction error
        error = y - output

        # TODO: Calculate error term for the output unit
        output_error_term = error * output * (1 - output)

        ## propagate errors to hidden layer

        # TODO: Calculate the hidden layer's contribution to the error
        #隱藏節(jié)點的誤差即為(輸出誤差)乘以(輸出層-隱藏層間的權(quán)重矩陣)
        hidden_error = np.dot(output_error_term, weights_hidden_output)

        # TODO: Calculate the error term for the hidden layer
        hidden_error_term = hidden_error * hidden_output * (1 - hidden_output)

        # TODO: Update the change in weights
        del_w_hidden_output += output_error_term * hidden_output
        del_w_input_hidden += hidden_error_term * x[:, None]

    # TODO: Update weights
    weights_input_hidden += learnrate * del_w_input_hidden / n_records
    weights_hidden_output += learnrate * del_w_hidden_output / n_records

    # Printing out the mean square error on the training set
    if e % (epochs / 10) == 0:
        hidden_output = sigmoid(np.dot(x, weights_input_hidden))
        out = sigmoid(np.dot(hidden_output,
                             weights_hidden_output))
        loss = np.mean((out - targets) ** 2)

        if last_loss and last_loss < loss:
            print("Train loss: ", loss, "  WARNING - Loss Increasing")
        else:
            print("Train loss: ", loss)
        last_loss = loss

# Calculate accuracy on test data
hidden = sigmoid(np.dot(features_test, weights_input_hidden))
out = sigmoid(np.dot(hidden, weights_hidden_output))
predictions = out > 0.5
accuracy = np.mean(predictions == targets_test)
print("Prediction accuracy: {:.3f}".format(accuracy))


最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末药磺,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子誉察,更是在濱河造成了極大的恐慌与涡,老刑警劉巖,帶你破解...
    沈念sama閱讀 216,372評論 6 498
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異驼卖,居然都是意外死亡氨肌,警方通過查閱死者的電腦和手機,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,368評論 3 392
  • 文/潘曉璐 我一進店門酌畜,熙熙樓的掌柜王于貴愁眉苦臉地迎上來怎囚,“玉大人,你說我怎么就攤上這事桥胞】沂兀” “怎么了?”我有些...
    開封第一講書人閱讀 162,415評論 0 353
  • 文/不壞的土叔 我叫張陵贩虾,是天一觀的道長催烘。 經(jīng)常有香客問我,道長缎罢,這世上最難降的妖魔是什么伊群? 我笑而不...
    開封第一講書人閱讀 58,157評論 1 292
  • 正文 為了忘掉前任,我火速辦了婚禮策精,結(jié)果婚禮上舰始,老公的妹妹穿的比我還像新娘。我一直安慰自己咽袜,他們只是感情好丸卷,可當我...
    茶點故事閱讀 67,171評論 6 388
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著询刹,像睡著了一般谜嫉。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上范抓,一...
    開封第一講書人閱讀 51,125評論 1 297
  • 那天骄恶,我揣著相機與錄音,去河邊找鬼匕垫。 笑死僧鲁,一個胖子當著我的面吹牛,可吹牛的內(nèi)容都是我干的象泵。 我是一名探鬼主播寞秃,決...
    沈念sama閱讀 40,028評論 3 417
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼偶惠!你這毒婦竟也來了春寿?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 38,887評論 0 274
  • 序言:老撾萬榮一對情侶失蹤忽孽,失蹤者是張志新(化名)和其女友劉穎绑改,沒想到半個月后谢床,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 45,310評論 1 310
  • 正文 獨居荒郊野嶺守林人離奇死亡厘线,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,533評論 2 332
  • 正文 我和宋清朗相戀三年识腿,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片造壮。...
    茶點故事閱讀 39,690評論 1 348
  • 序言:一個原本活蹦亂跳的男人離奇死亡渡讼,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出耳璧,到底是詐尸還是另有隱情成箫,我是刑警寧澤,帶...
    沈念sama閱讀 35,411評論 5 343
  • 正文 年R本政府宣布旨枯,位于F島的核電站蹬昌,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏攀隔。R本人自食惡果不足惜凳厢,卻給世界環(huán)境...
    茶點故事閱讀 41,004評論 3 325
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望竞慢。 院中可真熱鬧,春花似錦治泥、人聲如沸筹煮。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,659評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽败潦。三九已至,卻和暖如春准脂,著一層夾襖步出監(jiān)牢的瞬間劫扒,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 32,812評論 1 268
  • 我被黑心中介騙來泰國打工狸膏, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留沟饥,地道東北人。 一個月前我還...
    沈念sama閱讀 47,693評論 2 368
  • 正文 我出身青樓湾戳,卻偏偏與公主長得像贤旷,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子砾脑,可洞房花燭夜當晚...
    茶點故事閱讀 44,577評論 2 353

推薦閱讀更多精彩內(nèi)容