机器学习:梯度下降法,几种实现策略
生活随笔
收集整理的這篇文章主要介紹了
机器学习:梯度下降法,几种实现策略
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
文章目錄
- 梯度下降法
- 目標函數:軟間隔SVM的目標函數
- 第一種:使用誤差最大樣本做梯度下降
- 第二種:隨機選擇一個樣本做梯度下降
- 第三種:使用全部樣本做梯度
- 第四種:min-batch隨機梯度下降
- 第五種:選擇top K個誤差最大的樣本做梯度:
- 第六種:數據歸一化和步長自適應,略。
梯度下降法
梯度下降法是求解***無約束最優化問題***的最常見的手段之一。
所以前面提到的軟間隔SVM里面轉換為hingeloss之后就可以使用梯度下降法實現了。
目標函數:軟間隔SVM的目標函數
對應的目標函數為:
單個樣本的偏導:
針對上述目標函數,介紹一下幾個梯度下降的實現,目的是加深對梯度下降的理解
第一種:使用誤差最大樣本做梯度下降
首先這種做法是耗時而且有問題的,找出誤差最大的樣本,需要預測全體樣本,耗時,誤差最大的樣本一般情況下就是噪聲,誤人子弟。一般啟發式算法不會針對單個樣本來啟發,使用群體來啟發,比如某個屬性來啟發。
import numpy as npclass LinearSVM:def __init__(self):self._w = self._b = Nonedef fit(self, x, y, c=1, lr=0.01, epoch=10000):x, y = np.asarray(x, np.float32), np.asarray(y, np.float32)self._w = np.zeros(x.shape[1])self._b = 0.for _ in range(epoch):self._w *= 1 - lrerr = 1 - y * self.predict(x, True)# 選取誤差最大的樣本用來更新權值idx = np.argmax(err)# 注意即使所有 x, y 都滿足 w·x + b >= 1# 由于損失里面有一個 w 的模長平方# 所以仍然不能終止訓練,只能截斷當前的梯度下降if err[idx] <= 0:continuedelta = lr * c * y[idx]self._w += delta * x[idx]self._b += deltadef predict(self, x, raw=False):x = np.asarray(x, np.float32)y_pred = x.dot(self._w) + self._bif raw:return y_predreturn np.sign(y_pred).astype(np.float32)第二種:隨機選擇一個樣本做梯度下降
class LinearSVM_random_one(LinearSVM):def fit(self, x, y, c=1, lr=0.01, epoch=10000):x, y = np.asarray(x, np.float32), np.asarray(y, np.float32)self._w = np.zeros(x.shape[1])self._b = 0.for _ in range(epoch):self._w *= 1 - lr# 隨機選取 1 個樣本batch = np.random.choice(len(x), 1)x_batch, y_batch = x[batch], y[batch]err = 1 - y_batch * self.predict(x_batch, True)# 正確樣本,直接再挑選樣本if err <= 0:continue# 錯誤樣本,做梯度delta = lr * c * y_batchself._w += delta * x_batchself._b += delta第三種:使用全部樣本做梯度
class LinearSVM_all(LinearSVM):def fit(self, x, y, c=1, lr=0.01, epoch=10000):x, y = np.asarray(x, np.float32), np.asarray(y, np.float32)self._w = np.zeros(x.shape[1])self._b = 0.for _ in range(epoch):self._w *= 1 - lr# 直接使用全部樣本err = 1 - x * self.predict(y, True)if np.max(err) <= 0:continue# err<0的樣本對梯度沒作用因為誤差為0mask = err > 0delta = lr * c * y[mask]self._w += np.mean(delta[..., None] * y[mask], axis=0)self._b += np.mean(delta)第四種:min-batch隨機梯度下降
class LinearSVM_minBatch(LinearSVM):def fit(self, x, y, c=1, lr=0.01, batch_size=128, epoch=10000):x, y = np.asarray(x, np.float32), np.asarray(y, np.float32)batch_size = min(batch_size, len(y))self._w = np.zeros(x.shape[1])self._b = 0.for _ in range(epoch):self._w *= 1 - lr# 隨機選取 batch_size 個樣本batch = np.random.choice(len(x), batch_size)x_batch, y_batch = x[batch], y[batch]err = 1 - y_batch * self.predict(x_batch, True)if np.max(err) <= 0:continuemask = err > 0delta = lr * c * y_batch[mask]self._w += np.mean(delta[..., None] * x_batch[mask], axis=0)self._b += np.mean(delta)第五種:選擇top K個誤差最大的樣本做梯度:
啟發式選擇,又避免了噪點,但是有一點就是耗時,不見得比minBatch好多少。
class LinearSVM_topK(LinearSVM): # 用參數 batch_size 表示 Top n 中的 ndef fit(self, x, y, c=1, lr=0.01, topk=128, epoch=10000):x, y = np.asarray(x, np.float32), np.asarray(y, np.float32)# 如果 batch_size 設得比樣本總數還多、則將其改為樣本總數topk = min(topk, len(y))self._w = np.zeros(x.shape[1])self._b = 0.for _ in range(epoch):self._w *= 1 - lrerr = 1 - y * self.predict(x, True)# 利用 argsort 函數直接取出 Top n# 注意 argsort 的結果是從小到大的,所以要用 [::-1] 把結果翻轉一下batch = np.argsort(err)[-topk:][::-1]err = err[batch]if err[0] <= 0:continue# 注意這里我們只能利用誤分類的樣本做梯度下降# 因為被正確分類的樣本處、這一部分的梯度為 0mask = err > 0batch = batch[mask]# 取各梯度平均并做一步梯度下降delta = lr * c * y[batch]self._w += np.mean(delta[..., None] * x[batch], axis=0)self._b += np.mean(delta)第六種:數據歸一化和步長自適應,略。
總結
以上是生活随笔為你收集整理的机器学习:梯度下降法,几种实现策略的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 机器学习:SVM、软间隔、随机梯度下降S
- 下一篇: 机器学习:SVM算法的对偶形式