[{"content":"","permalink":"https://dineshcodes.netlify.app/education/aaauc/","summary":"","title":"University of Cincinnati (UC)"},{"content":"","permalink":"https://dineshcodes.netlify.app/education/au/","summary":"","title":"Anurag University (AU)"},{"content":"","permalink":"https://dineshcodes.netlify.app/education/citd/","summary":"","title":"Central Institute of Tool Design (CITD)"},{"content":"Introduction Ever wondered how Instagram applies stunning filters to your face? The software detects key points on your face and projects a mask on top. This tutorial will guide you on how to build one such software using Pytorch.\nDataset In this tutorial, we will use the official DLib Dataset which contains 6666 images of varying dimensions. Additionally, labels_ibug_300W_train.xml (comes with the dataset) contains the coordinates of 68 landmarks for each face. The script below will download the dataset and unzip it in Colab Notebook.\nif not os.path.exists(\u0026#39;/content/ibug_300W_large_face_landmark_dataset\u0026#39;): !wget http://dlib.net/files/data/ibug_300W_large_face_landmark_dataset.tar.gz !tar -xvzf \u0026#39;ibug_300W_large_face_landmark_dataset.tar.gz\u0026#39; !rm -r \u0026#39;ibug_300W_large_face_landmark_dataset.tar.gz\u0026#39; Here is a sample image from the dataset. We can see that the face occupies a very small fraction of the entire image. If we feed the full image to the neural network, it will also process the background (irrelevant information), making it difficult for the model to learn. Therefore, we need to crop the image and feed only the face portion.\nData Preprocessing To prevent the neural network from overfitting the training dataset, we need to randomly transform the dataset. We will apply the following operations to the training and validation dataset:\n Since the face occupies a very small portion of the entire image, crop the image and use only the face for training. Resize the cropped face into a (224x224) image. Randomly change the brightness and saturation of the resized face. Randomly rotate the face after the above three transformations. Convert the image and landmarks into torch tensors and normalize them between [-1, 1].  class Transforms(): def __init__(self): pass def rotate(self, image, landmarks, angle): angle = random.uniform(-angle, +angle) transformation_matrix = torch.tensor([ [+cos(radians(angle)), -sin(radians(angle))], [+sin(radians(angle)), +cos(radians(angle))] ]) image = imutils.rotate(np.array(image), angle) landmarks = landmarks - 0.5 new_landmarks = np.matmul(landmarks, transformation_matrix) new_landmarks = new_landmarks + 0.5 return Image.fromarray(image), new_landmarks def resize(self, image, landmarks, img_size): image = TF.resize(image, img_size) return image, landmarks def color_jitter(self, image, landmarks): color_jitter = transforms.ColorJitter(brightness=0.3, contrast=0.3, saturation=0.3, hue=0.1) image = color_jitter(image) return image, landmarks def crop_face(self, image, landmarks, crops): left = int(crops[\u0026#39;left\u0026#39;]) top = int(crops[\u0026#39;top\u0026#39;]) width = int(crops[\u0026#39;width\u0026#39;]) height = int(crops[\u0026#39;height\u0026#39;]) image = TF.crop(image, top, left, height, width) img_shape = np.array(image).shape landmarks = torch.tensor(landmarks) - torch.tensor([[left, top]]) landmarks = landmarks / torch.tensor([img_shape[1], img_shape[0]]) return image, landmarks def __call__(self, image, landmarks, crops): image = Image.fromarray(image) image, landmarks = self.crop_face(image, landmarks, crops) image, landmarks = self.resize(image, landmarks, (224, 224)) image, landmarks = self.color_jitter(image, landmarks) image, landmarks = self.rotate(image, landmarks, angle=10) image = TF.to_tensor(image) image = TF.normalize(image, [0.5], [0.5]) return image, landmarks Dataset Class Now that we have our transformations ready, let’s write our dataset class. The labels_ibug_300W_train.xml contains the image path, landmarks and coordinates for the bounding box (for cropping the face). We will store these values in lists to access them easily during training. In this tutorial, the neural network will be trained on grayscale images.\nclass FaceLandmarksDataset(Dataset): def __init__(self, transform=None): tree = ET.parse(\u0026#39;ibug_300W_large_face_landmark_dataset/labels_ibug_300W_train.xml\u0026#39;) root = tree.getroot() self.image_filenames = [] self.landmarks = [] self.crops = [] self.transform = transform self.root_dir = \u0026#39;ibug_300W_large_face_landmark_dataset\u0026#39; for filename in root[2]: self.image_filenames.append(os.path.join(self.root_dir, filename.attrib[\u0026#39;file\u0026#39;])) self.crops.append(filename[0].attrib) landmark = [] for num in range(68): x_coordinate = int(filename[0][num].attrib[\u0026#39;x\u0026#39;]) y_coordinate = int(filename[0][num].attrib[\u0026#39;y\u0026#39;]) landmark.append([x_coordinate, y_coordinate]) self.landmarks.append(landmark) self.landmarks = np.array(self.landmarks).astype(\u0026#39;float32\u0026#39;) assert len(self.image_filenames) == len(self.landmarks) def __len__(self): return len(self.image_filenames) def __getitem__(self, index): image = cv2.imread(self.image_filenames[index], 0) landmarks = self.landmarks[index] if self.transform: image, landmarks = self.transform(image, landmarks, self.crops[index]) landmarks = landmarks - 0.5 return image, landmarks dataset = FaceLandmarksDataset(Transforms()) Note: landmarks = landmarks - 0.5 is done to zero-centre the landmarks as zero-centred outputs are easier for the neural network to learn.\nThe output of the dataset after preprocessing will look something like this (landmarks have been plotted on the image).\nNeural Network We will use the ResNet18 as the basic framework. We need to modify the first and last layers to suit our purpose. In the first layer, we will make the input channel count as 1 for the neural network to accept grayscale images. Similarly, in the final layer, the output channel count should equal 68 * 2 = 136 for the model to predict the (x, y) coordinates of the 68 landmarks for each face.\nclass Network(nn.Module): def __init__(self,num_classes=136): super().__init__() self.model_name=\u0026#39;resnet18\u0026#39; self.model=models.resnet18() self.model.conv1=nn.Conv2d(1, 64, kernel_size=7, stride=2, padding=3, bias=False) self.model.fc=nn.Linear(self.model.fc.in_features, num_classes) def forward(self, x): x=self.model(x) return x Training the Neural Network We will use the Mean Squared Error between the predicted landmarks and the true landmarks as the loss function. Keep in mind that the learning rate should be kept low to avoid exploding gradients. The network weights will be saved whenever the validation loss reaches a new minimum value. Train for at least 20 epochs to get the best performance.\nnetwork = Network() network.cuda() criterion = nn.MSELoss() optimizer = optim.Adam(network.parameters(), lr=0.0001) loss_min = np.inf num_epochs = 10 start_time = time.time() for epoch in range(1,num_epochs+1): loss_train = 0 loss_valid = 0 running_loss = 0 network.train() for step in range(1,len(train_loader)+1): images, landmarks = next(iter(train_loader)) images = images.cuda() landmarks = landmarks.view(landmarks.size(0),-1).cuda() predictions = network(images) # clear all the gradients before calculating them optimizer.zero_grad() # find the loss for the current step loss_train_step = criterion(predictions, landmarks) # calculate the gradients loss_train_step.backward() # update the parameters optimizer.step() loss_train += loss_train_step.item() running_loss = loss_train/step print_overwrite(step, len(train_loader), running_loss, \u0026#39;train\u0026#39;) network.eval() with torch.no_grad(): for step in range(1,len(valid_loader)+1): images, landmarks = next(iter(valid_loader)) images = images.cuda() landmarks = landmarks.view(landmarks.size(0),-1).cuda() predictions = network(images) # find the loss for the current step loss_valid_step = criterion(predictions, landmarks) loss_valid += loss_valid_step.item() running_loss = loss_valid/step print_overwrite(step, len(valid_loader), running_loss, \u0026#39;valid\u0026#39;) loss_train /= len(train_loader) loss_valid /= len(valid_loader) print(\u0026#39;\\n--------------------------------------------------\u0026#39;) print(\u0026#39;Epoch: {}Train Loss: {:.4f}Valid Loss: {:.4f}\u0026#39;.format(epoch, loss_train, loss_valid)) print(\u0026#39;--------------------------------------------------\u0026#39;) if loss_valid \u0026lt; loss_min: loss_min = loss_valid torch.save(network.state_dict(), \u0026#39;/content/face_landmarks.pth\u0026#39;) print(\u0026#34;\\nMinimum Validation Loss of {:.4f}at epoch {}/{}\u0026#34;.format(loss_min, epoch, num_epochs)) print(\u0026#39;Model Saved\\n\u0026#39;) print(\u0026#39;Training Complete\u0026#39;) print(\u0026#34;Total Elapsed Time : {}s\u0026#34;.format(time.time()-start_time)) Predict on Unseen Data Use the code snippet below to predict landmarks in unseen images.\nimport time import cv2 import os import numpy as np import matplotlib.pyplot as plt from PIL import Image import imutils import torch import torch.nn as nn from torchvision import models import torchvision.transforms.functional as TF ####################################################################### image_path = \u0026#39;pic.jpg\u0026#39; weights_path = \u0026#39;face_landmarks.pth\u0026#39; frontal_face_cascade_path = \u0026#39;haarcascade_frontalface_default.xml\u0026#39; ####################################################################### class Network(nn.Module): def __init__(self,num_classes=136): super().__init__() self.model_name=\u0026#39;resnet18\u0026#39; self.model=models.resnet18(pretrained=False) self.model.conv1=nn.Conv2d(1, 64, kernel_size=7, stride=2, padding=3, bias=False) self.model.fc=nn.Linear(self.model.fc.in_features,num_classes) def forward(self, x): x=self.model(x) return x ####################################################################### face_cascade = cv2.CascadeClassifier(frontal_face_cascade_path) best_network = Network() best_network.load_state_dict(torch.load(weights_path, map_location=torch.device(\u0026#39;cpu\u0026#39;))) best_network.eval() image = cv2.imread(image_path) grayscale_image = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY) display_image = cv2.cvtColor(image, cv2.COLOR_BGR2RGB) height, width,_ = image.shape faces = face_cascade.detectMultiScale(grayscale_image, 1.1, 4) all_landmarks = [] for (x, y, w, h) in faces: image = grayscale_image[y:y+h, x:x+w] image = TF.resize(Image.fromarray(image), size=(224, 224)) image = TF.to_tensor(image) image = TF.normalize(image, [0.5], [0.5]) with torch.no_grad(): landmarks = best_network(image.unsqueeze(0)) landmarks = (landmarks.view(68,2).detach().numpy() + 0.5) * np.array([[w, h]]) + np.array([[x, y]]) all_landmarks.append(landmarks) plt.figure() plt.imshow(display_image) for landmarks in all_landmarks: plt.scatter(landmarks[:,0], landmarks[:,1], c = \u0026#39;c\u0026#39;, s = 5) plt.show()  ⚠️ The above code snippet will not work in Colab Notebook as some functionality of the OpenCV is not supported in Colab yet. To run the above cell, use your local machine.\n OpenCV Harr Cascade Classifier is used to detect faces in an image. Object detection using Haar Cascades is a machine learning-based approach where a cascade function is trained with a set of input data. OpenCV already contains many pre-trained classifiers for face, eyes, pedestrians, and many more. In our case, we will be using the face classifier for which you need to download the pre-trained classifier XML file and save it to your working directory.\nDetected faces in the input image are then cropped, resized to (224, 224) and fed to our trained neural network to predict landmarks in them.\nThe predicted landmarks in the cropped faces are then overlayed on top of the original image. The result is the image shown below. Pretty impressive, right!\nSimilarly, landmarks detection on multiple faces:\nHere, you can see that the OpenCV Harr Cascade Classifier has detected multiple faces including a false positive (a fist is predicted as a face). So, the network has plotted some landmarks on that.\nThat’s all folks! If you made it till here, hats off to you! You just trained your very own neural network to detect face landmarks in any image. Try predicting face landmarks on your webcam feed!!\n","permalink":"https://dineshcodes.netlify.app/blog/face-landmarks-detection/","summary":"Introduction Ever wondered how Instagram applies stunning filters to your face? The software detects key points on your face and projects a mask on top. This tutorial will guide you on how to build one such software using Pytorch.\nDataset In this tutorial, we will use the official DLib Dataset which contains 6666 images of varying dimensions. Additionally, labels_ibug_300W_train.xml (comes with the dataset) contains the coordinates of 68 landmarks for each face.","title":"Face Landmarks Detection using CNN"},{"content":"Introduction to machine learning In the traditional hard-coded approach, we program a computer to perform a certain task. We tell it exactly what to do when it receives a certain input. In mathematical terms, this is like saying that we write the f(x) such that when users feed the input x into f(x), it gives the correct output y.\nIn machine learning, however, we have a large set of inputs x and corresponding outputs y but not the function f(x). The goal here is to find the f(x) that transforms the input x into the output y. Well, that’s not an easy job. In this article, we will learn how this happens.\nDataset To visualize the dataset, let’s make our synthetic dataset where each data point (input x) is 3 dimensional, making it suitable to be plotted on a 3D chart. We will generate 250 points (cluster 0) in a cluster centered at the origin (0, 0, 0). A similar cluster of 250 points (cluster 1) is generated but not centered at the origin. Both clusters are relatively close but there is a clear separation as seen in the image below. These two clusters are the two classes of data points. The big green dot represents the centroid of the whole dataset.\nAfter generating the dataset, we will normalize it by subtracting the mean and dividing by the standard deviation. This is done to zero-center the data and map values in each dimension in the dataset to a common scale. This speeds up the learning.\nThe data will be saved in an array X containing the 3D coordinates of normalized points. We will also generate an array Y with the value either 0 or 1 at each index depending on which cluster the 3D point belongs.\nLearnable Function Now that we have our data ready, we can say that we have the x and y. We know that the dataset is linearly separable implying that there is a plane that can divide the dataset into the two clusters, but we don’t know what the equation of such an optimal plane is. For now, let’s just take a random plane.\nThe function f(x) should take a 3D coordinate as input and output a number between 0 and 1. If this number is less than 0.5, this point belongs to cluster 0 otherwise, it belongs to cluster 1. Let’s define a simple function for this task.\nx: input tensor of shape (num_points, 3)W: Weight (parameter) of shape (3, 1) chosen randomlyB: Bias (parameter) of shape (1, 1) chosen randomlySigmoid: A function that maps values between 0 and 1\nLet’s take a moment to understand what this function means. Before applying the sigmoid function, we are simply creating a linear mapping from the 3D coordinate (input) to 1D output. Therefore, this function will squish the whole 3D space onto a line meaning that each point in the original 3D space will now be lying somewhere on this line. Since this line will extend to infinity, we map it to [0, 1] using the Sigmoid function. As a result, for each given input, f(x) will output a value between 0 and 1.\nRemember that W and B are chosen randomly and so the 3D space will be squished onto a random line. The decision boundary for this transformation is the set of points that make f(x) = 0.5. Think why! As the 3D space is being squished onto a 1D line, a whole plane is mapped to the value 0.5 on the line. This plane is the decision boundary for f(x). Ideally, it should divide the dataset into two clusters but since W and B are randomly chosen, this plane is randomly oriented as shown below.\nOur goal is to find the right values for W and B that orients this plane (decision boundary) in such a way that it divides the dataset into the two clusters. This when done, yields a plane as shown below.\nLoss So, we are now at the starting point (random decision boundary) and we have defined the goal. We need a metric to decide how far we are from the goal. The output of the classifier is a tensor of shape (num_points, 1) where each value is between [0, 1]. If you think carefully, these values are just the probabilities of the points belonging to cluster 1. So, we can say that:\n f(x) = P(x belongs to cluster 1) 1-f(x) = P(x belongs to cluster 0)  It wouldn’t be wrong to say that [1-f(x), f(x)] forms a probability distribution over the clusters 0 and cluster 1 respectively. This is the predicted probability distribution. We know for sure which cluster every point in the dataset belongs to (from y). So, we also have the true probability distribution as:\n [0, 1] when x belongs to the cluster 1 [1, 0] when x belongs to the cluster 0  A good metric to calculate the incongruity between two probability distributions is the Cross-Entropy function. As we are dealing with just 2 classes, we can use Binary Cross-Entropy (BCE). This function is available in PyTorch’s torch.nn module. If the predicted probability distribution is very similar to the true probability distribution, this function returns a small value and vice versa. We can average this value for all the data points and use it as a parameter to test how the classifier is performing.\nThis value is called the loss and mathematically, our goal now is to minimize this loss.\nTraining Now that we have defined our goal mathematically, how do we reach our goal practically? In other words, how do we find optimal values for W and B? To understand this, we will take a look at some basic calculus. Recall that we currently have random values for W and B. The process of learning or training or reaching the goal or minimizing the loss can be divided into two steps:\n Forward-propagation: We feed the dataset through the classifier f(x) and use BCE to find the loss. Backpropagation: Using the loss, adjust the values of W and B to minimize the loss.  The above two steps will be repeated over and over again until the loss stops decreasing. In this condition, we say that we have reached the goal!\nBackpropagation Forward propagation is simple and already discussed above. However, it is essential to take a moment to understand backpropagation as it is the key to machine learning. Recall that we have 3 parameters (variables) in W and 1 in B. So, in total, we have 4 values to optimize.\nOnce we have the loss from forward-propagation, we will calculate the gradients of the loss function with respect to each variable in the classifier. If we plot the loss for different values of each parameter, we can see that the loss is minimum at a particular value for each parameter. I have plotted the loss vs parameter for each parameter.\nAn important observation to make here is that the loss is minimized at a particular value for each of these parameters as shown by the red dot.\nLet’s consider the first plot and discuss how w1 will be optimized. The process remains the same for the other parameters. Initially, the values for W and B are chosen randomly and so (w1, loss) will be randomly placed on this curve as shown by the green dot.\nNow, the goal is to reach the red dot, starting from the green dot. In other words, we need to move downhill. Looking at the slope of the curve at the green dot, we can tell that increasing w1 (moving right) will lower the loss and therefore move the green dot closer to the red one. In mathematical terms, if the gradient of the loss with respect to w1 is negative, increase w1 to move downhill and vice versa. Therefore, w1 should be updated as:\nThe equation above is known as gradient descent equation. Here, the learning_rate controls how much we want to increase or decrease w1. If the learning_rate is large, the update will be large. This could lead to w1 going past the red dot and therefore missing the optimal value. If this value is too small, it will take forever for w1 to reach the red dot. You can try experimenting with different values of learning rate to see which works the best. In general, small values like 0.01 works well for most cases.\nIn most cases, a single update is not enough to optimize these parameters; so, the process of forward-propagation and backpropagation is repeated in a loop until the loss stops reducing further. Let’s see this in action:\nAn important observation to make is that initially the green dot moves quickly and slows down as it gradually approaches the minima. The large slope (gradient) during the first few epochs (when the green dot is far from the minima) is responsible for this large update to the parameters. The gradient decreases as the green dot approaches the minima and thus the update becomes slow. The other three parameters are trained in parallel in the exact same way. Another important observation is that the shape of the curve changes with epoch. This is due to the fact that the other three parameters (w2, w3, b) are also being updated in parallel and each parameter contributes to the shape of the loss curve.\nVisualize Let’s see how the decision boundary updates in real-time as the parameters are being updated.\nThat’s all folks! If you made it till here, hats off to you! In this article, we took a visual approach to understand how machine learning works. So far, we have seen how a simple 3D to 1D mapping, f(x), can be used to fit a decision boundary (2D plane) to a linearly separable dataset (3D). We discussed how forward propagation is used to calculate the loss followed by backpropagation where gradients of the loss with respect to parameters are calculated and the parameters are updated repeatedly in a training loop.\n","permalink":"https://dineshcodes.netlify.app/blog/machine-learning-visualized/","summary":"Introduction to machine learning In the traditional hard-coded approach, we program a computer to perform a certain task. We tell it exactly what to do when it receives a certain input. In mathematical terms, this is like saying that we write the f(x) such that when users feed the input x into f(x), it gives the correct output y.\nIn machine learning, however, we have a large set of inputs x and corresponding outputs y but not the function f(x).","title":"Machine Learning - Visualized"},{"content":"Introduction In this article, we will learn how PCA can be used to compress a real-life dataset. We will be working with Labelled Faces in the Wild (LFW), a large scale dataset consisting of 13233 human-face grayscale images, each having a dimension of 64x64. It means that the data for each face is 4096 dimensional (there are 64x64 = 4096 unique values to be stored for each face). We will reduce this dimension requirement, using PCA, to just a few hundred dimensions!\nPrincipal Component Analysis (PCA) Principal component analysis (PCA) is a technique for reducing the dimensionality of datasets, exploiting the fact that the images in these datasets have something in common. For instance, in a dataset consisting of face photographs, each photograph will have facial features like eyes, nose, mouth. Instead of encoding this information pixel by pixel, we could make a template of each type of these features and then just combine these templates to generate any face in the dataset. In this approach, each template will still be 64x64 = 4096 dimensional, but since we will be reusing these templates (basis functions) to generate each face in the dataset, the number of templates required will be small. PCA does exactly this. Let’s see how!\nDataset Let’s visualize some images from the dataset. You can see that each image has a complete face, and the facial features like eyes, nose, and lips are clearly visible in each image. Now that we have our dataset ready, let’s compress it.\nCompression PCA is a 4 step process. Starting with a dataset containing n dimensions (requiring n-axes to be represented):\n Step 1: Find a new set of basis functions (naxes) where some axes contribute to most of the variance in the dataset while others contribute very little. Step 2: Arrange these axes in the decreasing order of variance contribution. Step 3: Now, pick the top k axes to be used and drop the remaining n-k axes. Step 4: Now, project the dataset onto these k axes.  These steps are well explained in my previous article. After these 4 steps, the dataset will be compressed from n-dimensions to just k-dimensions (k\u0026lt;n).\nStep 1 Finding a new set of basis functions (n-axes), where some axes contribute to most of the variance in the dataset while others contribute very little, is analogous to finding the templates that we will combine later to generate faces in the dataset. A total of 4096 templates, each 4096 dimensional, will be generated. Each face in the dataset can be represented as a linear combination of these templates.\nPlease note that the scalar constants (k1, k2, …, kn) will be unique for each face.\nStep 2 Now, some of these templates contribute significantly to facial reconstruction while others contribute very little. This level of contribution can be quantified as the percentage of variance that each template contributes to the dataset. So, in this step, we will arrange these templates in the decreasing order of variance contribution (most significant…least significant).\nStep 3 Now, we will keep the top k templates and drop the remaining. But, how many templates shall we keep? If we keep more templates, our reconstructed images will closely resemble the original images but we will need more storage to store the compressed data. If we keep too few templates, our reconstructed images will look very different from the original images.\nThe best solution is to fix the percentage of variance that we want to retain in the compressed dataset and use this to determine the value of k (number of templates to keep). If we do the math, we find that to retain 99% of the variance, we need only the top 577 templates. We will save these values in an array and drop the remaining templates.\nLet’s visualize some of these selected templates.\nPlease note that each of these templates looks somewhat like a face. These are called as Eigenfaces.\nStep 4 Now, we will construct a projection matrix to project the images from the original 4096 dimensions to just 577 dimensions. The projection matrix will have a shape (4096, 577), where the templates will be the columns of the matrix.\nBefore we go ahead and compress the images, let’s take a moment to understand what we really mean by compression. Recall that the faces can be generated by a linear combination of the selected templates. As each face is unique, every face in the dataset will require a different set of constants (k1, k2, …, kn) for the linear combination.\nLet’s start with an image from the dataset and compute the constants (k1, k2, …, kn), where n = 577. These constants along with the selected 577 templates can be plugged in the equation above to reconstruct the face. This means that we only need to compute and save these 577 constants for each image. Instead of doing this image by image, we can use matrices to compute these constants for each image in the dataset at the same time.\nRecall that there are 13233 images in the dataset. The matrix compressed_images contains the 577 constants for each image in the dataset. We can now say that we have compressed our images from 4096 dimensions to just 577 dimensions while retaining 99% of the information.\nCompression Ratio Let’s calculate how much we have compressed the dataset. Recall that there are 13233 images in the dataset and each image is 64x64 dimensional. So, the total number of unique values required to store the original dataset is13233 x 64 x 64 = 54,202,368 unique values.\nAfter compression, we store 577 constants for each image. So, the total number of unique values required to store the compressed dataset is13233 x 577 = 7,635,441 unique values. But, we also need to store the templates to reconstruct the images later. Therefore, we also need to store577 x 64 x 64 = 2,363,392 unique values for the templates. Therefore, the total number of unique values required to store the compressed dataset is7,635,441 + 2,363,392 = 9,998,883 unique values.\nWe can calculate the percentage compression as:\nReconstruct the Images The compressed images are just arrays of length 577 and can’t be visualized as such. We need to reconstruct it back to 4096 dimensions to view it as an array of shape (64x64). Recall that each template has a dimension of 64x64 and that each constant is a scalar value. We can use the equation below to reconstruct any face in the dataset.\nAgain, instead of doing this image by image, we can use matrices to reconstruct the whole dataset at once, with of course a loss of 1% variance.\nLet’s look at some reconstructed faces.\nWe can see that the reconstructed images have captured most of the relevant information about the faces and the unnecessary details have been ignored. This is an added advantage of data compression, it allows us to filter unnecessary details (and even noise) present in the data.\nThat’s all folks! If you made it till here, hats off to you! In this article, we learnt how PCA can be used to compress Labelled Faces in the Wild (LFW), a large scale dataset consisting of 13233 human-face images, each having a dimension of 64x64. We compressed this dataset by over 80% while retaining 99% of the information.\n","permalink":"https://dineshcodes.netlify.app/blog/face-dataset-compression/","summary":"Introduction In this article, we will learn how PCA can be used to compress a real-life dataset. We will be working with Labelled Faces in the Wild (LFW), a large scale dataset consisting of 13233 human-face grayscale images, each having a dimension of 64x64. It means that the data for each face is 4096 dimensional (there are 64x64 = 4096 unique values to be stored for each face). We will reduce this dimension requirement, using PCA, to just a few hundred dimensions!","title":"Face Dataset Compression using PCA"},{"content":"🔗 GitHub Description  Developed a real-time project with a team to automatically classify news articles based on their category using a pre-trained model. Collaborated with team members to successfully implement a system that accurately categorizes news in terms of its subject matter. Utilized advanced techniques and technologies to classify news articles in real-time, showcasing a strong interest in cutting-edge technologies.  ","permalink":"https://dineshcodes.netlify.app/projects/news-classification-ml/","summary":"🔗 GitHub Description  Developed a real-time project with a team to automatically classify news articles based on their category using a pre-trained model. Collaborated with team members to successfully implement a system that accurately categorizes news in terms of its subject matter. Utilized advanced techniques and technologies to classify news articles in real-time, showcasing a strong interest in cutting-edge technologies.  ","title":"News Classification Using Machine Learning"},{"content":"🔗 GitHub Description  Developed a SMS spam detection project using machine learning techniques. Utilized a dataset containing labeled examples of spam and non-spam messages. Implemented data preprocessing steps to clean and prepare the text data for analysis. Explored various machine learning algorithms, such as Logistic regression, Support Vector Machines, etc for classification. Split the dataset into training and testing sets to evaluate the model\u0026rsquo;s performance. Successfully identified and classified SMS messages as spam or non-spam with accuracy of about 89%.  ","permalink":"https://dineshcodes.netlify.app/projects/sms-spam/","summary":"🔗 GitHub Description  Developed a SMS spam detection project using machine learning techniques. Utilized a dataset containing labeled examples of spam and non-spam messages. Implemented data preprocessing steps to clean and prepare the text data for analysis. Explored various machine learning algorithms, such as Logistic regression, Support Vector Machines, etc for classification. Split the dataset into training and testing sets to evaluate the model\u0026rsquo;s performance. Successfully identified and classified SMS messages as spam or non-spam with accuracy of about 89%.","title":"SMS spam detection"},{"content":"🔗 GitHub Description  Conducted comprehensive analysis of dimensional hotel dataset and factorial tables. Addressed NaN values and outliers in the dataset. Utilized graphical representations to extract valuable insights from data. Used 6 Realtime datasets to derive insights and underlying patterns for better analysis. Assisted business analysts in improving their performance by over 60%.  ","permalink":"https://dineshcodes.netlify.app/projects/hotel-data-analysis/","summary":"🔗 GitHub Description  Conducted comprehensive analysis of dimensional hotel dataset and factorial tables. Addressed NaN values and outliers in the dataset. Utilized graphical representations to extract valuable insights from data. Used 6 Realtime datasets to derive insights and underlying patterns for better analysis. Assisted business analysts in improving their performance by over 60%.  ","title":"Hotel Data Analysis"},{"content":"🔗 GitHub Description  Engineered a machine learning project on a credit card dataset to determine the legitimacy or fraudulent nature of card details. Constructed a robust model to analyze and classify credit card transactions, ensuring the detection and prevention of potential fraud. Demonstrated a strong commitment to combating fraud by constructing a machine learning project using a credit card dataset to identify legitimate and fraudulent transactions. Achieved accuracy over 90% in credit card fraud analysis using Logistic Regression.  ","permalink":"https://dineshcodes.netlify.app/projects/credit-card-fraud/","summary":"🔗 GitHub Description  Engineered a machine learning project on a credit card dataset to determine the legitimacy or fraudulent nature of card details. Constructed a robust model to analyze and classify credit card transactions, ensuring the detection and prevention of potential fraud. Demonstrated a strong commitment to combating fraud by constructing a machine learning project using a credit card dataset to identify legitimate and fraudulent transactions. Achieved accuracy over 90% in credit card fraud analysis using Logistic Regression.","title":"Credit Card Fraud Analysis"},{"content":"🔗 GitHub 🔗 Website Description  Developed a Rock, Paper, Scissors game using HTML, CSS, and JavaScript with DOM manipulation. Designed a visually appealing user interface using HTML and CSS to enhance user experience. Implemented JavaScript logic to handle game mechanics, including user input and computer-generated choices. Utilized DOM manipulation to dynamically update the game interface based on user actions and outcomes. Incorporated event listeners to capture user clicks on the Rock, Paper, and Scissors buttons. Created functions to determine the winner of each round based on the game rules. Implemented a scoring system to keep track of user and computer scores throughout the game. Ensured responsive design to make the game accessible and enjoyable on various devices. Tested and debugged the application to ensure smooth and error-free gameplay.  ","permalink":"https://dineshcodes.netlify.app/projects/rock-paper-scissors/","summary":"🔗 GitHub 🔗 Website Description  Developed a Rock, Paper, Scissors game using HTML, CSS, and JavaScript with DOM manipulation. Designed a visually appealing user interface using HTML and CSS to enhance user experience. Implemented JavaScript logic to handle game mechanics, including user input and computer-generated choices. Utilized DOM manipulation to dynamically update the game interface based on user actions and outcomes. Incorporated event listeners to capture user clicks on the Rock, Paper, and Scissors buttons.","title":"Rock Paper Scissors Game"},{"content":"🔗 GitHub Description  Developed a personalized Financial Tracker website. Designed an intuitive and user-friendly interface that allows users to input and manage their financial data. Implemented JavaScript logic to handle data entry, storage, and retrieval for expense tracking. Utilized HTML forms to collect user input, such as expense details and amount. Employed CSS for styling to enhance the visual appeal and usability of the financial tracker. Integrated a salary input feature, allowing users to input their salary information for accurate expense tracking. Created a visualizer component using JavaScript to graphically represent and analyze expenses in relation to the user\u0026rsquo;s salary. Enabled dynamic updates to the visualizer, ensuring real-time reflection of expense changes. Implemented data visualization techniques, such as charts or graphs, to enhance the user\u0026rsquo;s understanding of their financial data. Ensured the security and privacy of user data by implementing appropriate measures for data handling and storage.  ","permalink":"https://dineshcodes.netlify.app/projects/rupeemap/","summary":"🔗 GitHub Description  Developed a personalized Financial Tracker website. Designed an intuitive and user-friendly interface that allows users to input and manage their financial data. Implemented JavaScript logic to handle data entry, storage, and retrieval for expense tracking. Utilized HTML forms to collect user input, such as expense details and amount. Employed CSS for styling to enhance the visual appeal and usability of the financial tracker. Integrated a salary input feature, allowing users to input their salary information for accurate expense tracking.","title":"Rupeemap"},{"content":"Description  Developing and implementing tech projects for the Operations Team. Engineering innovative solutions resulting in a noticeable improvement in the efficiency and effectiveness of the entire team. Spearheaded the construction of a business dashboard using PowerBI  ","permalink":"https://dineshcodes.netlify.app/experience/datawiseintern/","summary":"Description  Developing and implementing tech projects for the Operations Team. Engineering innovative solutions resulting in a noticeable improvement in the efficiency and effectiveness of the entire team. Spearheaded the construction of a business dashboard using PowerBI  ","title":"Tech Intern"},{"content":"Description  Organized varied student events, including hackathons, informative sessions, and seminars, to educate peers Collaborated on streamlit projects, translating machine learning code and Python into functional applications, demonstrating a dedication to practical development. Key player in team technical activities, driving an impressive 80% performance boost through strategic initiatives and collaboration.  ","permalink":"https://dineshcodes.netlify.app/experience/gdscau/","summary":"Description  Organized varied student events, including hackathons, informative sessions, and seminars, to educate peers Collaborated on streamlit projects, translating machine learning code and Python into functional applications, demonstrating a dedication to practical development. Key player in team technical activities, driving an impressive 80% performance boost through strategic initiatives and collaboration.  ","title":"Machine Learning Lead"},{"content":"Description  Core team member at GDSC (Google Developer Student Clubs) in 2023. Managed diverse responsibilities, including technology, discipline, team coordination, and registration processes. Held the position of overall coordinator, overseeing various aspects of GDSC operations. Introduced innovative ideas that led to an impressive performance improvement of over 80% for the team. Contributed significantly to the success and impact of GDSC during my tenure. Instrumental in making the event a great success through effective leadership and impactful contributions.  ","permalink":"https://dineshcodes.netlify.app/experience/gdscwow/","summary":"Description  Core team member at GDSC (Google Developer Student Clubs) in 2023. Managed diverse responsibilities, including technology, discipline, team coordination, and registration processes. Held the position of overall coordinator, overseeing various aspects of GDSC operations. Introduced innovative ideas that led to an impressive performance improvement of over 80% for the team. Contributed significantly to the success and impact of GDSC during my tenure. Instrumental in making the event a great success through effective leadership and impactful contributions.","title":"Core Team"},{"content":"Description  Standardized the training procedure for ML models, saving over 100 hours of development time for the ML team. Used multiple algorithms to predict using a dataset. Gained insights into the applications of AI and ML in startups and corporates. Acquired experience in working with limited and sensitive data.  ","permalink":"https://dineshcodes.netlify.app/experience/eduskillsintern/","summary":"Description  Standardized the training procedure for ML models, saving over 100 hours of development time for the ML team. Used multiple algorithms to predict using a dataset. Gained insights into the applications of AI and ML in startups and corporates. Acquired experience in working with limited and sensitive data.  ","title":"AIML Intern"}]