То, что вы сделали, будет работать нормально. Тем не менее, более переносимым подходом будет использование reshape
, которое будет возвращать представление, когда это возможно, но будет создавать непрерывную копию при необходимости. Таким образом, он сделает все возможное. В вашем случае данные должны быть скопированы, но всегда используя reshape
, есть случаи, когда копия не будет создана.
Так что вы можете использовать
out[:,0,:].reshape(-1)
Попался
Здесь есть одна важная ошибка. Если вы выполняете операции на месте для вывода reshape
, то это может повлиять или не повлиять на исходный тензор в зависимости от того, было ли возвращено представление или копия.
Например, предполагая out
уже является смежным, тогда в этом случае
>>> x = out[:,0,:].reshape(-1) # returns a copy
>>> x[0] = 10
>>> print(out[0,0,0].item() == 10)
False
x
является копией, поэтому изменения в ней не влияют на out
. Но в этом случае
>>> x = out[:,:,0].reshape(-1) # returns a view
>>> x[0] = 10
>>> print(out[0,0,0].item() == 10)
True
x
является представлением, поэтому изменения на месте на x
также изменят out
.
Альтернативы
Альтернативой пары являются
out[:,0,:].flatten() # .flatten is just a special case of .reshape
и
out[:,0,:].contiguous().view(-1)
Хотя, если вы хотите самый быстрый подход, я рекомендую против последнего метода, использующего contiguous().view
, поскольку, как правило, более вероятно, чем reshape
или flatten
, чтобы вернуть копию. Это связано с тем, что contiguous
создаст копию, даже если базовые данные имеют одинаковое количество байтов между последующими записями. Следовательно, существует разница между
out[:,:,0].contiguous().view(-1) # creates a copy
и
out[:,:,0].flatten() # creates a non-contiguous view (b/c underlying data has uniform spacing of out.shape[2] values between entries)
, когда подход contiguous().view
приводит к принудительному копированию, поскольку out[:,:,0]
не является смежным, а flatten
/ reshape
создаст представление, поскольку базовые данные расположены равномерно.
Иногда contiguous()
не создает копию, например, сравнивает
out[0,:,:].contiguous().view(-1) # creates a view b/c out[0,:,:] already is contiguous
и
out[0,:,:].flatten() # creates a view
которые оба производят просмотр исходных данных без копирования, так как out[0,:,:]
уже является смежным.
Если вы хотите убедиться, что out
полностью отделен от сплющенного аналога, тогда исходный подход использование .clone()
- это путь к go.