我一直试图通过以下网站上的文章创建一个小型神经网络来学习softmax函数:https://mlxai.github.io/2017/01/09/implementing-softmax-classifier-with-vectorized-operations.html
它适用于单次迭代。但是,当我创建一个用更新权重训练网络的循环时,我得到以下错误:ValueError:操作数不能与形状(5,10)(1,5)(5,10)一起广播。我在这里附上了输出的屏幕截图。
调试这个问题,我发现即使轴被设置为1,np.max()也会在不同的迭代中返回shape(5,1)和(1,5)的数组。请帮我确定一下在以下代码中出错。
import numpy as np
N = 5
D = 10
C = 10
W = np.random.rand(D,C)
X = np.random.randint(255, size = (N,D))
X = X/255
y = np.random.randint(C, size = (N))
#print (y)
lr = 0.1
for i in range(100):
print (i)
loss = 0.0
dW = np.zeros_like(W)
N = X.shape[0]
C = W.shape[1]
f = X.dot(W)
#print (f)
print (np.matrix(np.max(f, axis=1)))
print (np.matrix(np.max(f, axis=1)).T)
f -= np.matrix(np.max(f, axis=1)).T
#print (f)
term1 = -f[np.arange(N), y]
sum_j = np.sum(np.exp(f), axis=1)
term2 = np.log(sum_j)
loss = term1 + term2
loss /= N
loss += 0.5 * reg * np.sum(W * W)
#print (loss)
coef = np.exp(f) / np.matrix(sum_j).T
coef[np.arange(N),y] -= 1
dW = X.T.dot(coef)
dW /= N
dW += reg*W
W = W - lr*dW
答案 0 :(得分:3)
在您的第一次迭代中,W
是形状为np.ndarray
的{{1}}的实例。 (D, C)
会继承f
,因此当您执行ndarray
时,它会返回一个np.max(f, axis = 1)
形状ndarray
,(D,)
变为形状{{} 1}}然后转换为np.matrix()
但是在您的后续迭代中,(1, D)
是(D, 1)
的实例(它继承自W
中的np.matrix
)。 dW
然后会继承W = W - lr*dW
,而f
会返回np.matrix
形状np.max(f, axis = 1)
,它会np.matrix
未定相,然后变成{{1}在(D, 1)
要解决此问题,请确保不要将np.matrix()
与(1, D)
混合。要么将所有内容从头开始定义为.T
(例如np.ndarray
),要么使用np.matrix
来维护您的轴:
np.matrix
可让您保留所有2D内容而无需转换为W = np.matrix(np.random.rand(D,C))
。(也为keepdims
执行此操作)