SGD優化演算法——提升機器學習模型性能的必備利器

一、什麼是SGD優化演算法

SGD(Stochastic Gradient Descent)優化演算法是機器學習中常用的優化方法,它是一種迭代式的優化方法,用於尋找損失函數的最小值。相較於傳統的梯度下降演算法,SGD每次隨機選擇一個樣本進行迭代,因此可以避免一些複雜的計算量。常見的SGD演算法包括Mini-Batch SGD和普通SGD。

SGD演算法的核心思想是通過不斷的迭代尋找當損失函數的梯度為0時的參數取值,從而實現對模型的優化。在訓練過程中,SGD每次選取一個樣本計算梯度,並根據梯度的方向以一定的步長調節參數,以期逐步降低損失函數的值,直到達到預定的收斂精度。

二、SGD優化演算法的優點

相較於傳統的梯度下降演算法,SGD演算法具有以下優點:

1、節省內存:每次只需要處理一個樣本,可以節省大量的內存空間;

2、處理高維數據效果好:當數據維度比較高時,SGD演算法具有更好的效果;

3、收斂速度快:由於每次迭代只處理一個樣本,因此收斂的速度很快。

三、SGD優化演算法在機器學習中的應用

SGD優化演算法被廣泛應用在機器學習領域,特別是在深度學習中。以下是一些常見的機器學習模型中使用SGD演算法優化的例子:

1、線性回歸模型中的SGD優化器;

class LinearRegression:
    def __init__(self, lr=0.01, num_iter=100000, fit_intercept=True, verbose=False):
        self.lr = lr
        self.num_iter = num_iter
        self.fit_intercept = fit_intercept
        self.verbose = verbose
        
    def __add_intercept(self, X):
        intercept = np.ones((X.shape[0], 1))
        return np.concatenate((intercept, X), axis=1)
    
    def __loss(self, h, y):
        return (1/2*len(y)) * np.sum((h-y)**2)
    
    def fit(self, X, y):
        if self.fit_intercept:
            X = self.__add_intercept(X)
            
        self.theta = np.zeros(X.shape[1])
        
        for i in range(self.num_iter):
            rand_idx = np.random.randint(0, X.shape[0])
            X_i = X[rand_idx,:]
            y_i = y[rand_idx]
            h = np.dot(X_i, self.theta)
            gradient = X_i.T.dot(h-y_i)
            self.theta -= self.lr * gradient
                
            if self.verbose and i % 10000 == 0:
                h = np.dot(X, self.theta)
                print(f'Iteration {i}, loss = {self.__loss(h, y)}')
    
    def predict(self, X):
        if self.fit_intercept:
            X = self.__add_intercept(X)
            
        return np.dot(X, self.theta)

2、邏輯回歸模型中的SGD優化器;

class LogisticRegression:
    def __init__(self, lr=0.01, num_iter=100000, fit_intercept=True, verbose=False):
        self.lr = lr
        self.num_iter = num_iter
        self.fit_intercept = fit_intercept
        self.verbose = verbose
        
    def __add_intercept(self, X):
        intercept = np.ones((X.shape[0], 1))
        return np.concatenate((intercept, X), axis=1)
    
    def __sigmoid(self, z):
        return 1 / (1 + np.exp(-z))
    
    def __loss(self, h, y):
        return (-1/len(y)) * np.sum(y*np.log(h) + (1-y)*np.log(1-h))
    
    def fit(self, X, y):
        if self.fit_intercept:
            X = self.__add_intercept(X)
            
        self.theta = np.zeros(X.shape[1])
        
        for i in range(self.num_iter):
            rand_idx = np.random.randint(0, X.shape[0])
            X_i = X[rand_idx,:]
            y_i = y[rand_idx]
            z = np.dot(X_i, self.theta)
            h = self.__sigmoid(z)
            gradient = X_i.T.dot(h-y_i)
            self.theta -= self.lr * gradient
                
            if self.verbose and i % 10000 == 0:
                z = np.dot(X, self.theta)
                h = self.__sigmoid(z)
                print(f'Iteration {i}, loss = {self.__loss(h, y)}')
    
    def predict_proba(self, X):
        if self.fit_intercept:
            X = self.__add_intercept(X)
            
        return self.__sigmoid(np.dot(X, self.theta))
    
    def predict(self, X, threshold=0.5):
        return self.predict_proba(X) >= threshold

3、神經網路中的SGD優化器。

import numpy as np

def sigmoid(z):
    return 1 / (1 + np.exp(-z))

class NeuralNetwork:
    def __init__(self, lr=0.01, num_iter=100, hidden_size=4, fit_intercept=True, verbose=False):
        self.lr = lr
        self.num_iter = num_iter
        self.fit_intercept = fit_intercept
        self.verbose = verbose
        self.hidden_size = hidden_size
        
    def __add_intercept(self, X):
        intercept = np.ones((X.shape[0], 1))
        return np.concatenate((intercept, X), axis=1)
    
    def __loss(self, y, y_hat):
        return -np.mean(y * np.log(y_hat) + (1-y) * np.log(1-y_hat))
    
    def initialize_parameters(self, X):
        input_size = X.shape[1]
        output_size = 1
        
        self.params = {
            'W1': np.random.randn(input_size, self.hidden_size) * 0.01,
            'b1': np.zeros((1, self.hidden_size)),
            'W2': np.random.randn(self.hidden_size, output_size) * 0.01,
            'b2': np.zeros((1, output_size))
        }
        
    def forward_propagation(self, X):
        Z1 = np.dot(X, self.params['W1']) + self.params['b1']
        A1 = np.tanh(Z1)
        Z2 = np.dot(A1, self.params['W2']) + self.params['b2']
        y_hat = sigmoid(Z2)
        cache = {
            'A1': A1,
            'Z2': Z2,
            'Z1': Z1
        }
        return y_hat, cache
    
    def backward_propagation(self, X, y, y_hat, cache):
        dZ2 = y_hat - y
        dW2 = np.dot(cache['A1'].T, dZ2) / X.shape[0]
        db2 = np.sum(dZ2, axis=0, keepdims=True) / X.shape[0]
        dZ1 = np.dot(dZ2, self.params['W2'].T) * (1 - np.power(cache['A1'], 2))
        dW1 = np.dot(X.T, dZ1) / X.shape[0]
        db1 = np.sum(dZ1, axis=0, keepdims=True) / X.shape[0]
        
        grads = {
            'dW2': dW2,
            'db2': db2,
            'dW1': dW1,
            'db1': db1
        }
        
        return grads
    
    def update_parameters(self, grads):
        self.params['W1'] -= self.lr * grads['dW1']
        self.params['b1'] -= self.lr * grads['db1']
        self.params['W2'] -= self.lr * grads['dW2']
        self.params['b2'] -= self.lr * grads['db2']
        
    def fit(self, X, y):
        if self.fit_intercept:
            X = self.__add_intercept(X)
        
        self.initialize_parameters(X)
        
        for i in range(self.num_iter):
            y_hat, cache = self.forward_propagation(X)
            loss = self.__loss(y, y_hat)
            grads = self.backward_propagation(X, y, y_hat, cache)
            self.update_parameters(grads)
            
            if self.verbose and i % 10 == 0:
                print(f'Iteration {i}, loss = {loss}')
        
    def predict(self, X):
        if self.fit_intercept:
            X = self.__add_intercept(X)
        
        y_hat, _ = self.forward_propagation(X)
        return y_hat

四、如何選擇SGD的超參數

SGD演算法中的超參數主要有學習率(learning rate)、迭代次數、batch size等等。合適的超參數對於模型性能的提升至關重要,以下是一些常用的選擇方法:

1、學習率(learning rate):通常情況下,學習率的選擇會根據具體的數據集和模型來定。如果學習率過大,可能導致演算法無法收斂;如果學習率過小,則演算法的收斂速度會變得非常緩慢。通常情況下,我們可以初次設置學習率等於0.001,然後根據具體實驗進行調整;

2、迭代次數:迭代次數應該足夠大,以保證演算法能夠收斂到最優解。同時,迭代次數也不能太大,否則會導致演算法耗費大量的時間和資源。一般來說,可以根據實際數據集大小和模型複雜度來確定迭代次數;

3、batch size:batch size通常是一個比較小的數值,但不宜過小或過大。如果batch size過大,將會導致演算法內存不足,而過小則會影響模型的優化效果。因此,我們需要根據具體的數據集大小和配置環境確定一個合適的batch size。

原創文章,作者:小藍,如若轉載,請註明出處:https://www.506064.com/zh-tw/n/302890.html

(0)
打賞 微信掃一掃 微信掃一掃 支付寶掃一掃 支付寶掃一掃
小藍的頭像小藍
上一篇 2024-12-31 11:48
下一篇 2024-12-31 11:48

相關推薦

  • TensorFlow Serving Java:實現開發全功能的模型服務

    TensorFlow Serving Java是作為TensorFlow Serving的Java API,可以輕鬆地將基於TensorFlow模型的服務集成到Java應用程序中。…

    編程 2025-04-29
  • 蝴蝶優化演算法Python版

    蝴蝶優化演算法是一種基於仿生學的優化演算法,模仿自然界中的蝴蝶進行搜索。它可以應用於多個領域的優化問題,包括數學優化、工程問題、機器學習等。本文將從多個方面對蝴蝶優化演算法Python版…

    編程 2025-04-29
  • Python實現爬樓梯演算法

    本文介紹使用Python實現爬樓梯演算法,該演算法用於計算一個人爬n級樓梯有多少種不同的方法。 有一樓梯,小明可以一次走一步、兩步或三步。請問小明爬上第 n 級樓梯有多少種不同的爬樓梯…

    編程 2025-04-29
  • Python訓練模型後如何投入應用

    Python已成為機器學習和深度學習領域中熱門的編程語言之一,在訓練完模型後如何將其投入應用中,是一個重要問題。本文將從多個方面為大家詳細闡述。 一、模型持久化 在應用中使用訓練好…

    編程 2025-04-29
  • AES加密解密演算法的C語言實現

    AES(Advanced Encryption Standard)是一種對稱加密演算法,可用於對數據進行加密和解密。在本篇文章中,我們將介紹C語言中如何實現AES演算法,並對實現過程進…

    編程 2025-04-29
  • Harris角點檢測演算法原理與實現

    本文將從多個方面對Harris角點檢測演算法進行詳細的闡述,包括演算法原理、實現步驟、代碼實現等。 一、Harris角點檢測演算法原理 Harris角點檢測演算法是一種經典的計算機視覺演算法…

    編程 2025-04-29
  • Python刷課:優化學習體驗的利器

    Python刷課作為一種利用自動化技術優化學習體驗的工具已經被廣泛應用。它可以幫助用戶自動登錄、自動答題等,讓用戶在學習過程中可以更加專註於知識本身,提高效率,增加學習樂趣。 一、…

    編程 2025-04-29
  • 數據結構與演算法基礎青島大學PPT解析

    本文將從多個方面對數據結構與演算法基礎青島大學PPT進行詳細的闡述,包括數據類型、集合類型、排序演算法、字元串匹配和動態規劃等內容。通過對這些內容的解析,讀者可以更好地了解數據結構與算…

    編程 2025-04-29
  • lsw2u1:全能編程開發工程師的利器

    lsw2u1是一款多功能工具,可以為全能編程開發工程師提供便利的支持。本文將從多個方面對lsw2u1做詳細闡述,並給出對應代碼示例。 一、快速存取代碼段 在日常開發中,我們總會使用…

    編程 2025-04-29
  • 瘦臉演算法 Python 原理與實現

    本文將從多個方面詳細闡述瘦臉演算法 Python 實現的原理和方法,包括該演算法的意義、流程、代碼實現、優化等內容。 一、演算法意義 隨著科技的發展,瘦臉演算法已經成為了人們修圖中不可缺少…

    編程 2025-04-29

發表回復

登錄後才能評論