使用NumPy演示​​實現神經網路過程

banq發表於2024-03-08

在不斷髮展的人工智慧(模擬智慧)領域,有一個想法經久不衰,並被證明是當今機器學習的基礎:人工神經網路(ANN)。這些計算模型在人類思維不可預測的神經元網路的推動下,在從影像識別到自然語言處理的任務中表現出了驚人的能力。在本文中,我們將繼續揭開人工神經網路內部功能的神秘面紗,並重點討論為什麼從頭開始構建神經網路可能是一次無價的學習體驗。

人工神經網路
人工神經網路,通常稱為神經網路,有著豐富的歷史,可以追溯到二十世紀中葉。他們的起源是由於渴望製造能夠模擬人類大腦複雜動態迴圈的機器。早期的開拓者,例如普萊恩·羅森布拉特(Plain Rosenblatt)和沃倫·麥卡洛克(Warren McCulloch),為神經網路奠定了假設性的準備,而直到現代處理技術出現之後,這些想法才可以用於所有意圖和目的。

人工神經網路的核心是包含互連中樞或神經元的計算模型。這些神經元協同工作來處理和改變輸入資訊,最終給出結果。神經元之間的每一個關聯都與一個權重相關,權重決定了關聯的強度。神經元將啟動能力應用於其反饋位的加權量,從而使模型熟悉非線性。

  • 您可能會問,當可以使用 TensorFlow 和 PyTorch 等強大的深度學習庫時,為什麼有人需要從頭開始執行神經網路。
  • 深度學習結構提供了預先組裝的神經網路層和準備技術,使複雜的任務看起來具有誤導性。即便如此,這種妥協往往是以犧牲理解為代價的。
  • 從頭開始構建神經網路需要考慮對模型每個部分的細粒度命令。當您遇到錯誤或不可預見的行為方式時,您不會被忽視。
  • 深度學習領域正處於永無止境的發展狀態。新模型、驅動能力和改進策略不斷出現。

神經元:計算單位
任何神經網路的核心都是神經元。這些是負責處理資料的計算單元。神經元獲取輸入、執行估計併產生結果。在神經網路中,神經元被協調成層,通常包括資訊層、至少一個秘密層和結果層。神經元之間的關聯(每個關聯都與權重相關)增強了資料流的能力。

前饋過程
前饋過程是資訊透過神經網路從資訊層移動到結果層的組成部分。可以很好地總結如下:

輸入層:資訊在資訊層中處理。

加權總計:後續層中的每個神經元都會計算出其反饋位的加權量。

啟用函式:加權總和經過啟用函式,呈現非線性。

結果:啟用函式的結果成為下一層的貢獻,並且過程重新雜湊,直到到達結果層。

啟用函式:新增非線性
啟用函式在神經網路中扮演著重要的角色。它們呈現非線性,使神經網路能夠學習複雜的例子。兩個正常的啟用函式是 sigmoid 函式和 Corrected Direct Unit (ReLU) 函式:

Sigmoid 函式:它將資訊值壓縮在 0 到 1 之間的某個位置,可以將其解讀為機率。它對於配對錶徵問題的結果層很有幫助。

ReLU 函式:如果資訊值確定並且為零,它會生成資訊值。ReLU 因其輕鬆性和可行性而成為大多數隱藏層的預設選擇。

權重初始化和偏差項
神經網路中的負載對於學習來說是緊迫的。權重宣告包括設定這些負載的潛在優勢。正常程式包括任意介紹、Xavier/Glorot 和 He 陳述。適當的重量引入可以完全影響製備過程。

偏差項是神經元中新增的物質常數。它們允許神經元透過移動啟用函式的結果來顯示更復雜的功能。每個神經元都有其偏置項。

使用 NumPy 的神經網路實現程式碼過程

第 1 步:製作資料集
為了使用我們的神經網路,我們需要一個資料集來訓練和測試其表現:
生成示例:我們表徵字母 A、B 和 C 的矩陣示例。這些示例充當訓練和測試神經網路的輸入資料。每個示例都是雙重連續,用於解決單獨字母的狀態。


# 建立資料集  
letter_a = np.array([ 0 ,  0 ,  1 ,  1 ,  0 ,  0 ,  0 ,  1 ,  0 ,  0 ,  1 ,  0 ,  1 ,  1 ,  1 ,  1 ,  1 ,  1 ,  1 ,  0 ,  0 ,  0 ,  0 ,  1 ,  0 ,  0 ,  0 ,  0 ,  1 ])  
letter_b = np.array([ 0 ,  1 ,  1 ,  1 ,  1 ,  0 ,  0 ,  1 ,  0 ,  0 ,  1 ,  0 ,  0 ,  1 ,  1 ,  1 ,  1 ,  1 ,  1 ,  0 ,  0 ,  0 ,  0 ,  1 ,  0 ,  0 ,  0 ,  0 ,  1 ])  
letter_c = np.array([ 0 ,  1 ,  1 ,  1 ,  1 ,  0 ,  0 ,  1 ,  0 ,  0 ,  0 ,  0 ,  0 ,  1 ,  0 ,  0 ,  0 ,  0 ,  1 ,  0 ,  0 ,  0 ,  0 ,  1 ,  0 ,  0 ,  0 ,  0 ,  1 ])  
  
# 將模式合併到資料集中  
x = np.array([letter_a, letter_b, letter_c])  

步驟 2:描述標籤特徵
對於定向學習來說,我們希望標記能展示正確的反應:

命名資料:我們為字母 A、B 和 C 標出了單次編碼標記。
單次編碼是一種從數學角度處理直觀資料的方法,其中每一類都具有顯著的並行價值。在訓練過程中,這些名稱允許神經網路學習並將設計與其相關字母聯絡起來。

# Define labels (one-hot encoding)  
y = np. array([[1, 0, 0], [0, 1, 0], [0, 0, 1]])  

步驟 3:匯入程式庫並確定啟用函式的特性
在這一基礎步驟中,我們將建立神經網路:

匯入庫:我們匯入基本庫,如用於熟練數學任務的 NumPy 和用於資料視覺化的 Matplotlib。這些庫為我們提供了構建和評估神經網路所需的工具。

定義西格碼Sigmoid啟用函式:我們將描述神經網路的關鍵部分--西格碼啟用函式。該函式將非線性引入網路輸出,使其能夠展示資料中的複雜連線。

import numpy as np  
import matplotlib.pyplot as plt  
  
# Activation function (Sigmoid)  
def sigmoid(x):  
    return 1 / (1 + np.exp(-x))  

步驟 4:初始化權重
在這一步中,我們要為神經網路的可學習邊界設定基礎條件:

權重Weights:我們建立一個函式,為神經網路中神經元之間的關聯建立不規則權重。
這些權重非常重要,因為它們控制著資料在訓練過程中如何透過網路。
雜亂無章地隨機引入權重可以讓網路從資料中獲益,並長期調整權重。
(權重可能是代表不同上下文、場景和語境,不同權重能夠讓神經網路在不同場景下訓練學習,就像小孩要多動,多換不同場景,對小孩智力有好處)

# Initialize weights randomly  
def generate_weights(input_size, output_size):  
    return np.random.randn(input_size, output_size)  

步驟 5:描述前饋神經網路的特徵
這一步描述神經網路的工程和前向傳遞特性:

定義神經網路設計:我們確定神經網路的結構,記住每一層的層數和神經元數。在這種情況下,我們有一個輸入層、一個隱藏層和一個輸出層。前饋函式接收輸入,並透過這些層來計算網路的輸出。

# Create the Feedforward Neural Network  
輸入層 Input layer (1, 30)  
# 隱藏層Hidden layer (1, 5)  
輸出層 Output layer (3, 3)  
def feed_forward(x, w1, w2):  
    # Hidden layer  
    z1 = x.dot(w1)  # Input from layer 1  
    a1 = sigmoid(z1)  # Output of layer 2  
  
    # Output layer  
    z2 = a1.dot(w2)  # Input of output layer  
    a2 = sigmoid(z2)  # Output of output layer  
    return a2  

第 6 步:確定損失函式的特徵
在這一步中,我們將介紹神經網路如何評估其演示:

定義損失函式:我們描述了均方誤差(MSE:mean squared error)損失函式的特徵,該函式用於估算預期輸出與真實客觀質量之間的差異。MSE 可評估神經網路的預測與真實資料的吻合程度,為網路在訓練過程中計劃限制的數學收益提供依據。

# Mean Square Error (MSE) Loss Function  
def loss(output, target):  
    squared_error = np.square(output - target)  
    mean_squared_error = np.mean(squared_error)  
    return mean_squared_error  

步驟 7:誤差反向傳播
在這一步中,我們將根據預測誤差設定重新整理神經網路權重的元件:

執行反向傳播:我們進行反向傳播計算,這是訓練神經網路的重要部分。反向傳播計算有關網路權重損失的斜率,使我們能夠朝著減少損失的方向改變權重。這種迭代迴圈對網路的學習和演示工作至關重要。

這些基本步驟為構建、訓練和評估不同任務的神經網路奠定了基礎。程式碼中的後續步驟將在這些標準的基礎上進行擴充套件,從而形成一個完整的神經網路,並將其應用於特定問題。

# Backpropagation of error  
def back_propagation(x, y, w1, w2, learning_rate):  
    # Hidden layer  
    z1 = x.dot(w1)  # Input from layer 1  
    a1 = sigmoid(z1)  # Output of layer 2  
  
    # Output layer  
    z2 = a1.dot(w2)  # Input of output layer  
    a2 = sigmoid(z2)  # Output of output layer  
  
    # Error in the output layer  
    d2 = (a2 - y)  
    d1 = np.multiply(w2.dot(d2.T).T, np.multiply(a1, 1 - a1))  
  
    # w1 和 w2 的梯度  ;
    w1_gradient = x.T.dot(d1)  
    w2_gradient = a1.T.dot(d2)  
  
    # Update parameters  
    w1 -= learning_rate * w1_gradient  
    w2 -= learning_rate * w2_gradient  
  
    return w1, w2  


步驟 8:訓練神經網路
在這一步中,我們的中心工作是訓練神經網路,以便從資料集中獲取資訊,並在一段時間後進行改進:

訓練函式:我們確定一個專門的函式來訓練神經網路。該功能包括在預定的年齡段內對資料集進行強調。在每個年齡段,網路都會進行預測,處理精確度和損失測量,並利用反向傳播計算更新權重。結果就是一個不斷髮展的神經網路,它能從資料中獲益,並努力改善其表現形式。

# Training the neural network  
def train_neural_network(x, y, w1, w2, learning_rate=0.01, epochs=10):  
    accuracy = []  
    losses = []  
      
    for epoch in range(epochs):  
        epoch_losses = []  
        for i in range(len(x)):  
            output = feed_forward(x[i], w1, w2)  
            loss_value = loss(output, y[i])  
            epoch_losses.append(loss_value)  
            w1, w2 = back_propagation(x[i], y[i], w1, w2, learning_rate)  
          
        accuracy.append((1 - (sum(epoch_losses) / len(x))) * 100)  
        losses.append(sum(epoch_losses) / len(x))  
          
        print(f'Epoch: {epoch + 1}, Accuracy: {accuracy[-1]:.2f}%')  
      
    return accuracy, losses, w1, w2  


步驟 9:使用訓練後的模型進行預測
神經網路經過訓練後,往往會用於預測:

預測函式:我們將訓練好的模型(如 trained_w1 和 trained_w2)和輸入設計作為輸入,建立一個函式。該函式根據輸出層的最大輸出值預測最可能的字母(A、B 或 C)。這一步驟展示瞭如何將訓練有素的神經網路應用於新資料以進行預測。

# Predicting the letter from an input pattern  
def predict_letter(input_pattern, w1, w2):  
    output = feed_forward(input_pattern, w1, w2)  
    max_index = np.argmax(output)  
      
    if max_index == 0:  
        return 'A'  
    elif max_index == 1:  
        return 'B'  
    else:  
        return 'C'  

步驟 10:為訓練初始化權重
要開始訓練,我們需要為神經網路設定入門條件:

權重初始化:我們以不規則質量初始化權重 w1 和 w2。這些權重決定了資料如何在網路中移動,是學習的重要組成部分。不規則的初始化為網路提供了一個獲取資料的起始階段。

# Initialize weights  
w1 = generate_weights(30, 5)  
w2 = generate_weights(5, 3)  

步驟 11:訓練神經網路
準備好資料、標記和權重後,我們繼續訓練神經網路:

訓練互動:我們呼叫訓練函式(如 train_neural_network)來啟動訓練系統。神經網路會反覆重新整理權重、篩選精度和損失,並改變其邊界,以便在無數次(訓練週期)中進一步提高執行力。訓練包括調整網路以做出準確預測。

# Train the neural network  
acc, losses, trained_w1, trained_w2 = train_neural_network(x, y, w1, w2, learning_rate=0.1, epochs=100) 

輸出:

Epoch: 1, Accuracy: 33.33%
Epoch: 2, Accuracy: 66.67%
Epoch: 3, Accuracy: 66.67%
Epoch: 4, Accuracy: 66.67%
Epoch: 5, Accuracy: 66.67%
Epoch: 6, Accuracy: 66.67%
Epoch: 7, Accuracy: 66.67%
Epoch: 8, Accuracy: 66.67%
Epoch: 9, Accuracy: 66.67%
Epoch: 10, Accuracy: 66.67%
Epoch: 11, Accuracy: 66.67%
Epoch: 12, Accuracy: 66.67%
Epoch: 13, Accuracy: 66.67%
Epoch: 14, Accuracy: 66.67%
Epoch: 15, Accuracy: 66.67%
Epoch: 16, Accuracy: 66.67%
Epoch: 17, Accuracy: 66.67%
Epoch: 18, Accuracy: 66.67%
Epoch: 19, Accuracy: 66.67%
Epoch: 20, Accuracy: 66.67%
Epoch: 21, Accuracy: 66.67%
Epoch: 22, Accuracy: 66.67%
Epoch: 23, Accuracy: 66.67%
Epoch: 24, Accuracy: 66.67%
Epoch: 25, Accuracy: 66.67%
Epoch: 26, Accuracy: 66.67%
Epoch: 27, Accuracy: 66.67%
Epoch: 28, Accuracy: 66.67%
Epoch: 29, Accuracy: 66.67%
Epoch: 30, Accuracy: 66.67%
Epoch: 31, Accuracy: 66.67%
Epoch: 32, Accuracy: 66.67%
Epoch: 33, Accuracy: 66.67%
Epoch: 34, Accuracy: 66.67%
Epoch: 35, Accuracy: 66.67%
Epoch: 36, Accuracy: 66.67%
Epoch: 37, Accuracy: 66.67%
Epoch: 38, Accuracy: 66.67%
Epoch: 39, Accuracy: 66.67%
Epoch: 40, Accuracy: 66.67%
Epoch: 41, Accuracy: 66.67%
Epoch: 42, Accuracy: 66.67%
Epoch: 43, Accuracy: 66.67%
Epoch: 44, Accuracy: 66.67%
Epoch: 45, Accuracy: 66.67%
Epoch: 46, Accuracy: 66.67%
Epoch: 47, Accuracy: 66.67%
Epoch: 48, Accuracy: 66.67%
Epoch: 49, Accuracy: 66.67%
Epoch: 50, Accuracy: 66.67%
Epoch: 50, Accuracy: 66.67%
Epoch: 51, Accuracy: 100.00%
Epoch: 52, Accuracy: 100.00%
Epoch: 53, Accuracy: 100.00%
Epoch: 54, Accuracy: 100.00%
Epoch: 55, Accuracy: 100.00%
Epoch: 56, Accuracy: 100.00%
Epoch: 57, Accuracy: 100.00%
Epoch: 58, Accuracy: 100.00%
Epoch: 59, Accuracy: 100.00%
Epoch: 60, Accuracy: 100.00%
Epoch: 61, Accuracy: 100.00%
Epoch: 62, Accuracy: 100.00%
Epoch: 63, Accuracy: 100.00%
Epoch: 64, Accuracy: 100.00%
Epoch: 65, Accuracy: 100.00%
Epoch: 66, Accuracy: 100.00%
Epoch: 67, Accuracy: 100.00%
Epoch: 68, Accuracy: 100.00%
Epoch: 69, Accuracy: 100.00%
Epoch: 70, Accuracy: 100.00%
Epoch: 71, Accuracy: 100.00%
Epoch: 72, Accuracy: 100.00%
Epoch: 73, Accuracy: 100.00%
Epoch: 74, Accuracy: 100.00%
Epoch: 75, Accuracy: 100.00%
Epoch: 76, Accuracy: 100.00%
Epoch: 77, Accuracy: 100.00%
Epoch: 78, Accuracy: 100.00%
Epoch: 79, Accuracy: 100.00%
Epoch: 80, Accuracy: 100.00%
Epoch: 81, Accuracy: 100.00%
Epoch: 82, Accuracy: 100.00%
Epoch: 83, Accuracy: 100.00%
Epoch: 84, Accuracy: 100.00%
Epoch: 85, Accuracy: 100.00%
Epoch: 86, Accuracy: 100.00%
Epoch: 87, Accuracy: 100.00%
Epoch: 88, Accuracy: 100.00%
Epoch: 89, Accuracy: 100.00%
Epoch: 90, Accuracy: 100.00%
Epoch: 91, Accuracy: 100.00%
Epoch: 92, Accuracy: 100.00%
Epoch: 93, Accuracy: 100.00%
Epoch: 94, Accuracy: 100.00%
Epoch: 95, Accuracy: 100.00%
Epoch: 96, Accuracy: 100.00%
Epoch: 97, Accuracy: 100.00%
Epoch: 98, Accuracy: 100.00%
Epoch: 99, Accuracy: 100.00%
Epoch: 100, Accuracy: 100.00%

步驟 12:列印訓練過的權重
訓練結束後,我們可以檢視神經網路的學習邊界:

訓練過的權重:我們將列印訓練過的權重、trained_w1 和 trained_w2。這些權重涉及神經網路透過訓練獲得的內部資訊。它們決定了網路處理輸入資料和進行預測的方式。

# Print the trained weights  
print(<font>"Trained w1:\n", trained_w1)  
print(
"Trained w2:\n", trained_w2)  


輸出:

Trained w1:
 [[ 0.06927115  0.7170005   0.33890342 -0.3954869  -0.21926859]
 [ 0.39601103  0.24753036  0.62160906  0.63111717 -0.05278294]
 [ 0.18818433 -0.37276832 -0.30979065  0.11647701 -0.21607048]
 [-0.46407453 -0.36126427  0.57640027  0.0487203  -0.42107692]
 [-0.46414489  0.46295603  0.46470836 -0.00936389 -0.22831723]
 [-0.26479341 -0.46326617 -0.37647503  0.0966695   0.13562841]
 [ 0.15554735  0.48902724  0.09104169  0.44204394 -0.36605067]
 [-0.03405944  0.04821714  0.29438268 -0.18500043 -0.18425598]
 [ 0.4287369  -0.43919064  0.20607397 -0.39208925  0.01190859]
 [ 0.03697536 -0.2565317   0.49294935 -0.40878913 -0.0538658 ]
 [ 0.09247709 -0.46691897  0.2993611  -0.44151021 -0.11589155]
 [ 0.44711659  0.43345584 -0.14237594 -0.26750368 -0.35513504]
 [-0.40188012  0.15407098  0.20029012 -0.37305893  0.31064633]
 [-0.10865365 -0.19502014 -0.35841558  0.42077795  0.01395011]
 [-0.47082317  0.42016455  0.33085363 -0.36138929 -0.01264705]
 [ 0.35739056 -0.44810259  0.28772079 -0.47210845 -0.01000285]
 [ 0.28254812  0.23523711 -0.33713807  0.26875264 -0.29387359]
 [ 0.42204963  0.00467407 -0.35421835 -0.33040688 -0.00828009]
 [-0.17754328  0.01683268 -0.48541489 -0.44149293 -0.18717054]
 [ 0.09807447  0.22537154  0.18945719  0.43059284 -0.08616275]
 [ 0.44205102 -0.37058663 -0.00536636 -0.16823561 -0.38458703]
 [-0.2124118   0.26696481 -0.22020708  0.30137899  0.45820239]
 [-0.20769434 -0.10460072 -0.30606344 -0.36652411  0.31277555]
 [-0.2070754   0.15518452  0.23822402  0.45175688 -0.20221053]
 [ 0.29657844 -0.44922159 -0.20853836 -0.05554754 -0.05145613]
 [ 0.37466171 -0.26950233 -0.34559416 -0.45765506 -0.29738787]
 [ 0.16390897  0.45549364 -0.29073935 -0.21781543  0.41897006]
 [-0.37249767 -0.35012648 -0.08188436 -0.2364289   0.35996595]
 [ 0.21530958  0.12035867  0.2270742  -0.1902335   0.17511611]
 [-0.38768864  0.0706518  -0.02868765  0.00820532 -0.33814097]]

Trained w2:
 [[-0.51545134 -1.00575607  0.19420588]
 [-0.49013258 -0.9501272  -0.1448687 ]
 [ 0.76347089  1.28824926 -0.10032262]
 [ 0.43072838  0.72880314 -0.02726307]
 [ 0.08850882  0.22300994 -0.47452975]]

第 13 步:利用訓練的模型進行預測
有了訓練有素的神經網路,我們就可以將其應用於可證明的情況:

預測:我們利用訓練有素的模型對另一個輸入設計進行預測。將輸入透過網路,我們就能得到預測結果,顯示網路認為該示例與哪個字母(A、B 或 C)有關。這一步展示了訓練有素的模型的實用性。

# Make predictions with the trained model  
new_input = np.array([0, 1, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1])  
prediction = predict_letter(new_input, trained_w1, trained_w2)  
print(f'Predicted letter : {prediction}')  

輸出:
Predicted Letter: A
 

相關文章