机器学习算法原理实现——神经网络反向传播,链式求导核心

发布时间 2023-09-10 22:25:33作者: bonelee

记得先看之前的梯度下降文章!

 

 

 链式求导的核心来了,就高中数学知识:

 

代码实现:

import numpy as np
import matplotlib.pyplot as plt

# Sigmoid 激活函数及其导数
def sigmoid(z):
    return 1 / (1 + np.exp(-z))

def sigmoid_derivative(z):
    return sigmoid(z) * (1 - sigmoid(z))

# 前向传播
def forward(x, w, b):
    z = w * x + b
    return sigmoid(z), z

# 反向传播
def backward(y_pred, y_true, z, x):
    dz = (y_pred - y_true) * sigmoid_derivative(z)
    dw = dz * x
    db = dz
    return dw, db

# 初始化参数
w = 2
b = 1
# 生成数据:在真实函数上加入噪声
np.random.seed(42)
x = np.linspace(0, 5, 100)
y_true = 1 / (1 + np.exp(-(2 * x + 1))) # 这是我们的真实函数
y_true = y_true + np.random.normal(0, 0.02, len(x)) # 加入噪声

alpha = 0.1
epochs = 1000

losses = []

# 训练过程
for epoch in range(epochs):
    total_loss = 0
    for i in range(len(x)):
        y_pred, z = forward(x[i], w, b)
        error = y_true[i] - y_pred
        total_loss += error ** 2
        dw, db = backward(y_pred, y_true[i], z, x[i])
        
        # 更新参数
        w = w - alpha * dw
        b = b - alpha * db
    
    # 保存每个 epoch 的损失值
    losses.append(total_loss / len(x))
    if epoch % 100 == 0:
        print(f"Epoch {epoch}/{epochs} - Loss: {total_loss / len(x)}")


# 绘制预测值与实际值对比
y_preds = [forward(i, w, b)[0] for i in x]
plt.plot(x, y_true, 'ro', label="True values")
plt.plot(x, y_preds, 'bo', label="Predicted values")
plt.title("Predicted vs True values")
plt.xlabel("x")
plt.ylabel("y")
plt.legend()

plt.tight_layout()
plt.show()

  

看看输出: