Convolutional Neural Networks: Unmasking its Secrets
Neural networks are something of a black box. It is often very challenging to decipher how they make predictions. In this article, we’re going to take a fresh look inside a particular neural network, namely convolutional neural network and unmask some of its secrets.
Convolutional neural network is one of the common neural networks that implements computer vision tasks. It is entirely image-based, thus easy to demonstrate.
Let us consider InceptionV3 as our base network. It is one of the best-known convolutional neural networks available, thus suits our purpose of not compromising on generality. Its structure is illustrated as follows.
We use an InceptionV3 pre-trained with the ImageNet dataset to run our experiment. The task for the network is to classify the different objects in an image. An image enters the model (or network) as an input and the class number of the object in that image emerges as the output.
Let’s consider the following images to illustrate the network mechanism outlined above.
In the beginning, we need to test our first dog.
Top-5 metric scores for the maltese dog image are as follows.
1. Maltese_dog — 0.9292618
2. Lhasa — 0.0054057003
3. West_Highland_white_terrier — 0.0032469642
4. Shih-Tzu — 0.0026330198
5. Japanese_spaniel — 0.0022667362
The model identifies the object in the image as a Maltese dog with a probability 0.9293. I’m no dog expert, but a simple Google search reveals that the object is indeed a Maltese dog.
What if we paint over a part of the image? Would our network still be able to identify the object successfully? If it does, then it implies that the concealed part of the image is of little value for the task of identification. In contrast, if it fails, then it implies that the concealed part is indeed important and the network was looking at it first.
Let’s investigate. We begin by blocking a part of the image next to the dog.
The top-5 metric scores for the object in the modified image are now as follows.
1. Maltese_dog — 0.93191534
2. Lhasa — 0.008831738
3. Pekinese — 0.0027588836
4. Japanese_spaniel — 0.0026686913
5. Shih-Tzu — 0.0024955475
Note that the identification probability now increases from 0.9293 to 0.9319. Thus, cropping the image around the dog in fact increases model precision. Identical tests with the other images yields qualitatively similar results. It make good sense after all. The network pays more attention to the object and largely ignores its environment.
What if we block the object in the image as illustrated above? The top-5 metric scores for the object in the modified image are now as follows.
1. Partridge — 0.042628713
2. Black grouse — 0.035664327
3. Quail — 0.027290314
4. Magpie — 0.024524875
5. Loudspeaker — 0.020369
It appears from the probability scores reported above, the model is unable to identify the object accurately. Partridge is in the first place albeit with a very small probability of 0.0426. Small probability is indicative that the model doesn’t have much confidence in its answer. ‘Maltese dog’ appears further down the list with a probability of 0.0005.
The result here is unsurprising. To identify the object in the image, the model looks at the object. Everything around the object matters very little.
Let’s mix it up a bit. We’ll now conceal a different small part of the image as demonstrated below and examine model performance.
The top-5 metric scores for the object in the modified image above are as follows.
1. Maltese_dog — 0.602724
2. West_Highland_white_terrier — 0.11070298
3. Norfolk_terrier — 0.011860368
4. Lhasa — 0.005608953
5. Japanese_spaniel — 0.004504432
Noticeably the model arrives at the correct answer ‘Maltese dog’ albeit with significantly lower confidence. The probability of identification is now down at 0.60 compared to the previous high of 0.93.
Again, the result is robust for the other images. The model even recognizes our unicorn.
Can we construct a heatmap of where the network looks for its predictions? Perhaps we can. Let’s investigate. To do this, we randomly conceal up to 50% of the image and examine how the identification probability metric responds. We randomly close several small blocks at once so that the total area concealed amounts to 50% of the image. We write the confidence estimate in a two-dimensional array with sizes equal to the original image so that we can compare different random patterns. After each iteration, we add arrays to obtain an accumulated estimate after several runs. In order to take into account the correct definition of an object, we look at the answers of only one class.
To obtain a mask with blocks that will cover part of the images, let’s create a one-dimensional unit array with a size of 5% of our image and set to zero 50% of the values in it.
THRESHOLD_COEF = 0.5
IMG_SIZE_SMALL = int(IMG_SIZE*0.05)
rand_ar = np.ones(IMG_SIZE_SMALL*IMG_SIZE_SMALL, np.uint8)
rand_ar[0:int(IMG_SIZE_SMALL*IMG_SIZE_SMALL*THRESHOLD_COEF )] = 0
Next, mix all the values and restore the mask in the form of an image from the array.
random.shuffle(rand_ar)
rand_ar = rand_ar.reshape(IMG_SIZE_SMALL, IMG_SIZE_SMALL)
rand_ar = Image.fromarray(np.uint8(rand_ar))
rand_ar = rand_ar.resize((IMG_SIZE, IMG_SIZE), Image.NEAREST)
rand_ar = np.stack((rand_ar,rand_ar,rand_ar), axis=2)
We get the following mask.
Next, we overlay it onto our original image.
With this modified image, the network identifies it as Maltese_dog with a confidence of 0.00052775315.
But let’s not despair. Let’s create an array equal to the size of our image and add this probability to the unconcealed blocks. For the remaining blocks, let’s subtract the probability in order to introduce a penalty for errors.
acc = np.zeros(IMG_SIZE*IMG_SIZE*3).reshape(IMG_SIZE,IMG_SIZE,3)
rand_ar = rand_ar.astype(np.int8)
acc = acc + rand_ar * pred[0][CLASS_NUM]
acc = acc + (rand_ar - 1) * pred[0][CLASS_NUM]
After 5000 iterations, we obtain the following result. This is how the network visualizes the Maltese dog:
And this is how all our other little friends look like after the application of the thermal mask.
Commonly, we notice that the model pays attention to the faces.
But, what if we search for something else in our pictures? A hotdog? Who is the hottest?
Perhaps we should all cool down a little, and find some ice cream.
Our Maltese friend doesn’t look like ice cream, and model is trying to look around it. But not the unicorn.
That’s all for now. Next time we will go into the model and will explore more.
Don’t hesitate to experiment, and learn more about machine learning.
You can see the full experiment code here.