Convolutional Neural Networks: Unmasking its Secrets

Ildar Idrisov, PhD
Deelvin Machine Learning
6 min readJul 14, 2020

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.

Architecture of Inception v3 model

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.

Maltese dog, Pug and Unicorn
Maltese dog, Pug and Unicorn

In the beginning, we need to test our first dog.

Maltese 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 image with blocking a part 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.

The image with blocking of full object

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 image with blocking of part object

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.

Partly blocked images with outputs from the model

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.

The mask to overlay

Next, we overlay it onto our original image.

The image with mask

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:

Gif with result

And this is how all our other little friends look like after the application of the thermal mask.

Resulting heatmap with looking for right class

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?

Resulting heatmap with looking for “hotdog” class

Perhaps we should all cool down a little, and find some ice cream.

Resulting heatmap with looking for “ice cream” class

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.

--

--