Learn practical skills, build real-world projects, and advance your career

Image Classification using Logistic Regression in PyTorch

Part 3 of "PyTorch: Zero to GANs"

This post is the third in a series of tutorials on building deep learning models with PyTorch, an open source neural networks library. Check out the full series:

  1. PyTorch Basics: Tensors & Gradients
  2. Linear Regression & Gradient Descent
  3. Image Classfication using Logistic Regression
  4. Training Deep Neural Networks on a GPU
  5. Image Classification using Convolutional Neural Networks
  6. Data Augmentation, Regularization and ResNets
  7. Generating Images using Generative Adverserial Networks

In this tutorial, we'll use our existing knowledge of PyTorch and linear regression to solve a very different kind of problem: image classification. We'll use the famous MNIST Handwritten Digits Database as our training dataset. It consists of 28px by 28px grayscale images of handwritten digits (0 to 9), along with labels for each image indicating which digit it represents. Here are some sample images from the dataset:

mnist-sample

System setup

This tutorial takes a code-first approach towards learning PyTorch, and you should try to follow along by running and experimenting with the code yourself. The easiest way to start executing this notebook is to click the "Run" button at the top of this page, and select "Run on Kaggle". This will run the notebook on Kaggle, a free online service for running Jupyter notebooks (you might need to create an account).

Running on your computer locally

(Skip this if you're running on Kaggle) To run this notebook locally, clone this notebook, install the required dependencies using conda, and start Jupyter by running the following commands on the terminal / Conda prompt:

pip install jovian --upgrade # Install the jovian library jovian clone aakashns/03-logistic-regression # Download notebook & dependencies cd 03-logistic-regression # Enter the created directory conda create -n 03-logistic-regression python=3.8 # Create an environment conda activate 03-logistic-regression # Activate virtual env jupyter notebook # Start Jupyter

You can find the notebook_id by cliking the Clone button at the top of this page on Jovian. For a more detailed explanation of the above steps, check out the System setup section in the first notebook.

Exploring the Data

We begin by importing torch and torchvision. torchvision contains some utilities for working with image data. It also contains helper classes to automatically download and import popular datasets like MNIST.

# Uncomment and run the commands below if imports fail
!conda install numpy pytorch torchvision cpuonly -c pytorch -y
!pip install matplotlib --upgrade --quiet
Collecting package metadata (current_repodata.json): done Solving environment: | The environment is inconsistent, please check the package plan carefully The following packages are causing the inconsistency: - defaults/linux-64::wheel==0.33.6=py37_0 - defaults/linux-64::jsonschema==3.0.2=py37_0 - defaults/linux-64::spyder==3.3.6=py37_0 - defaults/linux-64::setuptools==41.4.0=py37_0 - defaults/noarch::qtawesome==0.6.0=py_0 - defaults/linux-64::seaborn==0.9.0=py37_0 - defaults/linux-64::statsmodels==0.10.1=py37hdd07704_0 - defaults/linux-64::singledispatch==3.4.0.3=py37_0 - defaults/noarch::jupyterlab==1.1.4=pyhf63ae98_0 - defaults/linux-64::pyrsistent==0.15.4=py37h7b6447c_0 - defaults/linux-64::numba==0.45.1=py37h962f231_0 - defaults/noarch::sphinx==2.2.0=py_0 - defaults/linux-64::jupyter_console==6.0.0=py37_0 - defaults/linux-64::anaconda-client==1.7.2=py37_0 - defaults/linux-64::cycler==0.10.0=py37_0 - defaults/noarch::jupyterlab_server==1.0.6=py_0 - defaults/linux-64::h5py==2.9.0=py37h7918eee_0 - defaults/linux-64::scikit-learn==0.21.3=py37hd81dba3_0 - defaults/linux-64::pywavelets==1.0.3=py37hdd07704_1 - defaults/linux-64::conda==4.8.3=py37_0 - defaults/linux-64::nose==1.3.7=py37_2 - defaults/linux-64::nbformat==4.4.0=py37_0 - defaults/noarch::pytest-openfiles==0.4.0=py_0 - defaults/linux-64::numexpr==2.7.0=py37h9e4a6bb_0 - defaults/noarch::pytest-doctestplus==0.4.0=py_0 - defaults/linux-64::matplotlib==3.1.1=py37h5429711_0 - defaults/noarch::qtconsole==4.5.5=py_0 - defaults/linux-64::anaconda-navigator==1.9.7=py37_0 - defaults/linux-64::mkl-service==2.3.0=py37he904b0f_0 - defaults/linux-64::keyring==18.0.0=py37_0 - defaults/linux-64::mkl_fft==1.0.14=py37ha843d7b_0 - defaults/linux-64::patsy==0.5.1=py37_0 - defaults/linux-64::jupyter_client==5.3.3=py37_1 - defaults/noarch::anaconda-project==0.8.3=py_0 - defaults/linux-64::clyent==1.2.2=py37_1 - defaults/linux-64::mock==3.0.5=py37_0 - defaults/linux-64::secretstorage==3.1.1=py37_0 - defaults/linux-64::astroid==2.3.1=py37_0 - defaults/linux-64::mkl_random==1.1.0=py37hd6b4f25_0 - defaults/linux-64::cython==0.29.13=py37he6710b0_0 - defaults/linux-64::bleach==3.1.0=py37_0 - defaults/linux-64::traitlets==4.3.3=py37_0 - defaults/linux-64::pytest-remotedata==0.3.2=py37_0 - defaults/noarch::dask==2.5.2=py_0 - defaults/linux-64::widgetsnbextension==3.5.1=py37_0 - defaults/linux-64::notebook==6.0.1=py37_0 - defaults/linux-64::conda-build==3.18.9=py37_3 - defaults/linux-64::bottleneck==1.2.1=py37h035aef0_1 - pytorch/linux-64::pytorch==1.5.0=py3.7_cpu_0 - defaults/linux-64::conda-package-handling==1.6.1=py37h7b6447c_0 - defaults/linux-64::imageio==2.6.0=py37_0 - defaults/noarch::conda-verify==3.4.2=py_1 - defaults/linux-64::pylint==2.4.2=py37_0 - defaults/linux-64::scipy==1.3.1=py37h7c811a0_0 - defaults/linux-64::astropy==3.2.2=py37h7b6447c_0 - defaults/noarch::ipywidgets==7.5.1=py_0 - defaults/noarch::jupyter_core==4.5.0=py_0 - defaults/linux-64::scikit-image==0.15.0=py37he6710b0_0 - defaults/linux-64::spyder-kernels==0.5.2=py37_0 - defaults/noarch::flask==1.1.1=py_0 - defaults/linux-64::pytest-arraydiff==0.3=py37h39e3cac_0 - defaults/linux-64::pytest-astropy==0.5.0=py37_0 - defaults/linux-64::pytest==5.2.1=py37_0 - defaults/linux-64::pyopenssl==19.0.0=py37_0 - defaults/noarch::networkx==2.3=py_0 - defaults/linux-64::ipykernel==5.1.2=py37h39e3cac_0 - defaults/linux-64::nltk==3.4.5=py37_0 - defaults/linux-64::pytables==3.5.2=py37h71ec239_1 - defaults/linux-64::nbconvert==5.6.0=py37_1 - defaults/noarch::prompt_toolkit==2.0.10=py_0 - defaults/linux-64::numpy==1.17.2=py37haad9e8e_0 - defaults/noarch::pygments==2.4.2=py_0 - defaults/linux-64::bokeh==1.3.4=py37_0 - defaults/linux-64::jupyter==1.0.0=py37_7 - defaults/linux-64::requests==2.22.0=py37_0 - defaults/linux-64::anaconda==2019.10=py37_0 - defaults/linux-64::ipython==7.8.0=py37h39e3cac_0 - defaults/linux-64::sympy==1.4=py37_0 - defaults/linux-64::isort==4.3.21=py37_0 - defaults/linux-64::gevent==1.4.0=py37h7b6447c_0 - defaults/linux-64::bkcharts==0.2=py37_0 - defaults/noarch::backports.functools_lru_cache==1.6.1=py_0 - defaults/linux-64::html5lib==1.0.1=py37_0 - defaults/linux-64::_ipyw_jlab_nb_ext_conf==0.1.0=py37_0 - defaults/noarch::jinja2==2.10.3=py_0 - defaults/linux-64::pathlib2==2.3.5=py37_0 - defaults/linux-64::multipledispatch==0.6.0=py37_0 - defaults/noarch::numpydoc==0.9.1=py_0 - defaults/noarch::packaging==19.2=py_0 done ## Package Plan ## environment location: /home/edl-147/anaconda3 added / updated specs: - cpuonly - numpy - pytorch - torchvision The following packages will be downloaded: package | build ---------------------------|----------------- _anaconda_depends-2020.02 | py37_0 6 KB anaconda-custom | py37_1 3 KB argh-0.26.2 | py37_0 36 KB autopep8-1.4.4 | py_0 43 KB beautifulsoup4-4.9.1 | py37_0 165 KB ca-certificates-2020.1.1 | 0 125 KB certifi-2020.4.5.1 | py37_0 155 KB cffi-1.14.0 | py37h2e261b9_0 224 KB cryptography-2.9.2 | py37h1ba5d50_0 552 KB diff-match-patch-20181111 | py_0 35 KB flake8-3.7.9 | py37_0 173 KB hypothesis-5.11.0 | py_0 231 KB intervaltree-3.0.2 | py_0 25 KB ld_impl_linux-64-2.33.1 | h53a641e_7 568 KB libspatialindex-1.9.3 | he6710b0_0 2.1 MB matplotlib-base-3.1.3 | py37hef1b27d_0 5.0 MB numpy-1.18.1 | py37h4f9e942_0 5 KB openssl-1.1.1g | h7b6447c_0 2.5 MB pandas-1.0.3 | py37h0573a6f_0 8.6 MB path-13.2.0 | py37_0 36 KB pathtools-0.1.2 | py_1 10 KB pip-20.0.2 | py37_3 1.7 MB pydocstyle-4.0.1 | py_0 35 KB pytest-astropy-header-0.1.2| py_0 12 KB python-dateutil-2.8.1 | py_0 215 KB python-jsonrpc-server-0.3.4| py_0 13 KB python-language-server-0.31.10| py37_0 78 KB pyxdg-0.26 | py_0 45 KB qdarkstyle-2.8.1 | py_0 176 KB rtree-0.9.4 | py37_1 47 KB six-1.15.0 | py_0 13 KB soupsieve-2.0.1 | py_0 33 KB ujson-1.35 | py37h14c3975_0 25 KB urllib3-1.24.3 | py37_0 161 KB watchdog-0.10.2 | py37_0 93 KB yapf-0.28.0 | py_0 119 KB ------------------------------------------------------------ Total: 23.2 MB The following NEW packages will be INSTALLED: _anaconda_depends pkgs/main/linux-64::_anaconda_depends-2020.02-py37_0 argh pkgs/main/linux-64::argh-0.26.2-py37_0 autopep8 pkgs/main/noarch::autopep8-1.4.4-py_0 beautifulsoup4 pkgs/main/linux-64::beautifulsoup4-4.9.1-py37_0 certifi pkgs/main/linux-64::certifi-2020.4.5.1-py37_0 cffi pkgs/main/linux-64::cffi-1.14.0-py37h2e261b9_0 cryptography pkgs/main/linux-64::cryptography-2.9.2-py37h1ba5d50_0 diff-match-patch pkgs/main/noarch::diff-match-patch-20181111-py_0 flake8 pkgs/main/linux-64::flake8-3.7.9-py37_0 hypothesis pkgs/main/noarch::hypothesis-5.11.0-py_0 intervaltree pkgs/main/noarch::intervaltree-3.0.2-py_0 ld_impl_linux-64 pkgs/main/linux-64::ld_impl_linux-64-2.33.1-h53a641e_7 libspatialindex pkgs/main/linux-64::libspatialindex-1.9.3-he6710b0_0 matplotlib-base pkgs/main/linux-64::matplotlib-base-3.1.3-py37hef1b27d_0 numpy-base pkgs/main/linux-64::numpy-base-1.18.1-py37hde5b4d6_1 pandas pkgs/main/linux-64::pandas-1.0.3-py37h0573a6f_0 path pkgs/main/linux-64::path-13.2.0-py37_0 pathtools pkgs/main/noarch::pathtools-0.1.2-py_1 pip pkgs/main/linux-64::pip-20.0.2-py37_3 pydocstyle pkgs/main/noarch::pydocstyle-4.0.1-py_0 pytest-astropy-he~ pkgs/main/noarch::pytest-astropy-header-0.1.2-py_0 python-dateutil pkgs/main/noarch::python-dateutil-2.8.1-py_0 python-jsonrpc-se~ pkgs/main/noarch::python-jsonrpc-server-0.3.4-py_0 python-language-s~ pkgs/main/linux-64::python-language-server-0.31.10-py37_0 pyxdg pkgs/main/noarch::pyxdg-0.26-py_0 qdarkstyle pkgs/main/noarch::qdarkstyle-2.8.1-py_0 rtree pkgs/main/linux-64::rtree-0.9.4-py37_1 six pkgs/main/noarch::six-1.15.0-py_0 soupsieve pkgs/main/noarch::soupsieve-2.0.1-py_0 torchvision pytorch/linux-64::torchvision-0.6.0-py37_cpu ujson pkgs/main/linux-64::ujson-1.35-py37h14c3975_0 urllib3 pkgs/main/linux-64::urllib3-1.24.3-py37_0 watchdog pkgs/main/linux-64::watchdog-0.10.2-py37_0 yapf pkgs/main/noarch::yapf-0.28.0-py_0 The following packages will be UPDATED: ca-certificates 2019.8.28-0 --> 2020.1.1-0 numpy 1.17.2-py37haad9e8e_0 --> 1.18.1-py37h4f9e942_0 openssl 1.1.1d-h7b6447c_2 --> 1.1.1g-h7b6447c_0 The following packages will be DOWNGRADED: anaconda 2019.10-py37_0 --> custom-py37_1 Downloading and Extracting Packages
certifi-2020.4.5.1 | 155 KB | ##################################### | 100% intervaltree-3.0.2 | 25 KB | ##################################### | 100% pytest-astropy-heade | 12 KB | ##################################### | 100% pydocstyle-4.0.1 | 35 KB | ##################################### | 100% ca-certificates-2020 | 125 KB | ##################################### | 100% path-13.2.0 | 36 KB | ##################################### | 100% watchdog-0.10.2 | 93 KB | ##################################### | 100% pyxdg-0.26 | 45 KB | ##################################### | 100% cryptography-2.9.2 | 552 KB | ##################################### | 100% flake8-3.7.9 | 173 KB | ##################################### | 100% yapf-0.28.0 | 119 KB | ##################################### | 100% soupsieve-2.0.1 | 33 KB | ##################################### | 100% openssl-1.1.1g | 2.5 MB | ##################################### | 100% pandas-1.0.3 | 8.6 MB | ##################################### | 100% libspatialindex-1.9. | 2.1 MB | ##################################### | 100% python-language-serv | 78 KB | ##################################### | 100% ld_impl_linux-64-2.3 | 568 KB | ##################################### | 100% hypothesis-5.11.0 | 231 KB | ##################################### | 100% six-1.15.0 | 13 KB | ##################################### | 100% diff-match-patch-201 | 35 KB | ##################################### | 100% autopep8-1.4.4 | 43 KB | ##################################### | 100% anaconda-custom | 3 KB | ##################################### | 100% argh-0.26.2 | 36 KB | ##################################### | 100% beautifulsoup4-4.9.1 | 165 KB | ##################################### | 100% numpy-1.18.1 | 5 KB | ##################################### | 100% ujson-1.35 | 25 KB | ##################################### | 100% rtree-0.9.4 | 47 KB | ##################################### | 100% pathtools-0.1.2 | 10 KB | ##################################### | 100% _anaconda_depends-20 | 6 KB | ##################################### | 100% pip-20.0.2 | 1.7 MB | ##################################### | 100% qdarkstyle-2.8.1 | 176 KB | ##################################### | 100% python-jsonrpc-serve | 13 KB | ##################################### | 100% python-dateutil-2.8. | 215 KB | ##################################### | 100% matplotlib-base-3.1. | 5.0 MB | ##################################### | 100% cffi-1.14.0 | 224 KB | ##################################### | 100% urllib3-1.24.3 | 161 KB | ##################################### | 100% Preparing transaction: done Verifying transaction: done Executing transaction: done WARNING: You are using pip version 20.1; however, version 20.1.1 is available. You should consider upgrading via the '/home/edl-147/anaconda3/bin/python -m pip install --upgrade pip' command.