├── 08. Object Detection ├── requirements.txt ├── Images │ ├── F9.jpg │ └── F9.mp4 ├── Dataset │ └── coco_classes.pickle └── README.md ├── 07. Pretrained CNNs ├── requirements.txt ├── Images │ └── Bal1.JPG └── README.md ├── 03. Image Classification ├── requirements.txt ├── Scripts │ └── simplepreprocessor.py ├── README.md └── Simplepreprocessor.ipynb ├── 01. OpenCV ├── requirements.txt ├── Images │ ├── MM.jpg │ ├── P.jpg │ ├── Bal1.JPG │ ├── Cat.jpg │ ├── Empire_cloudy1.jpg │ └── Empire_sunset1.jpg └── README.md ├── 04. Neural Networks ├── requirements.txt └── README.md ├── 02. ConvolutionalNeuralNetworks ├── requirements.txt ├── Images │ ├── Bal1.JPG │ └── Empire_cloudy1.jpg ├── README.md └── Convolutional Layers.ipynb ├── 05. LeNet Architecture ├── requirements.txt ├── README.md └── LeNet.ipynb ├── 06. VGGNet Architecture ├── requirements.txt ├── README.md └── Mini VGGNet.ipynb ├── LICENSE └── README.md /08. Object Detection/requirements.txt: -------------------------------------------------------------------------------- 1 | cv2 2 | numpy 3 | torch 4 | pickle -------------------------------------------------------------------------------- /07. Pretrained CNNs/requirements.txt: -------------------------------------------------------------------------------- 1 | cv2 2 | numpy 3 | tensorflow 4 | keras -------------------------------------------------------------------------------- /03. Image Classification/requirements.txt: -------------------------------------------------------------------------------- 1 | cv2 2 | imutils 3 | numpy 4 | matplotlib 5 | os -------------------------------------------------------------------------------- /01. OpenCV/requirements.txt: -------------------------------------------------------------------------------- 1 | cv2 2 | imutils 3 | numpy 4 | argparse 5 | matplotlib 6 | skimage -------------------------------------------------------------------------------- /04. Neural Networks/requirements.txt: -------------------------------------------------------------------------------- 1 | numpy 2 | sklearn 3 | tensorflow 4 | keras 5 | matplotlib 6 | -------------------------------------------------------------------------------- /02. ConvolutionalNeuralNetworks/requirements.txt: -------------------------------------------------------------------------------- 1 | cv2 2 | imutils 3 | numpy 4 | matplotlib 5 | skimage -------------------------------------------------------------------------------- /01. OpenCV/Images/MM.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ThinamXx/ComputerVision/HEAD/01. OpenCV/Images/MM.jpg -------------------------------------------------------------------------------- /01. OpenCV/Images/P.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ThinamXx/ComputerVision/HEAD/01. OpenCV/Images/P.jpg -------------------------------------------------------------------------------- /01. OpenCV/Images/Bal1.JPG: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ThinamXx/ComputerVision/HEAD/01. OpenCV/Images/Bal1.JPG -------------------------------------------------------------------------------- /01. OpenCV/Images/Cat.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ThinamXx/ComputerVision/HEAD/01. OpenCV/Images/Cat.jpg -------------------------------------------------------------------------------- /05. LeNet Architecture/requirements.txt: -------------------------------------------------------------------------------- 1 | cv2 2 | imutils 3 | numpy 4 | matplotlib 5 | skimage 6 | keras 7 | tensorflow -------------------------------------------------------------------------------- /08. Object Detection/Images/F9.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ThinamXx/ComputerVision/HEAD/08. Object Detection/Images/F9.jpg -------------------------------------------------------------------------------- /08. Object Detection/Images/F9.mp4: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ThinamXx/ComputerVision/HEAD/08. Object Detection/Images/F9.mp4 -------------------------------------------------------------------------------- /01. OpenCV/Images/Empire_cloudy1.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ThinamXx/ComputerVision/HEAD/01. OpenCV/Images/Empire_cloudy1.jpg -------------------------------------------------------------------------------- /01. OpenCV/Images/Empire_sunset1.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ThinamXx/ComputerVision/HEAD/01. OpenCV/Images/Empire_sunset1.jpg -------------------------------------------------------------------------------- /07. Pretrained CNNs/Images/Bal1.JPG: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ThinamXx/ComputerVision/HEAD/07. Pretrained CNNs/Images/Bal1.JPG -------------------------------------------------------------------------------- /06. VGGNet Architecture/requirements.txt: -------------------------------------------------------------------------------- 1 | cv2 2 | imutils 3 | numpy 4 | matplotlib 5 | skimage 6 | keras 7 | tensorflow 8 | scikit-learn -------------------------------------------------------------------------------- /02. ConvolutionalNeuralNetworks/Images/Bal1.JPG: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ThinamXx/ComputerVision/HEAD/02. ConvolutionalNeuralNetworks/Images/Bal1.JPG -------------------------------------------------------------------------------- /08. Object Detection/Dataset/coco_classes.pickle: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ThinamXx/ComputerVision/HEAD/08. Object Detection/Dataset/coco_classes.pickle -------------------------------------------------------------------------------- /02. ConvolutionalNeuralNetworks/Images/Empire_cloudy1.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ThinamXx/ComputerVision/HEAD/02. ConvolutionalNeuralNetworks/Images/Empire_cloudy1.jpg -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2021 Thinam Tamang 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /05. LeNet Architecture/README.md: -------------------------------------------------------------------------------- 1 | # **Computer Vision: LeNet Architecture** 2 | 3 | The [**LeNet Architecture**](https://github.com/ThinamXx/ComputerVision/blob/main/05.%20LeNet%20Architecture/LeNet.ipynb) notebook contains the implementation of LeNet Architecture. LeNet is a seminal work in the deep learning literature which demonstrates how neural networks could be trained to recognize objects in images without feture extraction. 4 | 5 | 📚**Notebooks:** 6 | - [**LeNet Notebook**](https://github.com/ThinamXx/ComputerVision/blob/main/05.%20LeNet%20Architecture/LeNet.ipynb) 7 | 8 | **LeNet** 9 | - I will define the build method of LeNet architecture below. It requires four parameters: width of input image, height of input image, depth of image, number of class labels in the classification task. The Sequential class, the building block of sequential networks sequentially stack one layer on top of the other layer initialized below. I have presented the implementation of LeNet Architecture, Training and Model Evaluation here in the snapshot. 10 | 11 | ![Image](https://github.com/ThinamXx/MachineLearning_DeepLearning/blob/main/Images/Day%2016a.PNG) 12 | ![Image](https://github.com/ThinamXx/MachineLearning_DeepLearning/blob/main/Images/Day%2016b.PNG) 13 | -------------------------------------------------------------------------------- /07. Pretrained CNNs/README.md: -------------------------------------------------------------------------------- 1 | # **Computer Vision: Pretrained Convolutional Neural Networks** 2 | 3 | - The [**Pretrained CNNs**](https://github.com/ThinamXx/ComputerVision/blob/main/07.%20Pretrained%20CNNs/PretrainedCNNs.ipynb) notebook contains the reviews of convolutional neural networks and implementation of VGG16 and Xception networks for classification of images. 4 | 5 | 📚**Notebook:** 6 | - [**Pretrained CNNs**](https://github.com/ThinamXx/ComputerVision/blob/main/07.%20Pretrained%20CNNs/PretrainedCNNs.ipynb) 7 | 8 | **Convolutional Neural Networks:** 9 | - Convolutions are just a type of matrix multiplication with two constraints on the weight matrix: some elements are always zero and some elements are tied or forced to always have the same value. Batch Normalization adds some extra randomness to the training process. Larger batches have gradients that are more accurate since they are calculated from more data. But larger batch size means fewer batches per epoch which means fewer opportunities for the model to update weights. VGG16, VGG19, and ResNet all accept 224 x 224 input images while InceptionV3 and Xception requires 299 x 299 pixel inputs. 10 | 11 | ![Image](https://github.com/ThinamXx/MachineLearning_DeepLearning/blob/main/Images/Day%2019.PNG) 12 | 13 | -------------------------------------------------------------------------------- /04. Neural Networks/README.md: -------------------------------------------------------------------------------- 1 | # **Computer Vision: Neural Networks** 2 | 3 | The [**Neural Networks**](https://github.com/ThinamXx/ComputerVision/blob/main/04.%20Neural%20Networks/NeuralNetworks.ipynb) notebook contains the implementation of **Perceptron** algorithm, backpropagation algorithm, and neural networks from scratch. 4 | 5 | 📚**Notebooks:** 6 | - [**Neural Network**](https://github.com/ThinamXx/ComputerVision/blob/main/04.%20Neural%20Networks/NeuralNetworks.ipynb) 7 | 8 | **Rectified Linear Unit** 9 | - ReLU is zero for negative inputs but increases linearly for positive inputs. The ReLU function is not saturable and is also extremely computationally efficient. ReLU is the most popular activation function used in deep learning and has stronger biological motivations. 10 | 11 | **Perceptron Algorithm** 12 | - I have presented the implementation of Perceptron Algorithm here in the snapshot. 13 | 14 | ![Image](https://github.com/ThinamXx/MachineLearning_DeepLearning/blob/main/Images/Day%2011.PNG) 15 | 16 | **Backpropagation Algorithm** 17 | - I have presented the implementation of Neural Network and Backpropagation here in the snapshot. 18 | 19 | ![Image](https://github.com/ThinamXx/MachineLearning_DeepLearning/blob/main/Images/Day%2012a.PNG) 20 | ![Image](https://github.com/ThinamXx/MachineLearning_DeepLearning/blob/main/Images/Day%2012b.PNG) 21 | -------------------------------------------------------------------------------- /02. ConvolutionalNeuralNetworks/README.md: -------------------------------------------------------------------------------- 1 | # **Computer Vision: Convolutional Neural Networks** 2 | 3 | The [**Convolutions**](https://github.com/ThinamXx/ComputerVision/blob/main/02.%20ConvolutionalNeuralNetworks/Convolutions.ipynb) notebook contains all the dependencies required to understand the implementation of Image Convolutions and Kernels. 4 | 5 | The [**Convolutional Layers**](https://github.com/ThinamXx/ComputerVision/blob/main/02.%20ConvolutionalNeuralNetworks/Convolutional%20Layers.ipynb) notebook contains all the dependencies required to understand Keras Conv2D Class and Convolutional Layers. 6 | 7 | **Notebooks:** 8 | - [**Convolutions**](https://github.com/ThinamXx/ComputerVision/blob/main/02.%20ConvolutionalNeuralNetworks/Convolutions.ipynb) 9 | - [**Convolutional Layers**](https://github.com/ThinamXx/ComputerVision/blob/main/02.%20ConvolutionalNeuralNetworks/Convolutional%20Layers.ipynb) 10 | 11 | **Strided Net** 12 | - I have presented the implementation of Strided Net here in the snapshot. 13 | 14 | ![Image](https://github.com/ThinamXx/300Days__MachineLearningDeepLearning/blob/main/Images/Day%20296.PNG) 15 | 16 | **Preparing Dataset** 17 | - I have presented the implementation of Label Binarizer and Preparing Dataset here in the snapshot. 18 | 19 | ![Image](https://github.com/ThinamXx/300Days__MachineLearningDeepLearning/blob/main/Images/Day%20297.PNG) 20 | 21 | **Training Model** 22 | - I have presented the implementation of Compiling and Training Model, Classification Report, Training Loss and Accuracy here in the snapshot. 23 | 24 | ![Image](https://github.com/ThinamXx/300Days__MachineLearningDeepLearning/blob/main/Images/Day%20298.PNG) 25 | -------------------------------------------------------------------------------- /08. Object Detection/README.md: -------------------------------------------------------------------------------- 1 | # **Computer Vision: Object Detection** 2 | 3 | The [**Object Detection**](https://github.com/ThinamXx/ComputerVision/blob/main/08.%20Object%20Detection/ObjectDetection.ipynb) notebook contains implementation of object detection with PyTorch and pretrained networks. It also contains brief description about object detection and image preprocessing. 4 | 5 | 📚**Notebook** 6 | - [**Object Detection**](https://github.com/ThinamXx/ComputerVision/blob/main/08.%20Object%20Detection/ObjectDetection.ipynb) 7 | 8 | **COCO Dataset** 9 | - The [COCO Dataset](https://cocodataset.org/#home): Common Objects in Context, tends to be the standard for object detection benchmarking. The dataset contains over 90 classes of common objects we will see in everyday world. 10 | 11 | **Object Detection** 12 | - Object Detection is a computer technology related to computer vision and image processing that deals with detecting instances of semantic objects of a certain class. I will use PyTorch to perform object detection using the following state-of-the-art classification networks: 13 | - Faster R-CNN with a ResNet50. 14 | - Faster R-CNN with a MobileNet V3. 15 | - RetinaNet with a ResNet50. 16 | 17 | **Image Preprocessing** 18 | - Converting color channel ordering from BGR to RGB. 19 | - Swapping color channel ordering from channels last to channels first. 20 | - Adding a batch dimension. 21 | - Scaling pixel intensities from the range [0, 255] to [0, 1]. 22 | - Converting the image from a numpy array to a floating point tensor. 23 | 24 | ![Image](https://github.com/ThinamXx/MachineLearning_DeepLearning/blob/main/Images/Day%2020a.PNG) 25 | 26 | ![Image](https://github.com/ThinamXx/MachineLearning_DeepLearning/blob/main/Images/Day%2020b.PNG) 27 | -------------------------------------------------------------------------------- /06. VGGNet Architecture/README.md: -------------------------------------------------------------------------------- 1 | # **Computer Vision: Mini VGGNet Architecture** 2 | 3 | The [**Mini VGGNet**](https://github.com/ThinamXx/ComputerVision/blob/main/06.%20VGGNet%20Architecture/Mini%20VGGNet.ipynb) notebook contains the implementation of VGGNet Architecture. It makes the use of only *3 X 3* filters regardless of network depth. 4 | 5 | 📚**Notebook** 6 | - [**Mini VGGNet Architecture**](https://github.com/ThinamXx/ComputerVision/blob/main/06.%20VGGNet%20Architecture/Mini%20VGGNet.ipynb) 7 | 8 | **Logistic Regression** 9 | - However, when unnecessary or excessive number of variables is used in logistic regression model, peculiarities i.e. special attributes of the underlying dataset disproportionately affect the coefficient of the model, the phenomena commonly known as overfitting. So, it is most important that the logistic regression model doesn't start training more variables than is justified for the given number of observations. 10 | 11 | **Batch Normalization** 12 | - Batch Normalization can lead to a faster, more stable convergence with higher accuracy. Batch Normalization will require more wall time to train the network even though the network will obtain higher accuracy in less epochs. 13 | 14 | **VGGNet Architecture** 15 | - I will define the build method of Mini VGGNet architecture below. It requires four parameters: width of input image, height of input image, depth of image, number of class labels in the classification task. The Sequential class, the building block of sequential networks sequentially stack one layer on top of the other layer initialized below. Batch Normalization operates over the channels, so in order to apply BN, we need to know which axis to normalize over. 16 | 17 | ![Image](https://github.com/ThinamXx/MachineLearning_DeepLearning/blob/main/Images/Day%2017.PNG) 18 | -------------------------------------------------------------------------------- /01. OpenCV/README.md: -------------------------------------------------------------------------------- 1 | # **Computer Vision: OpenCV** 2 | 3 | The [**OpenCV**](https://github.com/ThinamXx/ComputerVision/blob/main/01.%20OpenCV/OpenCV.ipynb) notebook contains the basics of **OpenCV** such as Loading an Image, Resizing Images, Rotating Image, Edge Detection, Thresholding, Drawing and Masking, Contour and Shape Detection. 4 | 5 | The [**OCV Project I**](https://github.com/ThinamXx/ComputerVision/blob/main/01.%20OpenCV/OCV%20Project%20I.ipynb) notebook contains the implementation of Rotating Images correctly without cut off. 6 | 7 | The [**OCV Project II**](https://github.com/ThinamXx/ComputerVision/blob/main/01.%20OpenCV/OCV%20Project%20II.ipynb) notebook contains the implementation of Color Detection and Histogram Matching on images. 8 | 9 | **Note:** 10 | - 📑[**OpenCV**](https://github.com/ThinamXx/ComputerVision/blob/main/01.%20OpenCV/OpenCV.ipynb) 11 | - 📑[**OCV Project I**](https://github.com/ThinamXx/ComputerVision/blob/main/01.%20OpenCV/OCV%20Project%20I.ipynb) 12 | - 📑[**OCV Project II**](https://github.com/ThinamXx/ComputerVision/blob/main/01.%20OpenCV/OCV%20Project%20II.ipynb) 13 | 14 | **Image Processing** 15 | - I have presented the implementation of OpenCV in Resizing and Rotating and Image, Smoothing and Drawing on an Image, Converting Image to Grayscale, Edge Detection, Thresholding, Detecting and Drawing Contours, Erosions and Dilations here in the snapshot. 16 | 17 | ![Image](https://github.com/ThinamXx/300Days__MachineLearningDeepLearning/blob/main/Images/Day%20291.PNG) 18 | ![Image](https://github.com/ThinamXx/300Days__MachineLearningDeepLearning/blob/main/Images/Day%20292.PNG) 19 | 20 | **Rotating Image** 21 | - I have presented the implementation of OpenCV in Rotating Images and Getting ROI of Images here in the snapshot. 22 | 23 | ![Image](https://github.com/ThinamXx/300Days__MachineLearningDeepLearning/blob/main/Images/Day%20293.PNG) 24 | 25 | **Histogram Matching** 26 | - Histogram Matching can be used as a normalization technique in an image processing pipeline as a form of color correction and color matching which allows to obtain a consistent, normalized representation of images even if lighting conditions change. I have presented the implementation of OpenCV in Histogram Matching here in the snapshot. 27 | 28 | ![Image](https://github.com/ThinamXx/300Days__MachineLearningDeepLearning/blob/main/Images/Day%20294.PNG) 29 | -------------------------------------------------------------------------------- /03. Image Classification/Scripts/simplepreprocessor.py: -------------------------------------------------------------------------------- 1 | #@ IMPORTING LIBRARIES AND PACKAGES: 2 | import cv2 3 | import numpy as np 4 | import os 5 | 6 | #@ INITIALIZING SIMPLE PREPROCESSOR: 7 | class SimplePreprocessor: # Defining Simple Preprocessor. 8 | def __init__(self, width, height, inter=cv2.INTER_AREA): # Initializing Constructor Function. 9 | self.width = width # Initialization. 10 | self.height = height # Initialization. 11 | self.inter = inter # Initialization. 12 | 13 | def preprocess(self, image): # Defining Preprocess Function. 14 | return cv2.resize(image, (self.width, self.height), 15 | interpolation=self.inter) # Resizing Image. 16 | 17 | 18 | #@ INITIALIZING DATASET LOADER: 19 | class SimpleDatasetLoader: # Defining Simple Image Loader. 20 | def __init__(self, preprocessors=None): # Initializing Constructor Function. 21 | self.preprocessors = preprocessors # Initialization. 22 | if self.preprocessors is None: # Inspection. 23 | self.preprocessors = [] # Initializing Empty List. 24 | 25 | def load(self, imagePaths, verbose=-1): # Defining Load Function. 26 | data, labels = [], [] # Initializing Empty List. 27 | for (i, imagePath) in enumerate(imagePaths): 28 | image = cv2.imread(imagePath) # Reading Image. 29 | label = imagePath.split(os.path.sep)[-2] # Getting Labels. 30 | if self.preprocessors is not None: 31 | for p in self.preprocessors: 32 | image = p.preprocess(image) # Preprocessing Image. 33 | data.append(image) # Updating Data. 34 | labels.append(label) # Updating Label. 35 | if verbose > 0 and i > 0 and (i+1)%verbose == 0: 36 | print("[INFO] processed {}/{}".format( 37 | i + 1, len(imagePaths))) # Showing Updates. 38 | return (np.array(data), np.array(labels)) # Initializing Array of Data. 39 | 40 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # **COMPUTER VISION** 2 | 3 | The repository contains a list of projects and notebooks which I have worked on while reading Computer Vision, Deep Learning and OpenCV from [**PyImageSearch**](https://www.pyimagesearch.com/). 4 | 5 | ### 📚**NOTEBOOKS:** 6 | 7 | [**1. OPEN CV**](https://github.com/ThinamXx/ComputerVision/tree/main/01.%20OpenCV) 8 | - The **OpenCV** notebook contains the basics of OpenCV such as Loading an Image, Resizing Images, Rotating Image, Edge Detection, Thresholding, Drawing and Masking, Contour and Shape Detection. The **OCV Project I** notebook contains the implementation of Rotating Images correctly without cut off. The OCV Project II notebook contains the implementation of Color Detection and Histogram Matching on images. 9 | 10 | [**2. CONVOLUTIONAL NEURAL NETWORKS**](https://github.com/ThinamXx/ComputerVision/tree/main/02.%20ConvolutionalNeuralNetworks) 11 | - The **Convolutions** notebook contains all the dependencies required to understand the implementation of Image Convolutions and Kernels. The **Convolutional Layers** notebook contains all the dependencies required to understand Keras Conv2D Class and Convolutional Layers. 12 | 13 | [**3. IMAGE CLASSIFICATION**](https://github.com/ThinamXx/ComputerVision/tree/main/03.%20Image%20Classification) 14 | - The **Simplepreprocessor** notebook contains implementation of simple image preprocessor, loading an image dataset into memory, and K-Nearest Neighbor Classifier. K-Nearest Neighbor Classifier doesn’t actually learn anything, but it directly relies on the distance between feature vectors. The **GradientDescent** notebook contains implementation of Gradient Descent Algorithms. The **StochasticGradientDescent** notebook contains implementation of Stochastic Gradient Descent, Image Classification and Regularization. 15 | 16 | [**4. NEURAL NETWORKS**](https://github.com/ThinamXx/ComputerVision/tree/main/04.%20Neural%20Networks) 17 | - The **Neural Networks** notebook contains the implementation of Perceptron algorithm, backpropagation algorithm, and neural networks from scratch. 18 | 19 | [**5. LENET ARCHITECTURE**](https://github.com/ThinamXx/ComputerVision/tree/main/05.%20LeNet%20Architecture) 20 | - The **LeNet Architecture** notebook contains the implementation of LeNet Architecture. LeNet is a seminal work in the deep learning literature which demonstrates how neural networks could be trained to recognize objects in images without feture extraction. 21 | 22 | [**6. VGGNET ARCHITECTURE**](https://github.com/ThinamXx/ComputerVision/tree/main/06.%20VGGNet%20Architecture) 23 | - The **Mini VGGNet** notebook contains the implementation of VGGNet Architecture. It makes the use of only 3 X 3 filters regardless of network depth. 24 | 25 | [**7. PRETRAINED CNN**](https://github.com/ThinamXx/ComputerVision/tree/main/07.%20Pretrained%20CNNs) 26 | - The **Pretrained CNNs** notebook contains the reviews of convolutional neural networks and implementation of VGG16 and Xception networks for classification of images. 27 | 28 | [**8. OBJECT DETECTION**](https://github.com/ThinamXx/ComputerVision/tree/main/08.%20Object%20Detection) 29 | - The **Object Detection** notebook contains implementation of object detection with PyTorch and pretrained networks. It also contains brief description about object detection and image preprocessing. 30 | -------------------------------------------------------------------------------- /03. Image Classification/README.md: -------------------------------------------------------------------------------- 1 | # **Computer Vision: Image Classification** 2 | 3 | The [**Simplepreprocessor**](https://github.com/ThinamXx/ComputerVision/blob/main/03.%20Image%20Classification/Simplepreprocessor.ipynb) notebook contains implementation of simple image preprocessor, loading an image dataset into memory, and K-Nearest Neighbor Classifier. K-Nearest Neighbor Classifier doesn’t actually learn anything, but it directly relies on the distance between feature vectors. 4 | 5 | The [**GradientDescent**](https://github.com/ThinamXx/ComputerVision/blob/main/03.%20Image%20Classification/GradientDescent.ipynb) notebook contains implementation of Gradient Descent Algorithms. 6 | 7 | The [**StochasticGradientDescent**](https://github.com/ThinamXx/ComputerVision/blob/main/03.%20Image%20Classification/StochasticGradientDescent.ipynb) notebook contains implementation of Stochastic Gradient Descent, Image Classification and Regularization. 8 | 9 | **Notebook:** 10 | - 📑[**Simplepreprocessor**](https://github.com/ThinamXx/ComputerVision/blob/main/03.%20Image%20Classification/Simplepreprocessor.ipynb) 11 | - 📑[**LinearClassifier**](https://github.com/ThinamXx/ComputerVision/blob/main/03.%20Image%20Classification/LinearClassifier.ipynb) 12 | - 📑[**GradientDescent**](https://github.com/ThinamXx/ComputerVision/blob/main/03.%20Image%20Classification/GradientDescent.ipynb) 13 | - 📑[**StochasticGradientDescent**](https://github.com/ThinamXx/ComputerVision/blob/main/03.%20Image%20Classification/StochasticGradientDescent.ipynb) 14 | 15 | **Linear Classifier** 16 | - I have presented the notes about K-Nearest Neighbor and Parameterized Learning here in the snapshot. 17 | 18 | ![Image](https://github.com/ThinamXx/MachineLearning_DeepLearning/blob/main/Images/Day%204.PNG) 19 | 20 | **Gradient Descent** 21 | - The gradient descent method is an iterative optimization algorithm that operates over a loss landscape also called and optimization surface. Also, gradient descent refers to the process of attempting to optimize the parameters for low loss and high classification accuracy via an iterative process of taking a step in the direction that minimize loss. I have presented the notes about Gradient Descent and Optimization here in the snapshot. 22 | 23 | ![Image](https://github.com/ThinamXx/MachineLearning_DeepLearning/blob/main/Images/Day%205.PNG) 24 | 25 | **Stochastic Gradient Descent** 26 | - Stochastic Gradient Descent is a simple modification to the standard gradient descent algorithm that computes the gradient and updates the weight matrix on small batches of training data, rather than the entire training set. I have presented the implementation of Sigmoid Activation Function and Stochastic Gradient Descent and notes about Regularization here in the snapshots. 27 | 28 | ![Image](https://github.com/ThinamXx/MachineLearning_DeepLearning/blob/main/Images/Day%207a.PNG) 29 | ![Image](https://github.com/ThinamXx/MachineLearning_DeepLearning/blob/main/Images/Day%207b.PNG) 30 | 31 | **Simple Preprocessor and Dataset Loader** 32 | - I will build an image preprocessor that resizes the image, ignoring the aspect ratio. I have presented the implementation of Image Preprocessor and Dataset Loader here in the snapshot. 33 | 34 | ![Image](https://github.com/ThinamXx/MachineLearning_DeepLearning/blob/main/Images/Day%202.PNG) 35 | 36 | **K-Nearest Neighbor** 37 | - K-Nearest Neighbor Classifier doesn’t actually learn anything, but it directly relies on the distance between feature vectors. I have presented the implementation of K-Nearest Neighbor Classifier and Model Evaluation here in the snapshot. 38 | 39 | ![Image](https://github.com/ThinamXx/MachineLearning_DeepLearning/blob/main/Images/Day%203.PNG) 40 | -------------------------------------------------------------------------------- /03. Image Classification/Simplepreprocessor.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "nbformat": 4, 3 | "nbformat_minor": 0, 4 | "metadata": { 5 | "colab": { 6 | "name": "Simplepreprocessor.ipynb", 7 | "provenance": [], 8 | "collapsed_sections": [] 9 | }, 10 | "kernelspec": { 11 | "name": "python3", 12 | "display_name": "Python 3" 13 | }, 14 | "language_info": { 15 | "name": "python" 16 | } 17 | }, 18 | "cells": [ 19 | { 20 | "cell_type": "markdown", 21 | "metadata": { 22 | "id": "xb0Eq2h3pkY0" 23 | }, 24 | "source": [ 25 | "**LIBRARIES AND DEPENDENCIES:**\n", 26 | "- I have downloaded all the libraries and dependencies required for the project in one particular cell." 27 | ] 28 | }, 29 | { 30 | "cell_type": "code", 31 | "metadata": { 32 | "id": "KpbKYZvxiPTd" 33 | }, 34 | "source": [ 35 | "#@ GETTING LIBRARIES AND DEPENDENCIES: UNCOMMENT BELOW: \n", 36 | "# !python /content/simplepreprocessor.py" 37 | ], 38 | "execution_count": 1, 39 | "outputs": [] 40 | }, 41 | { 42 | "cell_type": "code", 43 | "metadata": { 44 | "id": "eBJAB3K7jiZZ" 45 | }, 46 | "source": [ 47 | "#@ IMPORTING LIBRARIES AND PACKAGES: \n", 48 | "import cv2\n", 49 | "import numpy as np\n", 50 | "import os\n", 51 | "\n", 52 | "from sklearn.neighbors import KNeighborsClassifier\n", 53 | "from sklearn.preprocessing import LabelEncoder\n", 54 | "from sklearn.model_selection import train_test_split\n", 55 | "from sklearn.metrics import classification_report\n", 56 | "from simplepreprocessor import SimplePreprocessor\n", 57 | "from simplepreprocessor import SimpleDatasetLoader \n", 58 | "from imutils import paths" 59 | ], 60 | "execution_count": 2, 61 | "outputs": [] 62 | }, 63 | { 64 | "cell_type": "markdown", 65 | "metadata": { 66 | "id": "GwfQHwzSp3U8" 67 | }, 68 | "source": [ 69 | "**IMAGE PREPROCESSOR:**\n", 70 | "- I will build an image preprocessor that resizes the image, ignoring the aspect ratio. " 71 | ] 72 | }, 73 | { 74 | "cell_type": "code", 75 | "metadata": { 76 | "id": "pL3kk7skj0k4" 77 | }, 78 | "source": [ 79 | "#@ INITIALIZING SIMPLE PREPROCESSOR:\n", 80 | "class SimplePreprocessor: # Defining Simple Preprocessor. \n", 81 | " def __init__(self, width, height, inter=cv2.INTER_AREA): # Initializing Constructor Function. \n", 82 | " self.width = width # Initialization. \n", 83 | " self.height = height # Initialization. \n", 84 | " self.inter = inter # Initialization. \n", 85 | "\n", 86 | " def preprocess(self, image): # Defining Preprocess Function. \n", 87 | " return cv2.resize(image, (self.width, self.height), \n", 88 | " interpolation=self.inter) # Resizing Image. " 89 | ], 90 | "execution_count": 3, 91 | "outputs": [] 92 | }, 93 | { 94 | "cell_type": "markdown", 95 | "metadata": { 96 | "id": "Awkasacxq1OB" 97 | }, 98 | "source": [ 99 | "**IMAGE LOADER:**" 100 | ] 101 | }, 102 | { 103 | "cell_type": "code", 104 | "metadata": { 105 | "id": "tJGbNAsGleV0" 106 | }, 107 | "source": [ 108 | "#@ INITIALIZING DATASET LOADER: \n", 109 | "class SimpleDatasetLoader: # Defining Simple Image Loader. \n", 110 | " def __init__(self, preprocessors=None): # Initializing Constructor Function. \n", 111 | " self.preprocessors = preprocessors # Initialization. \n", 112 | " if self.preprocessors is None: # Inspection. \n", 113 | " self.preprocessors = [] # Initializing Empty List.\n", 114 | " \n", 115 | " def load(self, imagePaths, verbose=-1): # Defining Load Function. \n", 116 | " data, labels = [], [] # Initializing Empty List.\n", 117 | " for (i, imagePath) in enumerate(imagePaths):\n", 118 | " image = cv2.imread(imagePath) # Reading Image. \n", 119 | " label = imagePath.split(os.path.sep)[-2] # Getting Labels. \n", 120 | " if self.preprocessors is not None:\n", 121 | " for p in self.preprocessors:\n", 122 | " image = p.preprocess(image) # Preprocessing Image. \n", 123 | " data.append(image) # Updating Data. \n", 124 | " labels.append(label) # Updating Label. \n", 125 | " if verbose > 0 and i > 0 and (i+1)%verbose == 0:\n", 126 | " print(\"[INFO] processed {}/{}\".format(\n", 127 | " i + 1, len(imagePaths))) # Showing Updates. \n", 128 | " return (np.array(data), np.array(labels)) # Initializing Array of Data. " 129 | ], 130 | "execution_count": 4, 131 | "outputs": [] 132 | }, 133 | { 134 | "cell_type": "markdown", 135 | "metadata": { 136 | "id": "ewSTj0enq6PM" 137 | }, 138 | "source": [ 139 | "**K-NEAREST NEIGHBOR:**" 140 | ] 141 | }, 142 | { 143 | "cell_type": "code", 144 | "metadata": { 145 | "id": "y9x1Shb0sYg2" 146 | }, 147 | "source": [ 148 | "#@ GETTING DATASET: UNCOMMENT BELOW: \n", 149 | "# !unzip /content/drive/MyDrive/Data/animals.zip" 150 | ], 151 | "execution_count": 6, 152 | "outputs": [] 153 | }, 154 | { 155 | "cell_type": "code", 156 | "metadata": { 157 | "id": "CtUp594awpEO", 158 | "colab": { 159 | "base_uri": "https://localhost:8080/" 160 | }, 161 | "outputId": "b10b0fac-6de6-406f-b36a-ee3558e1a1a1" 162 | }, 163 | "source": [ 164 | "#@ PREPROCESSING DATASET: \n", 165 | "imagePaths = list(paths.list_images(\"/content/animals\")) # Getting Image Paths. \n", 166 | "sp = SimplePreprocessor(32, 32) # Initializing Image Resizing. \n", 167 | "sdl = SimpleDatasetLoader(preprocessors=[sp]) # Initializing Dataset Loader. \n", 168 | "(data, labels) = sdl.load(imagePaths, verbose=500) # Initializing Data and Labels. \n", 169 | "data = data.reshape((data.shape[0], 3072)) # Initializing Flatten. \n", 170 | "\n", 171 | "#@ ENCODING LABELS: \n", 172 | "le = LabelEncoder() # Initializing Label Encoder. \n", 173 | "labels = le.fit_transform(labels) # Encoding Labels as Integers. \n", 174 | "(trainX, testX, trainY, testY) = train_test_split(\n", 175 | " data, labels, test_size=0.25, random_state=42) # Initializing Training and Testing. \n", 176 | "\n", 177 | "#@ K-NEAREST NEIGHBOR ALGORITHMS: \n", 178 | "model = KNeighborsClassifier(n_neighbors=1, n_jobs=-1) # Initializing KNN Classifier. \n", 179 | "model.fit(trainX, trainY) # Training KNN Classifier. \n", 180 | "print(classification_report(testY, model.predict(testX), \n", 181 | " target_names=le.classes_)) # Inspecting Classification Report. " 182 | ], 183 | "execution_count": 8, 184 | "outputs": [ 185 | { 186 | "output_type": "stream", 187 | "name": "stdout", 188 | "text": [ 189 | "[INFO] processed 500/3000\n", 190 | "[INFO] processed 1000/3000\n", 191 | "[INFO] processed 1500/3000\n", 192 | "[INFO] processed 2000/3000\n", 193 | "[INFO] processed 2500/3000\n", 194 | "[INFO] processed 3000/3000\n", 195 | " precision recall f1-score support\n", 196 | "\n", 197 | " cats 0.41 0.53 0.46 249\n", 198 | " dogs 0.37 0.49 0.42 239\n", 199 | " panda 0.80 0.33 0.46 262\n", 200 | "\n", 201 | " accuracy 0.45 750\n", 202 | " macro avg 0.52 0.45 0.45 750\n", 203 | "weighted avg 0.53 0.45 0.45 750\n", 204 | "\n" 205 | ] 206 | } 207 | ] 208 | } 209 | ] 210 | } -------------------------------------------------------------------------------- /05. LeNet Architecture/LeNet.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "nbformat": 4, 3 | "nbformat_minor": 0, 4 | "metadata": { 5 | "colab": { 6 | "name": "LeNet.ipynb", 7 | "provenance": [], 8 | "collapsed_sections": [] 9 | }, 10 | "kernelspec": { 11 | "name": "python3", 12 | "display_name": "Python 3" 13 | }, 14 | "language_info": { 15 | "name": "python" 16 | }, 17 | "accelerator": "GPU" 18 | }, 19 | "cells": [ 20 | { 21 | "cell_type": "markdown", 22 | "source": [ 23 | "**INITIALIZATION:**\n", 24 | "- I use these three lines of code on top of my each notebooks because it will help to prevent any problems while reloading the same project. And the third line of code helps to make visualization within the notebook." 25 | ], 26 | "metadata": { 27 | "id": "N1PzyssnEIti" 28 | } 29 | }, 30 | { 31 | "cell_type": "code", 32 | "execution_count": 1, 33 | "metadata": { 34 | "id": "1_wJNjd8DzuH" 35 | }, 36 | "outputs": [], 37 | "source": [ 38 | "#@ INITIALIZATION: \n", 39 | "%reload_ext autoreload\n", 40 | "%autoreload 2\n", 41 | "%matplotlib inline" 42 | ] 43 | }, 44 | { 45 | "cell_type": "markdown", 46 | "source": [ 47 | "**LIBRARIES AND DEPENDENCIES:**\n", 48 | "- I have downloaded all the libraries and dependencies required for the project in one particular cell." 49 | ], 50 | "metadata": { 51 | "id": "h-6DXIcJEc7v" 52 | } 53 | }, 54 | { 55 | "cell_type": "code", 56 | "source": [ 57 | "#@ IMPORTING NECESSARY LIBRARIES AND DEPENDENCIES:\n", 58 | "from keras.models import Sequential\n", 59 | "from keras.layers.convolutional import Conv2D\n", 60 | "from keras.layers.convolutional import MaxPooling2D\n", 61 | "from keras.layers.core import Activation\n", 62 | "from keras.layers.core import Flatten\n", 63 | "from keras.layers.core import Dense\n", 64 | "from keras import backend as K\n", 65 | "from tensorflow.keras.optimizers import SGD\n", 66 | "from tensorflow.keras.datasets import mnist\n", 67 | "\n", 68 | "from sklearn.preprocessing import LabelBinarizer\n", 69 | "from sklearn.model_selection import train_test_split\n", 70 | "from sklearn.metrics import classification_report\n", 71 | "\n", 72 | "import matplotlib.pyplot as plt\n", 73 | "import numpy as np" 74 | ], 75 | "metadata": { 76 | "id": "fckOv3DcEad3" 77 | }, 78 | "execution_count": 2, 79 | "outputs": [] 80 | }, 81 | { 82 | "cell_type": "markdown", 83 | "source": [ 84 | "**LENET ARCHITECTURE:**\n", 85 | "- I will define the build method of **LeNet** architecture below. It requires four parameters: **width** of input image, **height** of input image, **depth** of image, number of **class labels** in the classification task. The **Sequential** class, the building block of sequential networks sequentially stack one layer on top of the other layer initialized below. " 86 | ], 87 | "metadata": { 88 | "id": "nQfvI-1YFaYo" 89 | } 90 | }, 91 | { 92 | "cell_type": "code", 93 | "source": [ 94 | "#@ DEFINING LENET ARCHITECTURE: \n", 95 | "class LeNet: # Defining LeNet Class. \n", 96 | " @staticmethod\n", 97 | " def build(width, height, depth, classes): # Defining Build Method. \n", 98 | " model = Sequential() # Initializing Sequential Model. \n", 99 | " inputShape = (height, width, depth) # Initializing Input Shape. \n", 100 | " if K.image_data_format() == \"channels_first\":\n", 101 | " inputShape = (depth, height, width) # Initializing Input Shape. \n", 102 | " model.add(Conv2D(20, (5, 5), padding=\"same\", \n", 103 | " input_shape=inputShape)) # Adding Convolutional Layer. \n", 104 | " model.add(Activation(\"relu\")) # Adding RELU Activation Function. \n", 105 | " model.add(MaxPooling2D(pool_size=(2,2),strides=(2,2))) # Decreasing 75% Input Size. \n", 106 | " model.add(Conv2D(50, (5, 5), padding=\"same\")) # Adding Convolutional Layer. \n", 107 | " model.add(Activation(\"relu\")) # Adding RELU Activation Function. \n", 108 | " model.add(MaxPooling2D(pool_size=(2,2),strides=(2,2))) # Decreasing 75% Input Size. \n", 109 | " model.add(Flatten()) # Adding Flatten Layer. \n", 110 | " model.add(Dense(500)) # Adding Fully Connected Layer. \n", 111 | " model.add(Activation(\"relu\")) # Adding RELU Activation Function. \n", 112 | " model.add(Dense(classes)) # Adding FC Dense Layer. \n", 113 | " model.add(Activation(\"softmax\")) # Adding Softmax Classifier. \n", 114 | " return model" 115 | ], 116 | "metadata": { 117 | "id": "bRzJKnSkFPO0" 118 | }, 119 | "execution_count": 3, 120 | "outputs": [] 121 | }, 122 | { 123 | "cell_type": "markdown", 124 | "source": [ 125 | "**LENET on MNIST:**\n", 126 | "- Each **MNIST** sample inside data is represented by a 784 dimensional raw pixel intensities of a 28X28 grayscale image. " 127 | ], 128 | "metadata": { 129 | "id": "WuUq9MJ4JhbA" 130 | } 131 | }, 132 | { 133 | "cell_type": "code", 134 | "source": [ 135 | "#@ GETTING THE DATASET: \n", 136 | "((trainData, trainLabels), (testData, testLabels)) = mnist.load_data() # Loading the Dataset. \n", 137 | "if K.image_data_format() == \"channels_first\":\n", 138 | " trainData = trainData.reshape((trainData.shape[0], 1, 28, 28)) # Reshaping the Dataset. \n", 139 | " testData = testData.reshape((testData.shape[0], 1, 28, 28)) # Reshaping the Dataset. \n", 140 | "else:\n", 141 | " trainData = trainData.reshape((trainData.shape[0], 28, 28, 1)) # Reshaping the Dataset. \n", 142 | " testData = testData.reshape((testData.shape[0], 28, 28, 1)) # Reshaping the Dataset. " 143 | ], 144 | "metadata": { 145 | "id": "3Xy_eCn7JV5q" 146 | }, 147 | "execution_count": 5, 148 | "outputs": [] 149 | }, 150 | { 151 | "cell_type": "code", 152 | "source": [ 153 | "#@ PROCESSING THE DATASET: \n", 154 | "trainData = trainData.astype('float32') / 255.0 # Normalizing the Data.\n", 155 | "testData = testData.astype('float32') / 255.0 # Normalizing the Data. \n", 156 | "lb = LabelBinarizer() # Initializing LabelBinarizer. \n", 157 | "trainLabels = lb.fit_transform(trainLabels) # Converting Labels into Vectors. \n", 158 | "testLabels = lb.transform(testLabels) # Converting Labels into Vectors. " 159 | ], 160 | "metadata": { 161 | "id": "WHXoDocPGa_0" 162 | }, 163 | "execution_count": 6, 164 | "outputs": [] 165 | }, 166 | { 167 | "cell_type": "code", 168 | "source": [ 169 | "#@ INITIALIZING OPTIMIZER AND MODEL: \n", 170 | "opt = SGD(0.01) # Initializing SGD Optimizer. \n", 171 | "model = LeNet.build(width=28, height=28, depth=1, classes=10) # Initializing LeNet Architecture. \n", 172 | "model.compile(loss=\"categorical_crossentropy\",optimizer=opt,\n", 173 | " metrics=[\"accuracy\"]) # Compiling LeNet Model. \n", 174 | "H = model.fit(trainData, trainLabels, \n", 175 | " validation_data=(testData, testLabels), \n", 176 | " batch_size=128, epochs=20, verbose=1) # Training LeNet Model." 177 | ], 178 | "metadata": { 179 | "id": "DZ6N_dwXNnMS", 180 | "colab": { 181 | "base_uri": "https://localhost:8080/" 182 | }, 183 | "outputId": "73d12ac8-a931-45d1-e73e-f3a940606393" 184 | }, 185 | "execution_count": 7, 186 | "outputs": [ 187 | { 188 | "output_type": "stream", 189 | "name": "stdout", 190 | "text": [ 191 | "Epoch 1/20\n", 192 | "469/469 [==============================] - 18s 13ms/step - loss: 0.9274 - accuracy: 0.7520 - val_loss: 0.3026 - val_accuracy: 0.9131\n", 193 | "Epoch 2/20\n", 194 | "469/469 [==============================] - 6s 13ms/step - loss: 0.2503 - accuracy: 0.9264 - val_loss: 0.2037 - val_accuracy: 0.9403\n", 195 | "Epoch 3/20\n", 196 | "469/469 [==============================] - 6s 12ms/step - loss: 0.1784 - accuracy: 0.9476 - val_loss: 0.1571 - val_accuracy: 0.9520\n", 197 | "Epoch 4/20\n", 198 | "469/469 [==============================] - 6s 12ms/step - loss: 0.1387 - accuracy: 0.9593 - val_loss: 0.1278 - val_accuracy: 0.9603\n", 199 | "Epoch 5/20\n", 200 | "469/469 [==============================] - 6s 13ms/step - loss: 0.1154 - accuracy: 0.9658 - val_loss: 0.1032 - val_accuracy: 0.9665\n", 201 | "Epoch 6/20\n", 202 | "469/469 [==============================] - 6s 12ms/step - loss: 0.1002 - accuracy: 0.9700 - val_loss: 0.0854 - val_accuracy: 0.9734\n", 203 | "Epoch 7/20\n", 204 | "469/469 [==============================] - 6s 12ms/step - loss: 0.0882 - accuracy: 0.9741 - val_loss: 0.0756 - val_accuracy: 0.9773\n", 205 | "Epoch 8/20\n", 206 | "469/469 [==============================] - 6s 13ms/step - loss: 0.0784 - accuracy: 0.9764 - val_loss: 0.0705 - val_accuracy: 0.9768\n", 207 | "Epoch 9/20\n", 208 | "469/469 [==============================] - 6s 14ms/step - loss: 0.0715 - accuracy: 0.9787 - val_loss: 0.0677 - val_accuracy: 0.9782\n", 209 | "Epoch 10/20\n", 210 | "469/469 [==============================] - 6s 12ms/step - loss: 0.0663 - accuracy: 0.9801 - val_loss: 0.0647 - val_accuracy: 0.9796\n", 211 | "Epoch 11/20\n", 212 | "469/469 [==============================] - 6s 12ms/step - loss: 0.0614 - accuracy: 0.9819 - val_loss: 0.0551 - val_accuracy: 0.9815\n", 213 | "Epoch 12/20\n", 214 | "469/469 [==============================] - 6s 12ms/step - loss: 0.0575 - accuracy: 0.9830 - val_loss: 0.0568 - val_accuracy: 0.9817\n", 215 | "Epoch 13/20\n", 216 | "469/469 [==============================] - 6s 12ms/step - loss: 0.0543 - accuracy: 0.9836 - val_loss: 0.0512 - val_accuracy: 0.9832\n", 217 | "Epoch 14/20\n", 218 | "469/469 [==============================] - 6s 12ms/step - loss: 0.0511 - accuracy: 0.9845 - val_loss: 0.0500 - val_accuracy: 0.9831\n", 219 | "Epoch 15/20\n", 220 | "469/469 [==============================] - 6s 12ms/step - loss: 0.0482 - accuracy: 0.9856 - val_loss: 0.0497 - val_accuracy: 0.9830\n", 221 | "Epoch 16/20\n", 222 | "469/469 [==============================] - 6s 12ms/step - loss: 0.0462 - accuracy: 0.9860 - val_loss: 0.0599 - val_accuracy: 0.9801\n", 223 | "Epoch 17/20\n", 224 | "469/469 [==============================] - 5s 12ms/step - loss: 0.0442 - accuracy: 0.9868 - val_loss: 0.0435 - val_accuracy: 0.9863\n", 225 | "Epoch 18/20\n", 226 | "469/469 [==============================] - 5s 12ms/step - loss: 0.0422 - accuracy: 0.9875 - val_loss: 0.0421 - val_accuracy: 0.9860\n", 227 | "Epoch 19/20\n", 228 | "469/469 [==============================] - 6s 12ms/step - loss: 0.0404 - accuracy: 0.9876 - val_loss: 0.0418 - val_accuracy: 0.9863\n", 229 | "Epoch 20/20\n", 230 | "469/469 [==============================] - 6s 12ms/step - loss: 0.0390 - accuracy: 0.9880 - val_loss: 0.0398 - val_accuracy: 0.9868\n" 231 | ] 232 | } 233 | ] 234 | }, 235 | { 236 | "cell_type": "markdown", 237 | "source": [ 238 | "**MODEL EVALUATION:**" 239 | ], 240 | "metadata": { 241 | "id": "j1xxfT38dUyN" 242 | } 243 | }, 244 | { 245 | "cell_type": "code", 246 | "source": [ 247 | "#@ INITIALIZING MODEL EVALUATION:\n", 248 | "predictions = model.predict(testData, batch_size=128) # Getting Model Predictions. \n", 249 | "print(classification_report(testLabels.argmax(axis=1),\n", 250 | " predictions.argmax(axis=1), \n", 251 | " target_names=[str(x) for x in lb.classes_])) # Inspecting Classification Report." 252 | ], 253 | "metadata": { 254 | "colab": { 255 | "base_uri": "https://localhost:8080/" 256 | }, 257 | "id": "Wyd0nl4H92eJ", 258 | "outputId": "2c641006-f034-4fc8-f02a-474165307e0a" 259 | }, 260 | "execution_count": 8, 261 | "outputs": [ 262 | { 263 | "output_type": "stream", 264 | "name": "stdout", 265 | "text": [ 266 | " precision recall f1-score support\n", 267 | "\n", 268 | " 0 0.98 0.99 0.99 980\n", 269 | " 1 0.99 0.99 0.99 1135\n", 270 | " 2 0.99 0.98 0.99 1032\n", 271 | " 3 0.99 0.98 0.99 1010\n", 272 | " 4 0.99 0.99 0.99 982\n", 273 | " 5 0.99 0.99 0.99 892\n", 274 | " 6 0.99 0.99 0.99 958\n", 275 | " 7 0.98 0.99 0.98 1028\n", 276 | " 8 0.99 0.98 0.98 974\n", 277 | " 9 0.99 0.97 0.98 1009\n", 278 | "\n", 279 | " accuracy 0.99 10000\n", 280 | " macro avg 0.99 0.99 0.99 10000\n", 281 | "weighted avg 0.99 0.99 0.99 10000\n", 282 | "\n" 283 | ] 284 | } 285 | ] 286 | }, 287 | { 288 | "cell_type": "code", 289 | "source": [ 290 | "#@ INSPECTING TRAINING LOSS AND ACCURACY:\n", 291 | "plt.style.use(\"ggplot\")\n", 292 | "plt.figure()\n", 293 | "plt.plot(np.arange(0, 20), H.history[\"loss\"], label=\"train_loss\")\n", 294 | "plt.plot(np.arange(0, 20), H.history[\"val_loss\"], label=\"val_loss\")\n", 295 | "plt.plot(np.arange(0, 20), H.history[\"accuracy\"], label=\"train_acc\")\n", 296 | "plt.plot(np.arange(0, 20), H.history[\"val_accuracy\"], label=\"val_acc\")\n", 297 | "plt.title(\"Training Loss and Accuracy\")\n", 298 | "plt.xlabel(\"Epoch\")\n", 299 | "plt.ylabel(\"Loss/Accuracy\")\n", 300 | "plt.legend()\n", 301 | "plt.show();" 302 | ], 303 | "metadata": { 304 | "colab": { 305 | "base_uri": "https://localhost:8080/", 306 | "height": 299 307 | }, 308 | "id": "13nhXxfDdqWn", 309 | "outputId": "47275c65-aa57-423a-8654-81434ac95c79" 310 | }, 311 | "execution_count": 9, 312 | "outputs": [ 313 | { 314 | "output_type": "display_data", 315 | "data": { 316 | "image/png": "iVBORw0KGgoAAAANSUhEUgAAAYUAAAEaCAYAAAD+E0veAAAABHNCSVQICAgIfAhkiAAAAAlwSFlzAAALEgAACxIB0t1+/AAAADh0RVh0U29mdHdhcmUAbWF0cGxvdGxpYiB2ZXJzaW9uMy4yLjIsIGh0dHA6Ly9tYXRwbG90bGliLm9yZy+WH4yJAAAgAElEQVR4nOzdeXwU9f348dfsvbmz2RyEhCtAuBSESLjkkHhyeKG2FjyAev7UWlsqFL5oVUCUilKsVBEqUksVtKJiBRQBQUW5PDljDJCQm9yb7M78/tiwEJKQTUiyC/t+PtzH7hyfmfcscd4785nP56NomqYhhBBCADpfByCEEMJ/SFIQQgjhIUlBCCGEhyQFIYQQHpIUhBBCeEhSEEII4SFJQXht06ZNKIrCkSNHmlROURTeeOONVooqcI0cOZKpU6f6OgxxgZGkcAFSFOWsr06dOjVru0OGDCErK4v4+PgmlcvKymLChAnN2mdTSQKq33333Yder2fx4sW+DkX4OUkKF6CsrCzPa/Xq1QDs3LnTM2/Hjh211q+qqvJquyaTibi4OHS6pv3ZxMXFYbFYmlRGtJyysjJWrlzJjBkzeOWVV3wdDuD935xoe5IULkBxcXGel81mAyA6OtozLyYmhhdffJHbbruN8PBwJk2aBMCf//xnevbsSVBQEImJidx7772cOHHCs90zbx+dnF6/fj3Dhw8nKCiIXr16sW7dulrxnPnrXVEUXnrpJSZNmkRoaCgJCQnMnTu3Vpn8/HxuvvlmgoODiY2NZdasWdxxxx2kpaWd03fzz3/+k169emEymUhISGDmzJk4nU7P8q1btzJ06FBCQ0MJDQ2lb9++/O9///MsnzNnDl26dMFsNhMdHc1VV11FRUVFg/v717/+RWpqKuHh4djtdsaMGcP+/fs9y3/++WcUReE///kPY8eOJSgoiC5durB8+fJa28nIyODqq6/GarWSmJjIokWLvD7mN998k27dujFz5kwyMjL48ssv66yzatUqBgwYgMViISoqimuuuYbCwkLP8sWLF9OrVy/MZjMxMTHcdNNNnmWdOnXiqaeeqrW9qVOnMnLkSM/0yJEjmTJlCrNmzaJdu3Z06NDBq+8HICcnh7vuuovY2FgsFgvJycm89tpraJpGly5dmDNnTq31y8rKCAsLY8WKFV5/R+IUSQoB6oknnmDIkCHs3LnT8z+01WrlH//4Bz/88APLly9n06ZNPPTQQ41u6w9/+AMzZsxgz549pKamcuutt9Y6oTS0/+HDh7N7926mT5/OjBkz2Lhxo2f5XXfdxZ49e3j//ff55JNPOHLkCO++++45HfMHH3zA5MmTmTRpEt999x0LFixg8eLFPPHEEwA4nU7Gjx9PamoqO3fuZOfOnTz++OMEBQUBsGbNGubNm8cLL7zAgQMHWL9+Pddcc81Z9+lwOJg5cyY7d+5k/fr16PV6xowZU+eX8mOPPcbtt9/O3r17+dWvfsXUqVM9J0dN07jhhhvIz89n06ZNrF27lvfee4+dO3d6ddxLlizhzjvvxGw286tf/YolS5bUWr5s2TImTpzI9ddfz86dO/n000+5+uqrcblcAMyePZs//elP3H///Xz77bd89NFH9O/f36t9n+4///kPubm5bNy4kfXr13v1/VRUVDBixAj27NnDypUr+eGHH1i0aBFBQUEoisJvf/tbli5dyum99fz73//GYDBw8803NzlGAWjigvbpp59qgJaZmemZB2iTJ09utOyaNWs0k8mkuVyuerd1cnr16tWeMtnZ2RqgffTRR7X2t2LFilrTDz74YK199ejRQ3vsscc0TdO0/fv3a4C2YcMGz/KqqiotISFBGz169FljPnNfpxs2bJh2880315q3cOFCzWKxaA6HQysoKNAA7dNPP623/F//+letW7duWlVV1VljOJv8/HwN0LZu3appmqalp6drgLZgwQLPOk6nUwsJCdFefvllTdM0bf369Rqg7du3z7NOTk6OZrFYtClTppx1f7t27dJMJpOWl5enaZqmbd++XQsKCtKKioo86yQmJmoPPPBAveVLS0s1i8WiPfvssw3uo2PHjtqTTz5Za96UKVO0ESNGeKZHjBihdevWzfO31JAzv59XX31VM5vNtf5+T5edna0ZjUZt/fr1nnmDBg3SHnroobPuRzRMrhQC1MCBA+vMW7NmDcOHDyc+Pp6QkBB+85vfUFVVRXZ29lm31a9fP8/n2NhY9Ho9x48f97oMQHx8vKfMDz/8AMCgQYM8y41GIykpKWc/qEZ8//33DB8+vNa8ESNGUFlZyaFDh4iMjGTq1KlcddVVXHPNNcybN499+/Z51r3llluorq6mY8eO3HnnnaxYsYKSkpKz7nP37t3ccMMNdO7cmdDQUM9tk4yMjFrrnf596PV6YmJian0fdrud7t27e9aJjo4mOTm50WNesmQJY8eOJSoqCnB/pwkJCZ7beTk5OWRmZnLllVfWW/7777+nsrKyweVNMWDAgDr1UY19P9988w29evUiISGh3m3GxsZy3XXXeepKvvvuO7744gt++9vfnnO8gUqSQoAKDg6uNf3ll19y8803M3z4cN555x127tzJyy+/DDReKWgymerMU1W1SWUURalTRlGUs26jNbzyyit88803XHHFFXz22Wf06dPHc7ulffv2/PTTT7z22mvExMTw5JNPkpycTGZmZr3bKi8v58orr0RRFJYtW8ZXX33Fjh07UBSlznfqzffRVCcrmN99910MBoPndeDAgRatcNbpdLVu3wBUV1fXWe/Mv7mmfD9nc++99/Luu++Sl5fHq6++yuDBg+nTp0/zDkZIUhBuW7duxW6389RTT5Gamkr37t2b3B6hpfTq1QuA7du3e+Y5nU6++eabc9pu79692bx5c615n332GVarlaSkJM+8Pn368Pvf/55169YxZcoU/vGPf3iWmc1mrr76aubPn8+3335LeXl5g3UdP/74I7m5uTz99NOMHDmSnj17UlhYWOcE2phevXqRl5fHgQMHPPPy8vJqXcXU580338RgMLB79+5ar02bNrF3716+/PJLYmJiSEhI4OOPP25w3xaLpcHlADExMRw7dqzWvF27djV6XN58PwMGDOCHH34469/i5ZdfTocOHViyZAkrVqyQq4RzZPB1AMI/JCcnk5uby9KlSxk1ahRbt27lpZde8kks3bp1Y9y4cTzwwAMsWbKE6OhoFixYQHFxsVdXD7/88gu7d++uNS8+Pp7p06czbtw45s2bx4033sju3bt5/PHHefTRRzGZTBw8eJBXXnmFcePGkZiYyLFjx9iyZYunUnXp0qWoqsrAgQOJiIhg48aNlJSUeJLYmTp27IjZbGbRokU8+uij/Pzzzzz22GNNvgIaPXo0ffv2ZeLEiSxatAiTycSf/vQnjEbjWcstWbKEG264gYsuuqjOskGDBrFkyRJSU1OZPXs29913H7GxsUyYMAFVVfn000/51a9+hd1u59FHH+Xxxx/HarVyxRVXUFFRwYcffsj06dMBSEtL46WXXuKGG26gY8eOvPzyy2RkZHiefGuIN9/Pr3/9a+bPn8/48eOZP38+SUlJHD58mLy8PG699VbAfVV19913M3PmTKxWq2e+aCYf12mIVtZQRXN9lbEzZ87UYmJitKCgIO2aa67R/vWvf2mAlp6eXu+26tu2pmmaXq/Xli1b1uD+6tv/6NGjtTvuuMMznZeXp910002a1WrVoqOjtVmzZmkTJkzQxo4de9bjBep9zZ07V9M0TVu+fLnWo0cPzWg0avHx8dqMGTO06upqTdM07dixY9oNN9ygtW/fXjOZTFq7du20qVOneiplV69erQ0ePFiLiIjQrFar1rt3b+3VV189azxvvfWW1rVrV81sNmv9+vXTNm3aVOv7OVnRvGXLllrlkpKStNmzZ3um09PTtSuuuEIzm81a+/bttYULF2ojRoxosKJ5165ddSr8T7dw4cJaFc5vvPGGdvHFF2smk0mz2WzatddeqxUWFmqapmmqqmoLFy7UunfvrhmNRi0mJkabMGGCZ1vFxcXaxIkTtYiICC06OlqbPXt2vRXN9cXa2PejaZqWlZWlTZo0SYuKitLMZrOWnJxca7mmaVpubq5mNBq1+++/v97jFd5TNE1GXhP+z+Vy0aNHD8aPH8+CBQt8HY7wM99//z19+vRh9+7d9O3b19fhnNfk9pHwS5s3byYnJ4dLLrmEkpISnn/+eX7++WfuvPNOX4cm/IjD4SAvL4/p06czatQoSQgtQJKC8Esul4unnnqKgwcPYjQa6dOnD59++mm998dF4HrzzTeZPHkyvXv35u233/Z1OBcEuX0khBDCQx5JFUII4SFJQQghhMd5X6dwZqMZb9ntdvLy8lo4mpYj8Z0bie/c+XuMEl/znW1MFLlSEEII4SFJQQghhIckBSGEEB5tUqfw0ksvsXPnTsLDw+ttjappGsuWLWPXrl2YzWbuv/9+unTp0hahCSGEOE2bXCmMHDmSGTNmNLh8165dZGdn8+KLL3L33Xfz6quvtkVYQgghztAmSaFXr16EhIQ0uPzrr79m+PDhKIpC9+7dKSsra3Q4RyGEEC3PLx5JLSgowG63e6ajoqIoKCggMjKyzrobNmxgw4YNAMybN69WuaYwGAzNLtsWJL5zI/GdO3+PUeJrHX6RFJoiLS2NtLQ0z3RznwP252eIQeI7VxLfuWvNGDVNA/d/p94BT6c7py0DzTP/1DyIjLSRn1+App22vTqv0+YDqqpRVeWgyuFAVVU0asZu0BQ0QKm1j5p5Gmesp6GgoGqngvT0FVQTqKppBAcFU1ZWdmqpVnu9k/FpgKaq7vVOzqu1vOb4PfPdr06do4hPjGjW93+2dgp+kRRsNlutP778/PxGB+gQwh9pmoamgqq5T0CqS8PpVKl2OnFWq7icLpxOJ/m5DopPFHv+51c10FTQNBW1ZhQItWb65PY0z3y1poyKpqq4VPe7qrrQNPe0e52ad1X1rKtqp5Zpp85Vp8WP5wSp1+lxupyA4jmx1jpBa4rnmEHxxHf6Nk/O086cByiKHp1iQMGAouhRFAO6mvda057lZ97tLq45XgeqWolLqzz1WXXgUitr5p/87H4/lYLOb1XVlxGfeEmLb9cvkkJKSgofffQRQ4cO5cCBAwQFBdV760icn5xOJ9XV1VRVVVFdXe15walxmBVFqfU6fd7p6wFoqoJL1XA5tZqTrIrT5cLl1HA6XbhcKibTL5SWlOJyqadeqorqcuFyabhc7hOo6jp1onSfOLVTJ9CTJ9aaaU3TUDVXzYn85EnXVfPZhYZa5zOc2zjL4hSdokOnN6DXG9Dr9FQ7q6iudjS4vtFoxmK2YDFbsZgjMJutmM0WLBb3u05Rai4NNPD8eZ1KGAqgKaddsiinL9ZO/U0qiru4UvM3W1M6OCSY8rKyU8tRUJRT6ys1+z/zb/9kXO53BV1NGc98nQ5FUYiIaN5VQmPaJCksXLiQH374gZKSEu69915uueUWnE4nAFdeeSWXXHIJO3fu5KGHHsJkMnH//fe3RVjCS06nk4qKCsrLyz0vnU5HYWGh52TvftX+XF1dhbO6GlXz9xNjzf+Q6FCU01/KGdO6mhOTe5leZ0Kn06HT6WteOvR692e9Xlfz7v7sfq95GfSEBAdT6ahwbxdQdFBzDnDvV6eg88w/dfLQ6UDBPa3X69Dr9Oj0upr9ndy/zvM6c/r018mTWkMdJUdFRTV4+6i+Mo11uHz6ck1zJ2an0+n50eByuaiurvbMO/115nyXy0V4eDgAVqsVq9WKxWIhKCgIq9WK2WxGr9d78W/fes6HW4T1Oe+7zpa+j5qnurrac4IvLSmntLSM0rJyysvc8yoqKqisLKfSUYHTWdXAVhR0OiM6xVhzqW9EUYzo6vtcs55OMWIwGjAajO4Tn05DUXCf7HSgKJr7swLKyWWKhqJTUBQNdDXTioJer6A3uE+6BoP7xKg36DHodUTYwqkoL8NgdE8bjPpT65xxomzqmMktwd///sD/Y5T4ms/v6xTEudE0DYfDQUVFBaWl5ZQUl1NaWkFZWQXlZeVUVFbgqKzE4aikqroCp9OBqjnr3ZZOMaHXWdDrrOh1EQQZ49CZrRgNFkxGK2ZzEGazldDQMBRFw2jSYTAoGI0KeqOC0aBgMCoYjLjfa6aNNZ/1BtrkJOzP/0MK4c8kKfgxVVXdv+RLSykpKeFEUSmFhSWUFJdSVlaGo+rUSb6hyjNFMaBXLOj1ZowGC8FB4ZhN7vuqFov7UjsoKIggaxAhIUGYzAbPydx42oldp699IpeTrhAXJkkKPuJ0OiktdZ/cS0tLPa+SklKKi0spLy+jvLyMuid7HQZ9EAZdEEZjKOEh0ZhN7vupVmsQQUEWgkOshIYGExpqJSjEiMns/jUvhBCNkaTQilRVpbS0lMLCQs+rqKiIwsJCSktL66yvU4zodUHo9UEYdLFEBAdhtQQTEhpCeHgoNnsoNlsQIWEGrEGKT+6FCyEubJIUWoDD4ah14j958i8qKsLlcnnWMxpNWEzh6JUYIoK7en7xm01BhIWHEh5pISRUT0iojoQOUVQ5i+UXvhCiTUlSaCKn08nPP/9MRkaGJwFUVFR4liuKQnh4OBEREcREJ6BoYVRXhuAoC0Gns2A0KUTHGomKMRAariMkVI/ZUvdXv81uJi9PEoIQom1JUvCCqqocOXKE/fv3c/DgQaqqqjCbzdhsNjp37kxkZCQRERFYzOE4yoPIz9HIy6mmshBQINKmp0uSkeg4AxE2PTqdnOyFEP5JkkIDNE0jJyeHffv2sX//fsrLyzEajXTt2pXk5GQSEhJwuRTyc5zkZlfz809OyktVoAprkEJ8oonoOAPRsQaMJhnLSAhxfgjIpKBuWkfuB6tg7qsohtpfQVFREfv27WPfvn0UFRWh0+no1KkTycnJdO7cGYPBQEmxi+2byijMc6FpoDeAPcZAl+5mouMMBIf4pkGUEEKcq4BMCuj1qEUF6E4UQFQMZWVlHDhwgH379nH8+HEAEhIS6N+/P127dsVisdQq/uOeCoqLXCT1cCcBW5ShznP8QghxPgrIpKBE2nHo9KTv3cu+ohKOHDmCpmlER0czbNgwunXrRmhoaL1lS0tcHD/mpHtvM8l9rG0cuRBCtK6ATAp7C4rZ2nM4rm9/ICwsjJSUFJKTk73qrjt9vwOdDjp1NbdBpEII0bYCMilEJSTSa8MHJF/Sn3bX/8rr+/9VDpXM9CradzBhtkjlsRDiwhOQSSGhSxLxJ45CRdcmVQj/crgKlws6d5erBCHEhSlgf+7q7TFohd536KaqGukHHNhjDIRH+rafdiGEaC0BmxR09lgo8D4pZGVWU1mh0SVZrhKEEBeugE0KensMeHmloGkah/c7CA7REdMuIO+4CSECRMAmBZ09BkpOoFU3NKrYKYV5LooKXHTubpZGaUKIC1rAJgV9VKz7gxdXC4f3OzAaFRI7mVo5KiGE8K3ATQr2GPeHRuoVystcZB2tpkOSCYNRrhKEEBe2gE0KOrv7SkFrJCmk769CATp3kwpmIcSFL2CTgj7q5JVCboPrOKs1fkl30C7RiDUoYL8qIUQACdgznWI2Q2j4WesUfkmvwlkNXaSxmhAiQARsUgAg0t7g7SNN1Ujf7yAySk9klDyGKoQIDIGdFGz2Bq8Uso9VU16mSmM1IURACeikoETaG3z66PB+B9Yghbj2xjaOSgghfCegkwI2O1SUoVWW15pdVOCkINfdWE3GUxZCBJLATgqRdvf7GVcLh/c70BugQ2e5dSSECCwBnRQUW7T7w2lJobJC5dgv1XTobMJokqsEIURgCeikgM19pXB6F9rpBxxomoyZIIQITIGdFMJtoCieKwWnUyPjUBVx7Y0Eh8iYCUKIwBPQSUExGCA8EgrdrZqP/FxFdZUmjdWEEAGrzVpl7d69m2XLlqGqKqNHj+b666+vtTwvL4/FixdTVlaGqqrcdttt9O/fv/UDq2nApmnuxmrhkXps0XKVIIQITG2SFFRVZenSpcycOZOoqCimT59OSkoKCQkJnnVWr17N4MGDufLKKzly5Ahz585tm6Rgs8PRDHKynZSWqFySGiRjJgghAlab3D46ePAgcXFxxMbGYjAYGDJkCDt27Ki1jqIolJe72wuUl5cTGRnZFqGhREZDQS6H9zkwWxTiE6WxmhAicLXJlUJBQQFRUVGe6aioKA4cOFBrnZtvvpmnnnqKjz76CIfDwaxZs+rd1oYNG9iwYQMA8+bNw263Nysmg8GA3W6nrEMnsozR5B130j/VRkysrVnba2kn4/NXEt+58ff4wP9jlPhah9/09Pb5558zcuRIxo0bx/79+1m0aBELFixAp6t9MZOWlkZaWppnOi/Pu3GWz2S328nLy0MzWUnvcBU6nUZ0O2ezt9fSTsbnryS+c+Pv8YH/xyjxNV98fHyDy9rk9pHNZiM/P98znZ+fj81W+xf5J598wuDBgwHo3r071dXVlJSUtHpsjtBojsUNISHsBCZzQD+MJYQQbZMUkpKSyMrKIicnB6fTybZt20hJSam1jt1u57vvvgPgyJEjVFdXExYW1uqxZZREoepNdNalt/q+hBDC37XJ7SO9Xs/kyZN5+umnUVWVUaNGkZiYyKpVq0hKSiIlJYXbb7+dJUuW8MEHHwBw//33t/pTQC6XRkamnuj8PYQYf2nVfQkhxPmgzeoU+vfvX+cR01tvvdXzOSEhgSeffLKtwgHg2C/VOBwanQq3g8lvqleEEMJnAvZMqGkah/dXEhquw24sRCuUtglCCBGwNavZRysoLlLp0t2MLjK6wcF2hBAikARsUvh+TxEms0L7jqaaYTnz0VTV12EJIYRPBWRSKC1xkflzOR2TTOj1ijspuJxQcsLXoQkhhE8FZFI48nMVOh106uruDVVpYAQ2IYQINAFZ0Zzc20LPPjFoSk3jONvJpJALnbv5LjAhhPCxgLxSUHQKUdGnjZkQ6R6WU6sZV0EIIQJVQCaFOkJCwWSS20dCiIAnSQF3t93IY6lCCCFJwcNmRyuUpCCECGySFGookXa5UhBCBDxJCifZ7HCiEM3l8nUkQgjhM5IUToq0g6ZCUYGvIxFCCJ+RpFBDOdlWQR5LFUIEMEkKJ51sqyD1CkKIAOZ1Uli+fDk///xzK4biY54rBUkKQojA5XU3F6qq8vTTTxMWFsZll13GZZddRlRUVGvG1qYUaxBYg+QJJCFEQPM6KUyePJk777yTXbt2sWXLFtasWUO3bt0YPnw4qampWCyW1oyzbUTa0QqkTkEIEbia1CGeTqdjwIABDBgwgMzMTF588UVeeuklXn31VYYOHcott9yCzWZrrVhbn03aKgghAluTkkJ5eTlffPEFW7ZsISMjg9TUVKZMmYLdbuf9999nzpw5PPfcc60Va6tTIu1oGYd8HYYQQviM10lhwYIF7Nmzh549e3LFFVdw6aWXYjQaPctvv/127rzzztaIse3Y7FByAq26CsVo8nU0QgjR5rxOCt26dWPKlClERETUu1yn0/HKK6+0WGA+YXM/lkphHsTE+zYWIQKUpmlUVlaiqqq7s8oGHD9+HIfD0YaRNY2v49M0DZ1Oh8ViOev3eCavk8LFF1+M0+msNS8vL4/S0lI6deoEgNlsrqfk+UOJtKOBu15BkoIQPlFZWYnRaMRgOPvpyWAwoNfr2yiqpvOH+JxOJ5WVlVitVq/LeN1OYdGiRbjO6BfI6XTyt7/9zfsI/Z1NGrAJ4WuqqjaaEIR3DAYDqqo2qYzXSSEvL4/Y2Nha8+Li4sjNvYAe4YysaXchDdiE8Jmm3OoQjWvq9+l1UrDZbBw+fLjWvMOHDxMZGdmkHfozxWSGkDB5LFUIEbC8vkYbM2YMzz77LOPHjyc2Npbjx4+zdu1abrzxxtaMr+3JYDtCiADm9ZVCWloat99+Ozt37uSNN95g586d3H777aSlpbVmfG0v0g7SqlmIgHXixAmWL1/e5HKTJk3ixIkTTS73u9/9jvfff7/J5VpLk2pzBg8ezODBg1srFr+g2OxoB773dRhCCED99ytomen1L1MUNE1r8jaVxM7ofvXbBpcXFxfz+uuv12l35XQ6z1oBvmLFiibH4o+alBSKioo4ePAgJSUltf4xLr/88hYPzGcio6G8DK2yHMUS5OtohBBtbM6cOWRkZHDFFVdgNBoxm82Eh4dz8OBBtm7dyuTJkzl27BgOh4MpU6YwceJEAFJTU1m3bh1lZWVMnDiR1NRUduzYQVxcHK+99ppXj4Vu2bKFJ598EpfLRd++fZk7dy5ms5k5c+bw8ccfYzAYGD58OP/3f//H2rVref7559HpdISFhbFmzZoWOX6vk8JXX33FokWLaNeuHZmZmSQmJpKZmUmPHj0urKRwsgvtgjyI7+DbWIQIcGf7RW8wGOq0nWoJM2bMYN++faxfv55t27Zx++2388knn9Chg/t8sGDBAiIjI6moqGDMmDFce+21dfp8S09PZ8mSJcyfP5977rmHDz/8kJtuuums+62srOSRRx5h1apVJCUl8dBDD/H6669z0003sW7dOjZv3oyiKJ5bVAsXLmTlypW0a9euWbetGuJ1ncKqVau4//77mT9/PhaLhfnz53P33XfTuXPnFgvGHyiRpyUFIUTA69evnychALz22mukpaUxbtw4jh07Rnp63dtbiYmJ9OnTB3A3/M3MzGx0P4cOHaJDhw4kJSUBcPPNN/Pll18SFhaG2Wzm0Ucf5cMPP/RccaSkpPDII4+wcuXKOm3IzkWT2imcWZ8wYsQINm/e3GLB+IWaKwV5AkkIARAUdOo28rZt29iyZQtr165lw4YN9OnTp96uLE7v3UGv15/TSdtgMPDBBx8wZswYNmzYwG9+8xsAnnnmGaZNm8axY8e45pprKChomfHlvb59FBYWRlFREREREURHR7N//35CQ0O9bi23e/duli1bhqqqjB49muuvv77OOtu2beOtt95CURQ6duzIww8/7P2RtJSIKFAUuVIQIkAFBwdTWlpa77KSkhLCw8OxWq0cPHiQnTt3tth+k5KSyMzMJD09nRcO1+kAACAASURBVM6dO7N69WoGDRpEWVkZFRUVjB49mksvvdTz4/znn3+mf//+9O/fn08//ZRjx461yNAFXieF0aNH89NPPzFo0CDGjBnDE088gaIojB07ttGyqqqydOlSZs6cSVRUFNOnTyclJYWEhATPOllZWbz77rs8+eSThISEtOg9sqZQDAYIi4RCeSxViEBks9m49NJLufzyy7FYLNjtds+ykSNHsmLFCkaMGEFSUhL9+/dvsf1aLBb++te/cs8993gqmidNmkRRURGTJ0/G4XCgaRqzZ88G4KmnniI9PR1N0xg2bBi9e/dukTgUzctnulRVRac7dbcpLy+PysrKWif2huzfv5+33nqLP//5zwC88847ANxwww2edd544w3atWvH6NGjm3QAx44da9L6J9ntdvLy6r8acM35A1is6H//ZLO23RLOFp8/kPjOjb/HB76Lsby8vNYtm4a0VkVzS/GX+Or7PuPjG+7w06srBVVVmTRpEsuXL/eMoXB69mxMQUFBrfGco6KiOHDgQK11Tp7cZ82ahaqq3HzzzfTr16/OtjZs2MCGDRsAmDdvXpPiOJ3BYGiwbFFce5y/HGr2tlvC2eLzBxLfufH3+MB3MR4/ftzrDvH8veM8f4jPbDY36d/Rq4h1Oh3x8fGUlJS02nCbqqqSlZXF7NmzKSgoYPbs2Tz33HMEBwfXWi8tLa1WK+rm/pI5268gNTgMLfc4ubm5Puucy99/SUp858bf4wPfxehwOLzqctpffok35Mz4ZsyYwY4dO2qtM3XqVG699dZWjcPhcNT5dzznKwWAYcOG8cwzz3DNNdcQFRVV62R58tGrhthsNvLz8z3T+fn5dZKLzWajW7duGAwGYmJiaNeu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\n", 317 | "text/plain": [ 318 | "
" 319 | ] 320 | }, 321 | "metadata": {} 322 | } 323 | ] 324 | } 325 | ] 326 | } -------------------------------------------------------------------------------- /06. VGGNet Architecture/Mini VGGNet.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "nbformat": 4, 3 | "nbformat_minor": 0, 4 | "metadata": { 5 | "colab": { 6 | "name": "Mini VGGNet.ipynb", 7 | "provenance": [] 8 | }, 9 | "kernelspec": { 10 | "name": "python3", 11 | "display_name": "Python 3" 12 | }, 13 | "language_info": { 14 | "name": "python" 15 | }, 16 | "accelerator": "GPU" 17 | }, 18 | "cells": [ 19 | { 20 | "cell_type": "markdown", 21 | "source": [ 22 | "**INITIALIZATION:**\n", 23 | "- I use these three lines of code on top of my each notebooks because it will help to prevent any problems while reloading the same project. And the third line of code helps to make visualization within the notebook." 24 | ], 25 | "metadata": { 26 | "id": "5Vmy0mCIIvZy" 27 | } 28 | }, 29 | { 30 | "cell_type": "code", 31 | "execution_count": 1, 32 | "metadata": { 33 | "id": "5L3NmJeWFUEA" 34 | }, 35 | "outputs": [], 36 | "source": [ 37 | "#@ INITIALIZATION: \n", 38 | "%reload_ext autoreload\n", 39 | "%autoreload 2\n", 40 | "%matplotlib inline" 41 | ] 42 | }, 43 | { 44 | "cell_type": "markdown", 45 | "source": [ 46 | "**LIBRARIES AND DEPENDENCIES:**\n", 47 | "- I have downloaded all the libraries and dependencies required for the project in one particular cell." 48 | ], 49 | "metadata": { 50 | "id": "tir9siflI3eF" 51 | } 52 | }, 53 | { 54 | "cell_type": "code", 55 | "source": [ 56 | "#@ IMPORTING NECESSARY LIBRARIES AND DEPENDENCIES:\n", 57 | "from keras.models import Sequential\n", 58 | "from keras.layers import BatchNormalization\n", 59 | "from keras.layers.convolutional import Conv2D\n", 60 | "from keras.layers.convolutional import MaxPooling2D\n", 61 | "from keras.layers.core import Activation\n", 62 | "from keras.layers.core import Flatten\n", 63 | "from keras.layers.core import Dense, Dropout\n", 64 | "from keras import backend as K\n", 65 | "from tensorflow.keras.optimizers import SGD\n", 66 | "from tensorflow.keras.datasets import cifar10\n", 67 | "from keras.callbacks import LearningRateScheduler\n", 68 | "\n", 69 | "from sklearn.preprocessing import LabelBinarizer\n", 70 | "from sklearn.model_selection import train_test_split\n", 71 | "from sklearn.metrics import classification_report\n", 72 | "\n", 73 | "import matplotlib.pyplot as plt\n", 74 | "import numpy as np" 75 | ], 76 | "metadata": { 77 | "id": "Bzk_8g75I05a" 78 | }, 79 | "execution_count": 3, 80 | "outputs": [] 81 | }, 82 | { 83 | "cell_type": "markdown", 84 | "source": [ 85 | "**VGG ARCHITECTURE:**\n", 86 | "- I will define the build method of Mini VGGNet architecture below. It requires four parameters: width of input image, height of input image, depth of image, number of class labels in the classification task. The Sequential class, the building block of sequential networks sequentially stack one layer on top of the other layer initialized below. Batch Normalization operates over the channels, so in order to apply BN, we need to know which axis to normalize over. " 87 | ], 88 | "metadata": { 89 | "id": "5gbRFH9iLGKN" 90 | } 91 | }, 92 | { 93 | "cell_type": "code", 94 | "source": [ 95 | "#@ DEFINING VGGNET ARCHITECTURE:\n", 96 | "class MiniVGGNet: # Defining VGG Network. \n", 97 | " @staticmethod\n", 98 | " def build(width, height, depth, classes): # Defining Build Method. \n", 99 | " model = Sequential() # Initializing Sequential Model.\n", 100 | " inputShape = (width, height, depth) # Initializing Input Shape. \n", 101 | " chanDim = -1 # Index of Channel Dimension.\n", 102 | " if K.image_data_format() == \"channels_first\":\n", 103 | " inputShape = (depth, width, height) # Initializing Input Shape. \n", 104 | " chanDim = 1 # Index of Channel Dimension. \n", 105 | " model.add(Conv2D(32, (3, 3), padding='same', \n", 106 | " input_shape=inputShape)) # Adding Convolutional Layer. \n", 107 | " model.add(Activation(\"relu\")) # Adding RELU Activation Function. \n", 108 | " model.add(BatchNormalization(axis=chanDim)) # Adding Batch Normalization Layer. \n", 109 | " model.add(Conv2D(32, (3, 3), padding='same')) # Adding Convolutional Layer. \n", 110 | " model.add(Activation(\"relu\")) # Adding RELU Activation Function. \n", 111 | " model.add(BatchNormalization(axis=chanDim)) # Adding Batch Normalization Layer. \n", 112 | " model.add(MaxPooling2D(pool_size=(2, 2))) # Adding Max Pooling Layer. \n", 113 | " model.add(Dropout(0.25)) # Adding Dropout Layer.\n", 114 | " model.add(Conv2D(64, (3, 3), padding=\"same\")) # Adding Convolutional Layer. \n", 115 | " model.add(Activation(\"relu\")) # Adding RELU Activation Function. \n", 116 | " model.add(BatchNormalization(axis=chanDim)) # Adding Batch Normalization Layer. \n", 117 | " model.add(Conv2D(64, (3, 3), padding='same')) # Adding Convolutional Layer. \n", 118 | " model.add(Activation(\"relu\")) # Adding RELU Activation Function. \n", 119 | " model.add(BatchNormalization(axis=chanDim)) # Adding Batch Normalization Layer. \n", 120 | " model.add(MaxPooling2D(pool_size=(2, 2))) # Adding Max Pooling Layer. \n", 121 | " model.add(Dropout(0.25)) # Adding Dropout Layer. \n", 122 | " model.add(Flatten()) # Adding Flatten Layer. \n", 123 | " model.add(Dense(512)) # Adding FC Dense Layer. \n", 124 | " model.add(Activation(\"relu\")) # Adding Activation Layer. \n", 125 | " model.add(BatchNormalization()) # Adding Batch Normalization Layer. \n", 126 | " model.add(Dropout(0.5)) # Adding Dropout Layer. \n", 127 | " model.add(Dense(classes)) # Adding Dense Output Layer. \n", 128 | " model.add(Activation(\"softmax\")) # Adding Softmax Layer. \n", 129 | " return model" 130 | ], 131 | "metadata": { 132 | "id": "Ej2z0nJ-Kblr" 133 | }, 134 | "execution_count": 4, 135 | "outputs": [] 136 | }, 137 | { 138 | "cell_type": "code", 139 | "source": [ 140 | "#@ CUSTOM LEARNING RATE SCHEDULER: \n", 141 | "def step_decay(epoch): # Definig step decay function. \n", 142 | " initAlpha = 0.01 # Initializing initial LR.\n", 143 | " factor = 0.25 # Initializing drop factor. \n", 144 | " dropEvery = 5 # Initializing epochs to drop. \n", 145 | " alpha = initAlpha*(factor ** np.floor((1 + epoch) / dropEvery))\n", 146 | " return float(alpha)" 147 | ], 148 | "metadata": { 149 | "id": "KwzG_O1NlqVI" 150 | }, 151 | "execution_count": 6, 152 | "outputs": [] 153 | }, 154 | { 155 | "cell_type": "markdown", 156 | "source": [ 157 | "**VGGNET ON CIFAR10**" 158 | ], 159 | "metadata": { 160 | "id": "hNQiqb5gAlAU" 161 | } 162 | }, 163 | { 164 | "cell_type": "code", 165 | "source": [ 166 | "#@ GETTING THE DATASET:\n", 167 | "((trainX, trainY), (testX, testY)) = cifar10.load_data() # Loading Dataset. \n", 168 | "trainX = trainX.astype(\"float\") / 255.0 # Normalizing Dataset. \n", 169 | "testX = testX.astype(\"float\") / 255.0 # Normalizing Dataset. \n", 170 | "\n", 171 | "#@ PREPARING THE DATASET:\n", 172 | "lb = LabelBinarizer() # Initializing LabelBinarizer. \n", 173 | "trainY = lb.fit_transform(trainY) # Converting Labels to Vectors. \n", 174 | "testY = lb.transform(testY) # Converting Labels to Vectors. \n", 175 | "labelNames = [\"airplane\", \"automobile\", \"bird\", \"cat\", \"deer\", \n", 176 | " \"dog\", \"frog\", \"horse\", \"ship\", \"truck\"] # Initializing LabelNames." 177 | ], 178 | "metadata": { 179 | "id": "z-EnWB4J-8kl" 180 | }, 181 | "execution_count": 7, 182 | "outputs": [] 183 | }, 184 | { 185 | "cell_type": "code", 186 | "source": [ 187 | "#@ INITIALIZING OPTIMIZER AND MODEL: \n", 188 | "callbacks = [LearningRateScheduler(step_decay)] # Initializing Callbacks. \n", 189 | "opt = SGD(0.01, nesterov=True, momentum=0.9) # Initializing SGD Optimizer. \n", 190 | "model = MiniVGGNet.build(width=32, height=32, depth=3, classes=10) # Initializing VGGNet Architecture. \n", 191 | "model.compile(loss=\"categorical_crossentropy\", optimizer=opt,\n", 192 | " metrics=[\"accuracy\"]) # Compiling VGGNet Model. \n", 193 | "H = model.fit(trainX, trainY, \n", 194 | " validation_data=(testX, testY), batch_size=64, \n", 195 | " epochs=40, verbose=1, callbacks=callbacks) # Training VGGNet Model." 196 | ], 197 | "metadata": { 198 | "colab": { 199 | "base_uri": "https://localhost:8080/" 200 | }, 201 | "id": "1lCPFWETBvgf", 202 | "outputId": "e1cdef1b-c28a-4e10-a935-5f602972acee" 203 | }, 204 | "execution_count": 8, 205 | "outputs": [ 206 | { 207 | "output_type": "stream", 208 | "name": "stdout", 209 | "text": [ 210 | "Epoch 1/40\n", 211 | "782/782 [==============================] - 29s 21ms/step - loss: 1.6339 - accuracy: 0.4555 - val_loss: 1.1509 - val_accuracy: 0.5970 - lr: 0.0100\n", 212 | "Epoch 2/40\n", 213 | "782/782 [==============================] - 16s 21ms/step - loss: 1.1813 - accuracy: 0.5932 - val_loss: 0.9222 - val_accuracy: 0.6733 - lr: 0.0100\n", 214 | "Epoch 3/40\n", 215 | "782/782 [==============================] - 16s 21ms/step - loss: 0.9908 - accuracy: 0.6567 - val_loss: 0.8341 - val_accuracy: 0.7159 - lr: 0.0100\n", 216 | "Epoch 4/40\n", 217 | "782/782 [==============================] - 16s 21ms/step - loss: 0.8854 - accuracy: 0.6945 - val_loss: 0.8282 - val_accuracy: 0.7167 - lr: 0.0100\n", 218 | "Epoch 5/40\n", 219 | "782/782 [==============================] - 16s 21ms/step - loss: 0.7380 - accuracy: 0.7421 - val_loss: 0.6881 - val_accuracy: 0.7598 - lr: 0.0025\n", 220 | "Epoch 6/40\n", 221 | "782/782 [==============================] - 17s 21ms/step - loss: 0.6845 - accuracy: 0.7586 - val_loss: 0.6600 - val_accuracy: 0.7711 - lr: 0.0025\n", 222 | "Epoch 7/40\n", 223 | "782/782 [==============================] - 17s 21ms/step - loss: 0.6628 - accuracy: 0.7683 - val_loss: 0.6435 - val_accuracy: 0.7744 - lr: 0.0025\n", 224 | "Epoch 8/40\n", 225 | "782/782 [==============================] - 16s 21ms/step - loss: 0.6391 - accuracy: 0.7755 - val_loss: 0.6362 - val_accuracy: 0.7784 - lr: 0.0025\n", 226 | "Epoch 9/40\n", 227 | "782/782 [==============================] - 16s 21ms/step - loss: 0.6204 - accuracy: 0.7830 - val_loss: 0.6499 - val_accuracy: 0.7744 - lr: 0.0025\n", 228 | "Epoch 10/40\n", 229 | "782/782 [==============================] - 16s 21ms/step - loss: 0.5912 - accuracy: 0.7909 - val_loss: 0.6161 - val_accuracy: 0.7856 - lr: 6.2500e-04\n", 230 | "Epoch 11/40\n", 231 | "782/782 [==============================] - 16s 21ms/step - loss: 0.5812 - accuracy: 0.7936 - val_loss: 0.6054 - val_accuracy: 0.7879 - lr: 6.2500e-04\n", 232 | "Epoch 12/40\n", 233 | "782/782 [==============================] - 16s 21ms/step - loss: 0.5730 - accuracy: 0.7978 - val_loss: 0.5994 - val_accuracy: 0.7907 - lr: 6.2500e-04\n", 234 | "Epoch 13/40\n", 235 | "782/782 [==============================] - 16s 21ms/step - loss: 0.5698 - accuracy: 0.7974 - val_loss: 0.6013 - val_accuracy: 0.7882 - lr: 6.2500e-04\n", 236 | "Epoch 14/40\n", 237 | "782/782 [==============================] - 16s 21ms/step - loss: 0.5623 - accuracy: 0.8009 - val_loss: 0.5973 - val_accuracy: 0.7910 - lr: 6.2500e-04\n", 238 | "Epoch 15/40\n", 239 | "782/782 [==============================] - 16s 21ms/step - loss: 0.5496 - accuracy: 0.8064 - val_loss: 0.5961 - val_accuracy: 0.7905 - lr: 1.5625e-04\n", 240 | "Epoch 16/40\n", 241 | "782/782 [==============================] - 16s 21ms/step - loss: 0.5484 - accuracy: 0.8048 - val_loss: 0.5937 - val_accuracy: 0.7914 - lr: 1.5625e-04\n", 242 | "Epoch 17/40\n", 243 | "782/782 [==============================] - 16s 21ms/step - loss: 0.5573 - accuracy: 0.8037 - val_loss: 0.5950 - val_accuracy: 0.7902 - lr: 1.5625e-04\n", 244 | "Epoch 18/40\n", 245 | "782/782 [==============================] - 16s 21ms/step - loss: 0.5477 - accuracy: 0.8062 - val_loss: 0.5927 - val_accuracy: 0.7907 - lr: 1.5625e-04\n", 246 | "Epoch 19/40\n", 247 | "782/782 [==============================] - 16s 21ms/step - loss: 0.5446 - accuracy: 0.8073 - val_loss: 0.5904 - val_accuracy: 0.7923 - lr: 1.5625e-04\n", 248 | "Epoch 20/40\n", 249 | "782/782 [==============================] - 16s 21ms/step - loss: 0.5391 - accuracy: 0.8104 - val_loss: 0.5926 - val_accuracy: 0.7920 - lr: 3.9062e-05\n", 250 | "Epoch 21/40\n", 251 | "782/782 [==============================] - 17s 21ms/step - loss: 0.5419 - accuracy: 0.8080 - val_loss: 0.5915 - val_accuracy: 0.7929 - lr: 3.9062e-05\n", 252 | "Epoch 22/40\n", 253 | "782/782 [==============================] - 16s 21ms/step - loss: 0.5438 - accuracy: 0.8099 - val_loss: 0.5909 - val_accuracy: 0.7925 - lr: 3.9062e-05\n", 254 | "Epoch 23/40\n", 255 | "782/782 [==============================] - 16s 21ms/step - loss: 0.5467 - accuracy: 0.8075 - val_loss: 0.5914 - val_accuracy: 0.7919 - lr: 3.9062e-05\n", 256 | "Epoch 24/40\n", 257 | "782/782 [==============================] - 16s 21ms/step - loss: 0.5376 - accuracy: 0.8103 - val_loss: 0.5918 - val_accuracy: 0.7920 - lr: 3.9062e-05\n", 258 | "Epoch 25/40\n", 259 | "782/782 [==============================] - 17s 21ms/step - loss: 0.5410 - accuracy: 0.8085 - val_loss: 0.5923 - val_accuracy: 0.7917 - lr: 9.7656e-06\n", 260 | "Epoch 26/40\n", 261 | "782/782 [==============================] - 17s 21ms/step - loss: 0.5406 - accuracy: 0.8084 - val_loss: 0.5910 - val_accuracy: 0.7915 - lr: 9.7656e-06\n", 262 | "Epoch 27/40\n", 263 | "782/782 [==============================] - 16s 21ms/step - loss: 0.5384 - accuracy: 0.8097 - val_loss: 0.5901 - val_accuracy: 0.7919 - lr: 9.7656e-06\n", 264 | "Epoch 28/40\n", 265 | "782/782 [==============================] - 16s 21ms/step - loss: 0.5431 - accuracy: 0.8089 - val_loss: 0.5915 - val_accuracy: 0.7927 - lr: 9.7656e-06\n", 266 | "Epoch 29/40\n", 267 | "782/782 [==============================] - 16s 21ms/step - loss: 0.5417 - accuracy: 0.8095 - val_loss: 0.5921 - val_accuracy: 0.7925 - lr: 9.7656e-06\n", 268 | "Epoch 30/40\n", 269 | "782/782 [==============================] - 17s 21ms/step - loss: 0.5385 - accuracy: 0.8108 - val_loss: 0.5900 - val_accuracy: 0.7926 - lr: 2.4414e-06\n", 270 | "Epoch 31/40\n", 271 | "782/782 [==============================] - 16s 21ms/step - loss: 0.5451 - accuracy: 0.8073 - val_loss: 0.5910 - val_accuracy: 0.7923 - lr: 2.4414e-06\n", 272 | "Epoch 32/40\n", 273 | "782/782 [==============================] - 16s 21ms/step - loss: 0.5402 - accuracy: 0.8103 - val_loss: 0.5899 - val_accuracy: 0.7925 - lr: 2.4414e-06\n", 274 | "Epoch 33/40\n", 275 | "782/782 [==============================] - 16s 21ms/step - loss: 0.5405 - accuracy: 0.8091 - val_loss: 0.5909 - val_accuracy: 0.7928 - lr: 2.4414e-06\n", 276 | "Epoch 34/40\n", 277 | "782/782 [==============================] - 16s 21ms/step - loss: 0.5427 - accuracy: 0.8091 - val_loss: 0.5914 - val_accuracy: 0.7921 - lr: 2.4414e-06\n", 278 | "Epoch 35/40\n", 279 | "782/782 [==============================] - 16s 21ms/step - loss: 0.5416 - accuracy: 0.8105 - val_loss: 0.5906 - val_accuracy: 0.7928 - lr: 6.1035e-07\n", 280 | "Epoch 36/40\n", 281 | "782/782 [==============================] - 16s 21ms/step - loss: 0.5375 - accuracy: 0.8109 - val_loss: 0.5905 - val_accuracy: 0.7927 - lr: 6.1035e-07\n", 282 | "Epoch 37/40\n", 283 | "782/782 [==============================] - 16s 21ms/step - loss: 0.5372 - accuracy: 0.8092 - val_loss: 0.5900 - val_accuracy: 0.7923 - lr: 6.1035e-07\n", 284 | "Epoch 38/40\n", 285 | "782/782 [==============================] - 16s 21ms/step - loss: 0.5438 - accuracy: 0.8090 - val_loss: 0.5907 - val_accuracy: 0.7927 - lr: 6.1035e-07\n", 286 | "Epoch 39/40\n", 287 | "782/782 [==============================] - 16s 21ms/step - loss: 0.5424 - accuracy: 0.8097 - val_loss: 0.5906 - val_accuracy: 0.7922 - lr: 6.1035e-07\n", 288 | "Epoch 40/40\n", 289 | "782/782 [==============================] - 16s 21ms/step - loss: 0.5385 - accuracy: 0.8116 - val_loss: 0.5909 - val_accuracy: 0.7928 - lr: 1.5259e-07\n" 290 | ] 291 | } 292 | ] 293 | }, 294 | { 295 | "cell_type": "markdown", 296 | "source": [ 297 | "**MODEL EVALUATION:**" 298 | ], 299 | "metadata": { 300 | "id": "VYWybYDuELRf" 301 | } 302 | }, 303 | { 304 | "cell_type": "code", 305 | "source": [ 306 | "#@ INITIALIZING MODEL EVALUATION:\n", 307 | "predictions = model.predict(testX, batch_size=64) # Getting Model Predictions. \n", 308 | "print(classification_report(testY.argmax(axis=1),\n", 309 | " predictions.argmax(axis=1), \n", 310 | " target_names=labelNames)) # Inspecting Classification Report." 311 | ], 312 | "metadata": { 313 | "colab": { 314 | "base_uri": "https://localhost:8080/" 315 | }, 316 | "id": "HZXqORsIDAtg", 317 | "outputId": "103704a3-ddf5-4503-eb09-cf1fc33fa3f3" 318 | }, 319 | "execution_count": 9, 320 | "outputs": [ 321 | { 322 | "output_type": "stream", 323 | "name": "stdout", 324 | "text": [ 325 | " precision recall f1-score support\n", 326 | "\n", 327 | " airplane 0.85 0.79 0.82 1000\n", 328 | " automobile 0.90 0.88 0.89 1000\n", 329 | " bird 0.73 0.65 0.69 1000\n", 330 | " cat 0.62 0.60 0.61 1000\n", 331 | " deer 0.72 0.81 0.76 1000\n", 332 | " dog 0.71 0.71 0.71 1000\n", 333 | " frog 0.80 0.89 0.84 1000\n", 334 | " horse 0.87 0.82 0.85 1000\n", 335 | " ship 0.89 0.89 0.89 1000\n", 336 | " truck 0.85 0.88 0.86 1000\n", 337 | "\n", 338 | " accuracy 0.79 10000\n", 339 | " macro avg 0.79 0.79 0.79 10000\n", 340 | "weighted avg 0.79 0.79 0.79 10000\n", 341 | "\n" 342 | ] 343 | } 344 | ] 345 | }, 346 | { 347 | "cell_type": "code", 348 | "source": [ 349 | "#@ INSPECTING TRAINING LOSS AND ACCURACY:\n", 350 | "plt.style.use(\"ggplot\")\n", 351 | "plt.figure()\n", 352 | "plt.plot(np.arange(0, 40), H.history[\"loss\"], label=\"train_loss\")\n", 353 | "plt.plot(np.arange(0, 40), H.history[\"val_loss\"], label=\"val_loss\")\n", 354 | "plt.plot(np.arange(0, 40), H.history[\"accuracy\"], label=\"train_acc\")\n", 355 | "plt.plot(np.arange(0, 40), H.history[\"val_accuracy\"], label=\"val_acc\")\n", 356 | "plt.title(\"Training Loss and Accuracy\")\n", 357 | "plt.xlabel(\"Epoch\")\n", 358 | "plt.ylabel(\"Loss/Accuracy\")\n", 359 | "plt.legend()\n", 360 | "plt.show();" 361 | ], 362 | "metadata": { 363 | "colab": { 364 | "base_uri": "https://localhost:8080/", 365 | "height": 299 366 | }, 367 | "id": "eCeJOSaJEdLC", 368 | "outputId": "779e2ecc-6ae8-4164-a170-6f5e8085df88" 369 | }, 370 | "execution_count": 10, 371 | "outputs": [ 372 | { 373 | "output_type": "display_data", 374 | "data": { 375 | "image/png": "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m67s9tBqtYSGhpbbHsHBwbRp08YxTUhICG3btq12nRctWsSIESMICgoC7Ns0MjLSUZ135coVzp07x+DBgyssf/ToUYqKiiodXxPdunW77npUddtn//79dOjQgcjIyArnGRYWxt133+24VnLkyBG+++47nnzyyRuOt7GSSaGR8vLyKvd97969PPDAA8THx/O///2PAwcO8J///Aeo/qKgwWC4bpiqqjUqoyjKdWUURalyHq7w3nvvsX//fgYNGsT27duJiYlxVLc0bdqUX375haVLlxIaGsrrr79O27ZtOXfuXIXzKigoYPDgwSiKwvvvv8/333/Pvn37UBTlum3qzPaoqdILzF9++SU6nc7xOnnyZJ1ecNZoNOWqbwCKi4uvm+7a31xNtk9VJk6cyJdffklaWhqLFy+mV69exMTE1G5lJJkUJLtdu3YRHBzMjBkziIuLo02bNjV+HqGudOjQAYBvv/3WMcxqtbJ///4bmm/Hjh3ZsWNHuWHbt2/Hw8ODqKgox7CYmBj++Mc/sn79esaPH8+7777rGGc0GhkyZAizZ8/mp59+oqCgoNJrHT///DOpqam88cYbJCQk0L59ezIzM6/bgVanQ4cOpKWlcfLkScewtLS0cmcxFfn444/R6XQcOnSo3Gvbtm38+OOP7N27l9DQUCIjI9m4cWOlyzaZTJWOBwgNDeXixYvlhh08eLDa9XJm+3Tr1o1jx45V+VscMGAAzZs3Z9GiRSxfvlyeJdwgXX0HIDUMbdu2JTU1lSVLltC/f3927drFwoUL6yWW6OhoRo4cyXPPPceiRYsICQlhzpw55OTkOHX2cPbsWQ4dOlRuWEREBJMnT2bkyJHMmjWL0aNHc+jQIV555RVeeuklDAYDp06d4r333mPkyJE0a9aMixcvsnPnTsdF1SVLlqCqKj169MDf35/NmzeTm5vrSGLXatGiBUajkfnz5/PSSy9x5swZXn755RqfAQ0cOJDOnTvzyCOPMH/+fAwGA3/961/R6/VVllu0aBH33nsvt99++3XjevbsyaJFi4iLi2P69Ok888wzhIWFcf/996OqKlu3buWhhx4iODiYl156iVdeeQUPDw8GDRpEYWEh69atY/LkyQAkJiaycOFC7r33Xlq0aMF//vMfkpOTHXe+VcaZ7fO73/2O2bNnM2rUKGbPnk1UVBS//fYbaWlpPPjg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\n", 376 | "text/plain": [ 377 | "
" 378 | ] 379 | }, 380 | "metadata": {} 381 | } 382 | ] 383 | }, 384 | { 385 | "cell_type": "markdown", 386 | "source": [ 387 | "**Note:**\n", 388 | "- Batch Normalization can lead to a faster, more stable convergence with higher accuracy. \n", 389 | "- Batch Normalization will require more wall time to train the network even though the network will obtain higher accuracy in less epochs. " 390 | ], 391 | "metadata": { 392 | "id": "cfm34boWToGw" 393 | } 394 | } 395 | ] 396 | } -------------------------------------------------------------------------------- /02. ConvolutionalNeuralNetworks/Convolutional Layers.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "nbformat": 4, 3 | "nbformat_minor": 0, 4 | "metadata": { 5 | "colab": { 6 | "name": "Convolutional Layers.ipynb", 7 | "provenance": [], 8 | "collapsed_sections": [] 9 | }, 10 | "kernelspec": { 11 | "name": "python3", 12 | "display_name": "Python 3" 13 | }, 14 | "language_info": { 15 | "name": "python" 16 | }, 17 | "accelerator": "GPU" 18 | }, 19 | "cells": [ 20 | { 21 | "cell_type": "markdown", 22 | "metadata": { 23 | "id": "zWddcLZPcLoU" 24 | }, 25 | "source": [ 26 | "**INITIALIZATION:**\n", 27 | "- I use these three lines of code on top of my each notebooks because it will help to prevent any problems while reloading the same project. And the third line of code helps to make visualization within the notebook." 28 | ] 29 | }, 30 | { 31 | "cell_type": "code", 32 | "metadata": { 33 | "id": "It4XA2PkcBZo" 34 | }, 35 | "source": [ 36 | "#@ INITIALIZATION: \n", 37 | "%reload_ext autoreload\n", 38 | "%autoreload 2\n", 39 | "%matplotlib inline" 40 | ], 41 | "execution_count": 3, 42 | "outputs": [] 43 | }, 44 | { 45 | "cell_type": "markdown", 46 | "metadata": { 47 | "id": "aCoJ3nIxcSfk" 48 | }, 49 | "source": [ 50 | "**DOWNLOADING LIBRARIES AND DEPENDENCIES:**\n", 51 | "- I have downloaded all the libraries and dependencies required for the project in one particular cell." 52 | ] 53 | }, 54 | { 55 | "cell_type": "code", 56 | "metadata": { 57 | "id": "tARh3Gx3cPNy" 58 | }, 59 | "source": [ 60 | "#@ DOWNLOADING LIBRARIES AND DEPENDENCIES: \n", 61 | "import cv2\n", 62 | "import imutils\n", 63 | "import numpy as np\n", 64 | "from google.colab.patches import cv2_imshow\n", 65 | "\n", 66 | "from tensorflow.keras.models import Sequential\n", 67 | "from tensorflow.keras.layers import BatchNormalization\n", 68 | "from tensorflow.keras.layers import Conv2D\n", 69 | "from tensorflow.keras.layers import Activation\n", 70 | "from tensorflow.keras.layers import Flatten, Dropout\n", 71 | "from tensorflow.keras.layers import Dense \n", 72 | "from tensorflow.keras import backend as K\n", 73 | "\n", 74 | "from sklearn.preprocessing import LabelBinarizer\n", 75 | "from sklearn.model_selection import train_test_split\n", 76 | "from sklearn.metrics import classification_report\n", 77 | "from tensorflow.keras.preprocessing.image import ImageDataGenerator\n", 78 | "from tensorflow.keras.optimizers import Adam\n", 79 | "from tensorflow.keras.regularizers import l2\n", 80 | "from imutils import paths\n", 81 | "import matplotlib.pyplot as plt\n", 82 | "import os\n", 83 | "%matplotlib inline" 84 | ], 85 | "execution_count": 4, 86 | "outputs": [] 87 | }, 88 | { 89 | "cell_type": "markdown", 90 | "metadata": { 91 | "id": "XusQfVezcewl" 92 | }, 93 | "source": [ 94 | "**GETTING THE DATA:**\n", 95 | "- I will use subset of **CALTECH-101** dataset. " 96 | ] 97 | }, 98 | { 99 | "cell_type": "code", 100 | "metadata": { 101 | "id": "65FwRa6brfTa" 102 | }, 103 | "source": [ 104 | "#@ DOWNLOADING THE DATASET: UNCOMMENT BELOW: \n", 105 | "# !tar -zxvf \"/content/drive/MyDrive/Data/101_ObjectCategories.tar.gz\" -C \"/content/\"" 106 | ], 107 | "execution_count": 6, 108 | "outputs": [] 109 | }, 110 | { 111 | "cell_type": "markdown", 112 | "metadata": { 113 | "id": "sZokBKC10hEU" 114 | }, 115 | "source": [ 116 | "**STRIDED NET:** \n", 117 | "The **StridedNet** has following important characteristics : \n", 118 | "- It uses strided convolutions rather than pooling operations to reduce volume size. \n", 119 | "- The first **Convolutional** layer uses 7X7 filters but all other layers in the network use 3X3 filters. \n", 120 | "- The normal distribution algorithm is used to initialize all weights in the network. " 121 | ] 122 | }, 123 | { 124 | "cell_type": "code", 125 | "metadata": { 126 | "id": "jHMU2OX1y9ze" 127 | }, 128 | "source": [ 129 | "#@ INITIALIZATION OF STRIDEDNET: \n", 130 | "class StridedNet: # Defining StridedNet Class. \n", 131 | " @staticmethod\n", 132 | " def build(width,height,depth,classes,reg,init=\"he_normal\"): # Defining Build Method. \n", 133 | " model = Sequential() # Initializing Sequential Model. \n", 134 | " inputShape = (height, width, depth) # Initializing Input Shape. \n", 135 | " chanDim = -1 # Initializing Channel. \n", 136 | " if K.image_data_format() == \"channels_first\": # Inspecting Data Format. \n", 137 | " inputShape = (depth, height, width) # Initializing Input Shape. \n", 138 | " chanDim = 1 # Initializing Channel. \n", 139 | " model.add(Conv2D(16,(7,7),strides=(2,2),padding=\"valid\",\n", 140 | " kernel_initializer=init,\n", 141 | " kernel_regularizer=reg,\n", 142 | " input_shape=inputShape)) # Initializing Convolutional Layer. \n", 143 | " model.add(Conv2D(32, (3,3), padding=\"same\", \n", 144 | " kernel_initializer=init,\n", 145 | " kernel_regularizer=reg)) # Initializing Convolutional Layer. \n", 146 | " model.add(Activation(\"relu\")) # Initializing Activation Function. \n", 147 | " model.add(BatchNormalization(axis=chanDim)) # Initializing BatchNormalization Layer. \n", 148 | " model.add(Conv2D(32, (3,3), strides=(2,2), padding=\"same\",\n", 149 | " kernel_initializer=init, \n", 150 | " kernel_regularizer=reg, \n", 151 | " activation=\"relu\")) # Initializing Convolutional Layer. \n", 152 | " model.add(BatchNormalization(axis=chanDim)) # Initializing BatchNormalization Layer.\n", 153 | " model.add(Dropout(0.25)) # Initializing Dropout Layer. \n", 154 | " model.add(Conv2D(64, (3,3), padding=\"same\", \n", 155 | " kernel_initializer=init, \n", 156 | " kernel_regularizer=reg)) # Initializing Convolutional Layer. \n", 157 | " model.add(Activation(\"relu\")) # Initializing Activation Function. \n", 158 | " model.add(BatchNormalization(axis=chanDim)) # Initializing BatchNormalization Layer.\n", 159 | " model.add(Conv2D(64, (3,3), strides=(2,2), padding=\"same\", \n", 160 | " kernel_initializer=init, \n", 161 | " kernel_regularizer=reg)) # Initializing Convolutional Layer. \n", 162 | " model.add(Activation(\"relu\")) # Initializing Activation Function.\n", 163 | " model.add(BatchNormalization(axis=chanDim)) # Initializing BatchNormalization Layer.\n", 164 | " model.add(Dropout(0.25)) # Initializing Dropout Layer.\n", 165 | " model.add(Conv2D(128, (3,3), padding=\"same\", \n", 166 | " kernel_initializer=init, \n", 167 | " kernel_regularizer=reg)) # Initializing Convolutional Layer. \n", 168 | " model.add(Activation(\"relu\")) # Initializing Activation Function. \n", 169 | " model.add(BatchNormalization(axis=chanDim)) # Initializing BatchNormalization Layer.\n", 170 | " model.add(Conv2D(128,(3,3), strides=(2,2), padding=\"same\", \n", 171 | " kernel_initializer=init, \n", 172 | " kernel_regularizer=reg)) # Initializing Convolutional Layer. \n", 173 | " model.add(Activation(\"relu\")) # Initializing Activation Function.\n", 174 | " model.add(BatchNormalization(axis=chanDim)) # Initializing BatchNormalization Layer.\n", 175 | " model.add(Dropout(0.25)) # Initializing Dropout Layer.\n", 176 | " model.add(Flatten()) # Initializing Fully Connected Layer. \n", 177 | " model.add(Dense(512, kernel_initializer=init)) # Initializing Dense Layer. \n", 178 | " model.add(Activation(\"relu\")) # Initializing Activation Function. \n", 179 | " model.add(BatchNormalization(axis=chanDim)) # Initializing BatchNormalization Layer.\n", 180 | " model.add(Dropout(0.5)) # Initializing Dropout Layer.\n", 181 | " model.add(Dense(classes, activation=\"softmax\")) # Initializing Dense Layer. \n", 182 | " return model" 183 | ], 184 | "execution_count": 7, 185 | "outputs": [] 186 | }, 187 | { 188 | "cell_type": "markdown", 189 | "metadata": { 190 | "id": "HaC43j2KXgqA" 191 | }, 192 | "source": [ 193 | "**PREPARING THE DATASET:**" 194 | ] 195 | }, 196 | { 197 | "cell_type": "code", 198 | "metadata": { 199 | "id": "HDK1a1jj_4Gh" 200 | }, 201 | "source": [ 202 | "#@ PREPARING THE DATASET: \n", 203 | "PATH = \"/content/101_ObjectCategories\" # Path to Dataset. \n", 204 | "LABELS = set([\"Faces\", \"Leopards\", \"Motorbikes\", \"airplanes\"]) # Initializing Labels. \n", 205 | "imagePaths = list(paths.list_images(PATH))\n", 206 | "data, labels = [], [] # Initializing List. \n", 207 | "\n", 208 | "#@ PREPARING THE DATASET: \n", 209 | "for imagePath in imagePaths:\n", 210 | " label = imagePath.split(os.path.sep)[-2] # Extracting Labels. \n", 211 | " if label not in LABELS: \n", 212 | " continue\n", 213 | " image = cv2.imread(imagePath) # Reading Image. \n", 214 | " image = cv2.resize(image, (96, 96)) # Resizing Image. \n", 215 | " data.append(image) # Updating Data. \n", 216 | " labels.append(label) # Updating Labels. " 217 | ], 218 | "execution_count": 8, 219 | "outputs": [] 220 | }, 221 | { 222 | "cell_type": "code", 223 | "metadata": { 224 | "id": "wo-EiZY3xLSe" 225 | }, 226 | "source": [ 227 | "#@ PREPARING THE DATASET: \n", 228 | "data = np.array(data, dtype=\"float\") / 255.0 # Converting into Array and Scaling. \n", 229 | "lb = LabelBinarizer() # Initializing Label Binarizer. \n", 230 | "labels = lb.fit_transform(labels) # Initializing One Hot Encoding. \n", 231 | "(trainX, testX, trainY, testY) = train_test_split(\n", 232 | " data,labels,test_size=0.25,stratify=labels,random_state=42) # Initializing Training and Test Dataset. \n", 233 | "aug = ImageDataGenerator(rotation_range=20, zoom_range=0.15, \n", 234 | " width_shift_range=0.2,\n", 235 | " height_shift_range=0.2,shear_range=0.15, \n", 236 | " horizontal_flip=True,fill_mode=\"nearest\") # Initializing Data Augmentation. " 237 | ], 238 | "execution_count": 9, 239 | "outputs": [] 240 | }, 241 | { 242 | "cell_type": "markdown", 243 | "metadata": { 244 | "id": "9mSdEjvTDQ9d" 245 | }, 246 | "source": [ 247 | "**TRAINING THE MODEL:**" 248 | ] 249 | }, 250 | { 251 | "cell_type": "code", 252 | "metadata": { 253 | "id": "39AQaVj5aUcu", 254 | "colab": { 255 | "base_uri": "https://localhost:8080/" 256 | }, 257 | "outputId": "216770fd-455e-4c9d-efd9-683e2b4ea699" 258 | }, 259 | "source": [ 260 | "#@ TRAINING THE MODEL: \n", 261 | "epochs = 50 # Initializing Epochs. \n", 262 | "opt = Adam(learning_rate=1e-4, decay=1e-4 / epochs) # Initializing Adam Optimizer. \n", 263 | "model = StridedNet.build(width=96, height=96, depth=3, \n", 264 | " classes=len(lb.classes_), reg=l2(0.0005)) # Initializing Model. \n", 265 | "model.compile(loss=\"categorical_crossentropy\", optimizer=opt, \n", 266 | " metrics=[\"accuracy\"]) # Compiling Model. \n", 267 | "H = model.fit(x=aug.flow(trainX, trainY, batch_size=32), \n", 268 | " validation_data=(testX, testY), \n", 269 | " steps_per_epoch=len(trainX) // 32, \n", 270 | " epochs=epochs) # Training Model. " 271 | ], 272 | "execution_count": 11, 273 | "outputs": [ 274 | { 275 | "output_type": "stream", 276 | "name": "stdout", 277 | "text": [ 278 | "Epoch 1/50\n", 279 | "52/52 [==============================] - 8s 118ms/step - loss: 1.8721 - accuracy: 0.5378 - val_loss: 2.1929 - val_accuracy: 0.4723\n", 280 | "Epoch 2/50\n", 281 | "52/52 [==============================] - 5s 99ms/step - loss: 1.4074 - accuracy: 0.6967 - val_loss: 1.3916 - val_accuracy: 0.7478\n", 282 | "Epoch 3/50\n", 283 | "52/52 [==============================] - 5s 99ms/step - loss: 1.2011 - accuracy: 0.7613 - val_loss: 1.5086 - val_accuracy: 0.7603\n", 284 | "Epoch 4/50\n", 285 | "52/52 [==============================] - 5s 97ms/step - loss: 1.1294 - accuracy: 0.7899 - val_loss: 1.3434 - val_accuracy: 0.8086\n", 286 | "Epoch 5/50\n", 287 | "52/52 [==============================] - 5s 101ms/step - loss: 1.0471 - accuracy: 0.8185 - val_loss: 1.3814 - val_accuracy: 0.7818\n", 288 | "Epoch 6/50\n", 289 | "52/52 [==============================] - 5s 103ms/step - loss: 1.0035 - accuracy: 0.8295 - val_loss: 1.0816 - val_accuracy: 0.8569\n", 290 | "Epoch 7/50\n", 291 | "52/52 [==============================] - 5s 104ms/step - loss: 0.9306 - accuracy: 0.8569 - val_loss: 0.9071 - val_accuracy: 0.8515\n", 292 | "Epoch 8/50\n", 293 | "52/52 [==============================] - 5s 103ms/step - loss: 0.9175 - accuracy: 0.8727 - val_loss: 0.6747 - val_accuracy: 0.9392\n", 294 | "Epoch 9/50\n", 295 | "52/52 [==============================] - 5s 102ms/step - loss: 0.8232 - accuracy: 0.8806 - val_loss: 0.7100 - val_accuracy: 0.9267\n", 296 | "Epoch 10/50\n", 297 | "52/52 [==============================] - 5s 101ms/step - loss: 0.8193 - accuracy: 0.8940 - val_loss: 0.6400 - val_accuracy: 0.9338\n", 298 | "Epoch 11/50\n", 299 | "52/52 [==============================] - 5s 102ms/step - loss: 0.8255 - accuracy: 0.8855 - val_loss: 0.6565 - val_accuracy: 0.9302\n", 300 | "Epoch 12/50\n", 301 | "52/52 [==============================] - 5s 100ms/step - loss: 0.7882 - accuracy: 0.8989 - val_loss: 0.6087 - val_accuracy: 0.9463\n", 302 | "Epoch 13/50\n", 303 | "52/52 [==============================] - 5s 101ms/step - loss: 0.7551 - accuracy: 0.9068 - val_loss: 0.6028 - val_accuracy: 0.9481\n", 304 | "Epoch 14/50\n", 305 | "52/52 [==============================] - 5s 102ms/step - loss: 0.7456 - accuracy: 0.9086 - val_loss: 0.5935 - val_accuracy: 0.9481\n", 306 | "Epoch 15/50\n", 307 | "52/52 [==============================] - 5s 102ms/step - loss: 0.7786 - accuracy: 0.9032 - val_loss: 0.5897 - val_accuracy: 0.9463\n", 308 | "Epoch 16/50\n", 309 | "52/52 [==============================] - 5s 100ms/step - loss: 0.7307 - accuracy: 0.9093 - val_loss: 0.5597 - val_accuracy: 0.9624\n", 310 | "Epoch 17/50\n", 311 | "52/52 [==============================] - 5s 101ms/step - loss: 0.6842 - accuracy: 0.9275 - val_loss: 0.5633 - val_accuracy: 0.9517\n", 312 | "Epoch 18/50\n", 313 | "52/52 [==============================] - 5s 99ms/step - loss: 0.6784 - accuracy: 0.9348 - val_loss: 0.5626 - val_accuracy: 0.9606\n", 314 | "Epoch 19/50\n", 315 | "52/52 [==============================] - 5s 101ms/step - loss: 0.7007 - accuracy: 0.9245 - val_loss: 0.5427 - val_accuracy: 0.9624\n", 316 | "Epoch 20/50\n", 317 | "52/52 [==============================] - 5s 99ms/step - loss: 0.6692 - accuracy: 0.9348 - val_loss: 0.5800 - val_accuracy: 0.9606\n", 318 | "Epoch 21/50\n", 319 | "52/52 [==============================] - 5s 101ms/step - loss: 0.6413 - accuracy: 0.9379 - val_loss: 0.5528 - val_accuracy: 0.9642\n", 320 | "Epoch 22/50\n", 321 | "52/52 [==============================] - 5s 102ms/step - loss: 0.6770 - accuracy: 0.9275 - val_loss: 0.5635 - val_accuracy: 0.9606\n", 322 | "Epoch 23/50\n", 323 | "52/52 [==============================] - 5s 101ms/step - loss: 0.6708 - accuracy: 0.9269 - val_loss: 0.5434 - val_accuracy: 0.9660\n", 324 | "Epoch 24/50\n", 325 | "52/52 [==============================] - 5s 97ms/step - loss: 0.6763 - accuracy: 0.9330 - val_loss: 0.5592 - val_accuracy: 0.9678\n", 326 | "Epoch 25/50\n", 327 | "52/52 [==============================] - 5s 95ms/step - loss: 0.6246 - accuracy: 0.9519 - val_loss: 0.5451 - val_accuracy: 0.9678\n", 328 | "Epoch 26/50\n", 329 | "52/52 [==============================] - 5s 94ms/step - loss: 0.6277 - accuracy: 0.9440 - val_loss: 0.6080 - val_accuracy: 0.9445\n", 330 | "Epoch 27/50\n", 331 | "52/52 [==============================] - 5s 97ms/step - loss: 0.5871 - accuracy: 0.9586 - val_loss: 0.6347 - val_accuracy: 0.9338\n", 332 | "Epoch 28/50\n", 333 | "52/52 [==============================] - 5s 97ms/step - loss: 0.6126 - accuracy: 0.9507 - val_loss: 0.5435 - val_accuracy: 0.9732\n", 334 | "Epoch 29/50\n", 335 | "52/52 [==============================] - 5s 99ms/step - loss: 0.6244 - accuracy: 0.9452 - val_loss: 0.5588 - val_accuracy: 0.9660\n", 336 | "Epoch 30/50\n", 337 | "52/52 [==============================] - 5s 100ms/step - loss: 0.6009 - accuracy: 0.9507 - val_loss: 0.5706 - val_accuracy: 0.9571\n", 338 | "Epoch 31/50\n", 339 | "52/52 [==============================] - 5s 99ms/step - loss: 0.5958 - accuracy: 0.9476 - val_loss: 0.5693 - val_accuracy: 0.9642\n", 340 | "Epoch 32/50\n", 341 | "52/52 [==============================] - 5s 101ms/step - loss: 0.6220 - accuracy: 0.9434 - val_loss: 0.5970 - val_accuracy: 0.9517\n", 342 | "Epoch 33/50\n", 343 | "52/52 [==============================] - 5s 98ms/step - loss: 0.6160 - accuracy: 0.9513 - val_loss: 0.5614 - val_accuracy: 0.9517\n", 344 | "Epoch 34/50\n", 345 | "52/52 [==============================] - 5s 99ms/step - loss: 0.5862 - accuracy: 0.9519 - val_loss: 0.5357 - val_accuracy: 0.9732\n", 346 | "Epoch 35/50\n", 347 | "52/52 [==============================] - 5s 99ms/step - loss: 0.5838 - accuracy: 0.9574 - val_loss: 0.5362 - val_accuracy: 0.9714\n", 348 | "Epoch 36/50\n", 349 | "52/52 [==============================] - 5s 101ms/step - loss: 0.5812 - accuracy: 0.9604 - val_loss: 0.5459 - val_accuracy: 0.9678\n", 350 | "Epoch 37/50\n", 351 | "52/52 [==============================] - 5s 102ms/step - loss: 0.5821 - accuracy: 0.9580 - val_loss: 0.5584 - val_accuracy: 0.9642\n", 352 | "Epoch 38/50\n", 353 | "52/52 [==============================] - 5s 101ms/step - loss: 0.5618 - accuracy: 0.9671 - val_loss: 0.5632 - val_accuracy: 0.9642\n", 354 | "Epoch 39/50\n", 355 | "52/52 [==============================] - 5s 100ms/step - loss: 0.5758 - accuracy: 0.9653 - val_loss: 0.5582 - val_accuracy: 0.9696\n", 356 | "Epoch 40/50\n", 357 | "52/52 [==============================] - 5s 99ms/step - loss: 0.5609 - accuracy: 0.9635 - val_loss: 0.5476 - val_accuracy: 0.9660\n", 358 | "Epoch 41/50\n", 359 | "52/52 [==============================] - 5s 98ms/step - loss: 0.5734 - accuracy: 0.9580 - val_loss: 0.5321 - val_accuracy: 0.9714\n", 360 | "Epoch 42/50\n", 361 | "52/52 [==============================] - 5s 99ms/step - loss: 0.5685 - accuracy: 0.9610 - val_loss: 0.5319 - val_accuracy: 0.9660\n", 362 | "Epoch 43/50\n", 363 | "52/52 [==============================] - 5s 99ms/step - loss: 0.5703 - accuracy: 0.9647 - val_loss: 0.5415 - val_accuracy: 0.9642\n", 364 | "Epoch 44/50\n", 365 | "52/52 [==============================] - 5s 100ms/step - loss: 0.5656 - accuracy: 0.9647 - val_loss: 0.6156 - val_accuracy: 0.9499\n", 366 | "Epoch 45/50\n", 367 | "52/52 [==============================] - 5s 99ms/step - loss: 0.5508 - accuracy: 0.9665 - val_loss: 0.5723 - val_accuracy: 0.9553\n", 368 | "Epoch 46/50\n", 369 | "52/52 [==============================] - 5s 100ms/step - loss: 0.5417 - accuracy: 0.9653 - val_loss: 0.5149 - val_accuracy: 0.9714\n", 370 | "Epoch 47/50\n", 371 | "52/52 [==============================] - 5s 102ms/step - loss: 0.5463 - accuracy: 0.9683 - val_loss: 0.5333 - val_accuracy: 0.9678\n", 372 | "Epoch 48/50\n", 373 | "52/52 [==============================] - 5s 101ms/step - loss: 0.5394 - accuracy: 0.9742 - val_loss: 0.5494 - val_accuracy: 0.9642\n", 374 | "Epoch 49/50\n", 375 | "52/52 [==============================] - 5s 100ms/step - loss: 0.5433 - accuracy: 0.9702 - val_loss: 0.5362 - val_accuracy: 0.9660\n", 376 | "Epoch 50/50\n", 377 | "52/52 [==============================] - 5s 102ms/step - loss: 0.5608 - accuracy: 0.9653 - val_loss: 0.5225 - val_accuracy: 0.9785\n" 378 | ] 379 | } 380 | ] 381 | }, 382 | { 383 | "cell_type": "markdown", 384 | "metadata": { 385 | "id": "oAw1dFaKGDnU" 386 | }, 387 | "source": [ 388 | "**MODEL EVALUATION:**" 389 | ] 390 | }, 391 | { 392 | "cell_type": "code", 393 | "metadata": { 394 | "colab": { 395 | "base_uri": "https://localhost:8080/" 396 | }, 397 | "id": "D25QXmtsFzy3", 398 | "outputId": "b25a82ab-fe9c-4cea-cdbb-9a9360ab1fc0" 399 | }, 400 | "source": [ 401 | "#@ INITIALIZING MODEL EVALUATION: \n", 402 | "predictions = model.predict(testX, batch_size=32) # Initializing Predictions. \n", 403 | "print(classification_report(testY.argmax(axis=1), \n", 404 | " predictions.argmax(axis=1), \n", 405 | " target_names=lb.classes_)) # Inspecting Classification Report. " 406 | ], 407 | "execution_count": 12, 408 | "outputs": [ 409 | { 410 | "output_type": "stream", 411 | "name": "stdout", 412 | "text": [ 413 | " precision recall f1-score support\n", 414 | "\n", 415 | " Faces 0.96 0.99 0.97 109\n", 416 | " Leopards 0.96 0.88 0.92 50\n", 417 | " Motorbikes 0.98 0.99 0.99 200\n", 418 | " airplanes 0.99 0.98 0.99 200\n", 419 | "\n", 420 | " accuracy 0.98 559\n", 421 | " macro avg 0.97 0.96 0.97 559\n", 422 | "weighted avg 0.98 0.98 0.98 559\n", 423 | "\n" 424 | ] 425 | } 426 | ] 427 | }, 428 | { 429 | "cell_type": "code", 430 | "metadata": { 431 | "colab": { 432 | "base_uri": "https://localhost:8080/", 433 | "height": 299 434 | }, 435 | "id": "CZwb2iVtHHJD", 436 | "outputId": "3aca53d8-6013-4021-a2f2-8ca5be1b9130" 437 | }, 438 | "source": [ 439 | "#@ PLOTTING TRAINING LOSS AND ACCURACY: \n", 440 | "N = epochs \n", 441 | "plt.style.use(\"ggplot\")\n", 442 | "plt.figure()\n", 443 | "plt.plot(np.arange(0, N), H.history[\"loss\"], label=\"train_loss\")\n", 444 | "plt.plot(np.arange(0, N), H.history[\"val_loss\"], label=\"val_loss\")\n", 445 | "plt.plot(np.arange(0, N), H.history[\"accuracy\"], label=\"train_acc\")\n", 446 | "plt.plot(np.arange(0, N), H.history[\"val_accuracy\"], label=\"val_acc\")\n", 447 | "plt.title(\"Training Loss and Accuracy\")\n", 448 | "plt.xlabel(\"Epochs\")\n", 449 | "plt.ylabel(\"Loss/Accuracy\")\n", 450 | "plt.legend(loc=\"upper right\")\n", 451 | "plt.show();" 452 | ], 453 | "execution_count": 15, 454 | "outputs": [ 455 | { 456 | "output_type": "display_data", 457 | "data": { 458 | "image/png": "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2yzqRpa7bWmN5RZCUF5ejtPprPfowwaDAavV2sA5a/kullsIgaqqGI3GSuew2dsswDU66OrVq7n++uurDRSpqals2LCBRYsWuQMF4B54LCAggMGDB5OcnOxVsJAk6epSXl6OTqdDq63/pUur1aLRaBowV63DpeW22+2Ul5djMpm8Tt8kXWeFELz44ou0b9+eiRMnVrlNdnY2zzzzDH/60588olt5ebl7LuPy8nKOHj3qnghFkqS2xel0XlGgkFy0Wm2d50VpkrN+8uRJ9u3bR0xMDA899BDgGmL44i3w2LFj2bZtG8XFxWzcuBHA3UW2oKCAZ555BnAN9TB8+PBKs6lJktQ2NMfEV1erup7Lq3q4j7q2WQgheOtYDoM6h9PF19FIuWq5WmMddkOQ5W49SktL8fHxuaJ9aLVa7HZ7A+Wo9bi83FWdyxbRZtEaKIrC29/nUqHq6dJLPtMhSZJ0kRzu4zJmvUqRte1965AkqXYFBQVs3ry5zummTZtGQUFBndPdf//9vPfee3VO1xhksLiMr15DUXnlSeUlSZIKCwt57bXXKi2vrVpry5YtBAQENFa2moSshrqMWa+hqLzttVdIUmvjfONlRFpK3dMpCtU11SrRnVB/d0+1aZcvX05qaipjxoxBp9NhMBgICAggOTmZzz77jFmzZpGeno7VamX27NlMnToVgLi4OHbt2kVJSQlTp07l2muv5eDBg0RERPDKK6941YV1//79PPnkkzgcDvr27ctTTz2FwWBg+fLlfPTRR2i1WkaMGMH//M//sHPnTp577jlUVcXf358dO3bU+TxdTgaLy5j1Gs6VyGooSZIqW7x4MSdPnmT37t0cOHCA6dOns2fPHnd3/tWrVxMUFERZWRkTJkzgpptucj8ndlFKSgrr1q1j1apV3HfffXzwwQfcdtttNR63vLycBx54gDfffJMuXbqwYMECXnvtNW677TZ27drFvn37UBTFXdW1Zs0atm7dSrt27epV/VUVGSwuY9arFOW2vac7Jam1qekOoCYN2RuqX79+Hs99vfLKK+zatQtw9cZMSUmpFCyio6Pp3bs3AH369CEtLa3W4/z444/ExMTQpUsXAG6//Xb++c9/MnPmTAwGAw8++CAJCQnuoZAGDRrEAw88wM0338z48eMbpKyyzeIyZtlmIUmSly7tenrgwAH279/Pzp07SUxM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\n", 459 | "text/plain": [ 460 | "
" 461 | ] 462 | }, 463 | "metadata": {} 464 | } 465 | ] 466 | } 467 | ] 468 | } --------------------------------------------------------------------------------