Learn data science and machine learning by building real-world projects on Jovian

An Introdcution to Pytorch and 5 basic functions it can do

In the current technological sphere the words Arificial Intelligence and Machine learning can be heard in almost all areas. Machine learning is a subset of Artifical Intelligence that deals with training a system (the learning part of the machine) to do certain functions without the aid of a user. Pytorch is a library used for machine learning. It's free and it's also open source. Here I'll be showing 5 functions it can do. These fucntions are:

  • torch.equal
  • torch.rand
  • torch.range
  • torch.chunk
  • torch.reshape

Before we begin, let's install and import PyTorch

In [ ]:
# Uncomment and run the appropriate command for your operating system, if required

# Linux / Binder
# !pip install numpy torch==1.7.0+cpu torchvision==0.8.1+cpu torchaudio==0.7.0 -f https://download.pytorch.org/whl/torch_stable.html

# Windows
# !pip install numpy torch==1.7.0+cpu torchvision==0.8.1+cpu torchaudio==0.7.0 -f https://download.pytorch.org/whl/torch_stable.html

# MacOS
# !pip install numpy torch torchvision torchaudio
In [2]:
# Import torch and other required modules
import torch

Function 1 - torch.equal

This function is used to check whether two tensors are of same size and has same elements.

In [ ]:
# Example 1 - creating two tensors of same size and value
t1 = torch.tensor([1,2])
t2 = torch.tensor([1,2])
torch.equal (t1, t2)
Out[]:
True

Here we created two tensors t1 and t2 of the size 1 x 2 and added values 1 and 2 respectively for both tensors. When we tried to check whether both are equal, we got the result as "True".

In [ ]:
# Example 2 - creating two tensors of same size and value
t1 = torch.tensor([[1,2],[3,4]])
t2 = torch.tensor([[1,2],[3,4]])
torch.equal (t1, t2)
Out[]:
True

Here we created two tensors t1 and t2 again. But this time we created a 2 x 2 matrix and added same values in both tensors. Again we checked the tensors using the equal function and returned "True" as output.

In [ ]:
# Example 3 - creating two sensors of different size and value
t1 = torch.tensor([1,2])
t2 = torch.tensor([3,4])
torch.equal (t1, t2)
Out[]:
False

Since the values of both tensor are different we recieved "False" as an output.

Using this function we can check whether two tensors are equal or not. This is especially useful for large sized tensors.

Function 2 - torch.rand

This function returns a tensor with random value of the specified size.

In [3]:
# Example 1 - working
torch.rand(3)
Out[3]:
tensor([0.8128, 0.1787, 0.0472])

Here we created a tensor with random values of the size 1 x 3.

In [4]:
# Example 2 - working
torch.rand(5,4)
Out[4]:
tensor([[0.7631, 0.5256, 0.1993, 0.6345],
        [0.5398, 0.2903, 0.8771, 0.3768],
        [0.5205, 0.9019, 0.2832, 0.8885],
        [0.1547, 0.1930, 0.2252, 0.2995],
        [0.6414, 0.4762, 0.5168, 0.2232]])

Here we created a tensor with random values of the size 5 x 4.

In [5]:
# Example 3 - breaking (to illustrate when it breaks)
torch.rand(-4)
--------------------------------------------------------------------------- RuntimeError Traceback (most recent call last) <ipython-input-5-09bf9a010192> in <module>() 1 # Example 3 - breaking (to illustrate when it breaks) ----> 2 torch.rand(-4) RuntimeError: Trying to create tensor with negative dimension -4: [-4]

Here we tried to create a tensor of the size -4. But this doesn't work because the size of a tensor cannot be negetive.

This function can be used when you don't have any specific value to work with and you want to create a tensor quickly to test out your program.

Function 3 - torch.range

This fucntion is used to create a tensor with the specified range by the user. You can mention the lower bound and the upper bound and you can also determine the step between each value (the gap between two values) while using this function.

In [12]:
# Example 1 - working
torch.range(1,5)
/usr/local/lib/python3.6/dist-packages/ipykernel_launcher.py:2: UserWarning: torch.range is deprecated and will be removed in a future release because its behavior is inconsistent with Python's range builtin. Instead, use torch.arange, which produces values in [start, end).
Out[12]:
tensor([1., 2., 3., 4., 5.])

Here we created a tensor using the range function with the lower bound being 1 and the upper bound being 5. If no step value is specified, the value of step by default is 1.

In [13]:
# Example 2 - working
torch.range(-4,4,2)
/usr/local/lib/python3.6/dist-packages/ipykernel_launcher.py:2: UserWarning: torch.range is deprecated and will be removed in a future release because its behavior is inconsistent with Python's range builtin. Instead, use torch.arange, which produces values in [start, end).
Out[13]:
tensor([-4., -2.,  0.,  2.,  4.])

Here we created a tensor using the range function with lower bound being -4 and the upper bound being 4 and we used a step value of 2, hence why each value differs by 2.

In [14]:
# Example 3 - breaking (to illustrate when it breaks)
torch.range(4,-4)
/usr/local/lib/python3.6/dist-packages/ipykernel_launcher.py:2: UserWarning: torch.range is deprecated and will be removed in a future release because its behavior is inconsistent with Python's range builtin. Instead, use torch.arange, which produces values in [start, end).
--------------------------------------------------------------------------- RuntimeError Traceback (most recent call last) <ipython-input-14-dd066adee74d> in <module>() 1 # Example 3 - breaking (to illustrate when it breaks) ----> 2 torch.range(4,-4) RuntimeError: upper bound and larger bound inconsistent with step sign

Here we tried creating a tensor with upper bound 4 and lower bound -4 but it shows an error because we cannot have the lower bound greater than the upper bound.

This function can be used if you want to create a tensor between a range of value with a specified interval in between them.

Function 4 - torch.chunk

This function is used to split a tensor in chunks of specified sizes.

In [17]:
# Example 1 - working
t1 = torch.tensor([1,2,3,4])
torch.chunk(t1,2)
Out[17]:
(tensor([1, 2]), tensor([3, 4]))

Here we created a tensor t1 with 4 values and used the chunk fucntion to split the tensor into 2 parts.

In [26]:
# Example 2 - working
t1 = torch.tensor([1,2,3,4,5,6,7,8])
torch.chunk(t1,4,0)
Out[26]:
(tensor([1, 2]), tensor([3, 4]), tensor([5, 6]), tensor([7, 8]))

Here we created a tensor t1 with 8 values and used the chunk function to split the tensor into 4 parts.

In [25]:
# Example 3 - breaking (to illustrate when it breaks)
t1 = torch.tensor([1,2,3,4])
torch.chunk(t1,2,0.5)
--------------------------------------------------------------------------- TypeError Traceback (most recent call last) <ipython-input-25-cd42ec92757b> in <module>() 1 # Example 3 - breaking (to illustrate when it breaks) 2 t1 = torch.tensor([1,2,3,4]) ----> 3 torch.chunk(t1,2,0.5) TypeError: chunk(): argument 'dim' (position 3) must be int, not float

Here we tried to split a tensor t1 which has 4 values into 2 parts but it shows an error because the value of dimension should be integer and not a floating value.

This function is useful if you want to split a large sized tensor into smaller pieces.

Function 5 - torch.reshape

This function is used to reshape a tensor of one size to another.

In [31]:
# Example 1 - working
t1 = torch.tensor([1,2,3,4])
torch.reshape(t1,(2,2))
Out[31]:
tensor([[1, 2],
        [3, 4]])

Here we created a tensor t1 and added 4 values to it. Then we used the reshapte function to convert the 1 x 4 matrix to a 2 x 2 matrix.

In [32]:
# Example 2 - working
t1 = torch.tensor([1,2,3,4,5,6])
torch.reshape(t1,(3,2))
Out[32]:
tensor([[1, 2],
        [3, 4],
        [5, 6]])

Here we created a tensor t1 of 6 values and reshaped the 1 x 6 matrix to a 3 x 2 matrix.

In [33]:
# Example 3 - breaking (to illustrate when it breaks)
t1 = torch.tensor([1,2,3,4,5,6,7,8])
torch.reshape(t1,(3,3))
--------------------------------------------------------------------------- RuntimeError Traceback (most recent call last) <ipython-input-33-334495a0744a> in <module>() 1 # Example 3 - breaking (to illustrate when it breaks) 2 t1 = torch.tensor([1,2,3,4,5,6,7,8]) ----> 3 torch.reshape(t1,(3,3)) RuntimeError: shape '[3, 3]' is invalid for input of size 8

Here we created a tensor t1 with 8 values and tried to reshape it into a 3 x 3 matrix. Since we only have 8 values and there are 9 values in a 3 x 3 matrix, the function doesn't work.

This function is useful for changing the shape of tensors to suit your needs.

Conclusion

In this notebook we have seen some of the function the pytroch library gives us in handling tensors. This is just a small part of a very large library. There are many materials online which you can refer to to see what functions are there and what it does. A good place to check out the tensor functions is to look at the documentation in the official website.

Reference Links

Places from where information pytorch and their function was obtained.

In [35]:
jovian.commit(project='01-tensor-operations')
[jovian] Detected Colab notebook... [jovian] Uploading colab notebook to Jovian...
--------------------------------------------------------------------------- TypeError Traceback (most recent call last) /usr/local/lib/python3.6/dist-packages/urllib3/connectionpool.py in _make_request(self, conn, method, url, timeout, chunked, **httplib_request_kw) 376 try: # Python 2.7, use buffering of HTTP responses --> 377 httplib_response = conn.getresponse(buffering=True) 378 except TypeError: # Python 3 TypeError: getresponse() got an unexpected keyword argument 'buffering' During handling of the above exception, another exception occurred: KeyboardInterrupt Traceback (most recent call last) <ipython-input-35-446dc3cb507f> in <module>() ----> 1 jovian.commit(project='01-tensor-operations') /usr/local/lib/python3.6/dist-packages/jovian/utils/commit.py in commit(message, files, outputs, environment, privacy, filename, project, new_project, git_commit, git_message, **kwargs) 134 return 135 --> 136 res = perform_colab_commit(project, privacy) 137 slug, username, version, title = res['slug'], res['owner']['username'], res['version'], res['title'] 138 /usr/local/lib/python3.6/dist-packages/jovian/utils/colab.py in perform_colab_commit(project, privacy) 41 res = post(url=_u('/gist/colab-commit'), 42 data=data, ---> 43 headers=auth_headers) 44 45 if res.status_code == 200: /usr/local/lib/python3.6/dist-packages/jovian/utils/request.py in _request_wrapper(*args, **kwargs) 12 def _request_wrapper(*args, **kwargs): 13 for i in range(2): ---> 14 res = request(*args, **kwargs) 15 if res.status_code == 401: 16 log('The current API key is invalid or expired.', error=True) /usr/local/lib/python3.6/dist-packages/jovian/utils/request.py in post(url, data, json, **kwargs) 36 def post(url, data=None, json=None, **kwargs): 37 """Retryable POST request""" ---> 38 return requests.post(url, data=data, json=json, **kwargs) 39 40 /usr/local/lib/python3.6/dist-packages/requests/api.py in post(url, data, json, **kwargs) 117 """ 118 --> 119 return request('post', url, data=data, json=json, **kwargs) 120 121 /usr/local/lib/python3.6/dist-packages/requests/api.py in request(method, url, **kwargs) 59 # cases, and look like a memory leak in others. 60 with sessions.Session() as session: ---> 61 return session.request(method=method, url=url, **kwargs) 62 63 /usr/local/lib/python3.6/dist-packages/requests/sessions.py in request(self, method, url, params, data, headers, cookies, files, auth, timeout, allow_redirects, proxies, hooks, stream, verify, cert, json) 528 } 529 send_kwargs.update(settings) --> 530 resp = self.send(prep, **send_kwargs) 531 532 return resp /usr/local/lib/python3.6/dist-packages/requests/sessions.py in send(self, request, **kwargs) 641 642 # Send the request --> 643 r = adapter.send(request, **kwargs) 644 645 # Total elapsed time of the request (approximately) /usr/local/lib/python3.6/dist-packages/requests/adapters.py in send(self, request, stream, timeout, verify, cert, proxies) 447 decode_content=False, 448 retries=self.max_retries, --> 449 timeout=timeout 450 ) 451 /usr/local/lib/python3.6/dist-packages/urllib3/connectionpool.py in urlopen(self, method, url, body, headers, retries, redirect, assert_same_host, timeout, pool_timeout, release_conn, chunked, body_pos, **response_kw) 598 timeout=timeout_obj, 599 body=body, headers=headers, --> 600 chunked=chunked) 601 602 # If we're going to release the connection in ``finally:``, then /usr/local/lib/python3.6/dist-packages/urllib3/connectionpool.py in _make_request(self, conn, method, url, timeout, chunked, **httplib_request_kw) 378 except TypeError: # Python 3 379 try: --> 380 httplib_response = conn.getresponse() 381 except Exception as e: 382 # Remove the TypeError from the exception chain in Python 3; /usr/lib/python3.6/http/client.py in getresponse(self) 1371 try: 1372 try: -> 1373 response.begin() 1374 except ConnectionError: 1375 self.close() /usr/lib/python3.6/http/client.py in begin(self) 309 # read until we get a non-100 response 310 while True: --> 311 version, status, reason = self._read_status() 312 if status != CONTINUE: 313 break /usr/lib/python3.6/http/client.py in _read_status(self) 270 271 def _read_status(self): --> 272 line = str(self.fp.readline(_MAXLINE + 1), "iso-8859-1") 273 if len(line) > _MAXLINE: 274 raise LineTooLong("status line") /usr/lib/python3.6/socket.py in readinto(self, b) 584 while True: 585 try: --> 586 return self._sock.recv_into(b) 587 except timeout: 588 self._timeout_occurred = True /usr/lib/python3.6/ssl.py in recv_into(self, buffer, nbytes, flags) 1010 "non-zero flags not allowed in calls to recv_into() on %s" % 1011 self.__class__) -> 1012 return self.read(nbytes, buffer) 1013 else: 1014 return socket.recv_into(self, buffer, nbytes, flags) /usr/lib/python3.6/ssl.py in read(self, len, buffer) 872 raise ValueError("Read on closed or unwrapped SSL socket.") 873 try: --> 874 return self._sslobj.read(len, buffer) 875 except SSLError as x: 876 if x.args[0] == SSL_ERROR_EOF and self.suppress_ragged_eofs: /usr/lib/python3.6/ssl.py in read(self, len, buffer) 629 """ 630 if buffer is not None: --> 631 v = self._sslobj.read(len, buffer) 632 else: 633 v = self._sslobj.read(len) KeyboardInterrupt:
In [ ]: