You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

纯Numpy实现三层单神经元神经网络权重无变化问题求助

问题分析与修复方案

问题描述

尝试用Numpy实现一个三层神经网络(输入层+ReLU隐藏层+Sigmoid输出层,每层仅1个神经元),通过梯度下降和均方误差(MSE)训练。数据集为随机生成的年龄数据:输入年龄>18时输出为1,否则为0。

现象:权重和偏置初始化为2,无论迭代多少epoch,权重与偏置均无变化,但损失值却在下降。网络结构如下:
(x)---((y1 = w1 * x + b1)|(z1 = relu(y1)))----((y2 = w2 * z1 + b2)|(z2 = sigmoid(y2)))

错误分析

代码存在多个关键bug导致权重偏置无法更新:

  • Sigmoid导数函数逻辑错误:d_of_sig函数中遍历空列表y(与函数内变量重名),且计算式错误,应使用输入值计算x*(1-x)。
  • ReLU导数的输入错误:计算dz1dy1时,应传入ReLU的输入y1而非输出z1,因为ReLU导数基于输入是否大于0判断。
  • 链式求导函数变量遗漏:多个链式求导循环中存在变量遍历不完整的问题,无法正确累积每个样本的梯度。
  • 未利用Numpy向量化:用列表循环实现运算,既低效又易出现索引错误。

修复后的完整代码

import numpy as np
import random as r

# 数据集生成
x = []
y = []
for i in range(100):
    age = r.randint(0, 80)
    x.append(age)
    y.append(1 if age > 18 else 0)
# 转换为numpy数组,支持向量化运算
x = np.array(x, dtype=np.float32)
y = np.array(y, dtype=np.float32)

# 前向传播函数
def sigmoid(x):
    return 1 / (1 + np.exp(-x))

def relu(x):
    return np.maximum(0, x)

def mse(y_true, y_pred):
    return np.mean((y_true - y_pred)**2)

# 反向传播导数函数
def dmse(y_true, y_pred):
    return 2 * (y_true - y_pred)

def d_relu(x):
    return np.where(x > 0, 1, 0)

def d_sigmoid(x):
    return x * (1 - x)

# 梯度下降实现
def gradient_descent(x, y, lr, epoch):
    w1 = w2 = b1 = b2 = 2.0
    for i in range(epoch):
        # 前向传播
        y1 = w1 * x + b1
        z1 = relu(y1)
        y2 = w2 * z1 + b2
        z2 = sigmoid(y2)
        cost = mse(y, z2)
        
        # 反向传播计算梯度
        dcdz2 = dmse(y, z2)
        dz2dy2 = d_sigmoid(z2)
        # 第二层权重/偏置梯度
        dw2 = np.mean(dcdz2 * dz2dy2 * z1)
        db2 = np.mean(dcdz2 * dz2dy2)
        
        # 第一层权重/偏置梯度
        dz1dy1 = d_relu(y1)
        dw1 = np.mean(dcdz2 * dz2dy2 * w2 * dz1dy1 * x)
        db1 = np.mean(dcdz2 * dz2dy2 * w2 * dz1dy1)
        
        # 更新参数
        w2 -= lr * dw2
        b2 -= lr * db2
        w1 -= lr * dw1
        b1 -= lr * db1
        
        # 可选:每10轮打印损失
        if (i+1) % 10 == 0:
            print(f"Epoch {i+1}, Cost: {cost:.4f}")
    
    return w2, b2, w1, b1, cost

# 执行训练
print(gradient_descent(x, y, 0.001, 300))

关键修改说明

  1. 修复导数计算:修正Sigmoid和ReLU导数的逻辑错误,确保梯度计算准确。
  2. 向量化重构:改用Numpy数组和向量化运算,简化代码并避免循环索引错误。
  3. 调整学习率:将原学习率0.1改为0.001,防止梯度爆炸,保证训练稳定。
  4. 优化参数更新:直接通过Numpy的均值计算批量梯度,替代复杂的循环累加。

内容的提问来源于stack exchange,提问作者PallabGhosh

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.09 00:40:30