Вопрос или проблема
Я хочу, чтобы мой тензор с плавающей запятой размерности Mx2xN стал комплексным тензором размерности MxN.
В этом минимальном примере я предоставляю матрицу 10×2, которая должна стать вектором [0+10j, 1+11j, 2+12k,…]
x = torch.stack([torch.arange(10.),torch.arange(10.,20)])
torch.view_as_complex(x.T)
выдает ошибку RuntimeError: Tensor must have a last dimension with stride 1
, потому что x.T.stride()
равно (1,10)
Попробуем
>>> x.T.as_strided(size=(2,10),stride=(10,1)).T.stride()
(1, 10)
Это не помогло, как эффективно это конвертировать?
Нашел это как хак, является ли это эффективным решением?
torch.complex(*x)
это распаковывает первое измерение и передает его в действительное и комплексное измерения
Ответ или решение
Понимание механики представления и шагов тензоров в PyTorch
При работе с тензорами в PyTorch, важно осознавать, как устроены представления (views) и шаги (strides) тензоров, особенно когда речь идет о преобразовании их формы. В данном случае мы имеем дело с необходимостью преобразовать тензор размером Mx2xN в тензор размером MxN с комплексными числами.
Проблема преобразования
Пример, который вы привели, показывает, что попытка выполнить операцию torch.view_as_complex()
на транспонированном тензоре x.T
вызывает ошибку RuntimeError: Tensor must have a last dimension with stride 1
. Это связано с тем, что для корректного выполнения данного метода необходимо, чтобы последняя размерность вашего тензора имела шаг равный 1. В случае с x.T
шаги имеют значения (1, 10)
, что не соответствует данной требованиям.
Изменение формы тензора
Когда вы вызвали x.T.as_strided(size=(2,10),stride=(10,1)).T.stride()
, вы попытались изменить шаги, но, тем не менее, последние шаги все еще остаются (1, 10)
. Это значит, что ваша модификация не достигает цели, которая заключается в получении шага последней размерности равным 1.
Для достижения желаемого результата, вы можете воспользоваться функцией torch.view()
для создания нового представления вашего тензора. Его использование требует, чтобы тот же интересующий тензор был организован так, чтобы соответствовать указанным требованиям.
Рабочее решение
Вы упомянули об использовании torch.complex(*x)
, что есть на самом деле довольно элегантное решение вашей задачи. Данная функция эффективно распаковывает первую размерность вашего тензора и подает его в качестве вещественной и мнимой части, что в конечном итоге приводит к созданию тензора комплексных чисел:
import torch
x = torch.stack([torch.arange(10.), torch.arange(10., 20)])
complex_tensor = torch.complex(*x)
Это простое и эффективное решение, так как оно позволяет избежать дополнительных манипуляций с шагами и представлениями тензоров.
Резюме
Объединяя вышеизложенное, ваше первоначальное преобразование тензоров в PyTorch требует понимания механики шагов и структуры данных. Решение с использованием torch.complex(*x)
оказывается наиболее эффективным, обрабатывая данные непосредственно и минимизируя вероятность ошибок, связанных с изменением шагов и форм. Важно также помнить о требованиях к размерности, особенно когда вы работаете с преобразованиями, чтобы избежать таких ошибок, как RuntimeError
.
Используйте это знание для оптимизации вашего кода и более глубокого понимания работы с тензорами в PyTorch, что в свою очередь улучшит производительность ваших моделей и алгоритмов машинного обучения.