深入理解softmax loss

在深度學習中,softmax loss是非常常見的損失函數。在許多領域,如計算機視覺、自然語言處理等,softmax loss被用於解決分類問題。在本文中,我們將從多個方面對softmax loss進行詳細的闡述。

一、softmax函數

softmax函數是一種常用的數學函數,它將一個向量作為輸入,並輸出一個概率分佈向量。在深度學習中,softmax函數常被用於處理多分類問題。softmax函數的數學形式如下:

def softmax(x):
    return np.exp(x) / np.sum(np.exp(x), axis=0)

其中,x是輸入向量,np.exp()表示計算向量中每個元素的指數值,np.sum()表示對向量中所有元素求和。softmax函數將輸入向量中的每個元素進行指數運算,得到新的向量,再將新的向量中的元素值除以所有元素值的和,即得到softmax函數的輸出向量。

二、softmax loss

在分類任務中,我們需要將每個輸入向量映射到一個輸出向量,輸出向量中每個元素表示對應類別的概率。為了訓練模型,我們需要定義損失函數來衡量模型預測結果與真實結果之間的差距。softmax loss是用於多分類問題的損失函數,它的數學形式如下:

def softmax_loss(W, X, y, reg):
    """
    W:權重矩陣
    X:輸入數據
    y:真實標籤
    reg:正則化係數
    """
    num_train = X.shape[0]
    num_classes = W.shape[1]
    
    # 計算scores
    scores = X.dot(W)
    
    # 計算各樣本的損失函數
    shift_scores = scores - np.max(scores, axis=1, keepdims=True)
    softmax_output = np.exp(shift_scores) / np.sum(np.exp(shift_scores), axis=1, keepdims=True)
    loss = -np.sum(np.log(softmax_output[range(num_train),y])) / num_train
    loss += 0.5 * reg * np.sum(W * W)
    
    # 計算梯度
    dscores = softmax_output.copy()
    dscores[range(num_train),y] -= 1
    dscores /= num_train
    
    dW = np.dot(X.T, dscores)
    dW += reg * W
    
    return loss, dW

其中,W是權重矩陣,X是輸入數據,y是真實標籤,reg是正則化係數。在softmax loss中,我們首先計算每個輸入向量對應的scores向量,然後將scores向量通過softmax函數得到概率分佈向量。接着,我們計算各樣本的損失函數,其中np.log()表示取對數運算。最後,我們計算損失函數對權重矩陣的梯度,並加上正則化項。

三、softmax loss的優化方法

1、隨機梯度下降(SGD)

隨機梯度下降是深度學習中最常見的優化方法之一。在每一步更新時,SGD隨機選擇一個樣本進行梯度計算,然後更新權重矩陣。SGD的核心代碼如下:

def sgd(W, dW, learning_rate):
    """
    W:權重矩陣
    dW:梯度
    learning_rate:學習率
    """
    W -= learning_rate * dW
    return W

2、帶動量的隨機梯度下降

帶動量的隨機梯度下降在每一步更新時,不僅考慮當前步的梯度方向,還考慮過去的梯度方向。這樣做的好處是可以在梯度方向變化較大的情況下,加速收斂。帶動量的SGD的核心代碼如下:

def momentum_sgd(W, dW, learning_rate, momentum, velocity):
    """
    W:權重矩陣
    dW:梯度
    learning_rate:學習率
    momentum:動量係數
    velocity:動量項
    """
    velocity = momentum * velocity - learning_rate * dW
    W += velocity
    return W, velocity

3、自適應學習率算法

自適應學習率算法是指在每一步更新時,動態調整學習率的算法。常見的自適應學習率算法有AdaGrad、RMSprop和Adam。其中,Adam是最常使用的自適應學習率算法之一。Adam的核心代碼如下:

def adam(W, dW, config=None):
    """
    W:權重矩陣
    dW:梯度
    config:Adam的配置
    """
    if config is None:
        config = {}
        config.setdefault("learning_rate", 1e-3)
        config.setdefault("beta1", 0.9)
        config.setdefault("beta2", 0.999)
        config.setdefault("epsilon", 1e-8)
        config.setdefault("m", np.zeros_like(dW))
        config.setdefault("v", np.zeros_like(dW))
        config.setdefault("t", 0)

    config["t"] += 1
    config["m"] = config["beta1"] * config["m"] + (1 - config["beta1"]) * dW
    config["v"] = config["beta2"] * config["v"] + (1 - config["beta2"]) * (dW ** 2)
    mb = config["m"] / (1 - config["beta1"] ** config["t"])
    vb = config["v"] / (1 - config["beta2"] ** config["t"])
    W -= config["learning_rate"] * mb / (np.sqrt(vb) + config["epsilon"])

    return W, config

四、softmax loss的應用

softmax loss在深度學習中有着廣泛的應用,尤其在計算機視覺、自然語言處理等領域。以計算機視覺領域為例,softmax loss可以用於解決圖像分類、目標檢測等問題。下面是一個圖像分類的實現代碼:

def train_softmax_loss(X_train, y_train, X_val, y_val, learning_rate=1e-3, reg=1e-5, num_epochs=10, batch_size=50, optimizer='sgd', verbose=True):

    num_train = X_train.shape[0]
    num_val = X_val.shape[0]
    num_batches = num_train // batch_size

    W = np.random.randn(X_train.shape[1], len(set(y_train))) * 0.001
    print('Training ...')

    for epoch in range(num_epochs):
        shuffle_idx = np.random.permutation(num_train)

        for i in range(0, num_train, batch_size):
            idx = shuffle_idx[i:i+batch_size]
            X_batch = X_train[idx]
            Y_batch = y_train[idx]

            loss, grad = softmax_loss(W, X_batch, Y_batch, reg)

            if optimizer == 'sgd':
                W = sgd(W, grad, learning_rate)

            elif optimizer == 'momentum':
                # 動量項初始化為0
                if epoch == 0 and i == 0:
                    velocity = np.zeros_like(W)
                W, velocity = momentum_sgd(W, grad, learning_rate, 0.9, velocity)

            elif optimizer == 'adam':
                if epoch == 0 and i == 0:
                    v = {}
                    v['m'] = np.zeros_like(grad)
                    v['v'] = np.zeros_like(grad)
                W, v = adam(W, grad, {'learning_rate': learning_rate, 'm': v['m'], 'v': v['v']})

        train_acc = (predict_softmax_loss(W, X_train) == y_train).mean()
        val_acc = (predict_softmax_loss(W, X_val) == y_val).mean()

        if verbose:
            print(f'Epoch {epoch+1}/{num_epochs}: train_loss = {loss:.6f}  train_accuracy = {train_acc:.6f}  val_accuracy = {val_acc:.6f}')

    return W

在上面的代碼中,我們定義了一個train_softmax_loss函數,用於訓練softmax loss模型。在訓練過程中,我們可以選擇不同的優化方法,如隨機梯度下降、帶動量的隨機梯度下降、Adam等。通過訓練softmax loss模型,我們可以得到一個能夠對輸入圖像進行分類的模型。

原創文章,作者:OIKIH,如若轉載,請註明出處:https://www.506064.com/zh-hk/n/351517.html

(0)
打賞 微信掃一掃 微信掃一掃 支付寶掃一掃 支付寶掃一掃
OIKIH的頭像OIKIH
上一篇 2025-02-16 18:10
下一篇 2025-02-17 17:02

相關推薦

  • eslint no-loss-of-precision requires at least eslint v7.1.0

    這篇文章將從以下幾個方面詳細闡述eslint no-loss-of-precision requires至少需要eslint v7.1.0版本的問題: 一、概述 如果使用較老的es…

    編程 2025-04-29
  • 深入解析Vue3 defineExpose

    Vue 3在開發過程中引入了新的API `defineExpose`。在以前的版本中,我們經常使用 `$attrs` 和` $listeners` 實現父組件與子組件之間的通信,但…

    編程 2025-04-25
  • 深入理解byte轉int

    一、位元組與比特 在討論byte轉int之前,我們需要了解位元組和比特的概念。位元組是計算機存儲單位的一種,通常表示8個比特(bit),即1位元組=8比特。比特是計算機中最小的數據單位,是…

    編程 2025-04-25
  • 深入理解Flutter StreamBuilder

    一、什麼是Flutter StreamBuilder? Flutter StreamBuilder是Flutter框架中的一個內置小部件,它可以監測數據流(Stream)中數據的變…

    編程 2025-04-25
  • 深入探討OpenCV版本

    OpenCV是一個用於計算機視覺應用程序的開源庫。它是由英特爾公司創建的,現已由Willow Garage管理。OpenCV旨在提供一個易於使用的計算機視覺和機器學習基礎架構,以實…

    編程 2025-04-25
  • 深入了解scala-maven-plugin

    一、簡介 Scala-maven-plugin 是一個創造和管理 Scala 項目的maven插件,它可以自動生成基本項目結構、依賴配置、Scala文件等。使用它可以使我們專註於代…

    編程 2025-04-25
  • 深入了解LaTeX的腳註(latexfootnote)

    一、基本介紹 LaTeX作為一種排版軟件,具有各種各樣的功能,其中腳註(footnote)是一個十分重要的功能之一。在LaTeX中,腳註是用命令latexfootnote來實現的。…

    編程 2025-04-25
  • 深入理解Python字符串r

    一、r字符串的基本概念 r字符串(raw字符串)是指在Python中,以字母r為前綴的字符串。r字符串中的反斜杠(\)不會被轉義,而是被當作普通字符處理,這使得r字符串可以非常方便…

    編程 2025-04-25
  • 深入探討馮諾依曼原理

    一、原理概述 馮諾依曼原理,又稱「存儲程序控制原理」,是指計算機的程序和數據都存儲在同一個存儲器中,並且通過一個統一的總線來傳輸數據。這個原理的提出,是計算機科學發展中的重大進展,…

    編程 2025-04-25
  • 深入了解Python包

    一、包的概念 Python中一個程序就是一個模塊,而一個模塊可以引入另一個模塊,這樣就形成了包。包就是有多個模塊組成的一個大模塊,也可以看做是一個文件夾。包可以有效地組織代碼和數據…

    編程 2025-04-25

發表回復

登錄後才能評論