Не удалось определить форму массива 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)

Другие вопросы по тегам