The term you are looking for is multi-label classification, i.e. where you are making more than one classification on each image (one for each label). Most examples you'll find online are in the NLP domain but it is just as easy with CNNs since it's essentially defined by the structure of the output layer and the loss function used. It's not as complicated as it might sound if you are already familiar with CNNs.
The output layer of a neural network (for 3 or more classes) has as many units as there are targets. The network learns to associate each of those units with a corresponding class. A multi-class classifier normally applies a softmax activation function to the raw unit output, which yields a probability vector. To get the final classification, the max()
of the probability vector is taken (the most probable class). The output would look like this:
Cat Bird Plane Superman Ball Dog
Raw output: -1 2 3 6 -1 -1
Softmax: 0.001 0.017 0.046 0.934 0.001 0.001
Classification: 0 0 0 1 0 0
Multi-label classification typically uses a sigmoid activation function since the probabilities of a label occuring can be treated independently. The classification is then determined by the probability (>=0.5 for True). For your problem, this output could look like:
Big nose Long hair Curly hair Superman Big ears Sharp Jawline
Raw output: -1 -2 3 6 -1 10
Sigmoid: 0.269 0.119 0.953 0.998 0.269 1.000
Classification: 0 0 1 1 0 1
The binary crossentropy loss function is normally used for a multi-label classifier since a n-label problem is essentially splitting up a multi-class classification problem into n binary classification problems.
Since all you need to do to get from a multi-class classifier to a multi-label classifier is change the output layer, its very easy to do with pre-trained networks. If you get the pre-trained model from Keras its as simple as including include_top=False
when downloading the model and then adding the correct output layer.
With 13000 images, I would recommend using Keras' ImageDataGenerator
class with the flow_from_dataframe
method. This allows you to use a simple pandas dataframe to label and feed in all your images. The dataframe would look like this:
Filename Big nose Long hair Curly hair Superman Big ears Sharp Jawline
0001.JPG 0 0 1 1 0 1
0002.JPG 1 0 1 0 1 1
. . . . . . .
flow_from_dataframe
's class_mode
parameter can be set to raw
or multi_output
along with x_col
to 'Filename'
and y_col
to ['Big nose', 'Long hair', 'Curly hair', 'Superman', 'Big ears', 'Sharp Jawline']
(in this example). Check out the documentation for more details.
The amount of data you need for each label depends on many factors and is essentially impossible to know without trying. 13000 sounds like a good start but it also depends on how many labels you have and how evenly distributed they are between the labels. A decent guide (one of many) on how to set up a multi-label classifier and how to implement it with Keras can be found here. It also covers imbalances on label frequency and is well worth a read. I'd highly recommend that you become as intimately familiar with your dataset as possible before you start tuning your neural network architecture.