无法确定包含转置操作的循环中 numpy 数组的形状
Could not determine shape of numpy array in a loop containing transpose operation
我一直在尝试创建一个小型神经网络来学习 softmax 函数,文章来自以下网站:https://mlxai.github.io/2017/01/09/implementing-softmax-classifier-with-vectorized-operations.html
它适用于单次迭代。但是,当我创建一个循环来训练具有更新权重的网络时,出现以下错误:ValueError:操作数无法与形状 (5,10) (1,5) (5,10) 一起广播。我在这里附上了输出的屏幕截图。
调试这个问题,我发现 np.max() returns 形状数组 (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)
时,它 returns 一个形状 (D,)
的 ndarray
,np.matrix()
变成变成 (1, D)
形状,然后转置为 (D, 1)
但是在您接下来的迭代中,W
是 np.matrix
的一个实例(它继承自 W = W - lr*dW
中的 dW
)。 f
则继承np.matrix
,np.max(f, axis = 1)
returns一个np.matrix
形(D, 1)
,无相地通过np.matrix()
变成.T
之后的形状 (1, D)
要解决此问题,请确保不要将 np.ndarray
与 np.matrix
混用。从一开始就将所有内容定义为 np.matrix
(即 W = np.matrix(np.random.rand(D,C))
),或者使用 keepdims
来维护您的坐标轴,例如:
f -= np.max(f, axis = 1, keepdims = True)
这将使您无需转换为 np.matrix
即可保留所有 2D 内容。(sum_j
也这样做)
我一直在尝试创建一个小型神经网络来学习 softmax 函数,文章来自以下网站:https://mlxai.github.io/2017/01/09/implementing-softmax-classifier-with-vectorized-operations.html
它适用于单次迭代。但是,当我创建一个循环来训练具有更新权重的网络时,出现以下错误:ValueError:操作数无法与形状 (5,10) (1,5) (5,10) 一起广播。我在这里附上了输出的屏幕截图。
调试这个问题,我发现 np.max() returns 形状数组 (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)
时,它 returns 一个形状 (D,)
的 ndarray
,np.matrix()
变成变成 (1, D)
形状,然后转置为 (D, 1)
但是在您接下来的迭代中,W
是 np.matrix
的一个实例(它继承自 W = W - lr*dW
中的 dW
)。 f
则继承np.matrix
,np.max(f, axis = 1)
returns一个np.matrix
形(D, 1)
,无相地通过np.matrix()
变成.T
(1, D)
要解决此问题,请确保不要将 np.ndarray
与 np.matrix
混用。从一开始就将所有内容定义为 np.matrix
(即 W = np.matrix(np.random.rand(D,C))
),或者使用 keepdims
来维护您的坐标轴,例如:
f -= np.max(f, axis = 1, keepdims = True)
这将使您无需转换为 np.matrix
即可保留所有 2D 内容。(sum_j
也这样做)