Build a Gender Classifier in Google Colab using TensorFlow and Keras | by Nachi Muthu | Towards Data Science

Hola amigos!, in this article, we are going to build a CNN based gender classifier using APIs provided by TensorFlow and Keras. We will be writing and execution the code on Google Colab. Colab provides free GPU services. We will be using those to train our model quickly.
I will be using Wikipedia images from the IMDB-WIKI dataset. I have already preprocessed the dataset and cropped out all the faces from the images and stored them as objects in .pickle format in my Google Drive. If you have your dataset ready you may go ahead, if you want to prepare a dataset same as the one I will be using in this article you can read my other article, where I have explained how to create a Colab notebook, process the data and store them.
medium.com
In this article, I have explained every line of code, in the end, you’ll be confident in building a multi-class classifier all by yourself.
Create a new notebook on Google Colabs and mount your Google drive. Do not miss out on changing your runtime type to GPU in your notebook.
If you are new to Google Colab don’t know how to do that, you can learn it in my previous article.
First, let’s import all the packages needed throughout this code. In a new cell import all the packages.
Now that we have imported all the packages that are needed, let us load the dataset that I have stored in my Google Drive (PS: I have shown how to preprocess data and store it in another article of mine. Please read it if you don't have a dataset of your own. I have added the link in the earlier section).
Line 1: Reading the data stored .pickle format in binary mode.
Line 2: Converting it to python object using pickle package.
Line 4–5: Taking the images and gender data alone from the loaded dataset.
Line 6: Displaying the shape of the images array, shape os a single image and the shape of the gender array.
In the above output, we can see that we have 42252 images each being a 32x32 RGB image. We also have a gender label for each image in a 2D array format with each subarray containing the gender value ( 1.0 : Male, 0.0 : Female). To get a better understanding you can print the array and check.
Next, let’s see what kind of images we are going to be training out model with.
Line 4–11: Printing 4 random images from our dataset and displaying them.
As you can see in the above output, the images we will be using to train our model contains only faces along with their gender.
We’ll now visualize the distribution of our data to get an insight into our data.
Line 1–12: I have created two category male and female and added it into “gender_plotting” variable. Using this categorical data we can plot the histogram using Plotly.
We have 30k male images and 10k female images. These images are enough as we are performing a binary classification.
We will now start TensorBoard. Execute the below code
%tensorboard --logdir "logs"
In the “logdir” parameter you are supposed to give the path to the directory where you will be saving you log data of the model. TensorBoard will search in the given directory for logs and display it. If you would like to save your log files in your Google Drive you can give the respective path. In few steps, I’ll show you how to add callbacks to our model that will save log files.
It’s time to create our CNN model. First, we’ll add all the layers needed for our model into a list and then create the model using Sequential class in Keras. Though this is a binary classification problem instead of using a sigmoid activation function in the last layer, I have used “binary_crossentropy” as the loss function. I have treated the problem as a multi-class classification problem which has only 2 classes. I have done this so that you will know how to implement multi-class classification using CNN.
Line 1: The first layer in the model is the input layer. We pass the shape of the image to it as a parameter.
Line 3: Creating a tuple which contains the number of filters that a particular Conv2D layer in our model will have respectively.
Line 5–11: Looping through the above-created tuple and creating Conv2D layers, which has “Relu” activation function. Then for each Conv2D function, a “BatchNormalization” function is added along with MaxPooling2D. MaxPooling2D has pool size 2x2 with 2 steps per stride. You can change these values.
Line 13–26: Whenever a dense layer is added after Conv2D layers, a Flatten layer should be added in between them. This layer will convert the weights of the Conv2D layers from 2D format to a single-dimensional format that can be used by Dense layers. Each dense layer is given a“Relu” activation function and “BatchNormalization” function. Dropout function is added to prevent overfitting of the model. The parameters passed inside the function is the dropout probability, if 0.1 is passed it means 1 in 10 inputs will be randomly dropped.
Line 27–28: As we are performing classification with 2 classes we use a Dense layer which has the output size as 2. The number of output size in the last dense layer is the same as the number of classes you want your model to classify. We also use a softmax layer for classification problems as it returns a list for each prediction which contains the probability of an image belonging to the respective class and the image is assigned the class with the highest probability.
Line 31: We then add all the created layers into a sequential model. There are other ways of adding layers to a sequential model, you can refer the documentation for that.
Line 32–34: We compile the model by specifying the optimization function and loss function. As it is treated as a multi-class classification problem we are using “categorical_crossentropy” as the loss function. When the model is created for a binary classification problem, we have to make the output in the last dense layer as 1 and use a sigmoid activation function for the last layer alone. Along with this the loss function used should be “binary_crossentropy”
Line 35: We are specifying the folder name for each of the model training. We have used the time at which the model is trained to be the folder name.
If you want your model logs to be stored in you Google Drive then you have to specify the path in such format.
eg log_dir = "drive/My Drive/Colab Notebooks/Tutorial/Gender Classifier/logs/" + datetime.datetime.now().strftime("%Y%m%D-%H%M%S")
The same path until “logs” folder should be provided when TensorBoard is being launched. log_dir = "drive/My Drive/Colab Notebooks/Tutorial/Gender Classifier/logs.
Line 36: In a variable called callbacks we are creating a list of all the callbacks that we are passing to the model. Here we are only creating a callback to save the logs for TensorBoard to use, to we call the TensorBoard class from “keras.callbacks” and pass the path for saving the logs as a parameter.
It’s time to train our model. We’ll be using 80:20 split for training and testing. The training data is further split into 80:20 for training and validation data.
Line 1–3: We are splitting the data into training data and testing data.
Line 4: We will be using only 80% of the training data for training the model, the rest will be used as validation data. So setting the “num_train_example” as 80% as the number of images available for training.
Line 5: Setting the batch size to 64. Our training data will be split into multiple batches containing 64 images each, for training purposes.
Line 6–8: We are calling the font function from the model object so that our model can train using our data.Epoch is set as 10 which means our entire data provided for training will be used to train the model 10 times. One epoch means performing one iteration of training using the data given, the entire data provided will be used once by our model.steps_per_epoch is the number of batches of data provided to our model. When the steps_per_epoch count is reached, the model knows that the particular epoch is over.batch_size is the number of images present in one batch of data.shuffle is the parameter which when set to true trains the model by taking the data provided in a shuffled manner. If it is set to false then the model takes the data in the order provided to it. It is advisable to set this to true so that the model doesn't get trained to a particular class.validation_split is the fraction of the training data provided that can be used for validation. callbacks are the functions or operations that have to be performed at the end of each epoch or each step. This is where our TensorBoard callback will be passed.
Line 11: Using the testing data we split earlier, we evaluate the accuracy of our model and check if overfitting hasn’t occurred.
The execution of the above cell provides us with the accuracy and loss value for each epoch.
As you can see in the above output, the model has good accuracy for our training data. Validation accuracy is also good which shows that our model has not overfitted to the data. The evaluation result shows that our model also performs well for unknown data. Its time for us to visualize the training of our model using TensorBoard.
Scroll up to the cell where you executed the command to launch TensorBoard. Now you can see the graphs that are displayed there. There will be one graph for plotting the accuracy of the model and another for the loss.
If you are not able to see this graph check if you have given the correct directory path to the log files. TensorBoard is a very powerful visualization tool, there are lots of things you can do with it. If you are interested in learning more about it I recommend you to watch the TensorFlow dev summit 2017.
Let’s move on to the next step. We’ll now take input from our computers camera and have our model classify the person in the image. Before we write the code to take the camera input, let us define a function to convert an image with RGBA format to RGB.
Line 1–20: This function performs the mathematical operation on the image to convert it. I have taken this code from a StackOverflow answer, thanks to Feng Wang.
Let’s define a function to capture an image using the webcam in computer. As this entire notebook is running on your browser, we’ll need to write JavaScript code to make the browser access the webcam, capture a picture and send it to the server for processing. I’ll explain the code in short. You can skip this part unless you are interested in using JavaScript to capture an image through webcam.
Line 1: We define a function which takes the size and the quality of the image we want as parameters.
Line 2: To the JavaScript function present in the Ipython.display package we pass our set code written in JavaScript to be executed.
Line 3–16: We are creating two elements. A div to display the input stream from our camera and a capture button to capture an image on click, “stream” contains the object of the class which is responsible for the video stream.
Line 22–31: The code waits for the capture button to be clicked. Once it is clicked, that particular frame of the video displayed on the output screen is captured and converted into a dictionary of pixels and then returned. You can learn more about the format of the data returned at MDN Web documentation.
Line 35: Executes the JS code written inside it. Here we call the JS function we defined above.
Line 5: We call the python function “take_photo” which in return calls the JS function and captures a photo.
Line 7–9: We sort the pixels returned by the JS function, based on the keys and then resize the image to our 3D array format.
Line 15: As the image obtained is in RGBA colour format, we are to converting it to RGB colour format and displaying it.
We have received our input data that has to be classified. We will detect and crop out faces from the image, pass the cropped image to the model and get its prediction and display the output. Let’s define two functions, one for extracting faces and another for displaying the result with its label.
Line 1–21: This function takes the image a parameter and detects all the faces in it using Dlib’s CNN based face recognition model and crops them out of the image. This function returns a dictionary containing all the faces and its respective coordinates on the image.
Line 23–33: This function takes the original image, the cropped faces, and the model’s prediction on each faces as its parameters. It draws rectangular boxes on all the faces and adds their respective labels above the boxes and displays the image.
It’s time to call these functions and get the output.
Line 1: We extract the faces from the image.
Line 3–6: We are creating an array of images which contains all the faces present in the image.
Line 9–10: We are predicting the label for each face image.
Line 12: We call the function for displaying our classified output.
You can also try to classify an image with multiple faces.
With this, I bring this article to an end. I hope you have learnt a lot from this article and can now build a multi-class classifier with any type of objects and any number of classes.
I have attached a link to my notebook for your reference.
Feel free to contact me regarding any queries.
Instagram: nachijr4
E-Mail: nachi2muthu13@gmail.com
Medium: Nachi Muthu
LinkedIn: Nachi Muthu