Flower Species Classifier. Build an image classifier to recognize... | by Silvio Mori Neto | Towards Data Science

• Artificial Intelligence • Deep Learning • Convolutional Neural Networks• Python • PyTorch • Numpy • Matplotlib • Jupyter Notebooks
In this article, I give an overview of the project I developed that led me to be awarded a scholarship to the Deep Learning Nanodegree program at Udacity.
I developed this project as the final test of the PyTorch Scholarship Challenge assessment held by Udacity and Facebook.
In this two-month challenge, I had my very first contact with Artificial Intelligence development. In addition to watching the videos and completing the assessments in the classroom, I also joined a private Slack community. So, I could connect with my peers and coaches in the program, share my progress, get feedback, ask questions, and help other scholars to complete the challenge.
Build a deep learning model that identifies 102 species of flowers from images.
The final application receives an image provided by the user and predicts the likelihood of being one of those known species.
The image dataset, found in this link, contains 7,370 photos of flowers taken in different angles and lightening.
You can see a few examples below.
I divided the images randomly into three sets:
Training  :  6552 images  /  205 batchesValidation:   409 images  /   18 batchesTesting   :   409 images  /   18 batches
For this project, I opted for using image normalization and data augmentation for the training set.
As the first step, I selected randomly one of the four transformations in each image, with the given probability of being chosen:
• 16,67% — Horizontal flip• 16,67% — Vertical flip• 33,33% — Random rotation, in a range of 360 degrees• 33,33% — Keep the image untouched
After that, I made a random crop in the images and resized them to 224x224 pixels.
For the test and validation sets, I only resized the images and made a 224x224 pixels center crop on each.
To detect the features in images, I used a pre-trained network, available in the package torchvision.models. Having being trained on the ImageNet dataset, those models can identify a myriad of features in images. However, the classifiers attached in their final part categorize images in classes other than the flower species contained in the dataset.
Thus, aiming at the final goal, I chose the ResNet-152 model. I kept its pre-trained convolutional layers and replaced its classifier, building a new network to sort images into new categories.
My brand new classifier was a fully-connected network containing a 2,048-nodes input layer, one 1,000-nodes hidden-layer, and one output layer to categorize the input data into 102 classes.
Once I had built my model, it was time to train it!
Having tested many optimizers, I chose to work with Adagrad. It is a quite powerful optimizer dropping the training loss very fast. Nevertheless, it is necessary to give some control to that potency. Otherwise, that strength might be converted into exploding gradients, not converging to an optimal solution. I did so by introducing a learning rate scheduler, which I detail better in the following section.
I divided the network training process into three phases, as described below.
Training phase 1:
The focus here was training the classifier.
As the convolutional layers had already been pre-trained, they were capable of recognizing a wide variety of features in images. So, I froze their parameters, disabling them to be updated. Thus, all the effort was in adjusting the weights of the classifier.
To limit the Adagrad power, I introduced a scheduler to decrease the learning rate if the error function reached a plateau. The learning rate started at 0.01 and was diminished by 0.1 in plateaus. As soon as the learning rate went under 0.0001, this phase was interrupted.
During this training phase, 39 epochs were performed, delivering an accuracy of 94.62% in the validation dataset.
Epoch: 39: lr: 0.00010000 Training Loss: 0.412109Validation Loss: 0.232272 Validation accuracy: 94.62%
Training phase 2:
Since the classifier had already acknowledgment about what to do, it was time to fine-tune the convolutional layers’ weights!
To do so, I unfroze all the network parameters, set up the learning rate at 0.0001, and trained the entire model for 20 epochs.
At the end of this training phase, the validation accuracy was 96.58%.
Epoch: 59: lr: 0.00010000 Training Loss: 0.201783Validation Loss: 0.141651 Validation accuracy: 96.58%
Training phase 3:
At this point, even though I had already obtained a strong result, I decided to push forward the limits of my network!
I dropped the learning rate to 0.000001, only to make a few minor adjustments to the classifier weights, and run other 10 epochs of training.
Then, the validation accuracy reached impressive 97.07%.
Epoch: 69: lr: 0.00000100 Training Loss: 0.187415Validation Loss: 0.142964 Validation accuracy: 97.07%
At this point, the network was accurate enough in recognizing the training and validation images, sorting them with superhuman accuracy.
The final test for this network was looking at a completely unknown dataset to classify the images correctly.
I could not picture a better result! The network performed the task with an astonishing accuracy of 99.27%, missing only 3 of 409 images!
As the final result, this network receives an image as input and makes predictions about the five most probable species for that flower.
One example of a real application for this project is a phone app that shows the name of the flower captured by the camera.
You can see some examples of the output below.
Notice that not only does the network predict the correct category but also it is very sure about that.
All the code for this project can be found in my GitHub profile: