### 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.