### NumPy to PyTorch

PyTorch is designed to be pretty compatible with NumPy. Because of this, converting a NumPy array to a PyTorch tensor is simple:

```
import torch
import numpy as np
x = np.eye(3)
torch.from_numpy(x)
# Expected result
# tensor([[1., 0., 0.],
# [0., 1., 0.],
# [0., 0., 1.]], dtype=torch.float64)
```

All you have to do is use the `torch.from_numpy()`

function.

Once the tensor is in PyTorch, you may want to change the data type:

```
x = np.eye(3)
torch.from_numpy(x).type(torch.float32)
# Expected result
# tensor([[1, 0, 0],
# [0, 1, 0],
# [0, 0, 1]])
```

All you have to do is call the `.type()`

method. Easy enough.

Or, you may want to send the tensor to a different device, like your GPU:

```
x = np.eye(3)
torch.from_numpy(x).to("cuda")
# Expected result
# tensor([[1., 0., 0.],
# [0., 1., 0.],
# [0., 0., 1.]], device='cuda:0', dtype=torch.float64)
```

The `.to()`

method sends a tensor to a different device. Note: the above only works if you’re running a version of PyTorch that was compiled with CUDA and have an Nvidia GPU on your machine. You can test whether that’s true with `torch.cuda.is_available()`

.

### PyTorch to NumPy

Going the other direction is slightly more involved because you will sometimes have to deal with two differences between a PyTorch tensor and a NumPy array:

- PyTorch can target different devices (like GPUs).
- PyTorch supports automatic differentiation.

In the simplest case, when you have a PyTorch tensor without gradients on a CPU, you can simply call the `.numpy()`

method:

```
x = torch.eye(3)
x.numpy()
# Expected result
# array([[1., 0., 0.],
# [0., 1., 0.],
# [0., 0., 1.]], dtype=float32)
```

But, if the tensor is part of a computation graph that requires a gradient (that is, if `x.requires_grad`

is true), you will need to call the `.detach()`

method:

```
x = torch.eye(3)
x.requires_grad = True
x.detach().numpy()
# Expected result
# array([[1., 0., 0.],
# [0., 1., 0.],
# [0., 0., 1.]], dtype=float32)
```

And if the tensor is on a device other than `"cpu"`

, you will need to bring it back to the CPU before you can call the `.numpy()`

method. We saw this above when sending a tensor to the GPU with `.to("cuda")`

. Now, we just go in reverse:

```
x = torch.eye(3)
x = x.to("cuda")
x.to("cpu").numpy()
# Expected result
# array([[1., 0., 0.],
# [0., 1., 0.],
# [0., 0., 1.]], dtype=float32)
```

Both the `.detach()`

method and the `.to("cpu")`

method are idempotent. So, if you want to, you can plan on calling them every time you want to convert a PyTorch tensor to a NumPy array, even when it’s not strictly necessary:

```
x = torch.eye(3)
x.detach().to("cpu").numpy()
# Expected result
# array([[1., 0., 0.],
# [0., 1., 0.],
# [0., 0., 1.]], dtype=float32)
```

By the way, if you want to perform image transforms on a NumPy array directly you can! All you need is to have a transform that accepts NumPy arrays as input. Check out my post on TorchVision transforms if you want to learn more.

MatthieuThanks for this intersting conversion review.

At the end of the explanations you mentioned:

“Both the .detach() method and the .to(“cpu”) method are idempotent. So, if you want to, you can plan on calling them every time you want to convert a PyTorch tensor to a NumPy array, even when it’s not strictly necessary.”

Don’t the calls to both .detach() and .to(“cpu”) methods even when it’s not strictly necessary have an increased computation time ?

Thanks!

jbencookGood call out — I’m not 100% certain, but I believe these methods are no-ops when they’re not required. I’m not too familiar with the PyTorch C++ code, but from what I can tell, this is what would happen if you call

`.detach()`

on a vanilla tensor.