Python Numpy Матричное умножение / Форма не совместима / Не соответствует математике? - PullRequest
0 голосов
/ 09 апреля 2020

Рассмотрим следующий код:

X = np.array([[1,1,1],
            [2,2,2],
            [3,3,3],
            [4,4,4]]) # shape of (4,3)

print("Matrix X is:\n", X)


print("\n --------- TEST 1 ---------\n")

W = np.array([1,2,3]) # 1D array (row)
print("W is:", W)
print("X * W is:\n", X*W)

print("\n --------- TEST 2 ---------\n")

W = np.array([[1,2,3]]) # 2D array (shape 1,3)
print("W is:", W)
print("X * W is:\n", X*W)


print("\n --------- TEST 3 ---------\n")

W = np.array([[1,2,3]]).T # 2D array (shape 3,1)
print("W is:\n", W)
print("X * W is:\n", X*W)


print("\n --------- TEST 4 ---------\n")

W = np.array([1,2,3]) # 1D array (row)
print("W is:\n", W)
print("X @ W is:\n", X@W.T) # dot product


print("\n --------- TEST 5 ---------\n")

W = np.array([[1,2,3]]) # 2D array (shape 1,3)
print("W is:\n", W)
print("X @ W is:\n", X@W.T) # dot product


print("\n --------- TEST 6 ---------\n")

W = np.array([[1,2,3]]).T # 2D array (shape 3,1)
print("W is:\n", W)
print("X @ W is:\n", X@W) # dot product

Выход (без теста 3):

Matrix X is:
 [[1 1 1]
 [2 2 2]
 [3 3 3]
 [4 4 4]]

 --------- TEST 1 ---------

W is: [1 2 3]
X * W is:
 [[ 1  2  3]
 [ 2  4  6]
 [ 3  6  9]
 [ 4  8 12]]

 --------- TEST 2 ---------

W is: [[1 2 3]]
X * W is:
 [[ 1  2  3]
 [ 2  4  6]
 [ 3  6  9]
 [ 4  8 12]]

 --------- TEST 4 ---------

W is:
 [1 2 3]
X @ W is:
 [ 6 12 18 24]

 --------- TEST 5 ---------

W is:
 [[1 2 3]]
X @ W is:
 [[ 6]
 [12]
 [18]
 [24]]

 --------- TEST 6 ---------

W is:
 [[1]
 [2]
 [3]]
X @ W is:
 [[ 6]
 [12]
 [18]
 [24]]

Проблема:

Тест 3 завершится неудачно со следующим сообщением об ошибке:

ValueError: не удалось передать операнды вместе с фигурами (4,3) (3,1 )

Однако математически это неверно и должно работать просто отлично. Матрица N-col, умноженная на матрицу или вектор N-строк, является допустимой математической операцией. И в этом случае есть 3 столбца в X и 3 строки в W. Так что же происходит?

Я ожидал бы такого рода ошибки от Теста 1 и Теста 2, но, возможно, может понять, как numpy будет "изменить" W, чтобы они совпадали. Но ошибка в Test3? Неужели?

Я полагаю, это как-то связано с вещанием в Numpy? Кажется математически несколько противоречивым. Нужно ли Numpy иметь столбцы множителя (2-й множитель / с этого момента «F2») всегда в форме, совпадающей со столбцами мультипликатора (1-й множитель / с этого момента «F1»)? Таким образом, в основном он проходит через каждую строку в F1 и умножает каждый столбец этой строки на столбец F2?

Просто для повторения этого математически правильного: Cols F1 = Rows F2. И вот кажется, что: Cols F1 = Cols F2.

И еще:

Расширение этого до точечного продукта после Теста 3, технически Тест 6 не должен работать и но внезапно это происходит (и математически правильно!).

Кроме этого теста 6 математически solid для меня, поэтому здесь нет вопросов.

Прав ли я со следующими предположениями:

Тест 4:

Если F2 - это 1-мерный вектор строки, скалярное произведение будет работать точно так же (как если бы это был вектор-столбец), но будет выводить 1-мерный вектор строки. В этом единственная реальная разница с таким умножением? Под капотом происходит точно такая же работа, как если бы это был двухмерный вектор?

Тест 5:

Итак, математически я предполагаю, что Numpy является "автоматически преобразующимся" F2 (строка) внутренне в столбец, так что тест 6 и тест 5 действительно одинаковы.

PS: Написание этого вопроса, я думаю, я понял, что Numpy соответствует позиции снова позиции. Почти как система сеток карт. Однако, что Тест 3 не позволен все еще сбивает с толку меня, чтобы быть честным. Имеет смысл, если вы смотрите, что «сетки» не совпадают друг с другом, но наверняка это могло быть реализовано? Если тест 6 работает, я не понимаю, почему тест 3 не должен.

Спасибо!

Ответы [ 2 ]

2 голосов
/ 09 апреля 2020

Я думаю, вы путаете оператор * с оператором @.

  • Первым является поэлементное умножение , и формы двух операндов должны совпадать или иметь возможность быть "переданными".
  • Последний - матричное умножение , поэтому вы можете использовать его, только если X.shape[1] совпадает с W.shape[0].

Ошибка, которую вы получаете в Тесте 3, заключается в том, что numpy широковещательная рассылка следует заданным c правилам, которые можно найти здесь и неприменимо в тесте 3, с другой стороны, в тесте 6 вы можете выполнять умножение матриц должным образом.

1 голос
/ 09 апреля 2020

Если X и W не являются numpy.matrix, * используется не для умножения матриц, а для вещания.

Как вы можете проверить в вещательной документации эта операция работает только тогда, когда

оба измерения равны или один из них равен 1

. Именно поэтому она работает в тестах 1 и 2. Как только W имеет форму (1 , 3) во время операции он будет растянут в массив с (4,3) формой

Подробнее о трансляции и растяжении массива можно узнать здесь .

В тесте 3 W имеет форму (3,1), которая вызывает конфликт в первом измерении (4 из X и 3 из W) , поскольку она не соблюдает 2 вышеупомянутых правила. С другой стороны, второе измерение было бы прекрасно (3,1)

...