Не удалось определить форму массива numpy в цикле, содержащем операцию транспонирования
Я пытался создать небольшую нейронную сеть для изучения функции 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
1 ответ
В вашей первой итерации, W
это пример np.ndarray
с формой (D, C)
, f
наследуется ndarray
поэтому, когда вы делаете np.max(f, axis = 1)
, он возвращает ndarray
формы (D,)
, который np.matrix()
превращается в форму (1, D)
который затем переносится в (D, 1)
Но на ваших следующих итерациях, W
это пример np.matrix
(от которого он наследует dW
в W = W - lr*dW
). f
потом наследует np.matrix
, а также np.max(f, axis = 1)
возвращает np.matrix
формы (D, 1)
, который проходит через np.matrix()
без фазы и превращается в форму (1, D)
после .T
Чтобы это исправить, убедитесь, что вы не смешиваете np.ndarray
с np.matrix
, Либо определите все как np.matrix
с самого начала (т.е. W = np.matrix(np.random.rand(D,C))
) или использовать keepdims
поддерживать ваши оси как:
f -= np.max(f, axis = 1, keepdims = True)
что позволит вам сохранить все 2D без необходимости приведения к np.matrix
.(также сделайте это для sum_j
)