torch.view
существует очень давно. Он вернет тензор с новой формой. Возвращенный тензор будет разделять подчиненные данные с исходным тензором. См. Документацию здесь .
С другой стороны, похоже, что torch.reshape
недавно появилась версия 0.4 . Согласно документу , этот метод будет
Возвращает тензор с теми же данными и количеством элементов, что и входные, но с указанной формой. По возможности, возвращаемый тензор будет видом ввода. В противном случае это будет копия. Смежные входы и входы с совместимыми шагами можно изменять без копирования, но вы не должны зависеть от поведения копирования или просмотра.
Это означает, что torch.reshape
может возвращать копию или представление исходного тензора. Вы не можете рассчитывать на то, что вернете представление или копию. По словам разработчика:
если вам нужна копия, используйте clone (), если вам нужно такое же хранилище, используйте view (). Семантика reshape () такова, что он может или не может совместно использовать хранилище, и вы не знаете заранее.
Другое отличие состоит в том, что reshape()
может работать как с непрерывным, так и с несмежным тензором, тогда как view()
может работать только с смежным тензором. Также см. Здесь о значении contiguous
.
Хотя оба
torch.view
иtorch.reshape
используются для изменения формы тензоров, вот различия между ними.torch.view
просто создает вид исходного тензора. Новый тензор всегда будет делиться своими данными с исходным тензором. Это означает, что если вы измените исходный тензор, измененный тензор изменится, и наоборот.>>> z = torch.zeros(3, 2) >>> x = z.view(2, 3) >>> z.fill_(1) >>> x tensor([[1., 1., 1.], [1., 1., 1.]])
torch.view
налагает некоторые ограничения смежности на формы двух тензоров [ docs ]. Чаще всего это не вызывает беспокойства, но иногдаtorch.view
вызывает ошибку, даже если формы двух тензоров совместимы. Вот известный контрпример.>>> z = torch.zeros(3, 2) >>> y = z.t() >>> y.size() torch.Size([2, 3]) >>> y.view(6) Traceback (most recent call last): File "<stdin>", line 1, in <module> RuntimeError: invalid argument 2: view size is not compatible with input tensor's size and stride (at least one dimension spans across two contiguous subspaces). Call .contiguous() before .view().
torch.reshape
не накладывает никаких ограничений на смежность, но также не гарантирует совместное использование данных. Новый тензор может быть представлением исходного тензора или может быть совершенно новым тензором.>>> z = torch.zeros(3, 2) >>> y = z.reshape(6) >>> x = z.t().reshape(6) >>> z.fill_(1) tensor([[1., 1.], [1., 1.], [1., 1.]]) >>> y tensor([1., 1., 1., 1., 1., 1.]) >>> x tensor([0., 0., 0., 0., 0., 0.])
TL; DR:
Если вы просто хотите изменить форму тензоров, используйте
torch.reshape
. Если вас также беспокоит использование памяти и вы хотите, чтобы два тензора использовали одни и те же данные, используйтеtorch.view
.источник
x
иy
выше оба смежны). Может быть, это можно прояснить? Возможно, будет полезным комментарий о том, когда reshape копируется, а когда нет?Tensor.reshape()
более надежен. Он будет работать с любым тензором, аTensor.view()
работает только с тензором,t
гдеt.is_contiguous()==True
.Объяснение несмежных и смежных функций - это другая история, но вы всегда можете сделать тензор
t
смежным, если вы вызываете,t.contiguous()
а затем вы можете позвонитьview()
без ошибки.источник