深入理解softmax求導

一、簡介

softmax函數是在深度學習和神經網絡中常用的函數,主要用於多分類問題和概率分佈。在反向傳播算法中,softmax函數的求導是一個非常重要的過程,本文將從多個方面闡述softmax函數的求導方法。

二、softmax函數的定義

在介紹softmax函數的求導方法之前,我們先來了解一下softmax函數的定義和基本性質。

def softmax(x):
    shift_x = x - np.max(x)
    exp_x = np.exp(shift_x)
    return exp_x / np.sum(exp_x)

softmax函數的定義是將任意的實數向量$\mathbf{x}$映射成一個概率分佈$\mathbf{p}$的函數,即:

$$
\mathrm{softmax}(\mathbf{x})_i = \frac{\exp(x_i)}{\sum_{j=1}^k \exp(x_j)}
$$

其中,$i \in \{1,2,\dots,k\}$,$k$ 是 $\mathbf{x}$ 中元素的個數,$x_i$ 是 $\mathbf{x}$ 的第 $i$ 個元素。

softmax函數具有以下性質:

  • 每個元素都非負,並且所有元素之和為1。
  • softmax函數是單調遞增函數,即對於所有 $i,j$,如果 $i<j$,則 $\mathrm{softmax}(\mathbf{x})_i < \mathrm{softmax}(\mathbf{x})_j$。
  • softmax函數是一個連續可微的函數。

三、softmax函數的求導方法

1. 簡單情況下的求導方法

在簡單情況下,我們可以根據softmax函數的定義求導。

設 $\mathbf{p} = \mathrm{softmax}(\mathbf{x})$,則:

$$
\begin{aligned}
\frac{\partial p_i}{\partial x_j} &= \frac{\partial}{\partial x_j}\frac{\exp(x_i)}{\sum_{k=1}^k \exp(x_k)} \\
&= \frac{\exp(x_i) \cdot \frac{\partial}{\partial x_j}\sum_{k=1}^k \exp(x_k) – \exp(x_j) \cdot \frac{\partial}{\partial x_j}\exp(x_i)}{\left(\sum_{k=1}^k \exp(x_k)\right)^2} \\
&= \frac{\exp(x_i)}{\sum_{k=1}^k \exp(x_k)} \cdot \left(\frac{\partial}{\partial x_j}\sum_{k=1}^k \exp(x_k)\right) – \frac{\exp(x_i) \cdot \exp(x_j)}{\left(\sum_{k=1}^k \exp(x_k)\right)^2} \\
&= \frac{\exp(x_i)}{\sum_{k=1}^k \exp(x_k)} \cdot \frac{\partial}{\partial x_j}(\exp(x_j)) – \frac{\exp(x_i) \cdot \exp(x_j)}{\left(\sum_{k=1}^k \exp(x_k)\right)^2} \\
&= \begin{cases}
\mathrm{softmax}(\mathbf{x})_i \cdot (1 – \mathrm{softmax}(\mathbf{x})_j) & i=j \\
-\mathrm{softmax}(\mathbf{x})_i \cdot \mathrm{softmax}(\mathbf{x})_j & i \neq j
\end{cases}
\end{aligned}
$$

這裡我們使用了兩個基本公式:

$$
\begin{aligned}
\frac{\partial}{\partial x}\exp(x) &= \exp(x) \\
\frac{\partial}{\partial x}\sum_{i=1}^k g(x_i) &= \sum_{i=1}^k \frac{\partial}{\partial x_i} g(x_i)
\end{aligned}
$$

2. 計算交叉熵損失函數的梯度

在深度學習中,我們通常使用交叉熵損失函數來評價模型的預測結果,交叉熵損失函數的定義是:

$$
L(y, \hat{y}) = -\sum_{i=1}^k y_i \log \hat{y}_i
$$

其中,$y$ 是真實的標籤向量,$\hat{y}$ 是模型的預測向量。

由於交叉熵損失函數是關於$\hat{y}$的函數,因此我們需要計算 $\frac{\partial L}{\partial \hat{y}}$ 來更新模型的參數。

設 $p = \mathrm{softmax}(\mathbf{x})$,則 $\hat{y} = p$,交叉熵損失函數可以表示為:

$$
L(y, p) = -\sum_{i=1}^k y_i \log p_i
$$

我們需要計算 $\frac{\partial L}{\partial x_i}$ 來更新模型的參數,根據鏈式法則,有:

$$
\frac{\partial L}{\partial x_i} = \sum_{j=1}^k \frac{\partial L}{\partial p_j} \cdot \frac{\partial p_j}{\partial x_i}
$$

由於 $p$ 與 $x$ 之間的關係已經求出,我們只需要計算 $\frac{\partial L}{\partial p_j}$ 即可。

根據交叉熵損失函數的定義,有:

$$
\frac{\partial L}{\partial p_j} = -\frac{y_j}{p_j}
$$

將其代入上式,有:

$$
\frac{\partial L}{\partial x_i} = -\sum_{j=1}^k \frac{y_j}{p_j} \cdot \frac{\partial p_j}{\partial x_i}
$$

接下來,我們將 $\frac{\partial L}{\partial x_i}$ 帶入求導公式,得到:

$$
\frac{\partial L}{\partial x_i} = \begin{cases}
(p_i – y_i) & i \in \{1,2,\dots,k\} \\
\end{cases}
$$

這個式子非常有用,我們可以直接使用它來更新模型的參數,例如在使用SGD、Adam等優化算法的時候。

3. 使用矩陣運算簡化求導過程

在實際中,我們通常使用矩陣形式表示softmax函數,即:

$$
\mathrm{softmax}(\mathbf{x}) = \frac{\exp(\mathbf{x})}{\mathbf{1}^\mathrm{T} \exp(\mathbf{x})}
$$

其中,$\mathbf{x} \in \mathbb{R}^d$ 是輸入向量,$\mathbf{1}$ 是全1向量。

我們可以使用矩陣運算來簡化求導過程。

首先,我們定義:

$$
\mathbf{P} = \mathrm{softmax}(\mathbf{x}) \\
\mathbf{Y} = \mathrm{diag}(\mathbf{y}) \\
\mathbf{J} = \mathbf{P} – \mathbf{Y}
$$

其中,$\mathrm{diag}(\cdot)$ 表示將向量轉化成對角矩陣。

根據第2節的求導公式,我們有:

$$
\frac{\partial L}{\partial x_i} = \sum_{j=1}^k \frac{\partial L}{\partial p_j} \cdot \frac{\partial p_j}{\partial x_i}
$$

根據求導公式,我們可以將 $\frac{\partial L}{\partial p_j}$ 表示為:

$$
\frac{\partial L}{\partial p_j} = -\frac{y_j}{p_j} = -y_j \cdot (\mathbf{P})_j = (\mathbf{Y})_{jj}(\mathbf{P})_{j} = (\mathbf{Y} \odot \mathbf{P})_{j}
$$

其中,$\odot$ 表示依元素相乘。

同樣的,我們可以將 $\frac{\partial p_j}{\partial x_i}$ 表示為:

$$
\frac{\partial p_j}{\partial x_i} = \begin{cases}
p_i \cdot (1 – p_i) & i=j \\
-p_i \cdot p_j & i \neq j
\end{cases} = \begin{cases}
(\mathbf{P})_i (1 – (\mathbf{P})_i) & i=j \\
-(\mathbf{P})_i (\mathbf{P})_j & i \neq j
\end{cases} = \begin{cases}
(\mathbf{P} \odot (1-\mathbf{P}))_i & i=j \\
-(\mathbf{P} \odot \mathbf{P})_{i,j} & i \neq j
\end{cases}
$$

使用矩陣運算,我們可以得到:

$$
\frac{\partial L}{\partial x} = \mathbf{J}^\mathrm{T}
$$

這個式子跟第2節的公式是等價的。

總結

本文從多個方面詳細闡述了softmax函數的求導方法,並介紹了如何使用矩陣運算來簡化求導過程。在深度學習和神經網絡中,softmax函數是非常重要的函數,softmax函數的求導是深度學習算法中必不可少的環節,對於深入理解深度學習算法具有重要意義。

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

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

相關推薦

  • diff函數是否能夠實現數值求導?

    答案是可以的。下面將從數學原理、實現過程和可行性三個方面對此進行詳細闡述。 一、數學原理 求導的定義是函數在某一點的變化率,也即在該點處的斜率。而數值求導便是使用有限差分近似求解該…

    編程 2025-04-28
  • 深入解析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
  • 深入探討馮諾依曼原理

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

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

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

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

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

    編程 2025-04-25

發表回復

登錄後才能評論