Pytorch is an open-source machine learning/deep learning library designed in Python, C++ & CUDA by Facebook's artificial-intelligence research group. It's based on the library `Torch`

designed in `Lua`

.

Pytorch provides linear algebra the same as that of Numpy but can run on GPU as well as CPU. It also provides an implementation of various neural network layers, optimization functions, few default neural models and many other things. Pytorch has other supporting packages like torchvision and torchtext for handling images and text data.

Pytorch provides Tensors which are the same as numpy's multidimensional arrays but can be easily moved to GPUs. We'll be learning about the basics of tensors.

```
import torch
import sys
import numpy as np
print('Python Version : '+sys.version)
print('Pytorch Version : '+torch.__version__)
```

```
empty_tensor = torch.empty(2,5) ## Please make a note that it intiates tensor with garbage values
print(empty_tensor, empty_tensor.dtype)
empty_tensor = torch.empty(2,5, dtype=torch.int32) ## One can provide data type same as that of numpy array creation
print(empty_tensor)
```

```
rand_tensor = torch.rand(3,3) ## Returns between [0,1)
print(rand_tensor, rand_tensor.dtype)
rand_tensor = torch.rand(3,3, dtype=torch.float64)
print(rand_tensor)
rand_tensor = torch.randn(2,4) ## Returns values between (-1,1)
print(rand_tensor)
rand_tensor = torch.randint(0,50, (2,4))
print(rand_tensor, rand_tensor.dtype)
```

```
zero_tensor = torch.zeros(2,4)
print(zero_tensor, zero_tensor.dtype)
zero_tensor = torch.zeros(2,4, dtype=torch.int32)
print(zero_tensor)
```

```
range_tensor = torch.arange(0,10,1)
print(range_tensor)
range_tensor = torch.arange(1,10,2)
print(range_tensor)
```

```
eye_tensor = torch.eye(3)
print(eye_tensor, eye_tensor.dtype)
eye_tensor = torch.eye(3,2)
print(eye_tensor, eye_tensor.dtype)
eye_tensor = torch.eye(3, dtype=torch.int32)
print(eye_tensor)
```

```
tensor = torch.Tensor([1,2,3,4])
print(tensor)
```

```
one_tensor = torch.ones(2,3)
print(one_tensor)
```

```
rand_tensor = torch.rand(2,3)
like_tensor = torch.rand_like(rand_tensor) ## *_like functions can take other tensor as input and outs new tensor of same size as that of input
print(like_tensor)
```

```
torch.from_numpy(np.eye(5))
```

```
like_tensor.shape, like_tensor.size(),
```

```
tensor.dim() ## Number of dimensions
```

```
tensor.requires_grad
```

```
tensor.device
```

```
tensor.diag() ## Creates diagonal tensor with elements of tensor
```

```
tensor.dtype
```

```
tensor = torch.rand(2,5)
print(tensor)
print(tensor.argmax()) ## Returns dimension as if applied on flat array
print(tensor.argmax(0))
print(tensor.argmax(1))
```

```
tensor.min(), tensor.max()
```

```
tensor.max(dim=1) ##Returns max lements at 1st dimension and location in that dimension as well for max element.
```

```
tensor.numpy()
```

```
tensor = tensor.unsqueeze(dim=0) ## Adds one dimension to specified index
print(tensor.shape)
tensor = tensor.squeeze(dim=0) ## Removes extra dimension at specified index
print(tensor.shape)
```

```
tensor.reshape(5,2), tensor.view(5,2)
```

```
tensor = torch.rand(2,4)
tensor + 5
```

```
torch.add(tensor, tensor)
```

```
tensor.add(5)
```

```
tensor.add(tensor) ## This one adds first argument to tensor and then multiply with second
```

```
out_tensor = torch.empty(2,4)
torch.add(tensor, 7, out=out_tensor) ## Stores addition results in another tensor provided to out parameter.
print(out_tensor)
out_tensor = torch.empty(2,4)
torch.add(tensor, tensor, out=out_tensor)
print(out_tensor)
```

```
summation = torch.sum(tensor)
print(summation, summation.item())
```

```
tensor * 10
```

**Note: **Please make a note that all operations on tensor ending with `'_'`

are `in-place`

operations on tensor.

```
tensor = torch.rand(2,4)
tensor.add_(10)
tensor
```

```
tensor = torch.rand(2,3)
print(tensor.t())
tensor = torch.mul(tensor, tensor) ## Element wise matrix multiplication
print(tensor)
tensor = torch.matmul(tensor, tensor.t()) ## Matrix dot product
print(tensor)
```

```
tensor.mean(), tensor.std(), tensor.var()
```

```
tensor = torch.rand(2,4)
tensor.clamp(0.2,0.4) ## It's same as numpy's clip function.
```

```
device = 'cuda' if torch.cuda.is_available() else 'cpu'
device
```

```
torch.device(device)
```

```
tensor = torch.rand(2,4,device='cuda')
print(tensor.device)
```

```
tensor1 = torch.rand(2,5, device = torch.device(device))
print(tensor1.device)
tensor2 = torch.rand(2,5)
print(tensor2.device)
```

```
tensor3 = tensor2.to(device)
tensor3.device
```

Operations can not be performed between tensor on GPU and CPU. Both should be on same device.

```
tensor1 + tensor2
```

Tensors can be easily moved from GPU to CPU.

```
tensor4 = tensor1.cpu()
print(tensor4.device)
```

If you are more comfortable learning through video tutorials then we would recommend that you subscribe to our **YouTube** channel.

When going through coding examples, it's quite common to have doubts and errors.

If you have doubts about some code examples or are stuck somewhere when trying our code, send us an email at **coderzcolumn07@gmail.com**. We'll help you or point you in the direction where you can find a solution to your problem.

You can even send us a mail if you are trying something new and need guidance regarding coding. We'll try to respond as soon as possible.

If you want to

- provide some suggestions on topic
- share your views
- include some details in tutorial
- suggest some new topics on which we should create tutorials/blogs