Exploring Architectures- CNN

In the essays that I have written before about Neural Networks and how they can be seen as simply an implementation of Linear Algebra and Vector calculus, I found that explaining them through this perspective exposed me to some new concepts and a new way of looking at Neural Networks. Thus followig these topics, in the upcoming essays, I will explore the different architectures of Neural Networks, following the same procedure of using only math to construct them. Thus in this essay, we shall explore Convolutional Neural Networks, basically the networks that give computers vision. These can be very powerful and complex (with the modern improvements and modifications), hence I shall explore only a basic convolutional neural network.

Convolutional Neural Networks

In the previous essays, I have written about linear regression through stochastic gradient descend, which were very powerful and efficient, but only when it came to certain type of problems. Regression works well when our output is of merely one-dimension. These type of problems (where our output is one dimensional) are well suited for linear regression and the loss function we used before: mean-squared error. But that is not the case when it comes to other problems. Vision: we want computers to recognize images. Linear Regression can prove to be slow and inefficient, not to mention we can do better on the loss function as well. There are a few things we must clarify first: color of the image, how many pre-determined categories are there and a new loss function. Since we are assuming a simple® network, we shall only take grayscale values (0-255) and three categories. What about the loss funtion ? Last time we used mean-squared error, which is not exactly the worst loss function to use, but there is one better, and we benefit more from using that. Let’s start by defining our input !

Since our input will be an image, it will be represented by a matrix of numbers between 0 and 255, where black is 0 and white is 255, which means our raw input will be a matrix instead of a vector, unlike in linear regression. Lets us define the input as I.

I = [i11i12i13i1mi21i31in1inm]n* mWhere, i ϵ [0, 255]

This is an (n x m) resolution image, passed in as a matrix. If we were to follow the usual steps (discussed inprevious essays) we simply multiply the input by a weight matrix, and add a bias vector/matrix to get to the output. With the addition of a hidden layer, we created a dense or deep neural network. But in this case, we are dealing with a matrix, possibly large with each value representing a pixel which contributes to a feature of the image (something unique to a particular class of image). A breakthrough was made, when we discovered that using convolutions (explained shortly), we can make the training much faster and efficient, greatly increasing the accuracy of our models.

Kernels

We have the input matrix I. This matrix has certain features in it. Let’s assume it is a picture of a dog, than some features would be an eye, ears or paws or tail. Our model , must associate each feature to the correct class of images (dog or cat or human, etc.). This is the learning part of the model. Given a cat, our model must identify it’s most prominent features, those which set it apart from dogs or humans and associate them to the same. This indeed seems like a daunting task to do, especially for a model (they lack sophisticated brain like ours). But this is where linear algebra shows it’s brilliant magic and comes to our aid, and we finish up in style with our usual gradient desecnt optimization. So what does linear algebra offer us ? In a nutshell: smaller matrices. Let me explain. Let us define a small matrix of dimensions (3 * 3), and an example matrix of random colors (20 * 20).

I = [i1,1i1,2i1,3i1,20i2,1i3,1i20,1i20,20]20* 20K = [k11k12k13k21k22k23k31k32k33]3* 3
The smaller matrix is known as a *kernel*. The input matrix **I** simply consists of numbers ranging from 0 to 255. Applying a convolution simply means doing an **elementwise multiplication of the kernel over the submatrices of *I* of the same dimensions, and adding up the results, which effectively reduces the dimension of the resultant matrix.**. A submatrix simply means a sub-part of a larger matrix, for example : I1 = [i11i12i13i21i22i23i31i32i33]3* 3

Is a sub-matrix of I. And we simply do an elementwise multiplication of this sub-matrix with our kernel.

[i11i12i13i21i22i23i31i32i33] × [k11k12k13k21k22k23k31k32k33]= [c]where, [c]= i11k11+i12k12+i13k13+i21k21+i22k22+i23k23+i31k31+i32k32+i33k33
The formula for the resultant matrix, given we have an input matrix I, and a kernel K, with their respective dimensions, the dimensions of the result of a convolution are given by: dim=(ihkh+1) × (iwkw+1)
We follow this with moving the kernel by one column and continuing the process, until we reach the end. This is the trick behind convolutional neural networks. Ok ? But *why* ? What does it exactly do ? Remember how I said that the network must be able to tell apart features that belong to a particular class of images ? Well if we select the kernel properly, it *highlights* certain features of images. For example, here is a very simple picture in our (20 * 20) grid input (forgive my lack of talent in art): This is a (20 * 20) image, with the white squares having value of 255, and the black ones having a value of 0. Suppose a prominent feature of the image above is it's vertical lines. Thus, we need to capture that particular feature of the image, i.e, a vertical line (or any vertical part for that matter) into a kernel. For now, let's try it out with this kernel below: K = [0000.50.50.5000]3* 3

We do the above operation of doing elementwise multiplication of this kernel with each submatrix (remember: the matrix is full of 255’s or 0’s) and we end up with the following image:

Heres what happened: [[i11.k11i12.k12i13.k13i21.k21i22.k22i23.k23i31.k31i32.k32i33.k33]i1,20i20,1i20,20][[i12.k11i13.k12i14.k13i22.k21i23.k22i24.k23i32.k31i33.k32i34.k33]i20,1i20,20]And we continue till the end

Note: The values of kernel did not change!

It is pretty evident (and satisfying) to see what the kernel did: it sort of highlighted the vertical lines in the image! This means that the kernel K encaptures vertical lines in this image! Just as is the case here, every image has a unique feature which it shares with other images of the same type (every stick man has a vertical line for a torso), and thus if we correctly encapture that exact feature in a kernel, we can more easily identify a class of an image. That is the learning part in these networks: they learn to find a kernel which best represents a particular feature (as the above kernel represents vertical lines) except they do so taking into account all of the images we provide, and finds kernels which encapture features which are similiar, but also have slight variations (a dog sitting vs standing). With this, we can now finally move forward!

Forward Propagation

After we get the convoluted matrix from the previous operations, we simply follow through with the same procedure as we did for normal neural networks: multiply by weights and add a bias term. But before we do that, let us not forget we have a matrix and not a vector. Why not convert our matrix into one than ? It makes it much simpler to deal with, as we always prefer less complicated or lower dimensional stuff ! Let C be the convoluted matrix.

 [c1,1c1,2c1,3c1,20c2,1c3,1c20,1c20,20]20* 20[c1,1c1,2c1,3c20,20]1* 20also written as :[c1,1c1,2c1,3c20,20]1* 20T

Now we can go ahead and use weights and biases to the convolution vector to get what we want: the output of the first “layer”. Let W be the weight matrix and B be the bias vector.

CW+B = O[c1,1c1,2c1,3c20,20]1* 20T[w1,1w12w13w1mw2,1w3,1w20,1wnm]20* m+[b1,1b1,2b1,3b20,20]1* mT=[o1,1o1,2o1,3o20,20]1* mT

This gives us our first output. Since I have covered this process before, in previous mentioned essays, I will only go over them briefly: we put these through an activation function, and add a hidden layer, except this time, there are new functions and dimensions to think (worry) about! Anyways, here is the ReLu activation function applied to the same:

ReLu activation function: 12([o1,1o1,2o1,3o20,20]1* mT+[|o1,1||o1,2||o1,3||o20,20|]1* mT)=[h1,1h1,2h1,3h20,20]1* mT

With this, we can finally arrive at the last problem: what will be our output exactly? Remember that this is a classification from, therefore we do not want quantity, but instead a class of an image (whether it is a dog, cat or human). Therefore our output must represent each of these categories. A very simple way would be to assign each label a vector, such as :

Cat : [001]Dog : [010]Human : [100]

With this, not only us, but even a computer model can distinguish between the three. Hence our output must be a (1 * 3) dimensional vector, with each number representing a class. With that, we can go ahead with our hidden layer, to calculate our final output. Let W2 be the weigths and B2 be the bias. (With W1 and B1 being the previous ones.)

[h1,1h1,2h1,3h20,20]1* mT[w11w12w13w21w31wm1wm2wm3]m* 3+[b11b12b13]1* 3T=[o11o12o13]1* 3T

With this process, we finally arrive at our final answer. The logical next step would be to somehow compare this vector to whatever is the true answer, but the question is how? Do we simply subtract it and square, like in mean-squared error ? No. What we need here is probability: our model must give probabilities about how certain it is about the given image, and we are going to build our loss function around that as well. This is a major difference between linear regression and classification: the use of probabilities and a different loss function, so let’s get started!

Softmax Function

One problem when thinking about probabilities, is that nothing restricts our output vector from containing negative values, which can be bothersome: as there cannot be negative probability. There is also the constraint of normality: all the values in the vector must add to one. To take care of both of these problems, we pass the output through what is known as the softmax function. This particular function takes in the values and returns a probability distribution. The function is defined as :

Softmax function: eoii=0Keoi

The following function works because: it takes the exponential of every term in the vector, which deals with the negative values, and it also divides with the sum total of all the exponential values of the vector elements, hence the total of the vector after softmax equals to one. Thus we must simply pass our final output into the function to get our true final probability distribution.

σ([o11o12o13]1* 3T) = [eo11i=03eoieo12i=03eoieo13i=03eoi]1* 3T

Note: The σ symbol denotes the softmax function

Let us clearly define what we have as our final product: we have what our model thinks is the distribution of probabilities of the given image and class of categories. For example, if the vector output is [0.4, 0.3, 0.3] than the model thinks the given image is 40% human, 30% dog and 30% cat, which indicates that it is far from the true probability distribution (which could be [1,0,0] or [0,1,0] or [0,0,1]). Our next step would be to define a loss function, but only this time, around probabilities.

Cross-Entropy Loss

As mentioned above, suppose we initialze a random matrix of kernels and weights and biases, and go through the above mentioned processes to get a final probability distribution. Let’s take an example of [0.2, 0.5, 0.3] as our model’s initial guess. Let’s assume the image was of a human, so the actual probability distribution is [1,0,0]. What we need now, is to somehow calculate the distance between these two distributions, or how wrong was the model’s guess. Doing so can be a bit unintuitive, as opposed to the mean squared error. What we start with to get to our loss function is a way to find the distance or difference between two distributions, which can be calculated by using the Kullback-Leibler Divergence, which in statistical theory is used to find the distance of errors between probability distributions.

Kullback-Leibler Divergence

Let’s assume we have two coins. Coin 1 has a p1 probability of giving heads and p2 for tails, whereas Coin 2 has a probability of q1 for heads and q2 for tails. Therefore their distribution can be simply given by :

Coin 1 distribution: p1H.p2TCoin 2 distribution: q1H.q2T

Where H is the number of heads and T is the number of tails (giving H+T as the total number of tosses or N). What we do next is very simple: get their ratio. And since we cannot forget the normalization condition, we must take the root to the Nth power. Giving our final equation the form of :

(p1H.p2Tq1H.q2T)1N

Believe it or not, we have already arrived at the KL divergence! Now we only have to simplify the equation by taking the log of the equation, and get to the final form.

log(p1HN.p2TNq1HN.q2HN)log(p1HN.p2TN)log(q1HN.q2HN)log(p1HN) + log(p2TN)  log(q1HN) + log(q2HN)HNlog(p1)+TNlog(p2)HNlog(q1)+TNlog(q2)

As N approaches infinity, H/N approaches p1 and T/N approaches p2 making our equations to be :

p1log(p1)+p2log(p2)q1log(q1)q2log(q2)p1log(p1)p1log(q1)+p2log(p2)p2log(q2) p1log(p1q1)+p2log(p2q2)

Hence we have arrived at our final equations, where given the probabilities of two different distributions, we can effectively quantify the difference between them, or how similiar they are. This formula can be applied to more than two probabilities as well, which gives us the technically accurate term for the KL divergence:

DKL(P||Q) = iP(i)log(P(i)Q(i))
For continous distributions:DKL(P||Q) =P(x)log(P(x)Q(x))dx

Since we are only dealing with discrete distributions, you can ignore the second formula. (If anyone is interested,here is an excellent youtube video on the same topic!) Before we get eager and utilize this formula to calculate what we want, we must take a little detour and derive our loss function from the KL divergence.

The Loss function

There is only a tiny difference between cross entropy and the KL divergence, and that is rooted in conditional probability. As mentioned before, we want to find the true probability distribution of a given output. Let us define paramters of our model to be 𝜃 (I am assuming just one, but they can be as many as you want). Thus our model, using these parameters, gets to a distribution through the above processes. Let this probability be,

P* (y|x;θ)

Which means the probability distribution of the output, given the input and the parameter 𝜃 ([0.4,0.3,0.3] in our case). On the other side, we have the true probability distribution, which is simply the probability of the output given the input ([1,0,0] in our case).

P(y|x)

We use the KL divergence on these to find how far away P* is from P,

DKL(P||P* ) = iP(y|x) log(P(y|x)P* (y|x;θ))

And on further simplification we get,

iP(y|x) (log(P(y|x))  log(P* (y|x;θ)))iP(y|x) log(P(y|x)) P(y|x) log(P* (y|x;θ)))iP(y|x) log(P(y|x)) iP(y|x) log(P* (y|x;θ)))

Now we must remember the purpose of the loss function: to somehow tweak the parameter 𝜃, so as to decrease the loss function. Hence, we only care about the part of the equation that we can control, or the part with 𝜃 in it. Upon closer inspection, we see that the first half of the equation has no 𝜃, and thus we can completely ignore it to finally arrive at our loss function: the cross-entropy loss.

Cross Entropy Loss = iP(y|xi) log(P*(y|xi;θ)))

We shall continue with backpropagation in the next essay, or else this essay will be too long (scrolling is not that fun after a point), follow the link below for part II.

Continure Reading
Home