3.4 Reshaping Tensors

Two methods:

  • view: Zero-copy reshape (by changing tensor metadata). Will fail if zero-copy reshape is not possible.
  • reshape: Uses zero-copy reshape (via metadata) when possible. If not, then will make a copy.
t <- torch_tensor(matrix(1:15, nrow = 3, byrow = TRUE))
t
## torch_tensor
##   1   2   3   4   5
##   6   7   8   9  10
##  11  12  13  14  15
## [ CPULongType{3,5} ]
t$stride()
## [1] 5 1

$stride() tells us the jump necessary to go from one element to the next in a single dimension (e.g. the stride necessary to get from one row to the next).

Next, change shape of t using view():

t2 <- t$view(c(5,3))
t2
## torch_tensor
##   1   2   3
##   4   5   6
##   7   8   9
##  10  11  12
##  13  14  15
## [ CPULongType{5,3} ]
t2$stride()
## [1] 3 1

Check memory location:

t$storage()$data_ptr()
## [1] "0x55e257ccb8c0"
t2$storage()$data_ptr() # same location
## [1] "0x55e257ccb8c0"

view() vs reshape():

When two operations that change the stride are done in sequence, this will likely fail. Below is an example of transpose, t() followed by view().

t$t()$view(15) # error

However, reshape() makes a copy of the underlying data and does not fail.

t3 <- t$t()$reshape(15) # no error
t3
## torch_tensor
##   1
##   6
##  11
##   2
##   7
##  12
##   3
##   8
##  13
##   4
##   9
##  14
##   5
##  10
##  15
## [ CPULongType{15} ]

Now the memory locations of t3 and the original data are different:

t$storage()$data_ptr()
## [1] "0x55e257ccb8c0"
t3$storage()$data_ptr() # different location
## [1] "0x55e25d8463c0"

Two additional functions that are zero-copy operations:

  • squeeze(): Removes singleton dimensions
  • unsqueeze(): Adds a singleton dimension
t <- torch_rand(3) # one dimensional tensor of shape 3
t
## torch_tensor
##  0.2418
##  0.9596
##  0.6296
## [ CPUFloatType{3} ]
t2 <- t$unsqueeze(1) # two dimensional tensor of shape {1,3}
t2
## torch_tensor
##  0.2418  0.9596  0.6296
## [ CPUFloatType{1,3} ]

Inspect location:

t$storage()$data_ptr()
## [1] "0x55e261f79e00"
t2$storage()$data_ptr() # same location
## [1] "0x55e261f79e00"