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

Python神经网络训练停滞求助:大卫之星点分类任务

大卫之星坐标分类神经网络训练问题解决方案

针对你开发的2层/4层神经网络训练仅首轮有效、后续权重更新停滞的问题,以下是具体的修复建议:

1. 输入数据归一化

你的输入坐标是0-1000的数值,直接传入sigmoid会导致激活函数饱和(sigmoid在|x|>5时梯度趋近于0),反向传播时梯度消失,权重无法更新。

修改方案:将输入缩放到0-1区间:

def normalize_points(points):
    return np.array(points) / 1000.0  # 把0-1000的坐标缩放到0-1

# 生成数据后执行归一化
points = set_of_points(1000)
normalized_points = normalize_points(points)
points_train = normalized_points[:800]  # 增大训练集
points_test = normalized_points[800:]
labels_train = np.array(labels[:800])
labels_test = np.array(labels[800:])

2. 修正权重初始化

4层网络的权重用np.random.randint(0,1000)生成了过大的初始值,导致前向传播的输入直接触发sigmoid饱和,梯度消失。

修改方案:使用小范围正态分布或Xavier初始化:

# 替换NeuralNetwork类__init__中的权重初始化代码
self.weights = np.random.normal(0, 0.1, (2, 1))  # 2层网络权重
# 4层网络权重(Xavier初始化,适合sigmoid)
def xavier_init(in_dim, out_dim):
    scale = np.sqrt(1.0 / (in_dim + out_dim))
    return np.random.uniform(-scale, scale, (in_dim, out_dim))
self.weights1 = xavier_init(2, 6)
self.weights2 = xavier_init(6, 2)
self.weights3 = xavier_init(2, 1)

3. 修复反向传播逻辑

2层网络反向传播

原代码手动循环易出错,改用向量运算简化:

def back_prop1(self, learning_rate, output, label, input):
    error = output - label
    delta = error * sigmoid_derivative(output)
    # 向量形式更新权重,避免循环错误
    self.weights -= learning_rate * delta * input.reshape(-1, 1)

4层网络反向传播

原代码存在矩阵维度错误、中间值复用初始化数据、循环逻辑混乱的问题,修复后如下:

# 先修改forward2,保存前向传播的中间结果
def forward2(self, input):
    self.z1 = np.dot(input, self.weights1)
    self.a1 = sigmoid(self.z1)
    self.z2 = np.dot(self.a1, self.weights2)
    self.a2 = sigmoid(self.z2)
    self.z3 = np.dot(self.a2, self.weights3)
    self.a3 = sigmoid(self.z3)
    return self.a3

# 修正反向传播
def back_prop2(self, learning_rate, output, label, input):
    error = output - label
    # 输出层梯度
    delta3 = error * sigmoid_derivative(output)
    self.weights3 -= learning_rate * self.a2.reshape(-1, 1) * delta3
    # 第二层梯度
    delta2 = np.dot(delta3, self.weights3.T) * sigmoid_derivative(self.a2)
    self.weights2 -= learning_rate * self.a1.reshape(-1, 1) * delta2
    # 第一层梯度
    delta1 = np.dot(delta2, self.weights2.T) * sigmoid_derivative(self.a1)
    self.weights1 -= learning_rate * input.reshape(-1, 1) * delta1

4. 修正预测阈值

原test函数中用output > 500/output > 800作为判断条件完全错误——sigmoid的输出范围是0-1,导致预测全为0,准确率固定。

修改方案:

# test函数中替换预测判断逻辑
# 2层网络
if output > 0.5:
    prediction = 1
else:
    prediction = 0

# 4层网络同理
if output > 0.5:
    prediction = 1
else:
    prediction = 0

5. 调整训练参数

  • 增大训练集:原训练集仅10个样本,模型无法学习到足够模式,改为800个样本(如上)。
  • 降低学习率:原learning_rate=26过大,会导致权重震荡或发散,改为learning_rate=0.1,可根据训练情况微调。
  • 打乱训练集:每轮epoch前打乱样本顺序,避免模型陷入局部最优:
def train(network, inputs, labels, epochs, learning_rate, quest):
    loss = []
    for j in range(epochs):
        # 打乱训练集顺序
        perm = np.random.permutation(len(inputs))
        shuffled_inputs = inputs[perm]
        shuffled_labels = labels[perm]
        
        errors_in_epoch = []
        # 后续用shuffled_inputs和shuffled_labels遍历训练
        # ...(原训练逻辑不变,替换样本集即可)

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.19 16:47:02