Week 3: MINST (Digit Classification)
Following are the YouTube sources I used and followed to get my MNIST working
What's an MNIST?ΒΆ
From wiki
The MNIST (Mixed National Institide of Standards and Technology database) is a large database of handwritten digits that is commonly used for training various image processing systems. The database is also wide used for training and testing in the field of machine learning.
For this section of the project, we're going to use MNIST to create a Multinomal Classifier that can detect if the MNIST image show is a member of class 0,1,2,3,4,5,6,7,8 or 9.
New Package Information:ΒΆ
PIL (Python Imaging Library):PIL, now maintained as Pillow, is a Python library for opening, editing, and processing images. It is commonly used for image resizing, format conversion, and basic image manipulation. Source
TensorFlow:TensorFlow is an open source machine learning framework developed by Google. it is used to build, train and deploy machine learning and deep learning models, including neural networks. Source
!pip show tensorflow
WARNING: Package(s) not found: tensorflow
!pip install tensorflow
Collecting tensorflow Using cached tensorflow-2.20.0-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl.metadata (4.5 kB) Collecting absl-py>=1.0.0 (from tensorflow) Using cached absl_py-2.3.1-py3-none-any.whl.metadata (3.3 kB) Collecting astunparse>=1.6.0 (from tensorflow) Using cached astunparse-1.6.3-py2.py3-none-any.whl.metadata (4.4 kB) Collecting flatbuffers>=24.3.25 (from tensorflow) Using cached flatbuffers-25.9.23-py2.py3-none-any.whl.metadata (875 bytes) Collecting gast!=0.5.0,!=0.5.1,!=0.5.2,>=0.2.1 (from tensorflow) Using cached gast-0.7.0-py3-none-any.whl.metadata (1.5 kB) Collecting google_pasta>=0.1.1 (from tensorflow) Using cached google_pasta-0.2.0-py3-none-any.whl.metadata (814 bytes) Collecting libclang>=13.0.0 (from tensorflow) Using cached libclang-18.1.1-py2.py3-none-manylinux2014_aarch64.whl.metadata (5.2 kB) Requirement already satisfied: opt_einsum>=2.3.2 in /opt/conda/lib/python3.13/site-packages (from tensorflow) (3.4.0) Requirement already satisfied: packaging in /opt/conda/lib/python3.13/site-packages (from tensorflow) (25.0) Requirement already satisfied: protobuf>=5.28.0 in /opt/conda/lib/python3.13/site-packages (from tensorflow) (6.31.1) Requirement already satisfied: requests<3,>=2.21.0 in /opt/conda/lib/python3.13/site-packages (from tensorflow) (2.32.5) Requirement already satisfied: setuptools in /opt/conda/lib/python3.13/site-packages (from tensorflow) (80.9.0) Requirement already satisfied: six>=1.12.0 in /opt/conda/lib/python3.13/site-packages (from tensorflow) (1.17.0) Collecting termcolor>=1.1.0 (from tensorflow) Using cached termcolor-3.2.0-py3-none-any.whl.metadata (6.4 kB) Requirement already satisfied: typing_extensions>=3.6.6 in /opt/conda/lib/python3.13/site-packages (from tensorflow) (4.15.0) Collecting wrapt>=1.11.0 (from tensorflow) Using cached wrapt-2.0.1-cp313-cp313-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl.metadata (9.0 kB) Collecting grpcio<2.0,>=1.24.3 (from tensorflow) Using cached grpcio-1.76.0-cp313-cp313-manylinux2014_aarch64.manylinux_2_17_aarch64.whl.metadata (3.7 kB) Collecting tensorboard~=2.20.0 (from tensorflow) Using cached tensorboard-2.20.0-py3-none-any.whl.metadata (1.8 kB) Collecting keras>=3.10.0 (from tensorflow) Downloading keras-3.13.0-py3-none-any.whl.metadata (6.3 kB) Requirement already satisfied: numpy>=1.26.0 in /opt/conda/lib/python3.13/site-packages (from tensorflow) (2.3.3) Requirement already satisfied: h5py>=3.11.0 in /opt/conda/lib/python3.13/site-packages (from tensorflow) (3.15.1) Requirement already satisfied: ml_dtypes<1.0.0,>=0.5.1 in /opt/conda/lib/python3.13/site-packages (from tensorflow) (0.5.4) Requirement already satisfied: charset_normalizer<4,>=2 in /opt/conda/lib/python3.13/site-packages (from requests<3,>=2.21.0->tensorflow) (3.4.4) Requirement already satisfied: idna<4,>=2.5 in /opt/conda/lib/python3.13/site-packages (from requests<3,>=2.21.0->tensorflow) (3.11) Requirement already satisfied: urllib3<3,>=1.21.1 in /opt/conda/lib/python3.13/site-packages (from requests<3,>=2.21.0->tensorflow) (2.5.0) Requirement already satisfied: certifi>=2017.4.17 in /opt/conda/lib/python3.13/site-packages (from requests<3,>=2.21.0->tensorflow) (2025.10.5) Collecting markdown>=2.6.8 (from tensorboard~=2.20.0->tensorflow) Using cached markdown-3.10-py3-none-any.whl.metadata (5.1 kB) Requirement already satisfied: pillow in /opt/conda/lib/python3.13/site-packages (from tensorboard~=2.20.0->tensorflow) (11.3.0) Collecting tensorboard-data-server<0.8.0,>=0.7.0 (from tensorboard~=2.20.0->tensorflow) Using cached tensorboard_data_server-0.7.2-py3-none-any.whl.metadata (1.1 kB) Collecting werkzeug>=1.0.1 (from tensorboard~=2.20.0->tensorflow) Using cached werkzeug-3.1.4-py3-none-any.whl.metadata (4.0 kB) Collecting wheel<1.0,>=0.23.0 (from astunparse>=1.6.0->tensorflow) Using cached wheel-0.45.1-py3-none-any.whl.metadata (2.3 kB) Collecting rich (from keras>=3.10.0->tensorflow) Using cached rich-14.2.0-py3-none-any.whl.metadata (18 kB) Collecting namex (from keras>=3.10.0->tensorflow) Using cached namex-0.1.0-py3-none-any.whl.metadata (322 bytes) Collecting optree (from keras>=3.10.0->tensorflow) Using cached optree-0.18.0-cp313-cp313-manylinux_2_26_aarch64.manylinux_2_28_aarch64.whl.metadata (34 kB) Requirement already satisfied: markupsafe>=2.1.1 in /opt/conda/lib/python3.13/site-packages (from werkzeug>=1.0.1->tensorboard~=2.20.0->tensorflow) (3.0.3) Collecting markdown-it-py>=2.2.0 (from rich->keras>=3.10.0->tensorflow) Using cached markdown_it_py-4.0.0-py3-none-any.whl.metadata (7.3 kB) Requirement already satisfied: pygments<3.0.0,>=2.13.0 in /opt/conda/lib/python3.13/site-packages (from rich->keras>=3.10.0->tensorflow) (2.19.2) Collecting mdurl~=0.1 (from markdown-it-py>=2.2.0->rich->keras>=3.10.0->tensorflow) Using cached mdurl-0.1.2-py3-none-any.whl.metadata (1.6 kB) Using cached tensorflow-2.20.0-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl (259.7 MB) Using cached grpcio-1.76.0-cp313-cp313-manylinux2014_aarch64.manylinux_2_17_aarch64.whl (6.4 MB) Using cached tensorboard-2.20.0-py3-none-any.whl (5.5 MB) Using cached tensorboard_data_server-0.7.2-py3-none-any.whl (2.4 kB) Using cached absl_py-2.3.1-py3-none-any.whl (135 kB) Using cached astunparse-1.6.3-py2.py3-none-any.whl (12 kB) Using cached wheel-0.45.1-py3-none-any.whl (72 kB) Using cached flatbuffers-25.9.23-py2.py3-none-any.whl (30 kB) Using cached gast-0.7.0-py3-none-any.whl (22 kB) Using cached google_pasta-0.2.0-py3-none-any.whl (57 kB) Downloading keras-3.13.0-py3-none-any.whl (1.5 MB) ββββββββββββββββββββββββββββββββββββββββ 1.5/1.5 MB 35.0 MB/s 0:00:00 Using cached libclang-18.1.1-py2.py3-none-manylinux2014_aarch64.whl (23.8 MB) Using cached markdown-3.10-py3-none-any.whl (107 kB) Using cached termcolor-3.2.0-py3-none-any.whl (7.7 kB) Using cached werkzeug-3.1.4-py3-none-any.whl (224 kB) Using cached wrapt-2.0.1-cp313-cp313-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl (123 kB) Using cached namex-0.1.0-py3-none-any.whl (5.9 kB) Using cached optree-0.18.0-cp313-cp313-manylinux_2_26_aarch64.manylinux_2_28_aarch64.whl (368 kB) Using cached rich-14.2.0-py3-none-any.whl (243 kB) Using cached markdown_it_py-4.0.0-py3-none-any.whl (87 kB) Using cached mdurl-0.1.2-py3-none-any.whl (10.0 kB) Installing collected packages: namex, libclang, flatbuffers, wrapt, wheel, werkzeug, termcolor, tensorboard-data-server, optree, mdurl, markdown, grpcio, google_pasta, gast, absl-py, tensorboard, markdown-it-py, astunparse, rich, keras, tensorflow ββββββββββββββββββββββββββββββββββββββββ 21/21 [tensorflow]1 [tensorflow]-py] Successfully installed absl-py-2.3.1 astunparse-1.6.3 flatbuffers-25.9.23 gast-0.7.0 google_pasta-0.2.0 grpcio-1.76.0 keras-3.13.0 libclang-18.1.1 markdown-3.10 markdown-it-py-4.0.0 mdurl-0.1.2 namex-0.1.0 optree-0.18.0 rich-14.2.0 tensorboard-2.20.0 tensorboard-data-server-0.7.2 tensorflow-2.20.0 termcolor-3.2.0 werkzeug-3.1.4 wheel-0.45.1 wrapt-2.0.1
!pip install --upgrade tensorflow
Requirement already satisfied: tensorflow in /opt/conda/lib/python3.13/site-packages (2.20.0) Requirement already satisfied: absl-py>=1.0.0 in /opt/conda/lib/python3.13/site-packages (from tensorflow) (2.3.1) Requirement already satisfied: astunparse>=1.6.0 in /opt/conda/lib/python3.13/site-packages (from tensorflow) (1.6.3) Requirement already satisfied: flatbuffers>=24.3.25 in /opt/conda/lib/python3.13/site-packages (from tensorflow) (25.9.23) Requirement already satisfied: gast!=0.5.0,!=0.5.1,!=0.5.2,>=0.2.1 in /opt/conda/lib/python3.13/site-packages (from tensorflow) (0.7.0) Requirement already satisfied: google_pasta>=0.1.1 in /opt/conda/lib/python3.13/site-packages (from tensorflow) (0.2.0) Requirement already satisfied: libclang>=13.0.0 in /opt/conda/lib/python3.13/site-packages (from tensorflow) (18.1.1) Requirement already satisfied: opt_einsum>=2.3.2 in /opt/conda/lib/python3.13/site-packages (from tensorflow) (3.4.0) Requirement already satisfied: packaging in /opt/conda/lib/python3.13/site-packages (from tensorflow) (25.0) Requirement already satisfied: protobuf>=5.28.0 in /opt/conda/lib/python3.13/site-packages (from tensorflow) (6.31.1) Requirement already satisfied: requests<3,>=2.21.0 in /opt/conda/lib/python3.13/site-packages (from tensorflow) (2.32.5) Requirement already satisfied: setuptools in /opt/conda/lib/python3.13/site-packages (from tensorflow) (80.9.0) Requirement already satisfied: six>=1.12.0 in /opt/conda/lib/python3.13/site-packages (from tensorflow) (1.17.0) Requirement already satisfied: termcolor>=1.1.0 in /opt/conda/lib/python3.13/site-packages (from tensorflow) (3.2.0) Requirement already satisfied: typing_extensions>=3.6.6 in /opt/conda/lib/python3.13/site-packages (from tensorflow) (4.15.0) Requirement already satisfied: wrapt>=1.11.0 in /opt/conda/lib/python3.13/site-packages (from tensorflow) (2.0.1) Requirement already satisfied: grpcio<2.0,>=1.24.3 in /opt/conda/lib/python3.13/site-packages (from tensorflow) (1.76.0) Requirement already satisfied: tensorboard~=2.20.0 in /opt/conda/lib/python3.13/site-packages (from tensorflow) (2.20.0) Requirement already satisfied: keras>=3.10.0 in /opt/conda/lib/python3.13/site-packages (from tensorflow) (3.13.0) Requirement already satisfied: numpy>=1.26.0 in /opt/conda/lib/python3.13/site-packages (from tensorflow) (2.3.3) Requirement already satisfied: h5py>=3.11.0 in /opt/conda/lib/python3.13/site-packages (from tensorflow) (3.15.1) Requirement already satisfied: ml_dtypes<1.0.0,>=0.5.1 in /opt/conda/lib/python3.13/site-packages (from tensorflow) (0.5.4) Requirement already satisfied: charset_normalizer<4,>=2 in /opt/conda/lib/python3.13/site-packages (from requests<3,>=2.21.0->tensorflow) (3.4.4) Requirement already satisfied: idna<4,>=2.5 in /opt/conda/lib/python3.13/site-packages (from requests<3,>=2.21.0->tensorflow) (3.11) Requirement already satisfied: urllib3<3,>=1.21.1 in /opt/conda/lib/python3.13/site-packages (from requests<3,>=2.21.0->tensorflow) (2.5.0) Requirement already satisfied: certifi>=2017.4.17 in /opt/conda/lib/python3.13/site-packages (from requests<3,>=2.21.0->tensorflow) (2025.10.5) Requirement already satisfied: markdown>=2.6.8 in /opt/conda/lib/python3.13/site-packages (from tensorboard~=2.20.0->tensorflow) (3.10) Requirement already satisfied: pillow in /opt/conda/lib/python3.13/site-packages (from tensorboard~=2.20.0->tensorflow) (11.3.0) Requirement already satisfied: tensorboard-data-server<0.8.0,>=0.7.0 in /opt/conda/lib/python3.13/site-packages (from tensorboard~=2.20.0->tensorflow) (0.7.2) Requirement already satisfied: werkzeug>=1.0.1 in /opt/conda/lib/python3.13/site-packages (from tensorboard~=2.20.0->tensorflow) (3.1.4) Requirement already satisfied: wheel<1.0,>=0.23.0 in /opt/conda/lib/python3.13/site-packages (from astunparse>=1.6.0->tensorflow) (0.45.1) Requirement already satisfied: rich in /opt/conda/lib/python3.13/site-packages (from keras>=3.10.0->tensorflow) (14.2.0) Requirement already satisfied: namex in /opt/conda/lib/python3.13/site-packages (from keras>=3.10.0->tensorflow) (0.1.0) Requirement already satisfied: optree in /opt/conda/lib/python3.13/site-packages (from keras>=3.10.0->tensorflow) (0.18.0) Requirement already satisfied: markupsafe>=2.1.1 in /opt/conda/lib/python3.13/site-packages (from werkzeug>=1.0.1->tensorboard~=2.20.0->tensorflow) (3.0.3) Requirement already satisfied: markdown-it-py>=2.2.0 in /opt/conda/lib/python3.13/site-packages (from rich->keras>=3.10.0->tensorflow) (4.0.0) Requirement already satisfied: pygments<3.0.0,>=2.13.0 in /opt/conda/lib/python3.13/site-packages (from rich->keras>=3.10.0->tensorflow) (2.19.2) Requirement already satisfied: mdurl~=0.1 in /opt/conda/lib/python3.13/site-packages (from markdown-it-py>=2.2.0->rich->keras>=3.10.0->tensorflow) (0.1.2)
!pip install protobuf==5.28.3
Collecting protobuf==5.28.3
Using cached protobuf-5.28.3-cp38-abi3-manylinux2014_aarch64.whl.metadata (592 bytes)
Using cached protobuf-5.28.3-cp38-abi3-manylinux2014_aarch64.whl (316 kB)
Installing collected packages: protobuf
Attempting uninstall: protobuf
Found existing installation: protobuf 6.31.1
Uninstalling protobuf-6.31.1:
Successfully uninstalled protobuf-6.31.1
Successfully installed protobuf-5.28.3
LibrariesΒΆ
import numpy as np
import matplotlib.pyplot as plt
%matplotlib inline
import tensorflow as tf
from tensorflow import keras
/opt/conda/lib/python3.13/site-packages/keras/src/export/tf2onnx_lib.py:8: FutureWarning: In the future `np.object` will be defined as the corresponding NumPy scalar. if not hasattr(np, "object"):
Train and Test SplitΒΆ
(X_train, y_train), (X_test, y_test) = tf.keras.datasets.mnist.load_data()
# samples in X_train
len(X_train)
60000
# samples in X_test
len(X_test)
10000
# Each individual sample is a 28x28 image
X_train[0].shape
(28, 28)
X_train[0]
array([[ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0],
[ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0],
[ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0],
[ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0],
[ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0],
[ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3,
18, 18, 18, 126, 136, 175, 26, 166, 255, 247, 127, 0, 0,
0, 0],
[ 0, 0, 0, 0, 0, 0, 0, 0, 30, 36, 94, 154, 170,
253, 253, 253, 253, 253, 225, 172, 253, 242, 195, 64, 0, 0,
0, 0],
[ 0, 0, 0, 0, 0, 0, 0, 49, 238, 253, 253, 253, 253,
253, 253, 253, 253, 251, 93, 82, 82, 56, 39, 0, 0, 0,
0, 0],
[ 0, 0, 0, 0, 0, 0, 0, 18, 219, 253, 253, 253, 253,
253, 198, 182, 247, 241, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0],
[ 0, 0, 0, 0, 0, 0, 0, 0, 80, 156, 107, 253, 253,
205, 11, 0, 43, 154, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0],
[ 0, 0, 0, 0, 0, 0, 0, 0, 0, 14, 1, 154, 253,
90, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0],
[ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 139, 253,
190, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0],
[ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 11, 190,
253, 70, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0],
[ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 35,
241, 225, 160, 108, 1, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0],
[ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
81, 240, 253, 253, 119, 25, 0, 0, 0, 0, 0, 0, 0,
0, 0],
[ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 45, 186, 253, 253, 150, 27, 0, 0, 0, 0, 0, 0,
0, 0],
[ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 16, 93, 252, 253, 187, 0, 0, 0, 0, 0, 0,
0, 0],
[ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 249, 253, 249, 64, 0, 0, 0, 0, 0,
0, 0],
[ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 46, 130, 183, 253, 253, 207, 2, 0, 0, 0, 0, 0,
0, 0],
[ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 39,
148, 229, 253, 253, 253, 250, 182, 0, 0, 0, 0, 0, 0,
0, 0],
[ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 24, 114, 221,
253, 253, 253, 253, 201, 78, 0, 0, 0, 0, 0, 0, 0,
0, 0],
[ 0, 0, 0, 0, 0, 0, 0, 0, 23, 66, 213, 253, 253,
253, 253, 198, 81, 2, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0],
[ 0, 0, 0, 0, 0, 0, 18, 171, 219, 253, 253, 253, 253,
195, 80, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0],
[ 0, 0, 0, 0, 55, 172, 226, 253, 253, 253, 253, 244, 133,
11, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0],
[ 0, 0, 0, 0, 136, 253, 253, 253, 212, 135, 132, 16, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0],
[ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0],
[ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0],
[ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0]], dtype=uint8)
Plotting imageΒΆ
Pixels on a x and y axis with pixels defined by numbers in an array
plt.matshow(X_train[0])
<matplotlib.image.AxesImage at 0xf9e8c5b174d0>
plt.matshow(X_train[2])
<matplotlib.image.AxesImage at 0xf9e8c24dd6d0>
print(y_train[0])
5
print(y_train[2])
4
print(y_train[:5])
[5 0 4 1 9]
Flattening the dataset using a function in pandas library called reshape
X_train.shape
(60000, 28, 28)
X_train_flattened = X_train.reshape(len(X_train), 28*28)
X_test_flattened = X_test.reshape(len(X_test), 28*28)
X_train_flattened
array([[0, 0, 0, ..., 0, 0, 0],
[0, 0, 0, ..., 0, 0, 0],
[0, 0, 0, ..., 0, 0, 0],
...,
[0, 0, 0, ..., 0, 0, 0],
[0, 0, 0, ..., 0, 0, 0],
[0, 0, 0, ..., 0, 0, 0]], shape=(60000, 784), dtype=uint8)
X_test_flattened
array([[0, 0, 0, ..., 0, 0, 0],
[0, 0, 0, ..., 0, 0, 0],
[0, 0, 0, ..., 0, 0, 0],
...,
[0, 0, 0, ..., 0, 0, 0],
[0, 0, 0, ..., 0, 0, 0],
[0, 0, 0, ..., 0, 0, 0]], shape=(10000, 784), dtype=uint8)
Creating a simple neural network with input later of 784 elements and output layer of 10 elements using keras.sequential.
Sequential will accept a stack of layers.
model = keras.Sequential([
keras.layers.Dense(10, input_shape=(784,), activation='sigmoid')
])
# optimizer - will allow you to train the model efficiently
# loss -
# metrics - to make the goal of the model more accurate
model.compile(
optimizer='adam',
loss='sparse_categorical_crossentropy',
metrics=['accuracy']
)
model.fit(X_train_flattened, y_train, epochs=5)
Epoch 1/5
/opt/conda/lib/python3.13/site-packages/keras/src/layers/core/dense.py:106: UserWarning: Do not pass an `input_shape`/`input_dim` argument to a layer. When using Sequential models, prefer using an `Input(shape)` object as the first layer in the model instead. super().__init__(activity_regularizer=activity_regularizer, **kwargs)
1875/1875 ββββββββββββββββββββ 3s 1ms/step - accuracy: 0.3556 - loss: 9.2259 Epoch 2/5 1875/1875 ββββββββββββββββββββ 2s 1ms/step - accuracy: 0.3514 - loss: 5.9672 Epoch 3/5 1875/1875 ββββββββββββββββββββ 2s 1ms/step - accuracy: 0.3465 - loss: 5.6984 Epoch 4/5 1875/1875 ββββββββββββββββββββ 2s 1ms/step - accuracy: 0.3404 - loss: 5.5488 Epoch 5/5 1875/1875 ββββββββββββββββββββ 2s 1ms/step - accuracy: 0.3337 - loss: 5.3441
<keras.src.callbacks.history.History at 0xf9e8c039c2f0>
Low accuracy since the values in the dataset were not scaled.
Scaling below and re-reunning the code.
# each value in X_train will be diveded by 255
# scaling improves the accuracy of machine learning model
X_train = X_train / 255
X_test = X_test / 255
X_train_flattened = X_train.reshape(len(X_train), 28*28)
X_test_flattened = X_test.reshape(len(X_test), 28*28)
X_train_flattened
array([[0., 0., 0., ..., 0., 0., 0.],
[0., 0., 0., ..., 0., 0., 0.],
[0., 0., 0., ..., 0., 0., 0.],
...,
[0., 0., 0., ..., 0., 0., 0.],
[0., 0., 0., ..., 0., 0., 0.],
[0., 0., 0., ..., 0., 0., 0.]], shape=(60000, 784))
X_test_flattened
array([[0., 0., 0., ..., 0., 0., 0.],
[0., 0., 0., ..., 0., 0., 0.],
[0., 0., 0., ..., 0., 0., 0.],
...,
[0., 0., 0., ..., 0., 0., 0.],
[0., 0., 0., ..., 0., 0., 0.],
[0., 0., 0., ..., 0., 0., 0.]], shape=(10000, 784))
model = keras.Sequential([
keras.layers.Dense(10, input_shape=(784,), activation='sigmoid')
])
model.compile(
optimizer='adam',
loss='sparse_categorical_crossentropy',
metrics=['accuracy']
)
model.fit(X_train_flattened, y_train, epochs=5)
Epoch 1/5 1875/1875 ββββββββββββββββββββ 3s 1ms/step - accuracy: 0.8746 - loss: 0.4785 Epoch 2/5 1875/1875 ββββββββββββββββββββ 2s 1ms/step - accuracy: 0.9146 - loss: 0.3048 Epoch 3/5 1875/1875 ββββββββββββββββββββ 2s 1ms/step - accuracy: 0.9204 - loss: 0.2836 Epoch 4/5 1875/1875 ββββββββββββββββββββ 2s 1ms/step - accuracy: 0.9232 - loss: 0.2734 Epoch 5/5 1875/1875 ββββββββββββββββββββ 2s 1ms/step - accuracy: 0.9255 - loss: 0.2667
<keras.src.callbacks.history.History at 0xf9e8c03c8910>
model.evaluate(X_test_flattened, y_test)
313/313 ββββββββββββββββββββ 0s 1ms/step - accuracy: 0.9261 - loss: 0.2659
[0.26594477891921997, 0.9261000156402588]
plt.matshow(X_test[0])
<matplotlib.image.AxesImage at 0xf9e8a4758190>
y_predicted = model.predict(X_test_flattened)
y_predicted[0]
313/313 ββββββββββββββββββββ 0s 822us/step
array([2.0603191e-02, 4.0582702e-07, 5.2030284e-02, 9.6463162e-01,
3.3707041e-03, 1.1293780e-01, 1.7198491e-06, 9.9983007e-01,
1.2574284e-01, 6.6464883e-01], dtype=float32)
The score from the array above assign values to each number 0-9
Use numpy's argmax funtion to determing the highest value.
print(np.argmax(y_predicted[0]))
7
plt.matshow(X_test[5])
<matplotlib.image.AxesImage at 0xf9e8a45c60d0>
y_predicted[5]
array([5.2582272e-05, 9.9760425e-01, 5.2462643e-01, 3.9638516e-01,
7.4713328e-03, 1.7477617e-02, 8.8016717e-03, 5.5080366e-01,
4.8039192e-01, 1.4387552e-01], dtype=float32)
print(np.argmax(y_predicted[5]))
1
Convert all the y_predicted to actual categorical labels 0-9
# passing each elment in y_predicted into np.argmax
y_predicted_labels = [np.argmax(i) for i in y_predicted]
print(y_predicted_labels[:10])
[np.int64(7), np.int64(2), np.int64(1), np.int64(0), np.int64(4), np.int64(1), np.int64(4), np.int64(9), np.int64(6), np.int64(9)]
print(y_test[:10])
[7 2 1 0 4 1 4 9 5 9]
To view the model in Confusion Matrix using TensorFlow
cm = tf.math.confusion_matrix(labels=y_test, predictions=y_predicted_labels)
cm
<tf.Tensor: shape=(10, 10), dtype=int32, numpy=
array([[ 959, 0, 1, 2, 0, 5, 7, 2, 4, 0],
[ 0, 1106, 3, 2, 1, 1, 4, 2, 16, 0],
[ 7, 8, 921, 18, 9, 4, 12, 10, 40, 3],
[ 1, 0, 18, 928, 0, 19, 2, 12, 24, 6],
[ 1, 1, 3, 1, 921, 0, 11, 4, 11, 29],
[ 8, 3, 1, 36, 11, 765, 18, 6, 38, 6],
[ 7, 3, 6, 2, 7, 11, 917, 2, 3, 0],
[ 1, 5, 21, 9, 9, 0, 0, 950, 2, 31],
[ 5, 7, 6, 20, 9, 18, 9, 11, 883, 6],
[ 11, 7, 1, 12, 29, 5, 0, 26, 7, 911]],
dtype=int32)>
import seaborn as sn
plt.figure(figsize = (10,7))
sn.heatmap(cm, annot=True, fmt='d')
plt.xlabel('Predicted')
plt.ylabel('Truth')
Text(95.72222222222221, 0.5, 'Truth')
The numbers in the black and white labels are errors. The colored labels are correct predictions for each class.
Creating a hidden layer to improve the performance(?)
# creating hidden layer with 'relu' activation
model = keras.Sequential([
keras.layers.Dense(100, input_shape=(784,), activation='relu'),
keras.layers.Dense(10, activation='sigmoid')
])
model.compile(
optimizer='adam',
loss='sparse_categorical_crossentropy',
metrics=['accuracy']
)
model.fit(X_train_flattened, y_train, epochs=5)
Epoch 1/5
/opt/conda/lib/python3.13/site-packages/keras/src/layers/core/dense.py:106: UserWarning: Do not pass an `input_shape`/`input_dim` argument to a layer. When using Sequential models, prefer using an `Input(shape)` object as the first layer in the model instead. super().__init__(activity_regularizer=activity_regularizer, **kwargs)
1875/1875 ββββββββββββββββββββ 4s 2ms/step - accuracy: 0.9227 - loss: 0.2711 Epoch 2/5 1875/1875 ββββββββββββββββββββ 4s 2ms/step - accuracy: 0.9642 - loss: 0.1207 Epoch 3/5 1875/1875 ββββββββββββββββββββ 4s 2ms/step - accuracy: 0.9744 - loss: 0.0843 Epoch 4/5 1875/1875 ββββββββββββββββββββ 4s 2ms/step - accuracy: 0.9802 - loss: 0.0638 Epoch 5/5 1875/1875 ββββββββββββββββββββ 4s 2ms/step - accuracy: 0.9841 - loss: 0.0516
<keras.src.callbacks.history.History at 0xf9e87c721810>
model.evaluate(X_test_flattened, y_test)
313/313 ββββββββββββββββββββ 1s 1ms/step - accuracy: 0.9766 - loss: 0.0776
[0.07763277739286423, 0.9765999913215637]
y_predicted = model.predict(X_test_flattened)
y_predicted_labels = [np.argmax(i) for i in y_predicted]
cm = tf.math.confusion_matrix(labels=y_test, predictions=y_predicted_labels)
plt.figure(figsize = (10,7))
sn.heatmap(cm, annot=True, fmt='d')
plt.xlabel('Predicted')
plt.ylabel('Truth')
313/313 ββββββββββββββββββββ 0s 945us/step
Text(95.72222222222221, 0.5, 'Truth')