深度學習模型的訓練依賴於梯度計算,而計算圖和反向傳播演算法是實作梯度計算的關鍵。計算圖以視覺化的方式展現了計算過程,方便理解複雜的運算流程。反向傳播演算法則利用鏈式法則,高效地計算梯度,進而更新模型引數。本文將逐步介紹計算圖、矩陣運算、啟用函式以及反向傳播演算法的原理和 Python 程式碼實作,幫助讀者深入理解深度學習的基本。

1.18 圖表翻譯:新增啟用函式的計算圖

現在,我們將新增一個啟用函式 $\sigma$ 到計算圖中。這個函式將矩陣乘法的結果作為輸入,並輸出一個新的值 $S$。

程式碼實作

import numpy as np

def matmul_backward_first(X: np.ndarray, W: np.ndarray) -> np.ndarray:
    """
    計算矩陣乘法的反向傳播相對於第一個引數的梯度。
    """
    # 計算梯度
    dNdX = np.transpose(W, (1, 0))
    return dNdX

def matrix_forward_extra(X: np.ndarray, W: np.ndarray, sigma: callable) -> np.ndarray:
    """
    計算矩陣乘法的結果並將其傳入啟用函式。
    """
    # 驗證矩陣形狀
    assert X.shape[1] == W.shape[0]
    
    # 進行矩陣乘法
    N = np.dot(X, W)
    
    # 將結果傳入啟用函式
    S = sigma(N)
    return S

內容解密:矩陣乘法的反向傳播

在上面的程式碼中,我們定義了兩個函式:matmul_backward_firstmatrix_forward_extra。第一個函式計算了矩陣乘法的反向傳播相對於第一個引數的梯度,而第二個函式則計算了矩陣乘法的結果並將其傳入啟用函式。

圖表翻譯:計算圖

以下是計算圖的視覺化表示:

  flowchart TD
    X[輸入矩陣 X] -->|矩陣乘法|> N[矩陣乘法結果]
    W[輸入矩陣 W] -->|矩陣乘法|> N
    N -->|傳入啟用函式|> S[啟用函式結果]

這個計算圖顯示了矩陣乘法和啟用函式之間的關係。

向量函式的導數:進一步探討

數學表示

考慮向量函式 $S = \sigma(N)$,其中 $\sigma$ 是一個嵌入函式,且 $N$ 是矩陣 $X$ 和 $W$ 的乘積。根據鏈式法則,$S$ 對 $X$ 的偏導數可以表示為:

$$ \frac{\partial S}{\partial X} = \frac{\partial S}{\partial N} \cdot \frac{\partial N}{\partial X} $$

由於 $\sigma$ 是一個連續函式,其導數可以在任何點計算,因此我們可以將 $N$ 的值代入 $\sigma$ 中,得到:

$$ \frac{\partial S}{\partial N} = \sigma’(N) $$

而 $N$ 對 $X$ 的偏導數可以表示為:

$$ \frac{\partial N}{\partial X} = W^T $$

因此,$S$ 對 $X$ 的偏導數可以表示為:

$$ \frac{\partial S}{\partial X} = \sigma’(N) \cdot W^T $$

視覺化

反向傳播的流程可以使用以下圖表表示:

γ [x]

[w] N

(N) Sσ ∂ γ ∂ x ∂ γ ∂ w ∂ σ ∂ u

圖 1.19:向量函式的反向傳播

程式碼實作

以下是反向傳播的程式碼實作:

import numpy as np

def matrix_function_backward_1(X: np.ndarray, W: np.ndarray, sigma: callable) -> np.ndarray:
    """
    計算函式 S 對 X 的偏導數。
    
    Parameters:
    X (np.ndarray): 輸入矩陣
    W (np.ndarray): 權重矩陣
    sigma (callable): 啟用函式
    
    Returns:
    np.ndarray: 函式 S 對 X 的偏導數
    """
    assert X.shape[1] == W.shape[0]
    
    # 矩陣乘法
    N = np.dot(X, W)
    
    # 將結果傳入啟用函式
    S = sigma(N)
    
    # 計算導數
    dSdN = deriv(sigma, N)
    dNdX = np.transpose(W, (1, 0))
    
    # 傳回結果
    return np.dot(dSdN, dNdX)

注意到,在程式碼中,我們首先計算矩陣乘法的結果 $N$,然後將其傳入啟用函式 $\sigma$ 中。接著,我們計算導數,並傳回結果。

驗證結果

為了驗證結果的正確性,我們可以稍微修改輸入值,並觀察結果的變化。例如,我們可以將輸入矩陣 $X$ 修改為:

print(X)

這樣,我們就可以觀察到結果的變化,並驗證導數的正確性。

重新組織和重寫內容

1.

在機器學習中,瞭解數學基礎是非常重要的。這章節將介紹如何使用計算圖來理解矩陣運算的梯度計算。

2. 計算圖

計算圖是一種視覺化工具,幫助我們理解複雜的計算過程。下面是一個簡單的計算圖範例:

  flowchart TD
    A[輸入] --> B[矩陣乘法]
    B --> C[啟用函式]
    C --> D[輸出]

3. 矩陣運算

矩陣運算是機器學習中的一個基本概念。給定兩個矩陣 X 和 W,我們可以計算它們的乘法:

import numpy as np

X = np.array([[1, 2], [3, 4]])
W = np.array([[5, 6], [7, 8]])

N = np.dot(X, W)

4. 啟用函式

啟用函式是一種非線性函式,常用於神經網路中。下面是一個簡單的啟用函式範例:

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

S = sigmoid(N)

5. 梯度計算

梯度計算是機器學習中的一個重要概念。給定一個輸出值,我們可以計算它對於輸入值的梯度:

def matrix_function_backward_1(X, W, sigmoid):
    # 計算梯度
    dS_dN = sigmoid(N) * (1 - sigmoid(N))
    dN_dX = W
    dN_dW = X
    
    # 計算梯度
    dL_dX = dS_dN * dN_dX
    dL_dW = dS_dN * dN_dW
    
    return dL_dX, dL_dW

dL_dX, dL_dW = matrix_function_backward_1(X, W, sigmoid)
圖表翻譯:

上述 Mermaid 圖表展示了計算圖的流程,從輸入到輸出,包括矩陣乘法、啟用函式和梯度計算等步驟。這個圖表幫助我們理解複雜的計算過程,使得我們可以更好地掌握機器學習中的數學基礎。

內容解密:

上述程式碼展示瞭如何計算矩陣運算的梯度。首先,我們計算矩陣乘法的結果 N,然後將其傳入啟用函式中,得到 S。接著,我們計算梯度,包括 dS_dN、dN_dX 和 dN_dW 等。最後,我們得到梯度 dL_dX 和 dL_dW。這個過程展示瞭如何使用計算圖來理解矩陣運算的梯度計算。

線性迴歸的反向傳遞

在深度學習中,反向傳遞(Backpropagation)是一種用於訓練神經網路的演算法。它可以用於計算損失函式對模型引數的梯度,從而實作模型的最佳化。在這裡,我們將探討線性迴歸中的反向傳遞。

線性迴歸模型

線性迴歸是一種基本的機器學習模型,假設輸出變數與輸入變數之間存線上性關係。給定輸入資料 $X$ 和權重 $W$,線性迴歸模型可以表示為:

$$N = X \cdot W$$

其中 $N$ 是預測輸出。

損失函式

損失函式(Loss Function)是用於衡量模型預測值與實際值之間差異的函式。常用的損失函式包括均方差(Mean Squared Error, MSE)等。在這裡,我們使用均方差作為損失函式:

$$L = \frac{1}{2} \sum_{i=1}^{n} (y_i - N_i)^2$$

其中 $y_i$ 是實際值,$N_i$ 是預測值。

反向傳遞

反向傳遞是計算損失函式對模型引數的梯度的過程。首先,我們需要計算損失函式對預測輸出 $N$ 的梯度:

$$\frac{\partial L}{\partial N} = - (y - N)$$

接下來,我們需要計算預測輸出 $N$ 對權重 $W$ 的梯度:

$$\frac{\partial N}{\partial W} = X$$

利用鏈式法則(Chain Rule),我們可以計算損失函式對權重 $W$ 的梯度:

$$\frac{\partial L}{\partial W} = \frac{\partial L}{\partial N} \cdot \frac{\partial N}{\partial W} = - (y - N) \cdot X$$

實作

以下是線性迴歸模型的反向傳遞實作:

import numpy as np

def linear_regression(X, W, y):
    # 預測輸出
    N = np.dot(X, W)
    
    # 損失函式
    L = np.sum((y - N) ** 2) / 2
    
    # 反向傳遞
    dL_dN = - (y - N)
    dN_dW = X
    dL_dW = np.dot(dL_dN, dN_dW)
    
    return dL_dW

在這個實作中,我們首先計算預測輸出 $N$,然後計算損失函式 $L$。接下來,我們計算損失函式對預測輸出 $N$ 的梯度,然後計算預測輸出 $N$ 對權重 $W$ 的梯度。最後,我們利用鏈式法則計算損失函式對權重 $W$ 的梯度。

簡介

在深度學習中,計算梯度是訓練模型的關鍵步驟。梯度代表了模型輸出的變化率與輸入的變化率之間的關係。在本文中,我們將探討如何使用鏈式法則(chain rule)計算矩陣函式的梯度。

鏈式法則

鏈式法則是一種用於計算複合函式梯度的方法。給定一個複合函式 $L = f(g(x))$,其中 $f$ 和 $g$ 是兩個函式,鏈式法則可以用於計算 $L$ 對 $x$ 的梯度:

$$ \frac{dL}{dx} = \frac{dL}{dg} \cdot \frac{dg}{dx} $$

在矩陣函式中,我們需要計算矩陣對元素的梯度。假設我們有一個矩陣函式 $L = f(XW)$,其中 $X$ 和 $W$ 是兩個矩陣,$f$ 是一個函式,我們需要計算 $L$ 對 $X$ 的梯度。

矩陣函式的梯度

使用鏈式法則,我們可以將 $L$ 對 $X$ 的梯度計算為:

$$ \frac{dL}{dX} = \frac{dL}{d(XW)} \cdot \frac{d(XW)}{dX} $$

其中,$\frac{dL}{d(XW)}$ 是 $L$ 對 $XW$ 的梯度,$\frac{d(XW)}{dX}$ 是 $XW$ 對 $X$ 的梯度。

實際計算

假設我們有一個矩陣函式 $L = \sum \sigma(XW)$,其中 $\sigma$ 是一個啟用函式,我們需要計算 $L$ 對 $X$ 的梯度。

首先,我們計算 $L$ 對 $XW$ 的梯度:

$$ \frac{dL}{d(XW)} = \frac{d}{d(XW)} \sum \sigma(XW) = \sigma’(XW) $$

其中,$\sigma’$ 是 $\sigma$ 的導數。

接下來,我們計算 $XW$ 對 $X$ 的梯度:

$$ \frac{d(XW)}{dX} = W^T $$

其中,$W^T$ 是 $W$ 的轉置。

最後,我們計算 $L$ 對 $X$ 的梯度:

$$ \frac{dL}{dX} = \frac{dL}{d(XW)} \cdot \frac{d(XW)}{dX} = \sigma’(XW) \cdot W^T $$

程式碼實作

以下是使用 Python 和 NumPy 實作的程式碼:

import numpy as np

def matrix_function_backward_sum_1(X, W, sigma):
    # 計算 XW
    N = np.dot(X, W)
    
    # 計算 L 對 XW 的梯度
    dLdN = sigma(N)
    
    # 計算 XW 對 X 的梯度
    dNdX = np.transpose(W, (1, 0))
    
    # 計算 L 對 X 的梯度
    dLdX = dLdN * dNdX
    
    return dLdX

在這個程式碼中,我們首先計算 $XW$,然後計算 $L$ 對 $XW$ 的梯度,接下來計算 $XW$ 對 $X$ 的梯度,最後計算 $L$ 對 $X$ 的梯度。

神經網路的基礎:從矩陣運算到反向傳播

在深度學習中,神經網路的核心是矩陣運算和反向傳播。要了解神經網路的工作原理,我們需要從基本的矩陣運算開始。

矩陣運算

矩陣運算是神經網路中最基本的運算單元。給定兩個矩陣 XW,我們可以計算其乘積 X * W。在 Python 中,我們可以使用 NumPy 函式庫來實作矩陣運算。

import numpy as np

# 初始化隨機數
np.random.seed(190204)

# 定義矩陣 X 和 W
X = np.random.randn(3, 3)
W = np.random.randn(3, 2)

# 計算矩陣乘積
result = np.dot(X, W)

sigmoid 函式

sigmoid 函式是一種常用的啟用函式,用於將輸入對映到 (0, 1) 的範圍內。sigmoid 函式的公式為:

$$\sigma(x) = \frac{1}{1 + e^{-x}}$$

在 Python 中,我們可以使用以下程式碼來實作 sigmoid 函式:

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

前向傳播

前向傳播是神經網路中的一個過程,用於計算輸出的值。給定輸入 X 和權重 W,我們可以計算輸出 L

def matrix_function_forward_sum(X, W, sigmoid):
    # 計算矩陣乘積
    result = np.dot(X, W)
    
    # 應用 sigmoid 函式
    result = sigmoid(result)
    
    # 傳回結果
    return result

反向傳播

反向傳播是神經網路中的一個過程,用於計算梯度。給定輸入 X、權重 W 和損失函式 L,我們可以計算梯度 dLdX

def matrix_function_backward_sum_1(X, W, sigmoid):
    # 計算矩陣乘積
    result = np.dot(X, W)
    
    # 應用 sigmoid 函式
    result = sigmoid(result)
    
    # 計算梯度
    dSdN = 1  # 假設損失函式為 1
    dNdX = result * (1 - result)  # sigmoid 函式的導函式
    
    # 計算梯度 dLdX
    dLdX = np.dot(dSdN, dNdX)
    
    # 傳回結果
    return dLdX

測試

現在,我們可以測試以上程式碼了。

print("X:")
print(X)

print("L:")
print(round(matrix_function_forward_sum(X, W, sigmoid), 4))

print()

print("dLdX:")
print(matrix_function_backward_sum_1(X, W, sigmoid))

這些程式碼將會輸出矩陣 X、輸出 L 和梯度 dLdX

簡介神經網路的反向傳播

在神經網路中,反向傳播(Backpropagation)是一種用於訓練人工神經網路的演算法。它的主要目的是計算神經網路中每個引數的梯度,以便於使用最佳化演算法更新這些引數,從而最小化損失函式。

基本概念

在反向傳播中,我們首先計算輸出層的誤差梯度,然後將其反向傳播到隱藏層和輸入層。這個過程涉及到計算每個神經元的輸出對於損失函式的梯度。

步驟

  1. 前向傳播:首先,我們需要計算神經網路的前向傳播結果,也就是輸出層的輸出。
  2. 計算誤差梯度:然後,我們計算輸出層的誤差梯度,也就是損失函式對於輸出層輸出的梯度。
  3. 反向傳播:接下來,我們將誤差梯度反向傳播到隱藏層和輸入層,計算每個神經元的輸出對於損失函式的梯度。
  4. 更新引數:最後,我們使用最佳化演算法更新神經網路中的引數,以最小化損失函式。

實作

在實作反向傳播時,我們需要計算每個神經元的輸出對於損失函式的梯度。這可以透過以下公式實作:

$$ \frac{\partial L}{\partial x_i} = \frac{\partial L}{\partial y_i} \cdot \frac{\partial y_i}{\partial x_i} $$

其中,$L$ 是損失函式,$x_i$ 是第 $i$ 個神經元的輸入,$y_i$ 是第 $i$ 個神經元的輸出。

範例

假設我們有一個簡單的神經網路,包含一個輸入層、一個隱藏層和一個輸出層。輸入層有兩個神經元,隱藏層有三個神經元,輸出層有一個神經元。損失函式是均方差。

import numpy as np

# 定義神經網路的結構
input_dim = 2
hidden_dim = 3
output_dim = 1

# 初始化權重和偏置
weights1 = np.random.rand(input_dim, hidden_dim)
weights2 = np.random.rand(hidden_dim, output_dim)
bias1 = np.zeros((1, hidden_dim))
bias2 = np.zeros((1, output_dim))

# 定義啟用函式
def sigmoid(x):
    return 1 / (1 + np.exp(-x))

# 定義損失函式
def loss(y_pred, y_true):
    return np.mean((y_pred - y_true) ** 2)

# 前向傳播
def forward(x):
    hidden_layer = sigmoid(np.dot(x, weights1) + bias1)
    output_layer = sigmoid(np.dot(hidden_layer, weights2) + bias2)
    return hidden_layer, output_layer

# 反向傳播
def backward(x, y_true, hidden_layer, output_layer):
    d_output_layer = 2 * (output_layer - y_true) * output_layer * (1 - output_layer)
    d_weights2 = np.dot(hidden_layer.T, d_output_layer)
    d_bias2 = np.sum(d_output_layer, axis=0, keepdims=True)
    d_hidden_layer = np.dot(d_output_layer, weights2.T) * hidden_layer * (1 - hidden_layer)
    d_weights1 = np.dot(x.T, d_hidden_layer)
    d_bias1 = np.sum(d_hidden_layer, axis=0, keepdims=True)
    return d_weights1, d_bias1, d_weights2, d_bias2

# 訓練神經網路
x = np.array([[0.5, 0.3]])
y_true = np.array([[0.8]])
for i in range(1000):
    hidden_layer, output_layer = forward(x)
    d_weights1, d_bias1, d_weights2, d_bias2 = backward(x, y_true, hidden_layer, output_layer)
    weights1 -= 0.01 * d_weights1
    bias1 -= 0.01 * d_bias1
    weights2 -= 0.01 * d_weights2
    bias2 -= 0.01 * d_bias2
    print(loss(output_layer, y_true))

這個範例展示瞭如何使用反向傳播演算法訓練一個簡單的神經網路。

深度學習基礎

在前一章中,您已經學習了深度學習的基礎數學知識,包括巢狀函式、連續函式和可微分函式。您還學習瞭如何將這些函式表示為計算圖,每個節點代表一個簡單的函式。此外,您已經知道如何計算巢狀函式的導數,即透過計算每個組成部分的導數並將它們相乘。

現在,我們將進一步探討深度學習的基礎知識。首先,我們將建立一個線性迴歸模型,然後觀察其訓練過程。接下來,我們將擴充套件這個模型為單層神經網路。

線性迴歸模型

線性迴歸是一種最常見的機器學習模型,它試圖找到一條直線來最好地描述輸入資料和輸出資料之間的關係。給定輸入資料 $X$ 和輸出資料 $y$,我們可以建立一個線性迴歸模型來預測輸出資料。

線性迴歸模型的建立

假設我們有 $n$ 個樣本,每個樣本有 $m$ 個特徵。輸入資料 $X$ 可以表示為一個 $n \times m$ 的矩陣,每行代表一個樣本,每列代表一個特徵。輸出資料 $y$ 可以表示為一個 $n \times 1$ 的矩陣,每行代表一個樣本的輸出值。

線性迴歸模型可以表示為:

$$y = Xw + b$$

其中 $w$ 是一個 $m \times 1$ 的權重矩陣,$b$ 是一個偏差項。

線性迴歸模型的訓練

線性迴歸模型的訓練目的是找到最佳的權重 $w$ 和偏差 $b$,使得模型對輸入資料的預測值與實際輸出值之間的誤差最小。

給定輸入資料 $X$ 和輸出資料 $y$,我們可以使用以下損失函式來評估模型的效能:

$$L = \frac{1}{2} \sum_{i=1}^n (y_i - (Xw + b)_i)^2$$

其中 $y_i$ 是第 $i$ 個樣本的實際輸出值,$(Xw + b)_i$ 是第 $i$ 個樣本的預測值。

單層神經網路

單層神經網路是一種簡單的神經網路,它只有一個隱藏層。給定輸入資料 $X$,單層神經網路可以表示為:

$$y = \sigma(Xw + b)$$

其中 $\sigma$ 是啟用函式,$w$ 是權重矩陣,$b$ 是偏差項。

單層神經網路的訓練

單層神經網路的訓練目的是找到最佳的權重 $w$ 和偏差 $b$,使得模型對輸入資料的預測值與實際輸出值之間的誤差最小。

給定輸入資料 $X$ 和輸出資料 $y$,我們可以使用以下損失函式來評估模型的效能:

$$L = \frac{1}{2} \sum_{i=1}^n (y_i - \sigma(Xw + b)_i)^2$$

其中 $y_i$ 是第 $i$ 個樣本的實際輸出值,$\sigma(Xw + b)_i$ 是第 $i$ 個樣本的預測值。

從技術架構視角來看,本文逐步拆解了神經網路反向傳播的計算過程,從單個啟用函式的引入到線性迴歸模型,再到單層神經網路,層層遞進,清晰地闡述了梯度計算的原理和方法。 分析段落中,程式碼示例與數學公式的結合,有效地降低了理解難度,同時也展現了反向傳播的實際應用。文章雖然聚焦於基礎概念,但深入淺出地解釋了鏈式法則在矩陣運算中的應用,並藉由計算圖的視覺化,更進一步強化了讀者對梯度計算流程的理解。技術限制深析方面,文章可以更明確地指出不同啟用函式的選擇對梯度計算的影響,以及在高維資料和複雜網路結構下可能遇到的計算挑戰。展望未來,隨著深度學習模型的日益複雜,更高效的梯度計算方法和硬體加速技術將成為研究熱點。對於初學者,理解這些基礎概念至關重要,它將為進一步學習更複雜的神經網路架構奠定堅實基礎。 玄貓認為,掌握反向傳播的原理和實作方法,是深入理解和應用深度學習技術的關鍵所在。