吳恩達機器學習課程 筆記5 神經網路

jhhhred發表於2024-10-03

神經網路原理

神經網路是一種受生物神經系統啟發的計算模型,用於學習和處理複雜的資料模式。神經網路透過一系列相互連線的簡單處理單元(稱為神經元或節點)來模擬大腦的功能。下面詳細介紹神經網路的基本原理。

神經網路的基本構成

  1. 神經元(Neuron)

    • 神經元是神經網路的基本計算單元,通常具有一個輸入端和一個輸出端。
    • 神經元接受來自多個輸入訊號的加權和,然後透過一個啟用函式(Activation Function)來產生輸出訊號。
  2. 啟用函式(Activation Function)

    • 啟用函式用於引入非線性,使得神經網路能夠擬合非線性關係。
    • 常見的啟用函式包括 Sigmoid 函式、ReLU(Rectified Linear Unit)函式、tanh(雙曲正切)函式等。
  3. 層(Layer)

    • 神經網路由多個層組成,包括輸入層、隱藏層和輸出層。
    • 輸入層接收原始輸入資料。
    • 隱藏層是介於輸入層和輸出層之間的層,可以有多層。
    • 輸出層產生最終的預測結果。

神經網路的工作原理

  1. 前向傳播(Forward Propagation)

    • 在前向傳播過程中,輸入資料從輸入層傳遞到隱藏層,再到輸出層。
    • 每個神經元計算其輸入的加權和,並透過啟用函式產生輸出。
    • 輸出層產生最終的預測結果。
  2. 損失函式(Loss Function)

    • 損失函式用於衡量模型預測結果與實際標籤之間的差異。
    • 常見的損失函式包括均方誤差(Mean Squared Error, MSE)用於迴歸問題,交叉熵損失(Cross-Entropy Loss)用於分類問題。
  3. 反向傳播(Backpropagation)

    • 在反向傳播過程中,損失函式關於每個引數的梯度被計算出來。
    • 梯度透過鏈式法則從輸出層向輸入層逐層傳遞。
    • 梯度用於更新每個權重和偏置,使損失函式最小化。
  4. 最佳化演算法(Optimization Algorithm)

    • 最佳化演算法用於更新神經網路的引數,使其逐漸逼近最小化損失函式的目標。
    • 常見的最佳化演算法包括隨機梯度下降(Stochastic Gradient Descent, SGD)、Adam、RMSprop 等。

神經網路的主要元件

  1. 輸入層(Input Layer)

    • 輸入層接收原始輸入資料,通常對應於特徵向量的維度。
  2. 隱藏層(Hidden Layers)

    • 隱藏層負責提取輸入資料中的特徵,並透過多層非線性變換來捕捉複雜的模式。
    • 隱藏層可以有多個,每層包含多個神經元。
  3. 輸出層(Output Layer)

    • 輸出層產生最終的預測結果,其結構取決於任務型別(如分類或迴歸)。

神經網路的學習過程

  1. 初始化

    • 初始階段,隨機初始化神經網路的所有權重和偏置。
  2. 訓練

    • 在訓練過程中,神經網路透過多次迭代來調整權重和偏置,以最小化損失函式。
    • 每次迭代包括前向傳播計算預測結果、計算損失、反向傳播計算梯度、更新引數。
  3. 評估與調優

    • 在訓練過程中,使用驗證集評估模型效能,並根據需要調整超引數(如學習率、批次大小、網路結構等)。
    • 透過交叉驗證等方法選擇最佳模型。
  4. 部署與應用

    • 訓練好的神經網路可以用於預測新資料,並應用於實際問題中。

神經網路的應用領域

  • 計算機視覺:影像識別、物體檢測、影像分割等。
  • 自然語言處理:情感分析、機器翻譯、文字生成等。
  • 語音識別:語音識別、語音合成等。
  • 推薦系統:個性化推薦、廣告投放等。
  • 遊戲與娛樂:遊戲AI、虛擬現實等。

神經網路的強大之處在於它們可以自動學習輸入資料中的複雜模式,並透過多層次的抽象來完成各種任務。隨著深度學習的發展,神經網路已經成為處理大規模複雜資料的重要工具。

隱藏層如何工作

舉例: 人臉識別
輸入特徵:100x100的圖片。
輸出:圖片中的人臉,是某個人的機率。

  • 隱藏層1:識別一些很小的邊緣或線,比如不同的神經元識別不同方向的小邊緣或線。
  • 隱藏層2:將小邊緣組合在一起,識別面部的某個區域,比如鼻子、眼睛、嘴等。
  • 隱藏層3:將上述面部區域再組合,檢測到整張人臉,然後再根據臉型對比和目標人臉的相似程度。

總結:越靠後的隱藏層,識別區域越大。
注:“汽車檢測”的隱藏層功能也相似。

神經網路的數學表示式

TensorFlow 是一個由 Google 開發的開源軟體庫,主要用於數值計算和機器學習。它支援多種程式語言,但最常用的是 Python。TensorFlow 提供了靈活的架構,可以部署在各種平臺(桌面、伺服器、移動裝置等)上,並且支援從單個工作站到分散式叢集的大規模計算。

TensorFlow

安裝 TensorFlow

你可以透過 pip 安裝 TensorFlow:

pip install tensorflow

如果你需要特定版本的 TensorFlow 或者想要安裝 GPU 版本,可以指定版本號或新增額外的安裝選項。

匯入庫

在 Python 中使用 TensorFlow 之前,你需要匯入相應的模組:

import tensorflow as tf

建立張量

TensorFlow 中的基本資料型別是張量(tensor),它可以被看作是一個 n 維陣列。建立一個張量很簡單:

# 建立一個標量 (0-D tensor)
a = tf.constant(2)

# 建立一個向量 (1-D tensor)
b = tf.constant([1.0, 2.0, 3.0])

# 建立一個矩陣 (2-D tensor)
c = tf.constant([[1.0, 2.0], [3.0, 4.0]])

張量運算

張量支援各種數學運算:

# 張量加法
d = tf.add(a, b)

# 張量乘法
e = tf.multiply(b, c)

# 矩陣乘法
f = tf.matmul(b, c)

構建模型

TensorFlow 提供了多種方式來定義模型,最常見的是使用 tf.keras API:

定義模型

model = tf.keras.Sequential([
    tf.keras.layers.Dense(64, activation='relu', input_shape=(input_dim,)),
    tf.keras.layers.Dense(10, activation='softmax')
])

編譯模型

model.compile(optimizer='adam',
              loss='sparse_categorical_crossentropy',
              metrics=['accuracy'])

訓練模型

model.fit(x_train, y_train, epochs=10, batch_size=32)

評估模型

test_loss, test_acc = model.evaluate(x_test, y_test)
print('Test accuracy:', test_acc)

預測

predictions = model.predict(x_new)

儲存和恢復模型

你可以儲存整個模型,包括其架構、權重和最佳化器的狀態:

model.save('my_model.h5')

恢復模型:

new_model = tf.keras.models.load_model('my_model.h5')

更多高階功能

TensorFlow 還支援許多高階功能,如自定義訓練迴圈、模型檢查、分散式訓練等。使用 TensorFlow 時,你可以參考官方文件獲取更多詳細資訊和教程。

以上是使用 TensorFlow 進行基本操作的一個概覽。TensorFlow 是一個非常強大且靈活的工具,適用於從研究到生產環境的各種機器學習應用。

搭建一個神經網路

要搭建一個簡單的神經網路,我們可以使用 TensorFlow 和 Keras API。下面是一個逐步指導,展示如何搭建一個簡單的多層感知器(MLP)神經網路,並使用 MNIST 資料集進行手寫數字識別。

步驟 1: 匯入必要的庫

首先,確保你已經安裝了 TensorFlow。然後匯入必要的庫:

import tensorflow as tf
from tensorflow.keras import layers, models, optimizers, losses, metrics
from tensorflow.keras.datasets import mnist
from tensorflow.keras.utils import to_categorical

步驟 2: 載入資料集

載入 MNIST 資料集,並對其進行預處理:

# 載入 MNIST 資料集
(train_images, train_labels), (test_images, test_labels) = mnist.load_data()

# 預處理資料
train_images = train_images.reshape((60000, 28 * 28))
train_images = train_images.astype('float32') / 255

test_images = test_images.reshape((10000, 28 * 28))
test_images = test_images.astype('float32') / 255

# 將標籤轉換為 one-hot 編碼
train_labels = to_categorical(train_labels)
test_labels = to_categorical(test_labels)

步驟 3: 定義模型

定義一個簡單的多層感知器模型:

def build_model():
    model = models.Sequential()
    model.add(layers.Dense(64, activation='relu', input_shape=(28 * 28,)))
    model.add(layers.Dense(64, activation='relu'))
    model.add(layers.Dense(10, activation='softmax')) # 對於多分類問題,使用 softmax 啟用函式
    return model

model = build_model()

步驟 4: 編譯模型

設定損失函式、最佳化器和評估指標:

model.compile(optimizer=optimizers.Adam(),
              loss=losses.CategoricalCrossentropy(),
              metrics=[metrics.CategoricalAccuracy()])

步驟 5: 訓練模型

使用訓練資料來訓練模型:

history = model.fit(train_images, train_labels,
                    epochs=10,
                    batch_size=128,
                    validation_split=0.1)  # 使用一部分資料作為驗證集

步驟 6: 評估模型

使用測試資料來評估模型的效能:

test_loss, test_accuracy = model.evaluate(test_images, test_labels)
print(f'Test accuracy: {test_accuracy}')

步驟 7: 使用模型進行預測

使用訓練好的模型對新資料進行預測:

predictions = model.predict(test_images[:10])  # 對前10個測試樣本進行預測
predicted_labels = [np.argmax(prediction) for prediction in predictions]
true_labels = [np.argmax(label) for label in test_labels[:10]]
print("Predicted labels:", predicted_labels)
print("True labels:", true_labels)

以上就是搭建一個簡單的多層感知器神經網路的完整流程。你可以根據具體的需求調整模型的架構、最佳化器、損失函式等引數,以適應不同的應用場景。

單個網路層上的前向傳播

單個神經網路層上的前向傳播是指資料從輸入到輸出經過一個神經網路層的過程。在這個過程中,輸入資料經過一系列的數學運算,包括加權求和(線性變換)和啟用函式的應用,最終產生輸出。

單個神經網路層的結構

假設我們有一個單個全連線層(也稱為密集層),其結構如下:

  • 輸入維度:( d )
  • 輸出維度:( k )
  • 權重矩陣:( W ) (維度為 ( k \times d ))
  • 偏置向量:( b ) (維度為 ( k ))
  • 啟用函式:( f ) (如 ReLU、Sigmoid、Tanh 等)

前向傳播步驟

  1. 加權求和(線性變換):

    • 輸入向量 ( \mathbf{x} ) (維度為 ( d ))
    • 權重矩陣 ( W ) (維度為 ( k \times d ))
    • 偏置向量 ( b ) (維度為 ( k ))

    線性變換的公式為:
    [
    \mathbf{z} = W \mathbf{x} + b
    ]

    其中 ( \mathbf{z} ) 是加權求和的結果(維度為 ( k ))。

  2. 啟用函式

    • 啟用函式 ( f ) 對線性變換的結果 ( \mathbf{z} ) 進行非線性變換。

    啟用函式的公式為:
    [
    \mathbf{a} = f(\mathbf{z})
    ]

    其中 ( \mathbf{a} ) 是啟用函式的輸出(維度為 ( k ))。

示例程式碼

假設我們有一個輸入向量 ( \mathbf{x} ) 和一個全連線層,我們可以用 TensorFlow 來演示單個神經網路層上的前向傳播:

import tensorflow as tf
import numpy as np

# 輸入向量
x = tf.constant(np.random.rand(1, 3))

# 權重矩陣
W = tf.Variable(tf.random.normal([5, 3]))

# 偏置向量
b = tf.Variable(tf.zeros([5]))

# 啟用函式
activation_function = tf.nn.relu

# 前向傳播過程
def forward_pass(x, W, b, activation_function):
    # 線性變換
    z = tf.matmul(W, tf.transpose(x)) + b
    
    # 啟用函式
    a = activation_function(z)
    
    return a

# 進行前向傳播
output = forward_pass(x, W, b, activation_function)

print("Output:", output.numpy())

詳細步驟解釋

  1. 初始化輸入向量

    • x 是一個 1x3 的向量,表示輸入資料。
  2. 初始化權重矩陣和偏置向量

    • W 是一個 5x3 的矩陣,表示權重。
    • b 是一個 1x5 的向量,表示偏置。
  3. 定義啟用函式

    • 使用 ReLU 啟用函式 tf.nn.relu
  4. 前向傳播函式

    • forward_pass 函式接受輸入向量、權重矩陣、偏置向量和啟用函式作為引數。
    • 線性變換:z = tf.matmul(W, tf.transpose(x)) + b
    • 啟用函式:a = activation_function(z)
  5. 執行前向傳播

    • 呼叫 forward_pass 函式,得到輸出 output

輸出解釋

輸出是一個經過啟用函式後的向量,表示該層的輸出。在這個例子中,輸出維度為 5,表示經過該層後產生的特徵向量。

透過這種方式,你可以理解和實現單個神經網路層上的前向傳播過程。對於更復雜的網路,這個過程會在多個層之間遞迴進行。

前向傳播基本實現

前向傳播(Forward Propagation)是神經網路中的一種計算過程,它描述了從輸入層到輸出層的資料流動。在前向傳播過程中,輸入資料透過各個層的計算,最終產生輸出結果。這一過程涉及多個步驟,包括線性變換(加權求和)和非線性變換(啟用函式)。

前向傳播的基本步驟

  1. 輸入層

    • 輸入資料 ( \mathbf{x} ) 傳入網路的第一層。
  2. 加權求和(線性變換)

    • 在每個隱藏層,輸入資料與權重矩陣 ( W ) 進行矩陣乘法,並加上偏置向量 ( b ):
      [
      \mathbf{z} = W \mathbf{x} + b
      ]
  3. 啟用函式

    • 將線性變換的結果 ( \mathbf{z} ) 透過啟用函式 ( f ),得到啟用後的輸出:
      [
      \mathbf{a} = f(\mathbf{z})
      ]
  4. 重複步驟

    • 對於多層網路,上述步驟會在每個隱藏層中重複進行,直到到達輸出層。
  5. 輸出層

    • 最終輸出層的啟用函式通常根據任務的不同而選擇,例如:
      • 對於分類任務,通常使用 softmax 函式;
      • 對於迴歸任務,通常使用線性啟用函式(即不使用啟用函式)。

實現前向傳播的程式碼示例

下面是一個使用 TensorFlow 實現前向傳播的簡單示例:

```plaintext
import tensorflow as tf
import numpy as np

# 設定隨機種子以獲得可重複的結果
np.random.seed(42)

# 輸入向量
x = tf.constant(np.random.rand(1, 3), dtype=tf.float32)  # 顯式指定資料型別為 tf.float32

# 權重矩陣和偏置向量
W = tf.Variable(tf.random.normal([5, 3]))
b = tf.Variable(tf.zeros([5]))

# 啟用函式
activation_function = tf.nn.relu


# 定義前向傳播函式
def forward_pass(x, W, b, activation_function):
    # 線性變換
    z = tf.matmul(W, tf.transpose(x)) + b

    # 啟用函式
    a = activation_function(z)

    return a


# 進行前向傳播
output = forward_pass(x, W, b, activation_function)

print("Output:", output.numpy())

### 程式碼解釋

1. **匯入庫**:
   - 匯入 TensorFlow 和 NumPy。

2. **設定隨機種子**:
   - 設定 NumPy 的隨機種子,以便每次執行時得到相同的結果。

3. **輸入向量**:
   - `x` 是一個 1x3 的向量,表示輸入資料。

4. **權重矩陣和偏置向量**:
   - `W` 是一個 5x3 的矩陣,表示權重。
   - `b` 是一個 1x5 的向量,表示偏置。

5. **啟用函式**:
   - 使用 ReLU 啟用函式 `tf.nn.relu`。

6. **前向傳播函式**:
   - `forward_pass` 函式接受輸入向量、權重矩陣、偏置向量和啟用函式作為引數。
   - 線性變換:`z = tf.matmul(W, tf.transpose(x)) + b`。
   - 啟用函式:`a = activation_function(z)`。

7. **執行前向傳播**:
   - 呼叫 `forward_pass` 函式,得到輸出 `output`。

8. **輸出結果**:
   - 列印輸出結果。

### 多層網路的前向傳播

對於多層神經網路,前向傳播的過程會在每個層中遞迴進行。以下是一個包含多個層的前向傳播示例:

```python
# 定義多層前向傳播函式
def multi_layer_forward_pass(x, layers):
    current_input = x
    for i, layer in enumerate(layers):
        W, b, activation_function = layer
        z = tf.matmul(W, tf.transpose(current_input)) + b
        current_input = activation_function(z)
    return current_input

# 定義多個層
layers = [
    (tf.Variable(tf.random.normal([5, 3])), tf.Variable(tf.zeros([5])), tf.nn.relu),
    (tf.Variable(tf.random.normal([5, 5])), tf.Variable(tf.zeros([5])), tf.nn.relu),
    (tf.Variable(tf.random.normal([10, 5])), tf.Variable(tf.zeros([10])), tf.nn.softmax)
]

# 進行多層前向傳播
output = multi_layer_forward_pass(x, layers)

print("Output:", output.numpy())

程式碼解釋

  1. 多層前向傳播函式

    • multi_layer_forward_pass 函式接受輸入向量和一個包含多個層的列表。
    • 每個層包含權重矩陣、偏置向量和啟用函式。
    • 對於每個層,依次進行線性變換和啟用函式的計算。
  2. 定義多個層

    • layers 是一個包含多個層的列表,每個層包含權重矩陣、偏置向量和啟用函式。
  3. 執行多層前向傳播

    • 呼叫 multi_layer_forward_pass 函式,得到輸出 output

透過這種方式,你可以理解和實現單個或多個神經網路層上的前向傳播過程。這對於構建和訓練神經網路是非常重要的基礎。

相關文章