Вычисление квадратичного отклика с использованием линейной алгебры - PullRequest
0 голосов
/ 17 октября 2019

У меня проблемы с манипулированием матрицами в numpy. У меня есть вектор из N входных данных, тета, и я хочу вычислить скалярный ответ, используя квадратичную модель, тета ^ TA, тета + тета ^ T b + c, где ^ T обозначает транспонирование, A - квадратная матрица NxN, b -N-мерный вектор, а с скаляр. Когда тэта представляет собой (NxM) матрицу, то есть у меня есть M-тета-значения для распространения, я должен вычислить тета-TA-тета, чтобы получить M-мерную матрицу. В индексной нотации вычислением является theta_ {mj} A_ {ji} theta_ {im}, где m не нужно суммировать.

Если у меня есть только один набор тэта-значений, линейная алгебра numpy работает как положено (здесь N = 10 и M = 1):

In [1]: import numpy as np                                            

In [2]: theta = np.ones(10)                                           

In [3]: A = np.ones((10, 10))                                         

In [4]: b = np.ones(10)                                               

In [5]: theta.T.dot(A).dot(theta) + theta.T.dot(b) + 1                
Out[5]: 111.0

Я думаю, что операция тета ^ TAтета может отличаться от точечного произведения здесь. Я не понимаю, что принципиально отличается, когда я делаю тета-матрицу NxM. Я думал, что дополнительное измерение будет естественным образом выполнять этот код, как это происходит с терминами b и c.

Как я могу заставить numpy возвращать M-мерный массив из операции theta ^ TA theta?

Я могу только сделать так, чтобы он возвращал квадратные матрицы. Функция точечного произведения, к сожалению, рассматривает эту операцию как матричное умножение (здесь N = 10 и M = 5):

In [6]: theta = np.ones((10, 5))
#       theta.T.dot(A).dot(theta) is equivalient to:
#             
#                 (M x N)           (N x N)  (N x M)
In [7]: np.matmul(theta.T, np.matmul(A,     theta))                      
Out[7]: 
array([[100., 100., 100., 100., 100.],
       [100., 100., 100., 100., 100.],
       [100., 100., 100., 100., 100.],
       [100., 100., 100., 100., 100.],
       [100., 100., 100., 100., 100.]]) 

Напротив, термины b и c естественно содержат дополнительные тета-термины и обеспечиваютМ-мерный вывод хочу:

In [8]: theta.T.dot(b) + 1                                           
Out[8]: array([11., 11., 11., 11., 11.])

1 Ответ

1 голос
/ 17 октября 2019

Две возможности:

N,M = 10,5
A = np.random.randint(0,10,(N,N))
theta = np.random.randint(0,10,(N,M))
b = np.random.randint(0,10,N)

1) использовать тот факт, что> двумерные операнды обрабатываются как матрица:

(theta.T[:,None]@A@theta.T[...,None])[...,0,0] + b@theta + 1
# array([ 8188, 14837,  7697,  9719,  7262])

или

2) использоватьeinsum

np.einsum("ik,ij,jk->k",theta,A,theta) + b@theta + 1
# array([ 8188, 14837,  7697,  9719,  7262])

Сравнение с оценкой по отдельности для проверки:

[t@A@t + b@t + 1 for t in theta.T]
# [8188, 14837, 7697, 9719, 7262]
...