<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom"><channel><title>Projects | Dat Nguyen</title><link>https://dat-nguyen.netlify.app/project/</link><atom:link href="https://dat-nguyen.netlify.app/project/index.xml" rel="self" type="application/rss+xml"/><description>Projects</description><generator>Wowchemy (https://wowchemy.com)</generator><language>en-us</language><lastBuildDate>Fri, 11 Dec 2020 00:00:00 +0000</lastBuildDate><image><url>https://dat-nguyen.netlify.app/images/icon_hu02d4214244b58f4d9dfd2bf839db7a24_243966_512x512_fill_lanczos_center_2.png</url><title>Projects</title><link>https://dat-nguyen.netlify.app/project/</link></image><item><title>Facial Expression Recognition with Deep Learning</title><link>https://dat-nguyen.netlify.app/project/facial_expression/</link><pubDate>Fri, 11 Dec 2020 00:00:00 +0000</pubDate><guid>https://dat-nguyen.netlify.app/project/facial_expression/</guid><description>&lt;h2 id="motivation">Motivation&lt;/h2>
&lt;p>Human emotion detection has a critical part in the interpersonal relationships. Emotions can generally be extracted from speech, hands and gestures of the body as well as
through facial expressions. Being able to understand human emotions could improve the quality of the communications between human and machine. Furthermore, there is a wide range of industries that could benefit from emotion recognition such as healthcare, automotive, gaming, and many more.&lt;/p>
&lt;p>While there are about 27 different human emotions, in this project, we plan to work with labeled data sets with seven distinct human emotions: happiness, sadness, fear, anger,
surprise, disgust, and neutral. We aim to implement a two-step model: first, localize human faces in an image and second, recognize emotion expressed in those faces.&lt;/p>
&lt;h2 id="part-1">Part 1&lt;/h2>
&lt;p>Our first data set (’Dataset 1’), which is provided and maintained by Dataturks, has about 400 images with a bit more than 1000 faces. The data is available as a JSON file with 2 main components, an URL address of the image, and the face labels and bounding boxes of that image. We extracted those information from the JSON file, made an annotate function, and showed the images with the correct bounding boxes for the faces.&lt;/p>
&lt;figure id="figure-images-from-dataset-1">
&lt;a data-fancybox="" href="https://dat-nguyen.netlify.app/media/face1.png" data-caption="Images from Dataset 1">
&lt;img src="https://dat-nguyen.netlify.app/media/face1.png" alt="" >
&lt;/a>
&lt;figcaption>
Images from Dataset 1
&lt;/figcaption>
&lt;/figure>
&lt;p>We selected a Faster R-CNN based model, the X101-FPN, available from Facebook’s Detectron2 package, Model Zoo for face detection task. Because this pre-trained model is developed for object recognition tasks with more than 30 different labels, we leverage the CNN layers for feature detections and then retrain the last few layers of the model using Dataset 1. The result is as follows:&lt;/p>
&lt;figure id="figure-face-detection-with-pre-trained-model">
&lt;a data-fancybox="" href="https://dat-nguyen.netlify.app/media/face2.png" data-caption="Face Detection with Pre-trained Model">
&lt;img src="https://dat-nguyen.netlify.app/media/face2.png" alt="" >
&lt;/a>
&lt;figcaption>
Face Detection with Pre-trained Model
&lt;/figcaption>
&lt;/figure>
&lt;h2 id="part-2">Part 2&lt;/h2>
&lt;p>For facial expression recognition task, we used the FER2013 dataset (&amp;lsquo;Dataset 2&amp;rsquo;). The data consists of 48x48 pixel grayscale images of human faces. The faces have been processed to be centered in the image and occupies about the same amount of space in each image. Each face is labeled as one of seven emotions.&lt;/p>
&lt;figure id="figure-images-from-dataset-2">
&lt;a data-fancybox="" href="https://dat-nguyen.netlify.app/media/fer1.png" data-caption="Images from Dataset 2">
&lt;img src="https://dat-nguyen.netlify.app/media/fer1.png" alt="" >
&lt;/a>
&lt;figcaption>
Images from Dataset 2
&lt;/figcaption>
&lt;/figure>
&lt;p>We started with KNN and MLP as our baseline models with accuracies of 31.5% and 22.8% respectively. A random classifier would have 14.3% accuracy (7 labels) so the baseline models, even though having better accuracies, are still not good enough. This is where a CNN based model shines. We used 2 different CNN architectures, one simple CNN model with only 3 convolutional layers and a ResNet based CNN model. Both models were trained on the FER data set using Adam optimizer with learning rate of 0.001 and the loss is calculated using cross-entropy loss. The architecture of the two models are presented below:&lt;/p>
&lt;figure id="figure-cnn-architecture">
&lt;a data-fancybox="" href="https://dat-nguyen.netlify.app/media/cnn.png" data-caption="CNN Architecture">
&lt;img src="https://dat-nguyen.netlify.app/media/cnn.png" alt="" >
&lt;/a>
&lt;figcaption>
CNN Architecture
&lt;/figcaption>
&lt;/figure>
&lt;p>The simple CNN model achieved a 54.8% accuracy, which already beat the 2 baseline models. The best accuracy we obtained is 62.8% from the ResNet based CNN model. The pre-trained ResNet model we are using as our initialization is trained on more than a million images from the ImageNet database. Therefore, it has already learned very good kernels in its convolutional layers and is able to extract useful features from the facial expression images without further training. That might be the reason why it outperforms our simple CNN model after the first training epoch.&lt;/p>
&lt;h2 id="final-thoughts">Final thoughts&lt;/h2>
&lt;p>While the Faster R-CNN based model and the ResNet based CNN model achieved a very good result, there are instances where the models overdetect the bounding boxes or fail to capture the true emotions.&lt;/p>
&lt;figure id="figure-an-example-of-overdetecting-faces-with-multiple-emotions">
&lt;a data-fancybox="" href="https://dat-nguyen.netlify.app/media/confusion.png" data-caption="An example of overdetecting faces with multiple emotions">
&lt;img src="https://dat-nguyen.netlify.app/media/confusion.png" alt="" >
&lt;/a>
&lt;figcaption>
An example of overdetecting faces with multiple emotions
&lt;/figcaption>
&lt;/figure>
&lt;p>Facial expression recognition is a very challenging task, even for a human being. A trained human can be excellent at hiding true emotions and there could be no way to find out through facial expressions. Furthermore, a human face could show multiple expressions at the same time. With that said, machine learning is getting closer at matching human’s level, which could be exciting and terrifying at the same time.&lt;/p></description></item><item><title>Jeopardy! Web Application</title><link>https://dat-nguyen.netlify.app/project/jeopardy/</link><pubDate>Tue, 01 Dec 2020 00:00:00 +0000</pubDate><guid>https://dat-nguyen.netlify.app/project/jeopardy/</guid><description>&lt;p>Our application is modeled after the show, Jeopardy!, which features a quiz competition in which contestants are presented with general knowledge clues in the form of answers and must phrase their responses in the form of questions. The questions can come from any category and in order to win, contestants must rack up the most amount of money. Having been aired for decades, this immensely popular show has gained worldwide recognition and continues to be an entertaining show for everyone to enjoy.&lt;/p>
&lt;p>Our application serves two main purposes. Primarily, our application is meant to be a fun trivia site for fans who want an interactive Jeopardy! experience. Additionally, our application can also be used by prospective contestants who want to sharpen their trivia skills and gain insights into the patterns of questions and answers before appearing on the show.&lt;/p>
&lt;p>The motivation behind this idea comes from the fact that we are Jeopardy! fans and there is currently no comprehensive site where fans can play the games as well as view statistics about the show. In recent history, some Jeopardy! winners have successfully used computer models in order to effectively and efficiently train for their appearances on the show, but for contestants without programming backgrounds, this type of training is not feasible. With our application, any prospective contestant is able to leverage analytical insights in order to best prepare for the show.&lt;/p>
&lt;p>The underlying technologies we used to create our application are as follows:&lt;/p>
&lt;ul>
&lt;li>Python - Web Scraping: We scraped two of our datasets relating to contestants from J! Archive using Python. The first dataset we scraped contained data about winners and contestants per episode. The second dataset contained data about each contestant themselves, unrelated to the show.&lt;/li>
&lt;li>Amazon Warehouse Services (AWS) Relational Database Services (RDS): Our database is maintained and hosted on AWS.&lt;/li>
&lt;li>Oracle SQL Developer: After establishing our database, we connected it to Oracle SQL Developer, which we used to load and query our data. Our application is also directly connected to this.&lt;/li>
&lt;li>Tableau: We integrated Tableau in order to create data visualizations that better communicated certain statistics on our Contestants and Questions pages.&lt;/li>
&lt;li>Node.js: We used Node.js as the JavaScript runtime environment that executes JavaScript code outside a web browser. It allows us to run scripts server-side to produce dynamic web page content before the page is sent to the user’s web browser.&lt;/li>
&lt;li>Vue.js: Vue is a model-view, front-end JavaScript framework. We used Vue to build the user interfaces for our trivia site.&lt;/li>
&lt;/ul>
&lt;h2 id="installation-instruction">Installation Instruction&lt;/h2>
&lt;ul>
&lt;li>
&lt;p>Server:&lt;/p>
&lt;ul>
&lt;li>Our server connects to Oracle. In order to run the application, please make sure you have Oracle Instant Client and SDK installed.&lt;/li>
&lt;li>Once it&amp;rsquo;s installed, update the path to the client in the routes.js file at the very top within oracledb.initOracleClient({ libDir: '' })&lt;/li>
&lt;li>Use &amp;ldquo;npm start&amp;rdquo; to run server from within server folder (after npm install)&lt;/li>
&lt;/ul>
&lt;/li>
&lt;li>
&lt;p>Client:&lt;/p>
&lt;ul>
&lt;li>Use &amp;ldquo;npm run serve &amp;ndash; &amp;ndash;port 3000&amp;rdquo; to run client from within client folder(after npm install)&lt;/li>
&lt;li>If this fails, first delete the &amp;ldquo;node_modules&amp;rdquo; folder in the client folder and run npm i. Then try again.&lt;/li>
&lt;/ul>
&lt;/li>
&lt;/ul>
&lt;h2 id="preview">Preview&lt;/h2>
&lt;figure id="figure-a-preview-of-the-play-page">
&lt;a data-fancybox="" href="https://dat-nguyen.netlify.app/media/play.png" data-caption="A Preview of the Play Page">
&lt;img src="https://dat-nguyen.netlify.app/media/play.png" alt="" >
&lt;/a>
&lt;figcaption>
A Preview of the Play Page
&lt;/figcaption>
&lt;/figure>
&lt;p>We hope you enjoy it!&lt;/p></description></item><item><title>Study of Car Accidents in the United States</title><link>https://dat-nguyen.netlify.app/project/car_severity/</link><pubDate>Thu, 05 Nov 2020 00:00:00 +0000</pubDate><guid>https://dat-nguyen.netlify.app/project/car_severity/</guid><description>&lt;p>We chose to work with a set of United States car accident data from 2016 - 2020. The data set consists of ~3.5 million samples, each of which has 49 features.&lt;/p>
&lt;h2 id="exploratory-data-analysis">Exploratory Data Analysis&lt;/h2>
&lt;p>The goal of this analysis is to assess the cleanliness and consistency of the data in order to engineer features that can be used to &lt;strong>train a predictor of accident severity&lt;/strong>. To this end, we systematically explore the features and their relationships with other features using both summary statistics and visualizations. Please see the Google Colab notebook for further EDA.&lt;/p>
&lt;h2 id="machine-learning">Machine Learning&lt;/h2>
&lt;p>Under the scope of this project, we chose to perform our severity prediction for Pennsylvania state. Given that this is a multi-class classification problem, we have several algorithms to consider. Let&amp;rsquo;s look at each of them and see how they perform with the PA subset.&lt;/p>
&lt;table>
&lt;thead>
&lt;tr>
&lt;th>ML Method&lt;/th>
&lt;th>Accuracy&lt;/th>
&lt;th>Training Time&lt;/th>
&lt;/tr>
&lt;/thead>
&lt;tbody>
&lt;tr>
&lt;td>&lt;code>Logistic Regression&lt;/code>&lt;/td>
&lt;td>80.6%&lt;/td>
&lt;td>3min 41s&lt;/td>
&lt;/tr>
&lt;tr>
&lt;td>&lt;code>K-Nearest Neighbor&lt;/code>&lt;/td>
&lt;td>75.9%&lt;/td>
&lt;td>0min 11s&lt;/td>
&lt;/tr>
&lt;tr>
&lt;td>&lt;code>Decision Tree&lt;/code>&lt;/td>
&lt;td>86.6%&lt;/td>
&lt;td>0min 5s&lt;/td>
&lt;/tr>
&lt;tr>
&lt;td>&lt;code>Random Forest&lt;/code>&lt;/td>
&lt;td>89.7%&lt;/td>
&lt;td>27min 37s&lt;/td>
&lt;/tr>
&lt;tr>
&lt;td>&lt;code>AdaBoost&lt;/code>&lt;/td>
&lt;td>79.7%&lt;/td>
&lt;td>1min 48s&lt;/td>
&lt;/tr>
&lt;tr>
&lt;td>&lt;code>XGBoost&lt;/code>&lt;/td>
&lt;td>92.0%&lt;/td>
&lt;td>57min 22s&lt;/td>
&lt;/tr>
&lt;tr>
&lt;td>&lt;code>LightGBM&lt;/code>&lt;/td>
&lt;td>91.3%&lt;/td>
&lt;td>0min 55s&lt;/td>
&lt;/tr>
&lt;/tbody>
&lt;/table>
&lt;p>XGBoost is the winner here. XGBoost is a gradient boosting method, one of the best algorithms for classification problems. It handles large sized datasets very well with good execution speed. It can automatically handle missing values and apply regularized boosting method, thus it&amp;rsquo;s less prone to overfitting. It also does pruning for you. As a matter of fact, XGBoost is a frequent winner in a lot of Kaggle competitions.&lt;/p>
&lt;p>Come very close is LightGBM. Light GBM is a fast, distributed, high-performance gradient boosting framework based on decision tree algorithm. It is capable of performing equally good with large datasets with a significant reduction in training time as compared to XGBoost.&lt;/p>
&lt;h2 id="deep-learning">Deep Learning&lt;/h2>
&lt;p>We attempt to predict the level of severity using the accident descriptions. We will use a Long Short Term Memory (LSTM) recurrent neural net (RNN) model for this task.&lt;/p>
&lt;h4 id="lstm-introduction">LSTM Introduction&lt;/h4>
&lt;p>The accident description is a form of sequential information. Intuitively, RNNs have memory that &amp;ldquo;captures&amp;rdquo; what have been calculated so far i.e. what happened in the last sentence will impact what happened in the next sentense. We then use these information to predict the &amp;ldquo;label&amp;rdquo; of the accident severity, i.e. category level 1 through 4. The architecture of the recurrent neural networks is below:&lt;/p>
&lt;figure id="figure-rnn-architecture">
&lt;a data-fancybox="" href="https://dat-nguyen.netlify.app/media/rnn1.png" data-caption="RNN Architecture">
&lt;img src="https://dat-nguyen.netlify.app/media/rnn1.png" alt="" >
&lt;/a>
&lt;figcaption>
RNN Architecture
&lt;/figcaption>
&lt;/figure>
&lt;p>A chunk of neural network, &amp;ldquo;A&amp;rdquo;, looks at some input x(t) and outputs a value h(t). X(t) could be a word or a sentence, and h(t) is the probability of the next word or next sentence.&lt;/p>
&lt;p>So how does that relate to our task of predicting accident severity given the description?&lt;/p>
&lt;ul>
&lt;li>We input a word or words of the description to the model&lt;/li>
&lt;li>At the end of each description, we give the model the label i.e. the severity category value&lt;/li>
&lt;li>RNNs, by passing input from last output, are able to retain information and able to leverage all these information at the end to make a severity prediction given a new accident description.&lt;/li>
&lt;/ul>
&lt;p>This works well for short descriptions but when we have to deal with a long descriptions, there will be a long term dependency problem. Therefore, we generally do not use vanilla RNNs, and we use Long Short Term Memory instead.&lt;/p>
&lt;p>LSTM is a type of RNNs that can solve the long term dependency problem.&lt;/p>
&lt;figure id="figure-different-lstm">
&lt;a data-fancybox="" href="https://dat-nguyen.netlify.app/media/rnn2.png" data-caption="Different LSTM">
&lt;img src="https://dat-nguyen.netlify.app/media/rnn2.png" alt="" >
&lt;/a>
&lt;figcaption>
Different LSTM
&lt;/figcaption>
&lt;/figure>
&lt;p>For this classification problem, we will use the many-to-one relationship model. The input are sequences of words, and the output is one single label, the accident severity.&lt;/p>
&lt;h4 id="model-training">Model Training&lt;/h4>
&lt;ul>
&lt;li>The first layer is the embedded layer that uses 100 length vectors to represent each word.&lt;/li>
&lt;li>The next layer is the LSTM layer with 100 memory units.&lt;/li>
&lt;li>The output layer creates 4 output values, one for each category.&lt;/li>
&lt;li>Activation function is softmax for multi-class classification.&lt;/li>
&lt;li>Because it is a multi-class classification problem, categorical_crossentropy is used as the loss function.&lt;/li>
&lt;li>We use Adam optimization, which is an adaptive learning rate optimization algorithm that&amp;rsquo;s been designed specifically for training deep neural networks.&lt;/li>
&lt;li>We also implement 2 regularization methods to prevent overfitting, which are dropout (at 20%) and early stopping.&lt;/li>
&lt;/ul>
&lt;pre>&lt;code>Epoch 1/10
633/633 [==============================] - 1076s 2s/step - loss: 0.3712 - accuracy: 0.8764 - val_loss: 0.2969 - val_accuracy: 0.9033
Epoch 2/10
633/633 [==============================] - 1091s 2s/step - loss: 0.2867 - accuracy: 0.9077 - val_loss: 0.2827 - val_accuracy: 0.9062
Epoch 3/10
633/633 [==============================] - 1076s 2s/step - loss: 0.2769 - accuracy: 0.9095 - val_loss: 0.2809 - val_accuracy: 0.9062
Epoch 4/10
633/633 [==============================] - 1073s 2s/step - loss: 0.2726 - accuracy: 0.9101 - val_loss: 0.2785 - val_accuracy: 0.9062
Epoch 5/10
633/633 [==============================] - 1073s 2s/step - loss: 0.2688 - accuracy: 0.9105 - val_loss: 0.2765 - val_accuracy: 0.9073
Epoch 6/10
633/633 [==============================] - 1071s 2s/step - loss: 0.2655 - accuracy: 0.9105 - val_loss: 0.2757 - val_accuracy: 0.9076
Epoch 7/10
633/633 [==============================] - 1071s 2s/step - loss: 0.2635 - accuracy: 0.9112 - val_loss: 0.2767 - val_accuracy: 0.9071
Epoch 8/10
633/633 [==============================] - 1073s 2s/step - loss: 0.2626 - accuracy: 0.9118 - val_loss: 0.2693 - val_accuracy: 0.9087
Epoch 9/10
633/633 [==============================] - 1074s 2s/step - loss: 0.2597 - accuracy: 0.9115 - val_loss: 0.2698 - val_accuracy: 0.9089
Epoch 10/10
633/633 [==============================] - 1073s 2s/step - loss: 0.2584 - accuracy: 0.9125 - val_loss: 0.2716 - val_accuracy: 0.9076
&lt;/code>&lt;/pre>
&lt;p>Using just 50,000 sample records (over 3.5 millions available records), we can achieve an accuracy of 91.1% with recurrent neural nets. This already beats almost all of our classical ML models. The downside is that it takes a long time to train our LSTM model.&lt;/p></description></item></channel></rss>