當在現實生活中的遇到問題時,咱們老是但願找到最佳的解決方案。製造軟件產品也是同樣的道理,最優化的程序纔是最理想的產品。python
最優化意味着得到最佳輸出。它既是一個數學的重要分支,也在現實生活中有着重要的做用。現代的計算機科學和人工智能科學把最優化做爲一個重要的領域來研究。咱們也認爲人工智能的一些算法,就是模擬了人類尋求實際問題最優解的過程。例如,利用人工智能算法設計軟件,配合外部的電子設備例如攝像頭識別人臉;利用數據挖掘和神經網絡算法來尋找投資的最佳時機等等,都是利用了最優化的原理。算法
機器學習中的最優化和其餘學科的應用比起來有輕微的差別。通常來講,在優化的同時,咱們確切地知道數據的外觀以及咱們想要改進的地方。 可是在機器學習中,咱們不知道「新數據」是怎麼樣的,更別提對其進行優化了。爲了解決這個問題,在機器學習中,咱們對訓練數據(training data)執行優化,並檢查由此新創造出的驗證數據(validation data)。bash
最優化的普遍應用網絡
許多流行的機器算法都依賴於線性迴歸,k最近鄰,神經網絡等技術。優化的應用是無限的,所以它成爲了學術界和工業界普遍研究的課題。在本文中,咱們將介紹一種稱爲梯度降低(Gradient Descent)的優化技術。 這是機器學習時最經常使用的優化技術。app
1.什麼是梯度降低?機器學習
咱們來看一下經典的爬山示例:假設你在山頂,你必須到達山谷最低點的一個湖。 可是你被矇住眼睛,看不到你的目標。 那麼,你會採起什麼方法到達湖邊?函數
最簡單的方法是檢查你附近的地面,找到土地向下傾斜的方向。 這是你該邁出第一步的方向。 沿着下坡路線一直走,頗有可能你會到達湖泊。下圖表示你走過的路:
學習
如今咱們來用數學術語來描述一下這個場景。
測試
假設咱們想要找出學習算法的最佳參數(θ0)和(θ1)。與上面的爬山示例相似,當咱們繪製成本空間J(θ)函數的3D圖像時發現了相似的山脈和山谷。當z軸表明成本J(θ),x軸和z軸分別對應參數θ0和θ1時,丘陵由紅色地區表明成本高,而山谷以藍色地區表明成本低。成本空間不過是算法在某個參數選擇特定值時的表現。優化
如今主要有兩種類型的梯度降低算法:
1.1 數據攝入基準法
全批梯度降低算法一次使用全部數據來計算梯度,而隨機梯度降低算法能夠在計算梯度時進行採樣。
1.2 分化技巧基準法
梯度降低須要經過成本函數J(θ)的微分方程來計算梯度。咱們可使用一階微分或二階微分。
2.執行梯度降低法所面臨的挑戰
梯度降低是一種適用於大多數狀況的技術。但也有時候梯度降低也不能正常工做,或徹底不能工做。發生這種狀況時有三個主要緣由:
2.1 來自數據的挑戰
2.2 來自梯度的挑戰
2.3 來自實際應用難度的挑戰
3.梯度降低算法的變體
最經常使用的梯度降低算法及其實施。
3.1 Vanilla(香草)梯度降低法
這是梯度降低技術的最簡單形式。香草意味着純粹/沒有任何摻假。其主要特色是經過採用成本函數的梯度向最小值方向不斷邁出小步。它的僞代碼以下:
update = learning_rate * gradient_of_parameters
parameters = parameters - update複製代碼
咱們經過獲取舊參數的梯度來不斷更新參數。把它乘以一個學習速率(learning_rate,一個常數),代表咱們想要達到最低點的速度。學習速率是一個超參數(hyper-parameter),在選擇它的大小時應該十分當心謹慎。
3.2動量梯度降低(Gradient Descent with Momentum)
經過調整Vanilla算法,能夠在每次進行下一步以前注意前一步驟。
update = learning_rate * gradient
velocity = previous_update * momentum
parameter = parameter + velocity – update
複製代碼
在這裏,update與香草梯度降低法相同。 可是引入了一個名爲velocity的新術語,它考慮了以前的update和一個稱爲momentum的常量。
3.3 Adagrad
Adagrad使用自適應技術進行學習速率的更新。 這個算法根據之前全部迭代的梯度變化狀況來改變學習速率。僞代碼以下:
grad_component = previous_grad_component + (gradient * gradient)
rate_change = square_root(grad_component)+epsilon
adapted_learning_rate = learning_rate * rate_change
update = adapted_learning_rate * gradient
parameter = parameter – update
複製代碼
其中,epsilon是一個常量,用於保持學習速率的變化率。
3.4 Adam
Adam是一種基於Adagrad的自適應技術,進一步緩解了它的不足。 換句話說,它就是 Momentum + Adagrad。僞代碼以下:
adapted_gradient = previous_gradient +
((gradient – previous_gradient) * (1 – beta1))
gradient_component = (gradient_change – previous_learning_rate)
adapted_learning_rate = previous_learning_rate +
(gradient_component * (1 – beta2))
update = adapted_learning_rate * adapted_gradient
parameter = parameter – update
複製代碼
其中,beta1和beta2是常量,用於檢查梯度和學習速率的變化。
4.梯度降低算法的實際應用
使用python進行梯度降低的基本應用。
接下來咱們使用梯度降低優化來找到深度學習模型的最佳參數,並將其用於圖像識別問題。 咱們的問題是:識別來自給定的28×28圖像裏的數字。準備的圖片中,有一部分圖像用於訓練,其他部分用於測試模型。
以下是定義Vanilla梯度降低的主要代碼:
params = [weights_hidden, weights_output, bias_hidden, bias_output]
def sgd(cost, params, lr=0.05):
grads = T.grad(cost=cost, wrt=params)
updates = []
for p, g in zip(params, grads):
updates.append([p, p - g * lr])
return updates
updates = sgd(cost, params)
複製代碼
咱們來拆分理解一下這段代碼。定義函數sgd做爲cost,params和lr的因變量,它和如前所述的J(θ)同出一轍;而以前的θ0,θ1在這裏是深度學習算法的參數和學習速率。 咱們將默認學習速率設置爲0.05,但該值可隨時被更改。
def sgd(cost, params, lr=0.05):
複製代碼
而後咱們定義了關於成本函數J(θ)的參數的梯度。 在這裏,咱們使用theano庫來找到相應梯度,而且咱們將theano做爲T導入
grads = T.grad(cost=cost, wrt=params)
複製代碼
最後把全部可能的參數更新,這裏應使用Vanilla梯度降低。
for p, g in zip(params, grads):
updates.append([p, p - g * lr]
複製代碼
咱們可使用這個函數來爲神經網絡找到最佳參數。 在使用這個函數時,該神經網絡出色地完成了任務,以下所示:
Prediction is: 8
複製代碼
在這個應用中,梯度降低法爲深度學習算法找到了最優參數。
5.應用梯度降低的實用技巧
上面提到的每一個梯度降低算法都有其優勢和缺點。下面的一些小提示可能會幫助您選擇正確的算法。
神經網絡沒法成功學習的緣由有不少。可是若是能夠找到算法出錯的地方,對將來的工做仍是很是有幫助的。
在應用梯度降低法時,有如下幾點常見注意事項:
但願您閱讀本文後,將熟練掌握有關梯度降低及其變體的基礎知識。但願你以爲我對這些算法的實際應用的解讀也有所幫助!