我一直在尝试创建一个小型神经网络,通过以下网站上的一篇文章学习softmax函数: https://mlxai.github.io/2017/01/09/implementing-softmax-classifier-with-vectorized-operations.html
它对于单个迭代非常有效。但是,当我创建一个循环以使用更新的权重训练网络时,我得到了以下错误:ValueError:操作数不能与形状(5,10)(1,5)(5,10)一起广播。我在这里附上了输出的屏幕截图。
调试这个问题时,我发现np。max()返回不同迭代次数下的形状(5,1)和(1,5)数组,即使轴设置为1。请帮助我识别以下代码中的错误。
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
在第一次迭代中, W 是的实例 np.ndarray 带形状 (D, C) 。 f 继承 ndarray ,所以当你 np.max(f, axis = 1) ,它返回一个 恩达雷 形状的 (D,) 哪一个 np.matrix() 变成形状 (1, D) 然后将其转换为 (D, 1)
W
np.ndarray
(D, C)
f
ndarray
np.max(f, axis = 1)
恩达雷
(D,)
np.matrix()
(1, D)
(D, 1)
但在接下来的迭代中, W 是的实例 np.matrix (继承自 dW 在里面 W = W - lr*dW )。 f 然后继承 np。矩阵 和 np。最大值(f,轴=1) 返回a np。矩阵 形状的 (D,1) ,通过 np。矩阵() 无相位并成形 (1,D) 之后 .T
np.matrix
dW
W = W - lr*dW
np。矩阵
np。最大值(f,轴=1)
(D,1)
np。矩阵()
(1,D)
.T
要解决这个问题,请确保您不要混音 np。恩达雷 具有 np。矩阵 。要么把一切都定义为 np。矩阵 从一开始(即。 W = np.matrix(np.random.rand(D,C)) )或使用 keepdims 要维护轴,请执行以下操作:
np。恩达雷
W = np.matrix(np.random.rand(D,C))
keepdims
f -= np.max(f, axis = 1, keepdims = True)
这样你就可以把所有东西都保持为2D,而不需要强制转换到 np。矩阵 。(也可针对 sum_j )
sum_j