神經網路的啟用函式是決定神經元是否被啟用的關鍵元件,不同的啟用函式具有不同的特性,適用於不同的場景。常見的啟用函式包含 Sigmoid、ReLU、Tanh 以及 Softmax,它們各自的輸出範圍和梯度特性影響著神經網路的訓練效率和效能。梯度下降法是一種重要的最佳化演算法,用於調整神經網路的權重和偏差,以最小化損失函式。梯度下降法透過計算損失函式對各個引數的梯度,並沿著梯度的反方向更新引數,逐步逼近最優解。選擇合適的學習率對於梯度下降法的收斂速度和穩定性至關重要。
Sigmoid 啟用函式
Sigmoid 啟用函式是一種常用的啟用函式,尤其是在早期的神經網路中。它的公式如下:
$$ \sigma(x) = \frac{1}{1 + e^{-x}} $$
其中,$e$ 是自然對數的底數,約等於 2.71828。Sigmoid 函式的輸出範圍是 $(0, 1)$,這使得它在二元分類問題中尤其有用。
ReLU 啟用函式
ReLU(Rectified Linear Unit)啟用函式是另一種廣泛使用的啟用函式。它的公式如下:
$$ \text{ReLU}(x) = \max(0, x) $$
ReLU 函式的優點在於它的計算簡單,且對於大於 0 的輸入,梯度始終為 1,這使得它在深度神經網路中尤其有用。
Tanh 啟用函式
Tanh(Hyperbolic Tangent)啟用函式的公式如下:
$$ \tanh(x) = \frac{e^x - e^{-x}}{e^x + e^{-x}} $$
Tanh 函式的輸出範圍是 $(-1, 1)$,這使得它在某些情況下比 Sigmoid 函式更有用,因為它的輸出對於正負輸入是對稱的。
Softmax 啟用函式
Softmax 啟用函式主要用於多分類問題,尤其是在輸出層。它的公式如下:
$$ \text{Softmax}(x_i) = \frac{e^{x_i}}{\sum_{j=1}^{n} e^{x_j}} $$
其中,$x_i$ 是第 $i$ 個神經元的輸出,$n$ 是神經元的總數。Softmax 函式確保輸出的所有元素都在 $(0, 1)$ 範圍內,並且所有元素的總和等於 1,這使得它非常適合用於機率預測。
啟用函式的選擇
選擇合適的啟用函式取決於具體的問題和神經網路的架構。一般而言,ReLU 和其變體(如 Leaky ReLU、Parametric ReLU 等)在隱藏層中很受歡迎,因為它們的計算簡單,且不容易出現梯度消失的問題。Sigmoid 和 Tanh 函式在某些情況下仍然有用,尤其是在輸出層或特定的應用中。Softmax 函式幾乎是多分類問題的標準選擇。
內容解密:
本節介紹了啟用函式在神經網路中的作用和選擇。啟用函式的選擇對於神經網路的效能有著重要的影響,瞭解不同啟用函式的特點和適用場景是設計和最佳化神經網路的關鍵。
import numpy as np
def sigmoid(x):
return 1 / (1 + np.exp(-x))
def relu(x):
return np.maximum(0, x)
def tanh(x):
return np.tanh(x)
def softmax(x):
e_x = np.exp(x - np.max(x))
return e_x / e_x.sum()
# 測試啟用函式
x = np.array([1, 2, 3])
print("Sigmoid:", sigmoid(x))
print("ReLU:", relu(x))
print("Tanh:", tanh(x))
print("Softmax:", softmax(x))
圖表翻譯:
以下是啟用函式的視覺化表示,使用 Mermaid 圖表語言:
graph LR A[Sigmoid] -->|輸出 (0, 1)|> B B --> C[二元分類] D[ReLU] -->|輸出 (0, +inf)|> E E --> F[隱藏層] G[Tanh] -->|輸出 (-1, 1)|> H H --> I[對稱輸出] J[Softmax] -->|輸出 (0, 1)|> K K --> L[多分類]
這個圖表展示了不同啟用函式的輸出範圍和典型的應用場景,幫助理解和選擇合適的啟用函式。
梯度下降法的實作
在神經網路中,梯度下降法是一種常用的最佳化演算法,用於調整模型的引數以最小化損失函式。以下是對梯度下降法的實作過程的描述:
損失函式的計算
首先,我們需要計算損失函式的值。假設我們的損失函式為 $L$,它是模型的輸出和真實標籤之間的差異。對於一個簡單的神經網路,損失函式可以表示為:
$$L = (y_c - y_{pred})^2$$
其中 $y_c$ 是真實標籤,$y_{pred}$ 是模型的預測輸出。
梯度的計算
接下來,我們需要計算損失函式對於模型引數的梯度。對於一個簡單的神經網路,梯度可以表示為:
$$\frac{\partial L}{\partial w_5} = -2(y_c - y_{pred}) \cdot \frac{\partial y_{pred}}{\partial w_5}$$
其中 $w_5$ 是模型的第五個引數,$\frac{\partial y_{pred}}{\partial w_5}$ 是模型的預測輸出對於 $w_5$ 的偏導數。
梯度下降法的更新
現在,我們可以使用梯度下降法來更新模型的引數。梯度下降法的更新規則可以表示為:
$$w_5^{new} = w_5 - \eta \cdot \frac{\partial L}{\partial w_5}$$
其中 $\eta$ 是學習率,$\frac{\partial L}{\partial w_5}$ 是損失函式對於 $w_5$ 的梯度。
實際計算
假設我們的學習率 $\eta = 0.7$,我們可以計算新的 $w_5$ 值。首先,我們需要計算損失函式的值:
$$L = (y_c - y_{pred})^2 = (0.6155 - 1)^2 \cdot 0.6155 \cdot (1 - 0.6155) \cdot 0.5868 = -0.0534$$
接下來,我們可以計算梯度的值:
$$\frac{\partial L}{\partial w_5} = -2(y_c - y_{pred}) \cdot \frac{\partial y_{pred}}{\partial w_5} = -2(0.6155 - 1) \cdot \frac{\partial y_{pred}}{\partial w_5}$$
假設 $\frac{\partial y_{pred}}{\partial w_5} = 0.5868$,我們可以計算新的 $w_5$ 值:
$$w_5^{new} = w_5 - \eta \cdot \frac{\partial L}{\partial w_5} = w_5 - 0.7 \cdot (-2(0.6155 - 1) \cdot 0.5868)$$
內容解密:
以上的計算過程展示瞭如何使用梯度下降法來更新模型的引數。首先,我們需要計算損失函式的值和梯度的值。然後,我們可以使用梯度下降法的更新規則來更新模型的引數。這個過程可以重複多次,以最小化損失函式和提高模型的準確性。
import numpy as np
# 定義損失函式
def loss(y_c, y_pred):
return (y_c - y_pred) ** 2
# 定義梯度函式
def gradient(y_c, y_pred, w_5):
return -2 * (y_c - y_pred) * 0.5868
# 定義梯度下降法的更新規則
def update(w_5, eta, gradient):
return w_5 - eta * gradient
# 設定初始值
y_c = 0.6155
y_pred = 1
w_5 = 0.5
eta = 0.7
# 計算損失函式的值
L = loss(y_c, y_pred)
# 計算梯度的值
grad = gradient(y_c, y_pred, w_5)
# 更新 w_5 的值
w_5_new = update(w_5, eta, grad)
print("新的 w_5 值:", w_5_new)
圖表翻譯:
以下的圖表展示了梯度下降法的過程:
flowchart TD A[初始化] --> B[計算損失函式] B --> C[計算梯度] C --> D[更新模型引數] D --> E[重複過程] E --> F[收斂]
這個圖表展示了梯度下降法的過程,從初始化開始,計算損失函式和梯度,更新模型引數,重複過程,直到收斂。
神經網路反向傳播的核心概念
在神經網路中,反向傳播(Backpropagation)是一種用於訓練人工神經網路的演算法。它的主要目的是透過最小化損失函式來最佳化神經網路的引數。這個過程涉及到計算損失函式對於每個神經元輸出的偏導數。
損失函式與偏導數
假設我們有一個神經網路,其輸出為 (y),真實標籤為 (\hat{y}),損失函式為 (L = (y - \hat{y})^2)。我們想要計算損失函式 (L) 對於神經網路中每個權重 (w_i) 的偏導數 (\frac{\partial L}{\partial w_i})。
反向傳播演算法
反向傳播演算法可以分為兩個主要步驟:前向傳播和反向傳播。
前向傳播:在這個步驟中,輸入資料透過神經網路,計算每個神經元的輸出。這個過程可以用以下公式表示: [ z = \sigma(w \cdot x + b) ] 其中,(x) 是輸入,(w) 是權重,(b) 是偏差,(\sigma) 是啟用函式。
反向傳播:在這個步驟中,計算損失函式對於每個神經元輸出的偏導數。這個過程可以用以下公式表示: [ \frac{\partial L}{\partial w} = \frac{\partial L}{\partial z} \cdot \frac{\partial z}{\partial w} ] 其中,(\frac{\partial L}{\partial z}) 是損失函式對於神經元輸出的偏導數,(\frac{\partial z}{\partial w}) 是神經元輸出對於權重的偏導數。
實際計算
假設我們有一個神經網路,其輸出為 (y = \sigma(w_5 \cdot y_C + w_6 \cdot y_D)),其中 (y_C = \sigma(w_1 \cdot x_A + w_2 \cdot x_B))。我們想要計算損失函式 (L) 對於 (w_1) 的偏導數 (\frac{\partial L}{\partial w_1})。
首先,計算 (y_C) 對於 (w_1) 的偏導數: [ \frac{\partial y_C}{\partial w_1} = \frac{\partial \sigma(w_1 \cdot x_A + w_2 \cdot x_B)}{\partial w_1} = \sigma’(w_1 \cdot x_A + w_2 \cdot x_B) \cdot x_A ]
接下來,計算 (y) 對於 (y_C) 的偏導數: [ \frac{\partial y}{\partial y_C} = \frac{\partial \sigma(w_5 \cdot y_C + w_6 \cdot y_D)}{\partial y_C} = \sigma’(w_5 \cdot y_C + w_6 \cdot y_D) \cdot w_5 ]
最後,計算損失函式 (L) 對於 (w_1) 的偏導數: [ \frac{\partial L}{\partial w_1} = \frac{\partial L}{\partial y} \cdot \frac{\partial y}{\partial y_C} \cdot \frac{\partial y_C}{\partial w_1} ]
內容解密:
在這個例子中,我們計算了損失函式對於 (w_1) 的偏導數 (\frac{\partial L}{\partial w_1})。這個過程涉及到計算 (y_C) 對於 (w_1) 的偏導數、(y) 對於 (y_C) 的偏導數,最後計算損失函式 (L) 對於 (w_1) 的偏導數。這個過程可以用於最佳化神經網路的引數,從而提高神經網路的效能。
import numpy as np
# 定義啟用函式
def sigmoid(x):
return 1 / (1 + np.exp(-x))
# 定義損失函式
def loss(y, y_hat):
return (y - y_hat) ** 2
# 定義神經網路
def neural_network(x, w1, w2, w5, w6):
y_c = sigmoid(w1 * x[0] + w2 * x[1])
y = sigmoid(w5 * y_c + w6 * x[2])
return y
# 計算損失函式對於 w1 的偏導數
def compute_gradient(x, w1, w2, w5, w6, y_hat):
y_c = sigmoid(w1 * x[0] + w2 * x[1])
y = sigmoid(w5 * y_c + w6 * x[2])
loss_value = loss(y, y_hat)
dy_dw1 = -2 * (y - y_hat) * w5 * sigmoid(w5 * y_c + w6 * x[2]) * (1 - sigmoid(w5 * y_c + w6 * x[2])) * x[0]
return dy_dw1
# 測試
x = np.array([1, 2, 3])
w1, w2, w5, w6 = 0.1, 0.2, 0.3, 0.4
y_hat = 0.5
print(compute_gradient(x, w1, w2, w5, w6, y_hat))
圖表翻譯:
此圖示神經網路的反向傳播過程。輸入資料透過神經網路,計算每個神經元的輸出。然後,計算損失函式對於每個神經元輸出的偏導數。最後,最佳化神經網路的引數,從而提高神經網路的效能。
graph LR A[輸入資料] --> B[神經網路] B --> C[計算損失函式] C --> D[計算偏導數] D --> E[最佳化引數] E --> F[提高效能]
神經網路引數更新
在神經網路中,引數的更新是一個非常重要的過程。以下是對於神經網路引數更新的詳細分析。
引數更新公式
神經網路的引數更新可以使用以下公式:
$$w_{new} = w_{old} - \alpha \cdot \frac{\partial L}{\partial w}$$
其中,$w_{new}$ 是更新後的引數,$w_{old}$ 是更新前的引數,$\alpha$ 是學習率,$\frac{\partial L}{\partial w}$ 是損失函式對於引數的偏導數。
引數更新過程
以下是引數更新的過程:
- 初始化引數:首先,需要初始化引數的值。
- 前向傳播:然後,需要進行前向傳播,以計算輸出值和損失函式。
- 反向傳播:接下來,需要進行反向傳播,以計算引數的偏導數。
- 引數更新:最後,需要使用上述公式更新引數的值。
範例
以下是對於一個簡單神經網路的引數更新過程的範例:
引數 | 舊值 | 新值 | 變化 |
---|---|---|---|
$w_1$ | 0.1 | 0.1007 | 0.7% |
$w_2$ | 0.5 | 0.502 | 0.4% |
$w_3$ | 0.4 | 0.4024 | 0.6% |
$w_4$ | 0.3 | 0.307 | 2.3% |
$w_5$ | 0.2 | 0.2373 | 18.7% |
$w_6$ | 0.6 | 0.6374 | 6.2% |
從範例中可以看到,引數的更新值與其原始值的差異,並且可以觀察到引數更新的趨勢。
Gradient Vanishing Phenomenon
在神經網路中,Gradient Vanishing Phenomenon是一種常見的問題,即引數的梯度值會隨著層數的增加而減小。這種現象會導致引數的更新值變小,從而影響神經網路的學習效率。
圖表翻譯:
graph LR A[引數初始化] --> B[前向傳播] B --> C[反向傳播] C --> D[引數更新] D --> E[輸出值計算] E --> F[損失函式計算] F --> G[引數更新]
此圖表示了神經網路的引數更新過程,包括引數初始化、前向傳播、反向傳播、引數更新、輸出值計算和損失函式計算等步驟。
神經網路基礎
15.1 前饋神經網路
在前饋神經網路中,資料的流動是單向的,從輸入層經過多個隱藏層,最終到達輸出層。這種網路結構使得資料不會在網路中迴圈,因此被稱為前饋神經網路。
15.1.2 批次和Epoch
當您有大量的資料需要進行訓練時,為了避免每次都對單個資料進行反向傳播,從而導致網路引數發生劇烈的變化,通常會將資料分成批次進行傳播。批次大小是系統中的一個超引數,需要由使用者設定。此外,僅僅透過所有批次一次是不夠的,需要重複這個過程多次,直到結果的準確度達到要求。每次對所有訓練資料進行一次完整的傳播和反向傳播的過程,被稱為一個Epoch。
15.1.3 如何閱讀神經網路的圖示
神經網路的圖示通常很複雜,包含了許多細節。為了更好地理解這些圖示,需要注意以下幾點:
- 圖示中通常會省略一些細節,讓讀者自己去推斷。
- 不同的圖示方法可能會對同一種神經網路有不同的表達方式。
- 圖示中可能會包含一些簡化或省略的部分,需要讀者根據自己的理解進行補充。
例如,圖15.2中展示了三種不同型別的圖示,都是對同一種前饋神經網路的表達。這種網路包含輸入層、兩個線性層和一個softmax層。每個圖示方法都有其自己的優點和缺點,讀者需要根據自己的需求選擇合適的圖示方法。
flowchart TD A[輸入層] --> B[線性層1] B --> C[線性層2] C --> D[softmax層]
圖表翻譯:
上述的Mermaid圖表展示了前饋神經網路的基本結構,從輸入層開始,經過兩個線性層,最終到達softmax層。這種結構使得資料可以被逐步處理和轉換,最終得到期望的輸出結果。
神經網路的視覺化表示
在瞭解神經網路的結構和運作之前,首先需要了解如何視覺化地表示神經網路。圖15.2(a)展示了一個簡單的前饋神經網路,其節點(或稱神經元)以圓角矩形表示,內含變數名稱。圖中的箭頭代表了資訊的傳遞,類似於圖15.1中的箭頭。每個箭頭對應於模型的一個引數,儘管在圖中沒有明確標示出來,但可以理解為節點之間的箭頭代表了引數的傳遞。
例如,節點 $x_i$(第2層)和節點 $y_j$(第3層)之間的箭頭代表了乘以權重 $w’{ij}$,其中 $w’{ij}$ 是權重矩陣 $W’$ 中的一個元素。啟用函式也沒有在圖中明確標示出來,但這個圖仍然展示了這個相對簡單的前饋神經網路的複雜性。
圖15.2(b)使用陰影區域取代了箭頭網路。這種表示方法與Jurafsky & Martin的方法不同,他們在某些地方使用了網路和陰影區域的混合方法。相反,我們將陰影區域附加到上層,以示相應的引數矩陣屬於上層,而不是下層。
這種視覺化方法有助於我們更好地理解神經網路的結構和運作,特別是當網路變得更加複雜時。透過使用陰影區域和箭頭,圖15.2(a)和(b)提供了兩種不同的視角來看待神經網路的表示。
內容解密:
神經網路的視覺化表示是理解其結構和運作的關鍵一步。透過使用節點、箭頭和陰影區域,圖15.2(a)和(b)提供了兩種不同的視角來看待神經網路的表示。這種視覺化方法有助於我們更好地理解神經網路的結構和運作,特別是當網路變得更加複雜時。
圖表翻譯:
以下是圖15.2(a)和(b)的Mermaid圖表:
graph LR A[節點 $x_i$] -->|乘以權重 $w'_{ij}$|> B[節點 $y_j$] B -->|啟用函式|> C[節點 $z_k$] style A fill:#f9f,stroke:#333,stroke-width:4px style B fill:#f9f,stroke:#333,stroke-width:4px style C fill:#f9f,stroke:#333,stroke-width:4px
這個圖表展示了節點 $x_i$、$y_j$ 和 $z_k$ 之間的關係,包括乘以權重 $w’_{ij}$ 和啟用函式。這種視覺化方法有助於我們更好地理解神經網路的結構和運作。
神經網路基礎
神經網路是一種模擬人類大腦結構的機器學習模型,廣泛用於各種應用中,如影像識別、語音辨識、自然語言處理等。在本節中,我們將介紹前饋神經網路(Feedforward Neural Networks)的基礎概念和實作。
神經網路的表示方法
神經網路可以用不同的方法表示,包括使用符號、圖表等。圖15.2展示了三種不同的表示方法:
- (a) 使用符號表示每個節點和引數
- (b) 使用簡化的圖表表示,節點和引數不使用符號
- (c) 使用層次表示,節點和引數不命名,使用圓形框表示向量
這些表示方法各有優缺點,選擇哪種方法取決於具體的應用和需求。
前饋神經網路
前饋神經網路是一種最基本的神經網路結構,資料從輸入層傳遞到隱藏層,然後到輸出層,且不會回饋到之前的層。這種結構簡單易於實作,廣泛用於各種應用中。
Python 實作
以下是使用 Python 和 Keras 包實作的前饋神經網路範例:
# 引入必要的函式庫
from keras.models import Sequential
from keras.layers import Dense
from keras.utils import to_categorical
from sklearn.model_selection import train_test_split
from sklearn.metrics import accuracy_score
import numpy as np
# 載入資料
# ...
# 預處理資料
# ...
# 分割資料
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2, random_state=42)
# 建立模型
model = Sequential()
model.add(Dense(64, activation='relu', input_shape=(784,)))
model.add(Dense(32, activation='relu'))
model.add(Dense(10, activation='softmax'))
# 編譯模型
model.compile(loss='categorical_crossentropy', optimizer='adam', metrics=['accuracy'])
# 訓練模型
model.fit(X_train, y_train, epochs=10, batch_size=128, validation_data=(X_test, y_test))
# 評估模型
y_pred = model.predict(X_test)
y_pred_class = np.argmax(y_pred, axis=1)
print("Accuracy:", accuracy_score(y_test, y_pred_class))
這個範例建立了一個簡單的前饋神經網路,使用 ReLU 啟用函式和 softmax 輸出層,實作了手寫數字識別的任務。
自然語言處理基礎
文字資料預處理
在進行自然語言處理任務時,預處理文字資料是一個非常重要的步驟。這個步驟涉及到讀取文字檔案、分詞、移除停用詞、詞幹提取或詞形還原等操作。
讀取文字檔案
首先,我們需要讀取文字檔案。以下是使用Python進行讀取的示例:
import io
import re
import random
# 開啟檔案
f = io.open("sf.txt", mode="r", encoding="utf-8")
# 初始化空列表和字典
BIG = []
WORDS = {}
COUNTS = {}
TAGS = {}
TAGcounter = 0
# 逐行讀取檔案
for line in f:
# 使用正規表示式匹配行內容
match = re.match(r'([a-z]+)\t(.+)', line)
# 如果匹配成功
if match:
# 提取標籤和內容
tag = match.group(1)
content = match.group(2)
# 進一步處理標籤和內容
# ...
文字分詞和詞彙統計
在上述程式碼中,我們已經讀取了文字檔案,並使用正規表示式提取了每行的標籤和內容。接下來,我們可以進行文字分詞和詞彙統計:
# 分詞
words = content.split()
# 更新詞彙統計
for word in words:
if word not in WORDS:
WORDS[word] = 0
WORDS[word] += 1
# 更新標籤統計
if tag not in TAGS:
TAGS[tag] = TAGcounter
TAGcounter += 1
詞幹提取或詞形還原
在某些自然語言處理任務中,詞幹提取或詞形還原是必要的步驟。這可以幫助減少詞彙的維度,並提高模型的泛化能力。
import nltk
from nltk.stem import WordNetLemmatizer
# 初始化詞形還原器
lemmatizer = WordNetLemmatizer()
# 進行詞形還原
words = [lemmatizer.lemmatize(word) for word in words]
內容解密:
上述程式碼示例展示瞭如何使用Python進行文字資料預處理,包括讀取文字檔案、分詞、詞彙統計和詞形還原等步驟。這些步驟是自然語言處理的基礎,對於後續的任務,如文字分類、情感分析等至關重要。
flowchart TD A[文字資料預處理] --> B[讀取文字檔案] B --> C[分詞] C --> D[詞彙統計] D --> E[詞幹提取或詞形還原] E --> F[自然語言處理任務]
圖表翻譯:
此圖表展示了自然語言處理的基礎步驟,包括文字資料預處理、分詞、詞彙統計、詞幹提取或詞形還原等。這些步驟是進行自然語言處理任務的基礎,對於後續的任務至關重要。
處理檔案和標籤計數
在這個步驟中,我們將檔案中的內容讀取出來,檔案中每一行包含一個類別標籤和一個文字單元,兩者之間以特定符號隔開。接著,我們將這些結果儲存到名為 BIG
的列表中。
從技術架構視角來看,啟用函式、梯度下降、反向傳播和引數更新是建構神經網路的基本。分析各個啟用函式的特性及應用場景,Sigmoid 適用於二元分類,ReLU 擅長處理隱藏層,Tanh 適用於對稱輸出,而 Softmax 則專精於多分類問題。梯度下降法和反向傳播演算法是訓練神經網路、最佳化引數的關鍵,理解其運作原理對於提升模型效能至關重要。然而,梯度消失現象是深度學習中的一大挑戰,需要透過調整網路架構或採用其他最佳化策略來克服。此外,批次大小、Epoch 數量的設定,以及不同視覺化表示方法的理解,也有助於更有效地訓練和分析神經網路。最後,文字資料預處理的步驟,如分詞、詞彙統計和詞形還原,是自然語言處理的基本,為後續的模型訓練奠定基礎。玄貓認為,掌握這些核心概念和技術,才能建構高效能的神經網路模型,並應用於實際的自然語言處理任務。