MLP正弦函数任务权重更新报错排查:XOR正常但Sin(x1-x2+x3-x4)失效
unsupported operand type(s) for *: 'float' and 'builtin_function_or_method'错误 这个错误的根源非常清晰:你在update_weights函数里尝试用浮点数learning_rate和一个函数对象做乘法运算,而不是和预期的numpy数组运算。结合你的代码场景,问题肯定出在self.delta_weights1或self.delta_weights2的定义环节。
最可能的触发原因
你大概率是在初始化delta_weights1/delta_weights2的时候,把数组生成函数的名称直接赋值给了变量,而没有调用函数(加括号并传入形状参数)。举个典型的错误例子:
# ❌ 错误:把np.zeros这个函数对象赋值给了delta_weights1 self.delta_weights1 = np.zeros # ✅ 正确:调用np.zeros生成和weights1同形状的零数组 self.delta_weights1 = np.zeros_like(self.weights1)
当delta_weights1是一个函数对象时,learning_rate * self.delta_weights1自然会触发类型不兼容的错误。
排查与修复步骤
检查初始化代码
找到你定义self.delta_weights1和self.delta_weights2的地方,确认它们被初始化为numpy数组,而不是函数对象。比如如果self.weights1是(4, 8)形状的权重矩阵,对应的梯度数组应该这么初始化:self.delta_weights1 = np.zeros((4, 8)) # 或者更灵活的方式,自动匹配权重的形状 self.delta_weights1 = np.zeros_like(self.weights1)检查反向传播中的赋值
确保在反向传播计算梯度时,你是把计算得到的数值数组赋值给delta_weights,而不是不小心把某个未调用的函数(比如写了np.sum而不是np.sum(...))赋值给了它们。快速调试验证
在update_weights函数开头加一行调试代码,打印变量类型,直接定位问题:def update_weights(self, learning_rate): # 调试用:查看delta_weights的类型 print("delta_weights1类型:", type(self.delta_weights1)) print("delta_weights2类型:", type(self.delta_weights2)) self.weights1 = np.add(self.weights1, learning_rate * self.delta_weights1) self.weights2 = np.add(self.weights2, learning_rate * self.delta_weights2) # ... 后续代码如果输出里出现
<class 'builtin_function_or_method'>,那就能直接锁定是哪个变量出了问题。
为什么XOR任务没报错?
大概率是XOR任务的代码中,你正确初始化了delta_weights,或者在反向传播步骤中覆盖了错误的赋值;而正弦函数任务的代码里,delta_weights的初始化/赋值环节出现了上述的函数对象赋值错误。
内容的提问来源于stack exchange,提问作者Bryce

