一、概述
本代碼實現了一個簡單的神經網絡進行線性回歸任務。通過生成包含噪聲的線性數據集,定義一個簡單的神經網絡類,使用梯度下降算法訓練網絡以擬合數據,并最終通過可視化展示原始數據、真實線性關系以及模型的預測結果。
二、依賴庫
numpy
:用于數值計算,包括生成數組、進行隨機數操作、執行數學運算等。matplotlib.pyplot
:用于數據可視化,繪制散點圖和折線圖以展示數據和模型的預測結果。
三、代碼詳解
1. 生成數據集
python
np.random.seed(42)
x = np.linspace(-10, 10, 100)
y = x + np.random.normal(0, 1, x.shape) # 添加噪聲
np.random.seed(42)
:設置隨機數種子,確保每次運行代碼時生成的隨機數序列相同,從而使結果可復現。np.linspace(-10, 10, 100)
:生成一個包含 100 個元素的一維數組x
,元素均勻分布在 - 10 到 10 之間。x + np.random.normal(0, 1, x.shape)
:生成因變量y
,它基于真實的線性關系y = x
,并添加了均值為 0、標準差為 1 的高斯噪聲。np.random.normal(0, 1, x.shape)
生成與x
形狀相同的隨機噪聲數組。
2. 定義神經網絡(線性回歸)
python
class SimpleNN:def __init__(self):self.w = np.random.randn() # 權重self.b = np.random.randn() # 偏置def forward(self, x):return self.w * x + self.b # 前向傳播def loss(self, y_true, y_pred):return np.mean((y_true - y_pred) **2) # 均方誤差def gradient(self, x, y_true, y_pred):dw = -2 * np.mean(x * (y_true - y_pred)) # 權重的梯度db = -2 * np.mean(y_true - y_pred) # 偏置的梯度return dw, dbdef train(self, x, y, lr=0.01, epochs=1000):for epoch in range(epochs):y_pred = self.forward(x)dw, db = self.gradient(x, y, y_pred)self.w -= lr * dw # 更新權重self.b -= lr * db # 更新偏置if (epoch + 1) % 100 == 0:print(f'Epoch [{epoch+1}/{epochs}], Loss: {self.loss(y, y_pred):.4f}')
__init__
方法:初始化神經網絡的權重self.w
和偏置self.b
,使用np.random.randn()
生成隨機的初始值。forward
方法:實現前向傳播,根據輸入x
、權重self.w
和偏置self.b
計算輸出y_pred
,即y_pred = self.w * x + self.b
。loss
方法:計算預測值y_pred
和真實值y_true
之間的均方誤差(MSE),公式為np.mean((y_true - y_pred) ** 2)
。gradient
方法:計算權重self.w
和偏置self.b
的梯度。dw
是權重的梯度,計算公式為-2 * np.mean(x * (y_true - y_pred))
;db
是偏置的梯度,計算公式為-2 * np.mean(y_true - y_pred)
。train
方法:使用梯度下降算法訓練神經網絡。在指定的epochs
(訓練輪數)內,每次迭代進行前向傳播計算預測值y_pred
,然后計算梯度dw
和db
,根據學習率lr
更新權重self.w
和偏置self.b
。每 100 輪打印一次當前輪數和損失值。
3. 訓練模型
python
model = SimpleNN()
model.train(x, y, lr=0.01, epochs=1000)
SimpleNN()
:創建一個SimpleNN
類的實例model
。model.train(x, y, lr=0.01, epochs=1000)
:調用model
的train
方法,使用生成的數據集x
和y
,學習率lr=0.01
,訓練輪數epochs=1000
進行訓練。
4. 可視化結果
python
y_pred = model.forward(x)
plt.scatter(x, y, label='Data points')
plt.plot(x, x, color='red', label='y = x')
plt.plot(x, y_pred, color='green', label='Predicted')
plt.legend()
plt.show()
model.forward(x)
:使用訓練好的模型model
對數據集x
進行前向傳播,得到預測值y_pred
。plt.scatter(x, y, label='Data points')
:繪制原始數據集的散點圖,標簽為Data points
。plt.plot(x, x, color='red', label='y = x')
:繪制真實的線性關系y = x
的折線圖,顏色為紅色,標簽為y = x
。plt.plot(x, y_pred, color='green', label='Predicted')
:繪制模型預測結果的折線圖,顏色為綠色,標簽為Predicted
。plt.legend()
:顯示圖例,方便區分不同的圖形。plt.show()
:顯示繪制好的圖形。
四、注意事項
- 本代碼實現的是一個簡單的線性回歸神經網絡,實際應用中可能需要更復雜的模型結構和優化方法。
- 學習率
lr
和訓練輪數epochs
是超參數,可能需要根據具體數據和任務進行調整以獲得更好的訓練效果。 - 代碼中使用的均方誤差損失函數和梯度計算公式是針對線性回歸問題的常見選擇,但在其他問題中可能需要使用不同的損失函數和梯度計算方法。
完整代碼
import numpy as np
import matplotlib.pyplot as plt# 1. 生成數據集
np.random.seed(42)
x = np.linspace(-10, 10, 100)
y = x + np.random.normal(0, 1, x.shape) # 添加噪聲# 2. 定義神經網絡(線性回歸)
class SimpleNN:def __init__(self):self.w = np.random.randn() # 權重self.b = np.random.randn() # 偏置def forward(self, x):return self.w * x + self.b # 前向傳播def loss(self, y_true, y_pred):return np.mean((y_true - y_pred) **2) # 均方誤差def gradient(self, x, y_true, y_pred):dw = -2 * np.mean(x * (y_true - y_pred)) # 權重的梯度db = -2 * np.mean(y_true - y_pred) # 偏置的梯度return dw, dbdef train(self, x, y, lr=0.01, epochs=1000):for epoch in range(epochs):y_pred = self.forward(x)dw, db = self.gradient(x, y, y_pred)self.w -= lr * dw # 更新權重self.b -= lr * db # 更新偏置if (epoch + 1) % 100 == 0:print(f'Epoch [{epoch+1}/{epochs}], Loss: {self.loss(y, y_pred):.4f}')# 3. 訓練模型
model = SimpleNN()
model.train(x, y, lr=0.01, epochs=1000)# 4. 可視化結果
y_pred = model.forward(x)
plt.scatter(x, y, label='Data points')
plt.plot(x, x, color='red', label='y = x')
plt.plot(x, y_pred, color='green', label='Predicted')
plt.legend()
plt.show()