实现Delta Rule时遇TypeError:'int'对象不可下标化求助
搞定Delta Rule实现里的TypeError和相关疑问
嘿,让我们一步步解决你遇到的问题:
一、先搞懂那个TypeError的根源
你碰到的TypeError: 'int' object is not subscriptable,核心原因是用错了np.dot:
- 当你写
y[i,j]和w[i,j]时,取到的都是单个标量(y里的是整数,w里的是浮点数)。 np.dot是用来计算向量、矩阵之间的点积的,它内部会尝试对输入做下标遍历,但标量(比如单个int)根本没有下标,所以就报错了。
至于你说归一化后错误消失,这其实是个巧合——大概率是你归一化时不小心改了代码逻辑(比如误把y[i,j]写成了y[i]这种向量),但归一化本身和这个错误没有直接关联。
二、修复错误的代码修改
把np.dot(y[i,j],w[i,j])换成直接相乘就行,因为这里你要的就是对应位置元素的乘积,不是点积:
import numpy as np import random y = np.array([[ 45, 85, -1], [ 50, 43, -1], [ 40, 80, -1], [ 55, 42, -1], [200, 43, -1], [ 48, 40, -1], [195, 41, -1], [ 43, 87, -1], [190, 40, -1]]) w = np.random.uniform(low=-1, high=1, size=(9,3)) o = np.zeros(shape=(9,3)) net = np.zeros(shape=(9,3)) e = np.e # 用numpy自带的自然常数比手动输入更准确 for i in range(9): for j in range(3): net[i,j] = y[i,j] * w[i,j] # 替换np.dot为直接乘法 o[i,j] = 2/(1 + e**(-net[i,j])) - 1 print(f"net[{i},{j}]: {net[i,j]}") print(f"o[{i},{j}]: {o[i,j]}")
三、关于激活函数的疑问解答
你想要o数组有类似np.sign的功能但输出浮点型,你现在用的公式2/(1+e^(-net)) -1其实是双曲正切函数的变形:
- 它的值域是
(-1, 1),和np.sign的输出范围完全匹配,趋势也一致:net为正的时候趋近于1,为负时趋近于-1,等于0时就是0,而且是连续的浮点输出,正好符合你的需求。 - 如果想让输出更接近
np.sign的离散感,可以给net做个缩放(比如乘以一个较大的数),这样函数会变得更陡,输出会更接近±1。
四、归一化导致net为0的解决办法
你提到归一化后最小值为0,导致部分net为0影响计算:
- 可以改用均值归一化:
(x - 均值) / (最大值 - 最小值),这样数据会分布在[-0.5, 0.5]左右,能避免大量0值出现。 - 或者用标准化:
(x - 均值) / 标准差,让数据分布在均值为0、标准差为1的区间,也能解决这个问题。
内容的提问来源于stack exchange,提问作者Bianca Trifanescu
相关产品推荐
相关产品推荐

