<?xml version="1.0" encoding="utf-8" standalone="yes"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:content="http://purl.org/rss/1.0/modules/content/">
  <channel>
    <title>Hemendra Singh Rajawat</title>
    <link>https://hemendra.in/</link>
    <description>Recent content on Hemendra Singh Rajawat</description>
    <generator>Hugo -- 0.154.0</generator>
    <language>en-us</language>
    <lastBuildDate>Fri, 02 Jan 2026 08:31:14 +0000</lastBuildDate>
    <atom:link href="https://hemendra.in/index.xml" rel="self" type="application/rss+xml" />
    <item>
      <title>Main Challenges of Machine Learning</title>
      <link>https://hemendra.in/blog/main-challenges-machine-learning/</link>
      <pubDate>Mon, 13 Mar 2023 17:58:45 +0000</pubDate>
      <guid>https://hemendra.in/blog/main-challenges-machine-learning/</guid>
      <description>Since the main task in machine learning is to select a model and train it on some data, the two things that can go wrong are &amp;#39;bad model&amp;#39; and &amp;#39;bad data&amp;#39;.</description>
      <content:encoded><![CDATA[<h2 id="introduction">Introduction</h2>
<p>In this blog, we will be going over the below 6 main challenges of Machine Learning:</p>
<ul>
<li>Insufficient quantity of training data</li>
<li>Non-representative training data</li>
<li>Poor quality data</li>
<li>Irrelevant Features</li>
<li>Overfitting the training data</li>
<li>Underfitting the training data</li>
</ul>
<h2 id="insufficient-quantity-of-training-data">Insufficient Quantity of Training Data</h2>
<p>To teach a toddler what a apple is, all it takes is for you to point to a apple and say &ldquo;apple&rdquo; or sometimes repeating this procedure a few times. Now the child is able to recognize apple in all sorts of colors and shapes.</p>
<p>Machine learning is not quite there yet; it takes a lot of data for most machine learning algorithms to work. Even for very simple tasks you typically need thousands of examples, and for complex tasks such as image or speech recognition, you may need millions of examples.</p>
<p>As shown in a famous paper &ldquo;<a href="https://dl.acm.org/doi/10.3115/1073012.1073017" target="_blank">Scaling to very very large corpora for natural language disambiguation</a>&rdquo; that even fairly simple machine learning algorithms performed almost identically well on a complex problem of natural language disambiguation, once they were given enough data (as you can see in below Figure 1).</p>
<figure>
    <img src="/blog/main_challenges_of_machine_learning/importance_of_data_vs_algo.png" width="550" style="margin: 0 auto;"/>
    <figcaption align="center">Figure 1. The importance of data versus alogrithms. <a href="https://dl.acm.org/doi/10.3115/1073012.1073017" target="_blank">Source</a></figcaption>
<figure>
<blockquote>
<p>As the author put it, &ldquo;these results suggest that we may want to reconsider the trade-off between spending time and money on algorithm development versus spending it on corpus development&rdquo;.</p>
</blockquote>
<h2 id="nonrepresentative-training-data">Nonrepresentative Training Data</h2>
<p>In order to generalize well, it is crucial that your training data be representative of the new cases you want to generalize to. This is true whether you use instance-based learning or model-based learning.</p>
<p>Having training set that is representative of the cases you want to generalize to is often harder than it sounds: if the sample if too small, you will have sampling noise, but even very large samples can be nonrepresentative if the sampling method is flawed. This is called sampling bias.</p>
<h2 id="poor-quality-data">Poor-Quality Data</h2>
<p>If your training data is full of errors, outliers, and noise, it will make it harder for the system to detect the underlying patterns, so your system is less likely to perform well. It is often well worth the effort to spend time cleaning up your training data. The truth is, most data scientists spend a significant part of their time doing just that.</p>
<p>The following are a couple examples of when you&rsquo;d want to clean up training data:</p>
<ul>
<li>If some instances are clearly outliers, it may help to simply discard them or try to fix the errors manually.</li>
<li>If some instances are missing a few features, you must decide whether you want to ignore this attribute altogether, ignore these instances, fill in missing values, or training one model with the features and one without it.</li>
</ul>
<h2 id="irrelevant-features">Irrelevant Features</h2>
<p>Your system will only be capable of learning if training data contains enough relevant features and not too many irrelevant ones. A critical part of the success of a machine learning project is coming up with a good set of features to train on.</p>
<p>This process, called feature engineering, involves the following steps:</p>
<ul>
<li><em>Feature selection</em> (selecting the most useful features to train on among existing features)</li>
<li><em>Feature extraction</em> (combining existing features to produce a more useful one)</li>
<li>Creating new features by gathering new data</li>
</ul>
<h2 id="overfitting-the-training-data">Overfitting the Training Data</h2>
<p>Overgeneralizing is something that we humans do all that often, and unfortunately machines can fall into the same trap if we are not careful. In machine learning, this is called overfitting: it means that the model performs well on the training data, but it does not generalize well.</p>
<p>Complex models such as deep neural networks can detect subtle pattterns in the data, but if the training set is noisy, or if it is too small, which introduces sampling noise, then the model is likely to detect patterns in the noise itself.</p>
<p>Overfitting happens when the model is too complex relative to the amount and noisiness of the training data. Here are possible solutions:</p>
<ul>
<li>Simplify the model by selecting one with fewer parameters, by reducing the number of attributes in the training data, or by constraining the model</li>
<li>Gather mode training data</li>
<li>Reduce the noise in the training data</li>
</ul>
<h2 id="underfitting-the-training-data">Underfitting the Training Data</h2>
<p>Underfitting occurs when your model is too simple to learn the underlying structure of the data. For example, a linear model is used to train on image classification; data is just more comples than the model, so its predictions are bound to be inaccurate, even on training examples.</p>
<p>Below are the options for fixing this problem:</p>
<ul>
<li>Select a more powerful model, with more parameters</li>
<li>Feed better features to the learning algorithms</li>
<li>Reduce the constraints on the model</li>
</ul>
<h2 id="references">References</h2>
<ol>
<li>Géron, A. (2022). Hands-On Machine Learning with Scikit-Learn, Keras, and TensorFlow: Concepts, Tools, and Techniques to Build Intelligent Systems. Japan: O&rsquo;Reilly Media.</li>
</ol>
]]></content:encoded>
    </item>
    <item>
      <title>Machine Learning Landscape</title>
      <link>https://hemendra.in/blog/machine-learning-landscape/</link>
      <pubDate>Sat, 11 Mar 2023 12:14:48 +0000</pubDate>
      <guid>https://hemendra.in/blog/machine-learning-landscape/</guid>
      <description>This blog introduces a lot of fundamental concepts (and jargons) that every data scientist should know by heart.</description>
      <content:encoded><![CDATA[<p>The first ML application that really became mainstream, improving the lives of hundereds of millions of people, took over the world back in 1990s: the spam filter.</p>
<h2 id="what-is-machine-learning">What is Machine Learning?</h2>
<p>Machine learning is the science (and art) of programming computers so they can learn from data.</p>
<p>More general definition:</p>
<blockquote>
<p>[Machine learning is the] field of study that gives computers the ability to learn without being explicitly programmed.</p>
<p>&ndash; <cite>Arthur Samuel, 1959</cite></p>
</blockquote>
<p>The examples that the system uses to learn are called the training set. Each training example is called a training instance (or sample). The part of a machine learning that learns and makes predictions is called a model. Neural networks and random forests are example of models.</p>
<h2 id="traditional-vs-machine-learning-approach">Traditional vs Machine Learning Approach</h2>
<p>In traditional programs, a developer designs logic or algorithms to solve a problem (Figure 1). The program applies this logic to input and computes the output.</p>
<p><img alt="Traditional Approach" loading="lazy" src="/blog/machine-learning-landscape/traditional_approach.png"></p>
<figcaption align="center">Figure 1. The traditional approach</figcaption>
<br/>
<p>But in machine learning, a model is built from the data, and that model is the logic (Figure 2). ML programs have two distict phases: Training and Inference.</p>
<p><img alt="Machine Learning Approach" loading="lazy" src="/blog/machine-learning-landscape/machine_learning_approach.png"></p>
<figcaption align="center">Figure 2. The machine learning approach</figcaption>
<h2 id="why-use-machine-learning">Why use Machine Learning?</h2>
<p>Machine learning is great for:</p>
<ul>
<li>Problems for which existing solutions require a lot of fine-tuining or long lists of rules</li>
<li>Complex problems for which using a traditional approach yields no good solution</li>
<li>Fluctuating evironments (a machine learning system can easily be retrained on new data, always keeping it up to date)</li>
<li>Getting insights about complex problems and large amounts of data</li>
</ul>
<p><em>Digging into large amounts of data to discover hidden patterns is called data mining, and machine learning excels at it.</em></p>
<h2 id="few-examples-of-applications">Few Examples of Applications</h2>
<p>Let&rsquo;s look at some concrete examples of machine learning tasks, along with the techniques that can tackle them. This will give you a sense of the incredible breadth and complexity of the tasks that machine learning can easily tackle.</p>
<ul>
<li><em>Analzing images of products on a production</em> <br/>
This is image classificaiton, typically performed using CNNs or sometime transformers</li>
<li><em>Detecting tumors in brain scans</em> <br/>
This is semantic image segmentation, using CNNs or transformers</li>
<li><em>Automatically flagging offensive comments on discussion fourms</em> <br/>
This is natural language processing (NLP), and more specifically text classification, which can be tackled using RNNs and CNNs</li>
<li><em>Making your app react to voice commands</em> <br/>
This is speech recognition, which requires processing audio samples: since they are long and complex sequences, they are typically processed using RNNs, CNNs, or transformers</li>
<li><em>Detecting credit card fraud</em> <br/>
This is anomly detection, which can be tackled using isolation forests, Gaussian mixture models, or autoencoders</li>
<li><em>Recommending a product that a client may be interested in, based on past purchases</em> <br/>
This is a recommender system</li>
<li><em>Building an intelligent bot for a game</em> <br/>
This is often tackled using reinforcement learning, which is a branch of machine learning that trains agent to pick the actions that will maximize the rewards over time, within a given environment</li>
</ul>
<h2 id="types-of-machine-learning-systems">Types of Machine Learning Systems</h2>
<p>There are so many differents types of machine learning systems that it is useful to classify them in broad categories, based on the following criteria:</p>
<ul>
<li>How they are supervised during training (training supervision)</li>
<li>Whether or not they can learn incrementally on the fly (online vs batch learning)</li>
<li>Whether they can work by simply comparing new data points to known data points, or instead by detecting a predictive model (instance-based vs model-based learning)</li>
</ul>
<p>These criteria are not exclusive, you can combine them in any way you like. For example, a state-of-the-art spam filter can be an online, model-based, supervised learning system.</p>
<p>Let&rsquo;s look at each one of these categoies a bit more closely.</p>
<h3 id="training-supervision">Training Supervision</h3>
<p>ML systems can be classifed according to the amount and type of supervision they get during training. There are many categories, but we will discuss the main ones:</p>
<h4 id="supervised-learning">Supervised learning</h4>
<p>The training set you feed to the algorithm includes the desired solutions, called labels. A typical supervised learning task is classification.</p>
<h4 id="unsupervised-learning">Unsupervised learning</h4>
<p>The training data is unlabeled and the system tries to learn without a teacher. Visualization alogrithms, anomaly detection, and dimensionality reduction are few examples of unsupervised learning.</p>
<h4 id="semi-supervised-learning">Semi-supervised learning</h4>
<p>Since labeling data is usually time-consuming and costly, you will often have plenty of unlabeled instances, and few labeled instances. Some algorithms can deal with data that&rsquo;s partially labeled. Most semi-supervised learning algorithms are combinations of unsupervised and supervised algorithms.</p>
<p>Some photo-hosting services, such as Google Photos, are good examples of this. Once you upload all your family photos, it automatically recognizes people in multiple photos, and group them, so you can add one label per person and it is able to name everyone in every photo.</p>
<h4 id="self-supervised-learning">Self-supervised learning</h4>
<p>Another approach to machine learning involves actually generating a fully labeled dataset from a fully unlabeled one. Again, once the whole dataset is labeled, any supervised learning can be used. This appraoch is called self-supervised learning.</p>
<p><em>Transferring knowledge from one task to another is called transfer learning.</em></p>
<h4 id="reinforcement-learning">Reinforcement learning</h4>
<p>The learning system, called an agent in this context, can observe the environment, select and perform actions, get rewards or penalties in return. It must then learn by itself what is the best strategy, called a policy, to get the most reward over time. A policy defines what action the agent should choose when it is in a given situation.</p>
<h3 id="batch-vs-online-learning">Batch vs Online Learning</h3>
<h4 id="batch-learning">Batch learning</h4>
<p>In batch learning, the system is incapable of learning incrementally: it must be trained using all the available data. This will generally take a lot of time and computing resources, so it is typically done offline.</p>
<p>First the system is trained, and then it is launced into production and runs without learning anymore; it just applies what it has learned.</p>
<h4 id="online-learning">Online learning</h4>
<p>In online learning, you train the system incrementally by feeding it data instances sequentially, either individually or in small groups called mini-batches. Each learning step is fast and cheap, so the system can learn about new data on the fly, as it arrives.</p>
<p>A big challenge with online learning is that if bad data is fed to the system, the system&rsquo;s performance will decline, possibly quickly (depending on the data quality and learning rate).</p>
<h3 id="instance-based-vs-model-based-learning">Instance-Based vs Model-Based Learning</h3>
<h4 id="instance-based-learning">Instance-based learning</h4>
<p>The system learns the examples by heart, then generalizes to new cases by using a similarity measure to compare them to the learned examples.</p>
<h4 id="model-based-learning">Model-based learning</h4>
<p>Another way to generalize from a set of examples is to build a model of these examples and then use that model to make <em>predictions</em>.</p>
<p>Model selection consists in choosing the type of model and fully specifying its architecture. Training a model means running an algorithm to find the model parameters, that will make it best fit the training data, and hopefully make good predictions on new data.</p>
<h2 id="summary">Summary</h2>
<p>Machine learning is about making machines get better at some task by learning from data, instead of having to explicity code rules.
There are so many different types of ML systems: supervised or not, batch or online, instance-based or model-based.</p>
]]></content:encoded>
    </item>
    <item>
      <title>Pizza vs Ice-cream Classifier</title>
      <link>https://hemendra.in/projects/pizza-vs-icecream/</link>
      <pubDate>Wed, 14 Sep 2022 12:08:31 +0000</pubDate>
      <guid>https://hemendra.in/projects/pizza-vs-icecream/</guid>
      <description>&lt;p&gt;A Deep Learning Vision Classifier built on Tensorflow to classify the provided image between ice cream 🍨 and pizza 🍕.
This is a simple exercise to start with machine learning. You can check the app at: &lt;a href=&#34;https://pizza-vs-icecream.streamlitapp.com/&#34;&gt;https://pizza-vs-icecream.streamlitapp.com/&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;In this project, we will be looking at the dataset journey(from gathering to preparation), and then will jump into the python code for creating the model, the FlaskAPI backend, and Streamlit python code.&lt;/p&gt;
&lt;h2 id=&#34;dataset&#34;&gt;Dataset&lt;/h2&gt;
&lt;p&gt;The dataset used is hosted on &lt;a href=&#34;https://www.kaggle.com/datasets/hemendrasr/pizza-vs-ice-cream&#34;&gt;Kaggle&lt;/a&gt;, and the data was captured from &lt;a href=&#34;https://www.freepik.com/&#34;&gt;Freepik&lt;/a&gt; using python script. Once the data was captured, &lt;a href=&#34;https://roboflow.com&#34;&gt;Roboflow&lt;/a&gt; was used to organize and annotate. Roboflow can be used for more advanced features like augmentation, pre-processing, getting more examples, and exporting the data in different formats.&lt;/p&gt;</description>
      <content:encoded><![CDATA[<p>A Deep Learning Vision Classifier built on Tensorflow to classify the provided image between ice cream 🍨 and pizza 🍕.
This is a simple exercise to start with machine learning. You can check the app at: <a href="https://pizza-vs-icecream.streamlitapp.com/">https://pizza-vs-icecream.streamlitapp.com/</a></p>
<p>In this project, we will be looking at the dataset journey(from gathering to preparation), and then will jump into the python code for creating the model, the FlaskAPI backend, and Streamlit python code.</p>
<h2 id="dataset">Dataset</h2>
<p>The dataset used is hosted on <a href="https://www.kaggle.com/datasets/hemendrasr/pizza-vs-ice-cream">Kaggle</a>, and the data was captured from <a href="https://www.freepik.com/">Freepik</a> using python script. Once the data was captured, <a href="https://roboflow.com">Roboflow</a> was used to organize and annotate. Roboflow can be used for more advanced features like augmentation, pre-processing, getting more examples, and exporting the data in different formats.</p>
<p>I exported the data in folder format which was able to give me the data in the below format:
<img src="/projects/pizza-vs-icecream/dataset-folder-structure.png" alt="Dataset folder structure" width="200"/></p>
<p>The dataset consists of around 1300 images. 718 images for training, 208 images for validation, and 106 images for testing.</p>
<h2 id="python-logic-for-model-creation">Python Logic for Model Creation</h2>
<p>The full code is accessible on GitHub through this <a href="https://github.com/hemendrarajawat/pizza-vs-icecream/blob/main/train_script.ipynb">link</a>. But we will go over the important points in this article.</p>
<h3 id="import-library">Import Library</h3>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-python" data-lang="python"><span style="display:flex;"><span><span style="color:#f92672">import</span> os
</span></span><span style="display:flex;"><span><span style="color:#f92672">import</span> math
</span></span><span style="display:flex;"><span><span style="color:#f92672">import</span> numpy <span style="color:#66d9ef">as</span> np
</span></span><span style="display:flex;"><span><span style="color:#f92672">import</span> matplotlib.pyplot <span style="color:#66d9ef">as</span> plt
</span></span><span style="display:flex;"><span><span style="color:#f92672">import</span> tensorflow <span style="color:#66d9ef">as</span> tf
</span></span><span style="display:flex;"><span><span style="color:#f92672">import</span> tensorflow_hub <span style="color:#66d9ef">as</span> hub
</span></span><span style="display:flex;"><span><span style="color:#f92672">from</span> tensorflow.keras <span style="color:#f92672">import</span> layers
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>print(tf<span style="color:#f92672">.</span>__version__)
</span></span></code></pre></div><h3 id="loading-data">Loading Data</h3>
<p>We have loaded the data using <code>ImageDataGenerator</code> with multiple augmentation layers as our dataset is quite small, with only 718 images for training.</p>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-python" data-lang="python"><span style="display:flex;"><span>train_datagen <span style="color:#f92672">=</span> tf<span style="color:#f92672">.</span>keras<span style="color:#f92672">.</span>preprocessing<span style="color:#f92672">.</span>image<span style="color:#f92672">.</span>ImageDataGenerator(
</span></span><span style="display:flex;"><span>    rescale<span style="color:#f92672">=</span><span style="color:#ae81ff">1.</span><span style="color:#f92672">/</span><span style="color:#ae81ff">255</span>,
</span></span><span style="display:flex;"><span>    rotation_range<span style="color:#f92672">=</span><span style="color:#ae81ff">40</span>,
</span></span><span style="display:flex;"><span>    width_shift_range<span style="color:#f92672">=</span><span style="color:#ae81ff">0.2</span>,
</span></span><span style="display:flex;"><span>    height_shift_range<span style="color:#f92672">=</span><span style="color:#ae81ff">0.2</span>,
</span></span><span style="display:flex;"><span>    shear_range<span style="color:#f92672">=</span><span style="color:#ae81ff">0.2</span>,
</span></span><span style="display:flex;"><span>    zoom_range<span style="color:#f92672">=</span><span style="color:#ae81ff">0.2</span>,
</span></span><span style="display:flex;"><span>    fill_mode<span style="color:#f92672">=</span><span style="color:#e6db74">&#39;nearest&#39;</span>,
</span></span><span style="display:flex;"><span>    horizontal_flip<span style="color:#f92672">=</span><span style="color:#66d9ef">True</span>,
</span></span><span style="display:flex;"><span>)
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>train_generator <span style="color:#f92672">=</span> train_datagen<span style="color:#f92672">.</span>flow_from_directory(
</span></span><span style="display:flex;"><span>    TRAIN_DIR,
</span></span><span style="display:flex;"><span>    target_size<span style="color:#f92672">=</span>(IMG_SIZE, IMG_SIZE),
</span></span><span style="display:flex;"><span>    batch_size<span style="color:#f92672">=</span>BATCH_SIZE,
</span></span><span style="display:flex;"><span>    class_mode<span style="color:#f92672">=</span><span style="color:#e6db74">&#39;sparse&#39;</span>
</span></span><span style="display:flex;"><span>)
</span></span></code></pre></div><pre tabindex="0"><code class="language-output" data-lang="output">Found 718 images belonging to 2 classes.
</code></pre><div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-python" data-lang="python"><span style="display:flex;"><span>val_datagen <span style="color:#f92672">=</span> tf<span style="color:#f92672">.</span>keras<span style="color:#f92672">.</span>preprocessing<span style="color:#f92672">.</span>image<span style="color:#f92672">.</span>ImageDataGenerator(
</span></span><span style="display:flex;"><span>    rescale<span style="color:#f92672">=</span><span style="color:#ae81ff">1.</span><span style="color:#f92672">/</span><span style="color:#ae81ff">255</span>
</span></span><span style="display:flex;"><span>)
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>val_generator <span style="color:#f92672">=</span> val_datagen<span style="color:#f92672">.</span>flow_from_directory(
</span></span><span style="display:flex;"><span>    VAL_DIR,
</span></span><span style="display:flex;"><span>    target_size<span style="color:#f92672">=</span>(IMG_SIZE, IMG_SIZE),
</span></span><span style="display:flex;"><span>    batch_size<span style="color:#f92672">=</span>BATCH_SIZE,
</span></span><span style="display:flex;"><span>    class_mode<span style="color:#f92672">=</span><span style="color:#e6db74">&#39;sparse&#39;</span>
</span></span><span style="display:flex;"><span>)
</span></span></code></pre></div><pre tabindex="0"><code class="language-output" data-lang="output">Found 208 images belonging to 2 classes.
</code></pre><div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-python" data-lang="python"><span style="display:flex;"><span>test_datagen <span style="color:#f92672">=</span> tf<span style="color:#f92672">.</span>keras<span style="color:#f92672">.</span>preprocessing<span style="color:#f92672">.</span>image<span style="color:#f92672">.</span>ImageDataGenerator(
</span></span><span style="display:flex;"><span>    rescale<span style="color:#f92672">=</span><span style="color:#ae81ff">1.</span><span style="color:#f92672">/</span><span style="color:#ae81ff">255</span>
</span></span><span style="display:flex;"><span>)
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>test_generator <span style="color:#f92672">=</span> test_datagen<span style="color:#f92672">.</span>flow_from_directory(
</span></span><span style="display:flex;"><span>    TEST_DIR,
</span></span><span style="display:flex;"><span>    target_size<span style="color:#f92672">=</span>(IMG_SIZE, IMG_SIZE),
</span></span><span style="display:flex;"><span>    batch_size<span style="color:#f92672">=</span>BATCH_SIZE,
</span></span><span style="display:flex;"><span>    class_mode<span style="color:#f92672">=</span><span style="color:#e6db74">&#39;sparse&#39;</span>
</span></span><span style="display:flex;"><span>)
</span></span></code></pre></div><pre tabindex="0"><code class="language-output" data-lang="output">Found 106 images belonging to 2 classes.
</code></pre><h3 id="data-visualization">Data Visualization</h3>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-python" data-lang="python"><span style="display:flex;"><span>show_examples(train_generator)
</span></span></code></pre></div><pre tabindex="0"><code class="language-output" data-lang="output">IMAGE SHAPE:  (480, 480, 3)
</code></pre><blockquote>
<p><img loading="lazy" src="/projects/pizza-vs-icecream/train-data-visualization.png"></p>
</blockquote>
<p>Now let&rsquo;s jump over the model architecture and see how we smartly used the pre-trained model as a feature extractor.</p>
<h3 id="model-architecture">Model Architecture</h3>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-python" data-lang="python"><span style="display:flex;"><span>FEATURE_EXTRACTOR_URL <span style="color:#f92672">=</span> <span style="color:#e6db74">&#39;https://tfhub.dev/google/imagenet/efficientnet_v2_imagenet21k_ft1k_m/feature_vector/2&#39;</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>model <span style="color:#f92672">=</span> tf<span style="color:#f92672">.</span>keras<span style="color:#f92672">.</span>Sequential([
</span></span><span style="display:flex;"><span>    hub<span style="color:#f92672">.</span>KerasLayer(FEATURE_EXTRACTOR_URL, trainable<span style="color:#f92672">=</span><span style="color:#66d9ef">False</span>, input_shape<span style="color:#f92672">=</span>(IMG_SIZE, IMG_SIZE, <span style="color:#ae81ff">3</span>)),
</span></span><span style="display:flex;"><span>    layers<span style="color:#f92672">.</span>Dense(<span style="color:#ae81ff">2</span>, activation<span style="color:#f92672">=</span><span style="color:#e6db74">&#39;softmax&#39;</span>)
</span></span><span style="display:flex;"><span>])
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>model<span style="color:#f92672">.</span>summary()
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>model<span style="color:#f92672">.</span>compile(
</span></span><span style="display:flex;"><span>    optimizer<span style="color:#f92672">=</span><span style="color:#e6db74">&#39;adam&#39;</span>,
</span></span><span style="display:flex;"><span>    loss<span style="color:#f92672">=</span><span style="color:#e6db74">&#39;sparse_categorical_crossentropy&#39;</span>,
</span></span><span style="display:flex;"><span>    metrics<span style="color:#f92672">=</span>[<span style="color:#e6db74">&#39;accuracy&#39;</span>]
</span></span><span style="display:flex;"><span>)
</span></span></code></pre></div><pre tabindex="0"><code class="language-output" data-lang="output">Model: &#34;sequential&#34;
_________________________________________________________________
 Layer (type)                Output Shape              Param #   
=================================================================
 keras_layer (KerasLayer)    (None, 1280)              53150388  
                                                                 
 dense (Dense)               (None, 2)                 2562      
                                                                 
=================================================================
Total params: 53,152,950
Trainable params: 2,562
Non-trainable params: 53,150,388
_________________________________________________________________
</code></pre><p>As we have fewer training images with drastic differences b/w images such as color, size, people, placement &amp; amount of target items, it is a quite time-consuming and complex task to train the model from scratch. That&rsquo;s why it&rsquo;s a best practice to check if a pre-trained model can be utilized.</p>
<p>After multiple iterations of custom model architecture, we have used the &lsquo;EfficientNet V2&rsquo; model from <a href="https://tfhub.dev">TensorFlow Hub</a> which was trained on imagenet-21k (Full ImageNet, Fall 2011 release) and fine-tuned on ImageNet1K as a feature extractor and a single dense layer which is used as output layer having 2 nodes defining 2 classes in the dataset.</p>
<h3 id="model-training">Model Training</h3>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-python" data-lang="python"><span style="display:flex;"><span>SAVED_MODEL_PATH <span style="color:#f92672">=</span> <span style="color:#e6db74">&#39;./models/pizza_vs_icecream_model.h5&#39;</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>model_checkpoint <span style="color:#f92672">=</span> tf<span style="color:#f92672">.</span>keras<span style="color:#f92672">.</span>callbacks<span style="color:#f92672">.</span>ModelCheckpoint(
</span></span><span style="display:flex;"><span>    SAVED_MODEL_PATH,
</span></span><span style="display:flex;"><span>    monitor<span style="color:#f92672">=</span><span style="color:#e6db74">&#39;val_loss&#39;</span>,
</span></span><span style="display:flex;"><span>    save_best_only<span style="color:#f92672">=</span><span style="color:#66d9ef">True</span>
</span></span><span style="display:flex;"><span>)
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>early_stopping <span style="color:#f92672">=</span> tf<span style="color:#f92672">.</span>keras<span style="color:#f92672">.</span>callbacks<span style="color:#f92672">.</span>EarlyStopping(
</span></span><span style="display:flex;"><span>    monitor<span style="color:#f92672">=</span><span style="color:#e6db74">&#39;val_loss&#39;</span>,
</span></span><span style="display:flex;"><span>    patience<span style="color:#f92672">=</span><span style="color:#ae81ff">5</span>
</span></span><span style="display:flex;"><span>)
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>history <span style="color:#f92672">=</span> model<span style="color:#f92672">.</span>fit(
</span></span><span style="display:flex;"><span>    train_generator,
</span></span><span style="display:flex;"><span>    steps_per_epoch<span style="color:#f92672">=</span>len(train_generator),
</span></span><span style="display:flex;"><span>    epochs<span style="color:#f92672">=</span><span style="color:#ae81ff">50</span>,
</span></span><span style="display:flex;"><span>    validation_data<span style="color:#f92672">=</span>val_generator,
</span></span><span style="display:flex;"><span>    validation_steps<span style="color:#f92672">=</span>len(val_generator),
</span></span><span style="display:flex;"><span>    callbacks<span style="color:#f92672">=</span>[model_checkpoint, early_stopping],
</span></span><span style="display:flex;"><span>    verbose<span style="color:#f92672">=</span><span style="color:#ae81ff">2</span>
</span></span><span style="display:flex;"><span>)
</span></span></code></pre></div><pre tabindex="0"><code class="language-output" data-lang="output">Epoch 1/50
23/23 - 52s - loss: 0.3017 - accuracy: 0.8900 - val_loss: 0.0705 - val_accuracy: 0.9952 - 52s/epoch - 2s/step
Epoch 2/50
23/23 - 35s - loss: 0.0480 - accuracy: 0.9903 - val_loss: 0.0363 - val_accuracy: 0.9952 - 35s/epoch - 2s/step
Epoch 3/50
23/23 - 35s - loss: 0.0348 - accuracy: 0.9889 - val_loss: 0.0221 - val_accuracy: 1.0000 - 35s/epoch - 2s/step
.
.
.
Epoch 38/50
23/23 - 34s - loss: 0.0015 - accuracy: 1.0000 - val_loss: 0.0031 - val_accuracy: 1.0000 - 34s/epoch - 1s/step
Epoch 39/50
23/23 - 34s - loss: 0.0064 - accuracy: 0.9972 - val_loss: 0.0024 - val_accuracy: 1.0000 - 34s/epoch - 1s/step
Epoch 40/50
23/23 - 34s - loss: 0.0050 - accuracy: 0.9972 - val_loss: 0.0027 - val_accuracy: 1.0000 - 34s/epoch - 1s/step
</code></pre><p>And, definitely in our use case, the pre-trained model has worked wonderfully. Let&rsquo;s finally evaluate the model.</p>
<h3 id="model-evaluation">Model Evaluation</h3>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-python" data-lang="python"><span style="display:flex;"><span>saved_model <span style="color:#f92672">=</span> tf<span style="color:#f92672">.</span>keras<span style="color:#f92672">.</span>models<span style="color:#f92672">.</span>load_model(
</span></span><span style="display:flex;"><span>    SAVED_MODEL_PATH,
</span></span><span style="display:flex;"><span>    custom_objects<span style="color:#f92672">=</span>{<span style="color:#e6db74">&#39;KerasLayer&#39;</span>: hub<span style="color:#f92672">.</span>KerasLayer}
</span></span><span style="display:flex;"><span>)
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>saved_model<span style="color:#f92672">.</span>evaluate(test_generator)
</span></span></code></pre></div><pre tabindex="0"><code class="language-output" data-lang="output">4/4 [==============================] - 7s 1s/step - loss: 0.0043 - accuracy: 1.0000
Out[15]:
[0.004329057410359383, 1.0]
</code></pre><p>As the model is working flawlessly even on the test data which the model has never seen, it&rsquo;s time to take this model to production. Upload the saved model to Google Cloud, which will be used in the next section for building the backend services.</p>
<h2 id="flask-api-backend-code">Flask API Backend Code</h2>
<p>Python code for Flask API is straightforward and the detailed code can be accessible at <a href="https://github.com/hemendrarajawat/pizza-vs-icecream/blob/main/main.py">main.py</a>. We load the saved(Google Cloud) TensorFlow model once the Flask run initially and we get the <code>POST</code> request at the root level along with the image and first thing will be, pre-processing the received image.</p>
<p>The pre-processing steps include:</p>
<ol>
<li>Decoding the base64 image</li>
<li>Reading the image using <code>tf.io.decode_image(image, channels=3)</code></li>
<li>Resizing the image to match the image size used to train the model i.e., 480</li>
<li>Converting the image to array</li>
<li>And finally, normalize the image array by dividing it with 255.0</li>
</ol>
<p>After pre-processing, we ran the input image array through the model using <code>model.predict(input)</code> and get the output as probability of classes. Using this the high-probability class is identified and returned.</p>
<h2 id="front-end-streamlit-app">Front-End Streamlit App</h2>
<p>To make the model easier to use, let&rsquo;s build a <a href="http://streamlit.io/">Streamlit App</a>, which provides astonishing UI with little python code. The code is accessible at <a href="https://github.com/hemendrarajawat/pizza-vs-icecream/blob/main/app.py">app.py</a>.</p>
<p>The purpose of this python code is to provide the upload facility to users, so they can upload an image that will be encoded and sent to the Flask API for prediction. Once the result is returned from the API request, using Streamlit functions, we can show the result in very beautiful formats along with the uploaded images.</p>
<h2 id="final-connections-bw-streamlit-and-flask-api">Final Connections b/w Streamlit and Flask API</h2>
<p>The whole code was uploaded to GitHub and the Flask API code was uploaded to the Google Cloud Run functionality and the Streamlit app code was connected to the Streamlit app.</p>
<h2 id="results">Results</h2>
<h3 id="result-1">Result 1</h3>
<p><img loading="lazy" src="/projects/pizza-vs-icecream/pizza-vs-icecream_result1.png"></p>
<h3 id="result-2">Result 2</h3>
<p><img loading="lazy" src="/projects/pizza-vs-icecream/pizza-vs-icecream_result2.png"></p>
<h2 id="closing-note">Closing Note</h2>
<p>This was a fun project for me as the binary classification task was simple, but if we look at the whole project in a nutshell from data collection to taking the model to production with beautiful UI, it was a challenging task too.</p>
<blockquote>
<p><em>A great beginner-friendly project.</em></p>
</blockquote>
]]></content:encoded>
    </item>
  </channel>
</rss>
