Как переписать используя numpy - PullRequest
0 голосов
/ 27 июня 2019

Мне интересно, как я могу переписать это, используя векторизацию с numpy, при условии, что я изменю все списки на numpy массивы.

# dcdw1 = m x m array
# a1 = len(x) x m array
# a2 = len(x) x 1 array
# w2 = m x 1 array
# x = len(x) x m array
# y = len(x) x 1 array



for i in range(len(x)):
      for j in range(m):
            for k in range(m):
                dcdw1[k, j] = (a2[i] - y[i]) * a2[i] * (1 - a2[i]) * w2[j] * a1[i, j] * (1 - a1[i, j]) * x[i, k]
      # other stuff that uses dcdw1

Ответы [ 2 ]

1 голос
/ 27 июня 2019

В этой строке

dcdw1[k, j] = (a2[i] - y[i]) * a2[i] * (1 - a2[i]) * w2[j] * a1[i, j] * (1 - a1[i, j]) * x[i, k]

длинная часть (a2[i] - y[i]) * a2[i] * (1 - a2[i]) * w2[j] * a1[i, j] * (1 - a1[i, j]), я назначу ее как temp, создаст массив len(x) x m, а x - массив len(x) x m. Таким образом, вы не можете получить массив m x m здесь только с помощью оператора *.

Вы имели в виду, что хотите добавить этот результат к dcdw1[k, j] для каждого i в range(len(x)), как показано ниже?

dcdw1 = np.zeros([m,m])
for i in range(len(x)):
      for j in range(m):
            for k in range(m):
                dcdw1[k, j] += (a2[i] - y[i]) * a2[i] * (1 - a2[i]) * w2[j] * a1[i, j] * (1 - a1[i, j]) * x[i][k]

Если это так, вот код, который вы хотите:

import numpy as np

# dcdw1 = m x m array
# a2 = len(x) x 1 array
# y = len(x) x 1 array
# w2 = m x 1 array
# a1 = len(x) x m array
# x = len(x) x m 

temp = (a2-y) * a2 * (1-a2) * w2.T * a1 * (1-a1)
dcdw1 = np.dot(temp.T, x).T

Почему я использую w2.T? Поскольку w2 - это вектор-столбец с формой m x 1. Он не может быть передан в массив len(x) x m, потому что их количество строк не совпадает. Вместо этого я перенесу w2 так, чтобы количество столбцов совпадало с a1 * (1-a1) s '. Аналогично temp.

1 голос
/ 27 июня 2019
# dcdw1 = m x m array
# a1 = len(x) x m array
# a2 = len(x) x 1 array
# w2 = m x 1 array
# x = len(x) x m array
# y = len(x) x 1 array

import numpy as np
m = 10
lx = 4 # len(x)

dcdw1 = np.zeros([lx, m, m])
dcdw2 = np.zeros_like(dcdw1)
a1 = np.ones([lx, m]) * 0.5
a2 = np.ones([lx, 1]) * 2
w2 = np.ones([m, 1]) * 3
x = np.ones([lx, m]) * 4
y = np.ones([lx, 1]) * 5

for i in range(lx):
      for j in range(m):
            for k in range(m):
                dcdw1[i, k, j] = (a2[i] - y[i]) * a2[i] * (1 - a2[i]) * w2[j] * a1[i, j] * (1 - a1[i, j]) * x[i][k]
                # Why are you using j on rows and k on columns? anyways

print(dcdw1[-1])

first_term = np.reshape( (a2-y) * a2 * (1-a2), [lx, 1, 1] ) 
# this is on 3d tensor level applied to each matrix seperately
# corresponds to (a2[i] - y[i]) * a2[i] * (1 - a2[i])
print(first_term.shape) # [lx, 1, 1] obviously

a1_term = (a1 * (1-a1))[:, :, np.newaxis]
# On each matrix calculate this vector product [lx, m] and shape to [lx, m, 1]
print(a1_term.shape) 
row_level_term = a1_term * w2 # Element wise multiplication yet again
# w2 is [m, 1] so it is broadcasted to every matrix

row_level_tensor = first_term * row_level_term 
# this applies first term values to every matrix -> [lx, m, 1]
print(row_level_tensor.shape)

x = np.reshape(x, [lx, 1, 10])
# x is weird. Foreach matrix it is used as a coefficient for matrix rows
# x[i][k] # ignoring i, k is basically telling takes this row vector
# and dstack it m times with different coeffs
# to create giant linearly dependent matrices
print(x.shape)
dcdw2 = np.matmul(row_level_tensor, x) # mxm matrix product lx times
print(dcdw2[-1])

Это довольно некрасиво, но оно выполняет свою работу (две формы и новая ось, тьфу. Люди обычно не выполняют поэлементную матричную операцию над тензорами, я думаю, по крайней мере, я так не делаю).Я не любил переписывать dcdw1.Это выше создает тензор, где ваш текущий dcdw1 является последним элементом.Я проверил это по вашему последовательному коду с помощью циклов, и результат такой же.Вам нужно немного подправить текущий код.

Вот ссылка Colab кода.

Улучшения и предложения приветствуются.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...