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

反向传播算法不收敛求助:单隐藏层神经网络预测错误排查

单隐藏层神经网络的关键错误排查

你的代码存在多处核心逻辑错误,这些错误直接导致网络无法正确学习,以下是具体问题和修正方案:

1. 前向传播的致命错误:Z2计算误用Z1而非A1

在fit和predict方法中,计算输出层线性组合Z2时,你错误使用了隐藏层的原始线性输出Z1,而非经过sigmoid激活后的A1。这导致隐藏层的非线性变换完全失效,网络退化为线性模型,根本无法拟合非线性数据。

错误代码:

# fit方法中
Z2 = np.dot(Z1, self.output_weights) + self.output_bias
# predict方法中
Z2 = np.dot(Z1, self.output_weights) + self.output_bias

修正后:

# fit方法中
Z2 = np.dot(A1, self.output_weights) + self.output_bias
# predict方法中
Z2 = np.dot(A1, self.output_weights) + self.output_bias

2. 隐藏层权重更新的维度与梯度错误

self.hidden_weights的形状是(输入特征数, 隐藏节点数),而delta_hidden_layer是(隐藏节点数,)的向量。直接用delta_hidden_layer更新权重会触发维度不匹配错误,且正确的梯度应该是输入样本x_one与delta_hidden_layer的外积(每个输入特征对每个隐藏节点的梯度贡献)。

错误代码:

self.hidden_weights -= self.alpha*delta_hidden_layer

修正后:

self.hidden_weights -= self.alpha * np.outer(x_one, delta_hidden_layer)

3. 隐藏层偏置更新逻辑错误

隐藏层每个节点的偏置梯度就是对应位置的delta_hidden_layer值,不需要对error_hidden_layer求和——求和会抹除每个节点的独立梯度信息,导致偏置更新完全错误。

错误代码:

self.hidden_bias -= self.alpha*np.sum(error_hidden_layer)

修正后:

self.hidden_bias -= self.alpha * delta_hidden_layer

4. 输出层权重更新的梯度计算错误

self.output_weights的形状是(隐藏节点数, 1),正确的梯度应该是隐藏层激活输出A1与delta_output_layer的外积,这样才能匹配权重的维度。直接使用delta_output_layer更新会导致维度不匹配,且梯度计算完全错误。

错误代码:

self.output_weights -= self.alpha*delta_output_layer

修正后:

self.output_weights -= self.alpha * np.outer(A1, delta_output_layer)

5. 输出层偏置更新优化

输出层偏置的梯度就是delta_output_layer本身,不需要对原始error求和——delta_output_layer已经包含了误差与激活导数的乘积,是更准确的梯度值。

错误代码:

self.output_bias -= self.alpha*np.sum(error)

修正后:

self.output_bias -= self.alpha * delta_output_layer

修正后的完整代码

import numpy as np

class ShallowNeuralNetwork:
    
    def sigmoid(self, val):
        return 1 / (1 + np.exp(-val))
    
    def sigmoid_derivative(self, val):
        return val *(1 - val)
    
    def __init__(self, hidden_nodes, alpha, epochs):
        self.hidden_nodes = hidden_nodes
        self.alpha = alpha
        self.epochs = epochs
        self.hidden_weights = None
        self.hidden_bias = None
        self.output_weights = None
        self.output_bias = None
                
    def fit(self, X, y):
        self.hidden_weights = np.random.rand(X.shape[1], self.hidden_nodes)
        self.hidden_bias = np.random.rand(self.hidden_nodes)
        self.output_weights = np.random.rand(self.hidden_nodes,1)
        self.output_bias = np.random.rand(1)
        
        for _ in range(self.epochs):
            for x_one, y_one in zip(X, y):
                Z1 = np.dot(x_one, self.hidden_weights) + self.hidden_bias
                A1 = self.sigmoid(Z1)
                # 修正Z2的计算,使用A1而非Z1
                Z2 = np.dot(A1, self.output_weights) + self.output_bias
                A2 = self.sigmoid(Z2)
                
                error = A2 - y_one
                delta_output_layer = error * self.sigmoid_derivative(A2)
                error_hidden_layer = np.dot(delta_output_layer, self.output_weights.T)
                delta_hidden_layer = error_hidden_layer * self.sigmoid_derivative(A1)

                # 修正隐藏层权重更新
                self.hidden_weights -= self.alpha * np.outer(x_one, delta_hidden_layer)
                # 修正隐藏层偏置更新
                self.hidden_bias -= self.alpha * delta_hidden_layer
                # 修正输出层权重更新
                self.output_weights -= self.alpha * np.outer(A1, delta_output_layer)
                # 修正输出层偏置更新
                self.output_bias -= self.alpha * delta_output_layer

    def predict(self, X):
        Z1 = np.dot(X, self.hidden_weights) + self.hidden_bias
        A1 = self.sigmoid(Z1)
        # 修正Z2的计算,使用A1而非Z1
        Z2 = np.dot(A1, self.output_weights) + self.output_bias
        pred = self.sigmoid(Z2)
        return pred

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.02 18:11:10