Вычисление линейного слоя в пространстве Tensor / Outer-Product в PyTorch очень медленное - PullRequest
1 голос
/ 02 февраля 2020

Я хотел бы создать модель PyTorch, которая берет на себя внешний продукт входных данных, а затем выполняет линейную регрессию. В качестве примера рассмотрим входной вектор [1,2,3], тогда я бы хотел вычислить w и b для оптимизации [1*1, 1*2, 1*3, 2*1, 2*2, 2*3, 3*1, 3*2, 3*3] @ w + b.

Для пакета input с r строками и c столбцов, я могу сделать это в PyTorch с

(input.reshape(r,c,1) @ input.reshape(r,1,c)).reshape(r,c**2) @ weigts + b

Моя проблема в том, что он чрезвычайно медленный. Как в 1000 раз медленнее и потребляет больше памяти, чем при добавлении полностью подключенного слоя c*c RELU, даже если он имеет такое же количество весов.

Мой вопрос: почему это происходит?

Является ли reshape очень дорогой операцией для PyTorch? Могу ли я переформулировать это по-другому, что сделало бы вещи более эффективными?

Другая эквивалентная формулировка, которую я знаю, это torch.diag(input @ weights @ input.T) + b, но теперь мы вычисляем намного больше значений, чем нам нужно (r*r), только чтобы бросить их снова прочь.

Ответы [ 2 ]

1 голос
/ 03 февраля 2020

Оказывается, у PyTorch есть torch.bilinear, который поддерживается CUDA и делает именно то, что мне нужно. Это аккуратно и очень быстро. Это все еще оставляет случай тензорирования высшего порядка. Я не вижу никаких torch.trilinear и так далее, но пока это здорово.

1 голос
/ 02 февраля 2020

Когда вам нужно изменить форму тензора во время обучения l oop модели, всегда лучше использовать view вместо изменения формы. Похоже, что с представлением не возникает никаких проблем с производительностью, но требуется, чтобы данные тензора были непрерывными.

Если ваши тензоры в начале не являются непрерывными , вы можете скопировать их заново. тензор и сделать его непрерывным .

...