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

神经网络训练循环问题:权重转Series后取值及循环正确性排查

神经网络训练问题解答

咱们一步步来解决你的这些问题,先还原你的代码场景:

样本数据与变量定义

import pandas as pd
import numpy as np

# 原始样本数据,复制生成100条观测值
data = [
 [3.5, 1.5, 1],
 [2.0, 1.0, 0],
 [4.0, 1.5, 1],
 [3.0, 1.0, 0],
 [3.5, 0.5, 1],
 [2.0, 0.5, 0],
 [5.5, 1.0, 1],
 [1.0, 1.0, 0]
]
data = pd.DataFrame(data, columns = ["Length", "Width", "Class"])

# 初始化权重与偏置
w1 = np.random.randn()
w2 = np.random.randn()
b = np.random.randn()
print(w1)
print(w2)
print(b)

训练循环代码

# 注意:这里需要先定义sigmoid和sigmoid_p函数,否则会报错
def sigmoid(z):
    return 1 / (1 + np.exp(-z))

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

# 扩展数据集为100条
train_data = pd.concat([data]*12 + [data[:4]], ignore_index=True)

learning_rate = 0.2
for x in range(50000):
 z = train_data["Length"] * w1 + train_data["Width"] + b  # 这里有错误!
 preds = sigmoid(z)
 target = train_data["Class"]
 cost = np.square(preds - target)
 derivcost_pred = 2 * (preds - target)
 derivpred_sigp = sigmoid_p(z)
 dcost_dz = derivcost_pred * derivpred_sigp
 dz_dw1 = train_data["Length"]
 dz_dw2 = train_data["Width"]
 dz_db = 1
 dcost_dw1 = dcost_dz * dz_dw1
 dcost_dw2 = dcost_dz * dz_dw2
 dcost_db = dcost_dz * dz_db
 w1 = w1 - learning_rate * dcost_dw1
 w2 = w2 - learning_rate * dcost_dw2
 b = b - learning_rate * dcost_db

问题1:如何获取训练完成后w1、w2、b的最终值?

你现在训练完后参数变成Series,核心原因是参数更新时用了单个样本的梯度而非平均梯度。正确的做法是在计算梯度后取所有样本的均值,这样参数始终保持单个数值类型,训练结束后直接打印就能拿到最终值。

修正后的参数更新逻辑:

# 计算梯度时取均值
dcost_dw1 = (dcost_dz * dz_dw1).mean()
dcost_dw2 = (dcost_dz * dz_dw2).mean()
dcost_db = dcost_dz.mean()  # dz_db是1,直接取dcost_dz的均值

# 更新参数
w1 = w1 - learning_rate * dcost_dw1
w2 = w2 - learning_rate * dcost_dw2
b = b - learning_rate * dcost_db

训练完成后,直接执行print("最终权重:w1={}, w2={}, b={}".format(w1, w2, b))就能得到单一的最终值。


问题2:当权重变为Series类型时,如何访问其最后一个值?

如果已经因为代码错误让参数变成了Series,有几种简单的方式取最后一个元素:

  • 用pandas的位置索引:w1.iloc[-1](最推荐的标准写法)
  • 转成numpy数组后取最后一个:w1.values[-1]
  • 快速访问单个位置:w1.iat[-1](适合取单个元素,速度略快)

不过还是建议优先修正训练循环的逻辑,让参数保持数值类型,避免后续麻烦。


问题3:训练循环的逻辑/代码错误排查

这里有几个关键错误,按严重程度排序:

  1. 线性组合z的计算遗漏w2乘法
    原代码中z = train_data["Length"] * w1 + train_data["Width"] + b,正确的线性组合应该是z = train_data["Length"] * w1 + train_data["Width"] * w2 + b——你完全漏掉了w2和Width的乘积项,这直接导致w2的更新毫无意义,等于模型没用到第二个特征!

  2. 梯度未取平均,导致参数类型异常
    批量梯度下降需要用所有样本的平均梯度更新参数,但你现在计算的dcost_dw1等是每个样本对应的梯度(一个Series),直接用它更新参数会让w1从单个数值变成和样本数量一样长的Series,完全不符合参数更新的逻辑。必须对梯度取均值,如问题1中的修正代码。

  3. 变量名不匹配
    你前面定义的数据集是data,但训练循环里用的是train_data,需要先把data扩展成100条观测值并赋值给train_data,比如:

    train_data = pd.concat([data]*12 + [data[:4]], ignore_index=True)
    
  4. 缺少sigmoid及导数函数的定义
    代码里用到了sigmoid(z)和sigmoid_p(z),但未给出定义,必须先补充这两个函数(我已经在前面的代码示例中补上了)。

  5. 可选优化:损失函数选择
    你现在用的是平方损失,对于逻辑回归(sigmoid激活的二分类任务),交叉熵损失会更合适,平方损失在sigmoid的饱和区梯度会非常小,导致训练缓慢。如果需要优化,可以把损失换成交叉熵:

    # 交叉熵损失
    cost = - (target * np.log(preds) + (1 - target) * np.log(1 - preds)).mean()
    # 对应的梯度会更简洁,dcost_dz = preds - target,不需要再乘2*(preds-target)
    

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.12 04:55:58