<?xml version="1.0" encoding="UTF-8"?><rss xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:atom="http://www.w3.org/2005/Atom" version="2.0" xmlns:cc="http://cyber.law.harvard.edu/rss/creativeCommonsRssModule.html">
    <channel>
        <title><![CDATA[Stories by Bharath Raj on Medium]]></title>
        <description><![CDATA[Stories by Bharath Raj on Medium]]></description>
        <link>https://medium.com/@thatbrguy?source=rss-7d6e83a807b8------2</link>
        <image>
            <url>https://cdn-images-1.medium.com/fit/c/150/150/0*0iNUvZ5Z4MC85pAS.</url>
            <title>Stories by Bharath Raj on Medium</title>
            <link>https://medium.com/@thatbrguy?source=rss-7d6e83a807b8------2</link>
        </image>
        <generator>Medium</generator>
        <lastBuildDate>Sat, 04 Apr 2026 00:40:55 GMT</lastBuildDate>
        <atom:link href="https://medium.com/@thatbrguy/feed" rel="self" type="application/rss+xml"/>
        <webMaster><![CDATA[yourfriends@medium.com]]></webMaster>
        <atom:link href="http://medium.superfeedr.com" rel="hub"/>
        <item>
            <title><![CDATA[How to deploy ONNX models on NVIDIA Jetson Nano using DeepStream]]></title>
            <link>https://medium.com/data-science/how-to-deploy-onnx-models-on-nvidia-jetson-nano-using-deepstream-b2872b99a031?source=rss-7d6e83a807b8------2</link>
            <guid isPermaLink="false">https://medium.com/p/b2872b99a031</guid>
            <category><![CDATA[computer-vision]]></category>
            <category><![CDATA[artificial-intelligence]]></category>
            <category><![CDATA[iot]]></category>
            <category><![CDATA[machine-learning]]></category>
            <category><![CDATA[video-analytics]]></category>
            <dc:creator><![CDATA[Bharath Raj]]></dc:creator>
            <pubDate>Thu, 05 Dec 2019 05:38:19 GMT</pubDate>
            <atom:updated>2019-12-05T05:38:19.412Z</atom:updated>
            <content:encoded><![CDATA[<h4>An experiment to test the multi-stream neural network inference performance of DeepStream on Jetson Nano.</h4><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*u8j1T5880DsonQJRSK_jLA.jpeg" /><figcaption>Jetson Nano. (<a href="https://developer.nvidia.com/embedded/jetson-nano-developer-kit">Source</a>)</figcaption></figure><p>Deploying complex deep learning models onto small embedded devices is challenging. Even with hardware optimized for deep learning such as the <a href="https://developer.nvidia.com/embedded/jetson-nano-developer-kit"><strong>Jetson Nano</strong></a> and inference optimization tools such as <a href="https://developer.nvidia.com/tensorrt"><strong>TensorRT</strong></a>, bottlenecks can still present itself in the I/O pipeline. These bottlenecks can potentially compound if the model has to deal with complex I/O pipelines with multiple input and output streams. Wouldn’t it be great to have a tool that can take care of all bottlenecks in an end-to-end fashion?</p><h3>Say Hello to DeepStream</h3><p>Turns out there is a SDK that attempts to mitigate this problem. <a href="https://developer.nvidia.com/deepstream-sdk">DeepStream</a> is an SDK that is optimized for NVIDIA Jetson and T4 platforms to provide a seamless end-to-end service to convert raw streaming data into actionable insights. It is built on top of the <a href="https://gstreamer.freedesktop.org/">GStreamer</a> framework. Here, “raw streaming data” is typically continuous (and multiple) video streams and “actionable insights” are the final outputs of your deep learning or other analytics algorithms.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*SL0-s417iMMXcgMOxvRXCQ.png" /><figcaption>The DeepStream pipeline. (<a href="https://developer.nvidia.com/deepstream-sdk">Source</a>)</figcaption></figure><p>DeepStream SDK uses its custom <a href="https://developer.nvidia.com/deepstream-sdk#plugins">GStreamer Plugins</a> to provide various functionalities. Notably, it has plugins for <a href="https://developer.nvidia.com/tensorrt">TensorRT</a> based inference and object tracking. The below image lists out the capabilities of their plugins. For an exhaustive technical guide about their plugins, you can refer to their <a href="https://docs.nvidia.com/metropolis/deepstream/plugin-manual/index.html">Plugin Manual</a>.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*D9uLhdeZVagy0U5QSKG6gQ.png" /><figcaption>Plugins available in DeepStream. (<a href="https://developer.nvidia.com/deepstream-sdk#plugins">Source</a>)</figcaption></figure><p>One feature I particularly liked about DeepStream is that it optimally takes care of the entire I/O processing in a pipelined fashion. We can also stack multiple deep learning algorithms to process information asynchronously. This allows you to increase throughput without the hassle of manually creating and managing a multiprocessing system design.</p><p>The best part is, for some supported applications such as object detection, tracking, classification or semantic segmentation, DeepStream is easy to use! For such an application, as long you have a deep learning model in a compatible format, you can easily launch DeepStream by just setting a few parameters in some text files.</p><p>In this blog, we will design and run an experiment on DeepStream to test out its features and to see if it is easy to use on the Jetson Nano.</p><h3>The Experiment</h3><p>To test the features of DeepStream, let&#39;s deploy a pre-trained object detection algorithm on the <a href="https://developer.nvidia.com/embedded/jetson-nano-developer-kit">Jetson Nano</a>. This is an ideal experiment for a couple of reasons:</p><ul><li>DeepStream is optimized for inference on NVIDIA T4 and Jetson platforms.</li><li>DeepStream has a plugin for inference using TensorRT that supports object detection. Moreover, it automatically converts models in the ONNX format to an optimized TensorRT engine.</li><li>It has plugins that support multiple streaming inputs. It also has plugins to save the output in multiple formats.</li></ul><p>The ONNX <a href="https://github.com/onnx/models">model zoo</a> has a bunch of pre-trained object detection models. I chose the <strong>Tiny YOLO v2</strong> <a href="https://github.com/onnx/models/tree/master/vision/object_detection_segmentation/tiny_yolov2">model</a> from the zoo as it was readily compatible with DeepStream and was also light enough to run fast on the Jetson Nano.</p><blockquote><strong>Note:</strong> I did try using the SSD and YOLO v3 models from the <a href="https://github.com/onnx/models">zoo</a>. But there were some compatibility issues. These issues are discussed in my <a href="https://github.com/thatbrguy/Deep-Stream-ONNX/blob/master/FAQ.md">GitHub repository</a>, along with tips to verify and handle such cases. I ended up using Tiny YOLO v2 as it was readily compatible without any additional effort.</blockquote><p>Now, the features we want to investigate are as follows:</p><ol><li><strong>Multiple input streams:</strong> Run DeepStream to perform inference on multiple video streams simultaneously. Specifically, we will try using up-to 4 video streams.</li><li><strong>Multiple output sinks: </strong>Display the result on screen and stream it using RTSP. The stream will be accessed by another device connected to the network.</li></ol><p>The performance (Frames per Second, FPS) and ease-of-use will be evaluated for the experiment. The next few sections will guide you through how to set up DeepStream on Jetson Nano to run this experiment. All code used for this experiment is available on my <a href="https://github.com/thatbrguy/Deep-Stream-ONNX">GitHub repository</a>. If you are just curious about how it turned out, feel free to skip to the <strong>results</strong> section.</p><h3>Getting Started</h3><p>In this section, we will walk through some instructions to set things up for our experiment.</p><h4>Part 1: Setting up your Jetson Nano</h4><p>Follow the instructions on the <a href="https://docs.nvidia.com/metropolis/deepstream/dev-guide/index.html">Getting Started With Jetson Nano Developer Kit</a> to set up and boot your Jetson Nano. In case you face some issues with the setup, I would highly recommend following <a href="https://www.hackster.io/news/getting-started-with-the-nvidia-jetson-nano-developer-kit-43aa7c298797">these</a> <a href="https://medium.com/@ageitgey/build-a-hardware-based-face-recognition-system-for-150-with-the-nvidia-jetson-nano-and-python-a25cb8c891fd">resources</a>.</p><p>I would like to highlight some pointers that might save you some trouble:</p><ul><li>It is recommended to use at least a 32GB MicroSD card (I used 64GB).</li><li>You need a wired ethernet connection. If you need to connect your Jetson Nano to WiFi, you need to use a dongle such as the Edimax EW-7811Un.</li><li>You need a monitor that directly accepts HDMI input. I could not use my VGA monitor using a VGA-HDMI adapter.</li></ul><h4>Part 2: Installing the DeepStream SDK</h4><p>Now that you have your Jetson Nano up and running, we can install DeepStream. Nvidia has put together the <a href="https://docs.nvidia.com/metropolis/deepstream/dev-guide/index.html">DeepStream quick start guide</a> where you can follow the instructions under the section <strong>Jetson Setup</strong>.</p><p>Before you go ahead and install DeepStream using the above link, I would like to highlight a few points from my setup experience:</p><ul><li>The setup would suggest you install Jetpack using the Nvidia SDK Manager. I skipped that step as I realized using the OS image in Part-1 (above) had most of the required dependencies by default.</li><li>In the sub-section “To install the DeepStream SDK” of the quick start guide, I used Method-2.</li></ul><p>After installing DeepStream and boosting the clocks (as mentioned in the guide), we can run one of their samples to verify that the installation is properly done. Move (<strong>cd</strong>) into your DeepStream installation folder and run the following command:</p><pre>deepstream-app -c ./samples/configs/deepstream-app/source8_1080p_dec_infer-resnet_tracker_tiled_display_fp16_nano.txt</pre><p>On execution, you should see something like this:</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*6_2ILhsdpOEgubZ1SbBAzw.png" /><figcaption>Output on executing DeepStream using the sample configuration file.</figcaption></figure><p>If you see something similar, congrats! You can play around with more samples if you would like. The guide has a section named “Reference Application Source Details” which provides a description of the samples.</p><h4>Part 3: Setting up the Experiment</h4><p>Now that you have installed and tested DeepSteam, we can go ahead with our experiment. I have bundled up all the files required for the experiment in my <a href="https://github.com/thatbrguy/Deep-Stream-ONNX">GitHub repository</a>. You can follow the step by step instruction in the repository’s <a href="https://github.com/thatbrguy/Deep-Stream-ONNX/blob/master/README.md">readme</a> file about the setup instructions.</p><p>Before moving on with the experiment, if you have not used GStreamer before, it would be worth your time to go through their <a href="https://gstreamer.freedesktop.org/documentation/application-development/introduction/basics.html?gi-language=c"><strong>foundations</strong></a> page. This helps with better understanding of some of the jargons used in DeepStream’s documentation.</p><h3>Interfacing your custom ONNX model with DeepStream</h3><p>In this section, we will explore how to interface the output of our ONNX model with DeepStream. More specifically, we will walk-through the process of creating a custom processing function in <strong>C++</strong> to extract bounding box information from the output of the ONNX model and provide it to DeepStream.</p><h4>Part 1: Understanding the Output of Tiny YOLOv2</h4><p>The ONNX model outputs a tensor of shape <strong>(125, 13, 13)</strong> in the <strong>channels-first</strong> format. However, when used with DeepStream, we obtain the <strong>flattened </strong>version of the tensor which has shape <strong>(21125)</strong>. Our goal is to manually extract the bounding box information from this flattened tensor.</p><p>Let us first try to visually understand the output tensor output by the ONNX model. Consider the output tensor to be a cuboid of dimensions <strong>(B, H, W)</strong>, which in our case B=<strong>125</strong>,H=<strong>13</strong>,W=<strong>13</strong>. We can consider the axes X, Y and B along the width (W), height (H) and depth (B) respectively. Now, each location in the XY plane represents a single grid cell.</p><p>Let us visualize a single grid cell <strong>(X=0, Y=0)</strong>. There 125 values along the depth axis (B) for this given (X,Y) location. Let us rearrange the 125 values in groups of 25 as shown below:</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*ZfE5tog6D7Xs319zRUJFWA.png" /><figcaption>Figure A: Interpreting the meaning of the 125 b-values along the B-axis for the grid cell (X = 0, Y = 0).</figcaption></figure><p>As we see here, each of the contiguous 25 values belong to a separate bounding box. Among each set of 25 values, the first 5 values are of the bounding box parameters and the last 20 values are class probabilities. Using this, we can extract the coordinates and confidence score for each of the 5 bounding boxes as shown here:</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/585/1*7_z6sinutiwfddCFtp2xtg.png" /><figcaption>Formulae for extracting the bounding box parameters. (<a href="https://pjreddie.com/media/files/papers/YOLO9000.pdf">Source</a>)</figcaption></figure><p>Note that we have only performed this operation at one grid cell (X=0, Y=0). We must iterate over all combinations of X and Y to find the 5 bounding box predictions at each grid cell.</p><p>Now that we have a visual idea of how the information is stored, let us try to extract it using indexing. After <strong>flattening</strong> the output tensor, we get a single array in which information is stored as shown in the image below:</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*6maY2VB9rHD5oaWj4Qr9Lw.png" /><figcaption>Figure B: Flattened representation of the output tensor.</figcaption></figure><p>The flattened array has 125 * 13 * 13 = <strong>21125</strong> elements. As shown above, each location in the array corresponds to the indices <strong>(b, y, x)</strong>. We can observe that for a given <strong>(y,x) </strong>value, the corresponding <strong>b </strong>values are separated by 13 * 13 = <strong>169</strong> .</p><p>The following code snippet in <strong>Python</strong> shows how we can obtain the locations of <strong>b</strong> values corresponding to each of the 5 bounding boxes in a given <strong>(y, x)</strong> location. Do note that, as shown in <strong>Figure A</strong>, there are 25 <strong>b</strong> values for <strong>each </strong>bounding box for a given <strong>(y, x)</strong> location.</p><pre>## Let <strong>arr </strong>be the flattened array.<br>## The array <strong>values </strong>contains the value of <strong>arr</strong> at the 25 b_values per ## bbox,x,y combination.<strong><br>num_anchors</strong> = 5<br><strong>num_classes</strong> = 20<br><strong>xy_offset</strong> = y * 13 + x<br><strong>b_offset</strong> = 13 * 13<br><strong>bbox_offset</strong> = 5 + num_classes<br>for <strong>bbox</strong> in range(<strong>num_anchors</strong>):<br>  <strong>values</strong> = []<br>  for <strong>b</strong> in range(<strong>bbox_offset</strong>):<br>     value = <strong>arr</strong>[xy_offset + b_offset * (b + bbox * bbox_offset)]<br>     values.append(value)</pre><p>All that is left to do is to write the <strong>C++</strong> equivalent of the same.</p><h4>Part 2: Writing the Bounding Box Parsing Function</h4><p>Now that we understand how the output is stored and can be extracted, we need to write a function in C++ to do the same. DeepStream expects a function with arguments as shown below:</p><pre>extern &quot;C&quot; bool <strong>NvDsInferParseCustomYoloV2Tiny</strong>(<br>    std::vector&lt;NvDsInferLayerInfo&gt; const&amp; <strong>outputLayersInfo</strong>,<br>    NvDsInferNetworkInfo const&amp; <strong>networkInfo</strong>,<br>    NvDsInferParseDetectionParams const&amp; <strong>detectionParams</strong>,<br>    std::vector&lt;NvDsInferParseObjectInfo&gt;&amp; <strong>objectList</strong><br>);</pre><p>In the above function prototype, <strong>outputLayersInfo </strong>is a <strong>std::vector</strong> containing information and data about each output layer of our ONNX model. In our case, since we have just one output layer, we can access the data using <strong>outputLayersInfo[0].buffer</strong>. The variable <strong>networkInfo </strong>has information about the height and width expected by the model and<strong> </strong><strong>detectionParams </strong>has<strong> </strong>information about some configurations such as<strong> </strong><strong>numClassesConfigured</strong>.</p><p>The variable <strong>objectList </strong>should be updated with a <strong>std::vector</strong> of bounding box information stored as objects of type <strong>NvDsInferParseObjectInfo </strong>at every call of the function. Since the variable was passed by reference, we don’t need to return it as the changes will be reflected at the source. However, the function must return <strong>true </strong>at the end of its execution.</p><p>For our use case, we create <strong>NvDsInferParseCustomYoloV2Tiny </strong>such that it will first decode the output of the ONNX model as described in Part-1 of this section. For each bounding box, we create an object of type <strong>NvDsInferParseObjectInfo </strong>to store its information. We then apply <a href="https://www.coursera.org/lecture/convolutional-neural-networks/non-max-suppression-dvrjH">non-maximum suppression</a> to remove duplicate bounding box detections of the same object. We then add the resulting bounding boxes to the <strong>objectList </strong>vector.</p><p>My <a href="https://github.com/thatbrguy/Deep-Stream-ONNX">GitHub repository</a> has <strong>nvdsparsebbox_tiny_yolo.cpp</strong> inside the directory <strong>custom_bbox_parser </strong>with the function already written for you. The below <strong>flowchart</strong> explains the flow of logic within the <a href="https://github.com/thatbrguy/Deep-Stream-ONNX/blob/master/custom_bbox_parser/nvdsparsebbox_tiny_yolo.cpp">file</a>. The code may seem large but that is only because it is heavily documented and commented for your understanding!</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/957/1*R9UV41Cx0Ilr_gQ4LnG9VA.png" /><figcaption>Flowchart approximately describing the flow of logic in the code file.</figcaption></figure><h4>Part 3: Compiling the Function</h4><p>All that’s left now is to compile the function into a <strong>.so</strong> file so that DeepStream can load and use it. Before you compile it, you may need to set some variables inside the Makefile. You can refer to step 4 of the ReadMe in my <a href="https://github.com/thatbrguy/Deep-Stream-ONNX">GitHub repository</a> for instructions. Once that is done, <strong>cd</strong> into the GitHub repository and run the following command:</p><pre>make -C custom_bbox_parser</pre><h3>Setting the Configuration Files</h3><p>The good news is that most of the heavy lifting work is done. All that is left is to set up some configuration files which will tell DeepStream how to run the experiments. A configurations file has a set of “groups”, each of which has a set of “properties” that are written in the <a href="https://specifications.freedesktop.org/desktop-entry-spec/latest/">key-file format</a>.</p><p>For our experiment, we need to set up two configuration files. In this section we will explore some important properties within these configuration files.</p><h4>Part 1: Configuration file for Tiny YOLOv2</h4><p>Our ONNX model is used by the <strong>Gst-Nvinfer</strong> plugin of DeepStream. We need to set-up some properties to tell the plugin information such as the location of our ONNX model, location of our compiled bounding box parser and so on.</p><p>In the GitHub repository, the configuration file named <strong>config_infer_custom_yolo.txt</strong> is already setup for our experiment. Comments are given in the file with reasoning for each property setting. For a detailed list of all the supported properties, check out this <a href="https://docs.nvidia.com/metropolis/deepstream/plugin-manual/index.html#page/DeepStream_Plugin_Manual%2Fdeepstream_plugin_details.02.01.html%23wwpID0E0IZ0HA">link</a>.</p><p>Some interesting properties that we have not used are the “net-scale-factor” and the “offset” properties. They essentially scale the input (x) using the formula: net_scale_factor * (x — mean). We did not use those properties as our network directly takes the unscaled image as the input.</p><h4>Part 2: Configuration file for DeepStream</h4><p>We also need to set a configuration file for DeepStream to enable and configure the various plugins that will be used by it. As mentioned before, the GitHub repository contains the configuration file <strong>deepstream_app_custom_yolo.txt</strong> which is already setup for our experiment.</p><p>Unlike the previous part, this configuration has a lot of groups such as “osd” (On Screen Display), “primary-gie” (Primary GPU Inference Engine) and so on. This <a href="https://docs.nvidia.com/metropolis/deepstream/dev-guide/index.html#page/DeepStream_Development_Guide%2Fdeepstream_app_config.3.2.html%23">link</a> has information about all possible groups that can be configured and the properties supported for each group.</p><p>For our experiment, we define a single source group (source0) and three sink groups (sink0, sink1 and sink2). The single source group is responsible for reading <strong>four</strong> input video streams parallely. The three sink groups are used for displaying output on screen, streaming output using <a href="https://en.wikipedia.org/wiki/Real_Time_Streaming_Protocol">RTSP</a> and for saving output to disk respectively. We provide the path of the configuration file of Tiny YOLOv2 in the primary-gie group. Moreover, we also set the titled-display and osd groups to control how the output appears on screen.</p><h3>Running DeepStream</h3><p>This is the easiest part. All you have to do is to run the following command:</p><pre>deepstream-app -c ./config/deepstream_app_custom_yolo.txt</pre><p>Launching DeepStream for the first time would take a while as the ONNX model would need to be converted to a TensorRT Engine. It is recommended to close memory hungry apps such as Chromium during this process. Once the engine file is created, subsequent launches will be fast provided the path of the engine file is defined in the Tiny YOLOv2 configuration file.</p><h3>Results</h3><p>On running DeepStream, once the engine file is created we are presented with a 2x2 tiled display as shown in the video below. Each unit in the tiled display corresponds to a different streaming input. As expected, all <strong>four different inputs</strong> are processed simultaneously.</p><iframe src="https://cdn.embedly.com/widgets/media.html?src=https%3A%2F%2Fwww.youtube.com%2Fembed%2FbeX7RqX_FFo%3Ffeature%3Doembed&amp;url=https%3A%2F%2Fwww.youtube.com%2Fwatch%3Fv%3DbeX7RqX_FFo&amp;image=https%3A%2F%2Fi.ytimg.com%2Fvi%2FbeX7RqX_FFo%2Fhqdefault.jpg&amp;key=a19fcc184b9711e1b4764040d3dc5c07&amp;type=text%2Fhtml&amp;schema=youtube" width="854" height="480" frameborder="0" scrolling="no"><a href="https://medium.com/media/486e46fd52126c761103ee84ee45235e/href">https://medium.com/media/486e46fd52126c761103ee84ee45235e/href</a></iframe><p>Since we also enabled RTSP, we can access the stream at rtsp://localhost:8554/ds-test. I used VLC and the RTSP address (after replacing localhost with the IP address of my Jetson Nano) to access the stream on my laptop which was connected to the same network. Note that, another sink is also used to save the output stream to disk. It is impressive to note that the console periodically logs an FPS of nearly <strong>6.7</strong> per video stream!</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/606/1*J224jhQU4TVhbD_5TASn1w.png" /><figcaption>FPS per video stream while simultaneously using four video streams.</figcaption></figure><p>If we had a single input stream, then our FPS should ideally be four times greater than this four video case. I test this out by changing the values in the configuration files and launching DeepStream once again. As expected, we get a whopping near <strong>27 FPS </strong>for the single video stream! The performance is impressive considering it still is sending output to three different sinks.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/191/1*8yMyc8kBqtm96QHFWurAng.png" /><figcaption>FPS while using a single video stream.</figcaption></figure><p>We do however note that the detection accuracy of Tiny YOLOv2 is not as phenomenal as the FPS. This is particularly because the model was optimized for speed at the cost of some accuracy. Moreover, the people in the video had blurred faces and the model might not have encountered this blurriness while training. Hence, the model might have faced additional difficulty for that class.</p><h3>Verdict and Thoughts</h3><p>DeepStream is blazingly fast. Even though Tiny YOLOv2 is optimized for speed rather than accuracy, a stable high FPS performance while providing amazing features such as seamless multi-stream processing and an RTSP stream is something to be appreciated.</p><p>However, using DeepStream may not be straightforward, especially if your model is not completely compatible with TensorRT. In such cases, manually writing your own TensorRT layers might be a more viable (albeit tedious) option. Moreover, it may so happen that the readily available ONNX models may have an opset version greater than what is currently accepted by DeepStream.</p><p>Nevertheless, I do feel that the functionality offered by DeepStream is worth the effort. I would recommend you to give it a shot by replicating my <a href="https://github.com/thatbrguy/Deep-Stream-ONNX">experiment</a>!</p><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=b2872b99a031" width="1" height="1" alt=""><hr><p><a href="https://medium.com/data-science/how-to-deploy-onnx-models-on-nvidia-jetson-nano-using-deepstream-b2872b99a031">How to deploy ONNX models on NVIDIA Jetson Nano using DeepStream</a> was originally published in <a href="https://medium.com/data-science">TDS Archive</a> on Medium, where people are continuing the conversation by highlighting and responding to this story.</p>]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[An Introduction to Super Resolution using Deep Learning]]></title>
            <link>https://medium.com/beyondminds/an-introduction-to-super-resolution-using-deep-learning-f60aff9a499d?source=rss-7d6e83a807b8------2</link>
            <guid isPermaLink="false">https://medium.com/p/f60aff9a499d</guid>
            <category><![CDATA[deep-learning]]></category>
            <category><![CDATA[neural-networks]]></category>
            <category><![CDATA[super-resolution]]></category>
            <category><![CDATA[artificial-intelligence]]></category>
            <category><![CDATA[machine-learning]]></category>
            <dc:creator><![CDATA[Bharath Raj]]></dc:creator>
            <pubDate>Mon, 01 Jul 2019 17:17:57 GMT</pubDate>
            <atom:updated>2019-07-01T17:17:57.667Z</atom:updated>
            <content:encoded><![CDATA[<h4>An elaborate discussion on the various Components, Loss Functions and Metrics used for Super Resolution using Deep Learning.</h4><p><em>Written by </em><a href="https://medium.com/u/7d6e83a807b8"><em>Bharath Raj</em></a><em> with feedback from </em><a href="https://www.linkedin.com/in/yoni-osin-41791aa5/"><em>Yoni Osin</em></a><em>.</em></p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*CuhKY2XQHitDB5vQjuJZOQ.jpeg" /><figcaption>Photo by <a href="https://unsplash.com/@jeremythomasphoto?utm_source=unsplash&amp;utm_medium=referral&amp;utm_content=creditCopyText">Jeremy Thomas</a> on <a href="https://unsplash.com/search/photos/space?utm_source=unsplash&amp;utm_medium=referral&amp;utm_content=creditCopyText">Unsplash</a></figcaption></figure><h3>Introduction</h3><p>Super Resolution is the process of recovering a High Resolution (HR) image from a given Low Resolution (LR) image. An image may have a “lower resolution” due to a smaller spatial resolution (i.e. size) or due to a result of degradation (such as blurring). We can relate the HR and LR images through the following equation: <strong>LR = degradation(HR)</strong></p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*5_BEtRwVWKFwwbNOX0pZ1g.jpeg" /><figcaption>A low resolution image kept besides its high resolution version. (Photo by <a href="https://unsplash.com/@maviccbr?utm_source=unsplash&amp;utm_medium=referral&amp;utm_content=creditCopyText">Jarrad Horne</a> on <a href="https://unsplash.com/search/photos/beach-hut?utm_source=unsplash&amp;utm_medium=referral&amp;utm_content=creditCopyText">Unsplash</a>)</figcaption></figure><p>Clearly, on applying a degradation function, we obtain the LR image from the HR image. But, can we do the inverse? In the ideal case, yes! If we know the exact degradation function, by applying its inverse to the LR image, we can recover the HR image.</p><p>But, there in lies the problem. We usually do not know the degradation function before hand. Directly estimating the inverse degradation function is an <a href="https://en.wikipedia.org/wiki/Well-posed_problem">ill-posed</a> problem. In spite of this, Deep Learning techniques have proven to be effective for Super Resolution.</p><p>This blog primarily focuses on providing an introduction to performing Super Resolution using Deep Learning by using Supervised training methods. Some important loss functions and metrics are also discussed. A lot of the content is derived from this <a href="https://arxiv.org/abs/1902.06068">literature review</a> which the reader can refer to.</p><h3>Supervised Methods</h3><p>As mentioned before, deep learning can be used to estimate the High Resolution (HR) image given a Low Resolution (LR) image. By using the HR image as a target (or ground-truth) and the LR image as an input, we can treat this like a supervised learning problem.</p><p>In this section, we group various deep learning approaches in the manner the convolution layers are organized. Before we move on to the groups, a primer on data preparation and types of convolutions is presented. Loss functions used to optimize the model are presented separately towards the end of this blog.</p><h4>Preparing the Data</h4><p>One easy method of obtaining LR data is to degrade HR data. This is often done by blurring or adding noise. Images of lower spatial resolution can also be scaled by a classic upsampling method such as <a href="https://en.wikipedia.org/wiki/Bilinear_interpolation">Bilinear</a> or <a href="https://en.wikipedia.org/wiki/Bicubic_interpolation">Bicubic</a> interpolation. JPEG and quantization artifacts can also be introduced to degrade the image.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*4ucP01fc7XmjcP64ZmtPtA.jpeg" /><figcaption>Degrading a high resolution image to obtain a low resolution version of it. (Photo by <a href="https://unsplash.com/@maviccbr?utm_source=unsplash&amp;utm_medium=referral&amp;utm_content=creditCopyText">Jarrad Horne</a> on <a href="https://unsplash.com/search/photos/beach-hut?utm_source=unsplash&amp;utm_medium=referral&amp;utm_content=creditCopyText">Unsplash</a>)</figcaption></figure><p>One important thing to note is that it is recommended to store the HR image in an uncompressed (or lossless compressed) format. This is to prevent degradation of the quality of the HR image due to lossy compression, which may give sub-optimal performance.</p><h4>Types of Convolutions</h4><p>Besides classic 2D Convolutions, several interesting variants can be used in networks for improved results. Dilated (<a href="https://arxiv.org/pdf/1706.05587.pdf">Atrous</a>) convolutions can provide a greater effective field of view, hence using information that are separated by a large distance. <a href="https://arxiv.org/abs/1512.03385">Skip connections</a>, <a href="https://arxiv.org/abs/1406.4729">Spatial Pyramid Pooling</a> and <a href="https://arxiv.org/abs/1608.06993">Dense Blocks</a> motivate combining both low level and high level features to enhance performance.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*NbvviwZ4N3c9FrrkNrJkVw.png" /><figcaption>Network design strategies. (<a href="https://arxiv.org/abs/1902.06068">Source</a>)</figcaption></figure><p>The above image mentions a number of network design strategies. You can refer to this <a href="https://arxiv.org/abs/1902.06068">paper</a> for more information. For a primer on the different types of convolutions commonly used in deep learning, you may refer to this <a href="https://towardsdatascience.com/types-of-convolutions-in-deep-learning-717013397f4d">blog</a>.</p><h4>Group 1 — Pre-Upsampling</h4><p>In this method, the low resolution images are first interpolated to obtain a “coarse” high resolution image. Now, CNNs are used to learn an end-to-end mapping from the interpolated low resolution images to the high resolution images. The intuition was that it may be easier to first upsample the low-resolution images using traditional methods (such as Bilinear interpolation) and then refine the resultant than learn a direct mapping from a low-dimensional space to a high-dimensional space.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/521/1*0g8smWyC3SfrzGVNyArCWA.png" /><figcaption>A typical pre-upsampling network. (<a href="https://arxiv.org/abs/1902.06068">Source</a>)</figcaption></figure><p>You can refer to page 5 of this <a href="https://arxiv.org/abs/1902.06068">paper</a> for some models using this technique. The advantage is that since the upsampling is handled by traditional methods, the CNN only needs to learn how to refine the coarse image, which is simpler. Moreover, since we are not using transposed convolutions here, <a href="https://distill.pub/2016/deconv-checkerboard/">checkerboard artifacts</a> maybe circumvented. However the downside is that the predefined upsampling methods may amplify noise and cause blurring.</p><h4>Group 2— Post-Upsampling</h4><p>In this case the low resolution images are passed to the CNNs as such. Upsampling is performed in the last layer using a learnable layer.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/419/1*bfLS2BU_d7HMkzwF8aUbDg.png" /><figcaption>A typical post-upsampling network. (<a href="https://arxiv.org/abs/1902.06068">Source</a>)</figcaption></figure><p>The advantage of this method is that feature extraction is performed in the lower dimensional space (before upsampling) and hence the computational complexity is reduced. Furthermore, by using an learnable upsampling layer, the model can be trained end-to-end.</p><h4>Group 3— Progressive Upsampling</h4><p>In the above group, even though the computational complexity was reduced, only a single upsampling convolution was used. This makes the learning process harder for large scaling factors. To address this drawback, a progressive upsampling framework was adopted by works such as Laplacian Pyramid SR Network (<a href="https://arxiv.org/abs/1710.01992">LapSRN</a>) and Progressive SR (<a href="http://openaccess.thecvf.com/content_cvpr_2018_workshops/papers/w13/Wang_A_Fully_Progressive_CVPR_2018_paper.pdf">ProSR</a>). The models in this case use a cascade of CNNs to progressively reconstruct high resolution images at smaller scaling factors at each step.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/563/1*3BXi4oKHRjLSJRqcHXwG5Q.png" /><figcaption>A typical progressive-upsampling network. (<a href="https://arxiv.org/abs/1902.06068">Source</a>)</figcaption></figure><p>By decomposing a difficult task into simpler tasks, the learning difficulty is greatly reduced and better performance can be obtained. Moreover, learning strategies like <a href="https://ronan.collobert.com/pub/matos/2009_curriculum_icml.pdf">curriculum learning</a> can be integrated to further reduce learning difficulty and improve final performance.</p><h4>Group 4 — Iterative Up and Down Sampling</h4><p>Another popular model architecture is the hourglass (or <a href="https://arxiv.org/abs/1505.04597">U-Net</a>) structure. Some variants such as the <a href="https://arxiv.org/abs/1603.06937">Stacked Hourglass</a> network use several hourglass structures in series, effectively alternating between the process of upsampling and downsampling.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/608/1*ps5_DIIrnY6TEw5q7xYjSQ.png" /><figcaption>A typical iterative up-and-down sampling network. (<a href="https://arxiv.org/abs/1902.06068">Source</a>)</figcaption></figure><p>The models under this framework can better mine the deep relations between the LR-HR image pairs and thus provide higher quality reconstruction results.</p><h3>Loss Functions</h3><p>Loss functions are used to measure the difference between the generated High Resolution image and the ground truth High Resolution image. This difference (error) is then used to optimize the supervised learning model. Several classes of loss functions exist where each of which penalize a different aspect of the generated image.</p><p>Often, more than one loss function is used by weighting and summing up the errors obtained from each loss function individually. This enables the model to focus on aspects contributed by multiple loss functions simultaneously.</p><p><strong>total_loss</strong> = weight_1 * loss_1 + weight_ 2 * loss_2 + weight_3 * loss_3</p><p>In this section we will explore some popular classes of loss functions used for training the models.</p><h4>Pixel Loss</h4><p>Pixel-wise loss is the simplest class of loss functions where each pixel in the generated image is directly compared with each pixel in the ground-truth image. Popular loss functions such as the L1 or L2 loss or advanced variants such as the Smooth L1 loss are used.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/602/1*7dxfmmRmBqAyos9paJYG3g.png" /><figcaption>Plot of Smooth L1 Loss. (<a href="https://www.researchgate.net/figure/Plots-of-the-L1-L2-and-smooth-L1-loss-functions_fig4_321180616">Source</a>)</figcaption></figure><p>The PSNR metric (discussed below) is highly correlated with the pixel-wise difference, and hence minimizing the pixel loss directly maximizes the PSNR metric value (indicating good performance). However, pixel loss does not take into account the image quality and the model often outputs perceptually unsatisfying results (often lacking high frequency details).</p><h4>Content Loss</h4><p>This loss evaluates the image quality based on its perceptual quality. An interesting way to do this is by comparing the high level features of the generated image and the ground truth image. We can obtain these high level features by passing both of these images through a pre-trained image classification network (such as a VGG-Net or a ResNet).</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/584/1*hJRcoMUajhDz8VGB8z1VQw.png" /><figcaption>Content loss between a ground truth image and a generated image. (<a href="https://arxiv.org/abs/1902.06068">Source</a>)</figcaption></figure><p>The equation above calculates the content loss between a ground-truth image and a generated image, given a pre-trained network (Φ) and a layer (<em>l</em>) of this pre-trained network at which the loss is computed. This loss encourages the generated image to be perceptually similar to the ground-truth image. For this reason, it is also known as the <a href="https://arxiv.org/abs/1603.08155">Perceptual loss</a>.</p><h4>Texture Loss</h4><p>To enable the generated image to have the same style (texture, color, contrast etc.) as the ground truth image, texture loss (or style reconstruction loss) is used. The texture of an image, as described by <a href="https://www.cv-foundation.org/openaccess/content_cvpr_2016/papers/Gatys_Image_Style_Transfer_CVPR_2016_paper.pdf">Gatys et. al</a>, is defined as the correlation between different feature channels. The feature channels are usually obtained from a feature map extracted using a pre-trained image classification network (Φ).</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/393/1*zFDiql0MwKTEr3zwD6e38A.png" /><figcaption>Computing the Gram Matrix. (<a href="https://arxiv.org/abs/1902.06068">Source</a>)</figcaption></figure><p>The correlation between the feature maps is represented by the Gram matrix (G), which is the inner product between the vectorized feature maps <strong>i</strong> and <strong>j</strong> on layer <strong><em>l </em></strong>(shown above). Once the Gram matrix is calculated for both images, calculating the texture loss is straight-forward, as shown below:</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/533/1*soSxUrEjvqiRP-bThQebwQ.png" /><figcaption>Computing the Texture Loss. (<a href="https://arxiv.org/abs/1902.06068">Source</a>)</figcaption></figure><p>By using this loss, the model is motivated to create realistic textures and visually more satisfying results.</p><h4>Total Variation Loss</h4><p>The Total Variation (TV) loss is used to suppress noise in the generated images. It takes the sum of the absolute differences between neighboring pixels and measures how much noise is in the image. For a generated image, the TV loss is calculated as shown below:</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/640/1*-Pj6nDqnkNM38oOi00DURA.png" /><figcaption>Total Variation Loss used on a generated High Resolution image. (<a href="https://arxiv.org/abs/1902.06068">Source</a>)</figcaption></figure><p>Here, i,j,k iterates over the height, width and channels respectively.</p><h4>Adversarial Loss</h4><p>Generative Adversarial Networks (GANs) have been increasingly used for several image based applications including Super Resolution. GANs typically consist of a system of two neural networks — the Generator and the Discriminator — dueling each other.</p><p>Given a set of target samples, the Generator tries to produce samples that can fool the Discriminator into believing they are real. The Discriminator tries to resolve real (target) samples from fake (generated) samples. Using this iterative training approach, we eventually end up with a Generator that is really good at generating samples similar to the target samples. The following image shows the structure of a typical GAN.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/926/1*lhPwxtvyEntvCYnuRQd1nQ.png" /><figcaption>GANs in action. (<a href="https://leonardoaraujosantos.gitbooks.io/artificial-inteligence/content/generative_models.html">Source</a>)</figcaption></figure><p>Advances to the basic GAN architecture were introduced for improved performance. For instance, <a href="http://openaccess.thecvf.com/content_ECCV_2018/papers/Seong-Jin_Park_SRFeat_Single_Image_ECCV_2018_paper.pdf">Park et. al</a>. used a feature-level discriminator to capture more meaningful potential attributes of real High Resolution images. You can checkout this <a href="https://medium.com/beyondminds/advances-in-generative-adversarial-networks-7bad57028032?source=friends_link&amp;sk=9f420a2c96c228a3f6d1a9f52b382109">blog</a> for a more elaborate survey about the advances in GANs.</p><p>Typically, models trained with adversarial loss have better perceptual quality even though they might lose out on PSNR compared to those trained on pixel loss. One minor downside is that, the training process of GANs is a bit difficult and unstable. However, methods to stabilize GAN training are actively worked upon.</p><h3>Metrics</h3><p>One big question is how do we quantitatively evaluate the performance of our model. A number of Image Quality Assessment (IQA) techniques (or metrics) are used for the same. These metrics can be broadly classified into two categories — <strong>Subjective</strong> metrics and <strong>Objective</strong> metrics.</p><p>Subjective metrics are based on the human observer’s perceptual evaluation whereas objective metrics are based on computational models that try to assess the image quality. Subjective metrics are often more “perceptually accurate”, however some of these metrics are inconvenient, time-consuming or expensive to compute. Another issue is that these two categories of metrics may not be consistent with each other. Hence, researchers often display results using metrics from both categories.</p><p>In this section, we will briefly explore a couple of the widely used metrics to evaluate the performance of our super resolution model.</p><h4>PSNR</h4><p>Peak Signal-to-Noise Ratio (PSNR) is commonly used objective metric to measure the reconstruction quality of a lossy transformation. PSNR is inversely proportional to the logarithm of the Mean Squared Error (MSE) between the ground truth image and the generated image.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/351/1*aPRl6RGliFrJotbih8lmaQ.png" /><figcaption>Calculation of PSNR. (<a href="https://arxiv.org/abs/1902.06068">Source</a>)</figcaption></figure><p>In the above formula, L is the maximum possible pixel value (for 8-bit RGB images, it is 255). Unsurprisingly, since PSNR only cares about the difference between the pixel values, it does not represent perceptual quality that well.</p><h4>SSIM</h4><p>Structural Similarity (SSIM) is a subjective metric used for measuring the structural similarity between images, based on three relatively independent comparisons, namely luminance, contrast, and structure. Abstractly, the SSIM formula can be shown as a weighted product of the comparison of luminance, contrast and structure computed independently.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/485/1*O6z44G7t7mxx4LGRtiyfkQ.png" /><figcaption>SSIM is a weighted product of comparisons as described above. (<a href="https://arxiv.org/abs/1902.06068">Source</a>)</figcaption></figure><p>In the above formula, alpha, beta and gamma are the weights of the luminance, contrast and structure comparison functions respectively. The commonly used representation of the SSIM formula is as shown below:</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/501/1*M39etNqTAQ2V3RaXVh6PUg.png" /><figcaption>Commonly used representation of the SSIM formula. (<a href="https://arxiv.org/abs/1902.06068">Source</a>)</figcaption></figure><p>In the above formula <strong>μ(I)</strong>represents the mean of a particular image, <strong>σ(I) </strong>represents the standard deviation of a particular image,<strong>σ(I,I’)</strong>represents the covariance between two images, and <strong>C1, C2</strong> are constants set for avoiding instability. For brevity, the significance of the terms and the exact derivation is not explained in this blog and the interested reader can checkout Section 2.3.2 in this <a href="https://arxiv.org/abs/1902.06068">paper</a>.</p><p>Due to the possible unevenly distribution of image statistical features or distortions, assessing image quality locally is more reliable than applying it globally. Mean SSIM (<strong>MSSIM</strong>), which splits the image into multiple windows and averages the SSIM obtained at each window, is one such method of assessing quality locally.</p><p>In any case, since SSIM evaluates the reconstruction quality from the perspective of the Human Visual System, it better meets the requirements of the perceptual assessment.</p><h4>Other IQA Scores</h4><p>Without explanation, some other methods of assessing image quality are listed below. The interested reader can refer to this <a href="https://arxiv.org/abs/1902.06068">paper</a> for more details.</p><ul><li>Mean Opinion Score (MOS)</li><li>Task-based Evaluation</li><li>Information Fidelity Criterion (IFC)</li><li>Visual Information Fidelity (VIF)</li></ul><h3>Conclusion</h3><p>This blog article covered some introductory material and procedures for training deep learning models for Super Resolution. There are indeed more advanced techniques introduced by state of the art research which may yield better performance. Furthermore, researching on avenues such as unsupervised super resolution, better normalization techniques and better representative metrics could greatly further this field. The interested reader is encouraged to experiment with their innovative ideas by participating in challenges such as the <a href="http://openaccess.thecvf.com/content_ECCVW_2018/papers/11133/Blau_2018_PIRM_Challenge_on_Perceptual_Image_Super-resolution_ECCVW_2018_paper.pdf">PIRM Challenge</a>.</p><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=f60aff9a499d" width="1" height="1" alt=""><hr><p><a href="https://medium.com/beyondminds/an-introduction-to-super-resolution-using-deep-learning-f60aff9a499d">An Introduction to Super Resolution using Deep Learning</a> was originally published in <a href="https://medium.com/beyondminds">BeyondMinds</a> on Medium, where people are continuing the conversation by highlighting and responding to this story.</p>]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[An Overview of Human Pose Estimation with Deep Learning]]></title>
            <link>https://medium.com/beyondminds/an-overview-of-human-pose-estimation-with-deep-learning-d49eb656739b?source=rss-7d6e83a807b8------2</link>
            <guid isPermaLink="false">https://medium.com/p/d49eb656739b</guid>
            <category><![CDATA[artificial-intelligence]]></category>
            <category><![CDATA[machine-learning]]></category>
            <category><![CDATA[pose-estimation]]></category>
            <category><![CDATA[deep-learning]]></category>
            <category><![CDATA[data-science]]></category>
            <dc:creator><![CDATA[Bharath Raj]]></dc:creator>
            <pubDate>Sun, 28 Apr 2019 16:50:19 GMT</pubDate>
            <atom:updated>2019-05-01T14:09:06.190Z</atom:updated>
            <content:encoded><![CDATA[<h4>An introduction to the techniques used in Human Pose Estimation based on Deep Learning.</h4><p><em>Written by </em><a href="https://medium.com/u/7d6e83a807b8"><em>Bharath Raj</em></a><em> with feedback from </em><a href="https://www.linkedin.com/in/yoni-osin-41791aa5/"><em>Yoni Osin</em></a><em>.</em></p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*ggI0hgH-psWNqKzg_AVxUQ.jpeg" /><figcaption>Photo by <a href="https://unsplash.com/photos/P_qvsF7Yodw?utm_source=unsplash&amp;utm_medium=referral&amp;utm_content=creditCopyText">Alain Pham</a> on <a href="https://unsplash.com/search/photos/lines?utm_source=unsplash&amp;utm_medium=referral&amp;utm_content=creditCopyText">Unsplash</a></figcaption></figure><p>A Human Pose Skeleton represents the orientation of a person in a graphical format. Essentially, it is a set of coordinates that can be connected to describe the pose of the person. Each co-ordinate in the skeleton is known as a part (or a joint, or a keypoint). A valid connection between two parts is known as a pair (or a limb). Note that, not all part combinations give rise to valid pairs. A sample human pose skeleton is shown below.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/600/1*Q8sk8FwMIYuLoLmptsT-MA.png" /><figcaption>Left: COCO keypoint format for human pose skeletons. Right: Rendered human pose skeletons. (<a href="https://github.com/CMU-Perceptual-Computing-Lab/openpose">Source</a>)</figcaption></figure><p>Knowing the orientation of a person opens avenues for several real-life applications, some of which are discussed towards the end of this blog. Several approaches to Human Pose Estimation were introduced over the years. The earliest (and slowest) methods typically estimating the pose of a single person in an image which only had one person to begin with. These methods often identify the individual parts first, followed by forming connections between them to create the pose.</p><p>Naturally, these methods are not particularly useful in many real-life scenarios where images contain multiple people.</p><h4>Multi-Person Pose Estimation</h4><p>Multi-Person pose estimation is more difficult than the single person case as the location and the number of people in an image are unknown. Typically, we can tackle the above issue using one of two approaches:</p><ul><li>The simple approach is to incorporate a person detector first, followed by estimating the parts and then calculating the pose for each person. This method is known as the <strong>top-down</strong> approach.</li><li>Another approach is to detect all parts in the image (i.e. parts of every person), followed by associating/grouping parts belonging to distinct persons. This method is known as the <strong>bottom-up</strong> approach.</li></ul><figure><img alt="" src="https://cdn-images-1.medium.com/max/800/1*DMdb6SwPEeQBvqbFF6bXNg.jpeg" /><figcaption>Top: Typical Top-Down approach. Bottom: Typical Bottom-Up approach. (<a href="https://unsplash.com/photos/XuN44TajBGo?utm_source=unsplash&amp;utm_medium=referral&amp;utm_content=creditCopyText">Image Source</a>)</figcaption></figure><p>Typically, the top-down approach is easier to implement than the bottom-up approach as adding a person detector is much simpler than adding associating/grouping algorithms. It is hard to judge which approach has better performance overall as it really comes down to which among the person detector and associating/grouping algorithms is better.</p><p>In this blog, we will focus on multi-person human pose estimation using deep learning techniques. In the next section, we will review some of the popular top-down and bottom-up approaches for the same.</p><h3>Deep Learning Methods</h3><h4>1. OpenPose</h4><p><a href="https://arxiv.org/pdf/1812.08008.pdf">OpenPose</a> is one of the most popular bottom-up approaches for multi-person human pose estimation, partly because of their well documented <a href="https://github.com/CMU-Perceptual-Computing-Lab/openpose">GitHub</a> implementation.</p><p>As with many bottom-up approaches, OpenPose first detects parts (keypoints) belonging to every person in the image, followed by assigning parts to distinct individuals. Shown below is the architecture of the OpenPose model.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/728/1*AZjnPjb-Uuj-H_moHicFFw.png" /><figcaption>Flowchart of the OpenPose architecture. (<a href="https://arxiv.org/pdf/1611.08050.pdf">Source</a>)</figcaption></figure><p>The OpenPose network first extracts features from an image using the first few layers (VGG-19 in the above flowchart). The features are then fed into two parallel branches of convolutional layers. The first branch predicts a set of 18 confidence maps, with each map representing a particular part of the human pose skeleton. The second branch predicts a set of 38 Part Affinity Fields (PAFs) which represents the degree of association between parts.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*WClpOwPiG4Glg6WOWlNK_Q.png" /><figcaption>Steps involved in human pose estimation using OpenPose. (<a href="https://arxiv.org/pdf/1812.08008.pdf">Source</a>)</figcaption></figure><p>Successive stages are used to refine the predictions made by each branch. Using the part confidence maps, bipartite graphs are formed between pairs of parts (as shown in the above image). Using the PAF values, weaker links in the bipartite graphs are pruned. Through the above steps, human pose skeletons can be estimated and assigned to every person in the image. For a more thorough explanation of the algorithm, you may refer to their <a href="https://arxiv.org/pdf/1812.08008.pdf">paper</a> and to this <a href="https://arvrjourney.com/human-pose-estimation-using-openpose-with-tensorflow-part-2-e78ab9104fc8">blog post</a>.</p><h4>2. DeepCut</h4><p><a href="https://arxiv.org/abs/1511.06645">DeepCut</a> is a bottom-up approach for multi-person human pose estimation. The authors approached the task by defining the following problems:</p><ol><li>Produce a set of <strong>D </strong>body part candidates. This set represents all possible locations of body parts for every person in the image. Select a subset of body parts from the above set of body part candidates.</li><li>Label each selected body part with one of <strong>C</strong> body part classes. The body part classes represent the types of parts, such as “arm”, “leg”, “torso” etc.</li><li>Partition body parts that belong to the same person.</li></ol><figure><img alt="" src="https://cdn-images-1.medium.com/max/556/1*UG4TgYMB1Irof8v9h3ifVg.png" /><figcaption>Pictorial representation of the approach. (<a href="https://arxiv.org/pdf/1511.06645.pdf">Source</a>)</figcaption></figure><p>The above problems were jointly solved by modeling it into an <a href="https://en.wikipedia.org/wiki/Integer_programming">Integer Linear Programming</a> (ILP) problem. It is modeled by considering triples <strong>(x, y, z)</strong> of binary random variables with domains as stated in the images below.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/880/1*O_Qcua8fa3q7fW2_NBnYXw.png" /><figcaption>Domains of the binary random variables. (<a href="https://arxiv.org/pdf/1511.06645.pdf">Source</a>)</figcaption></figure><p>Consider two body part candidates d and d&#39; from the set of body part candidates D and classes c and c&#39; from the set of classes C. The body part candidates were obtained through a <a href="https://arxiv.org/abs/1506.01497">Faster RCNN</a> or a Dense CNN. Now, we can develop the following set of statements.</p><ul><li>If x(d,c) = 1 then it means that body part candidate d belongs to class c.</li><li>Also, y(d,d&#39;) = 1 indicates that body part candidates d and d&#39; belong to the same person.</li><li>They also define z(d,d’,c,c’) = x(d,c) * x(d’,c’) * y(d,d’). If the above value is 1, then it means that body part candidate d belongs to class c, body part candidate d&#39; belongs to class c&#39;, and finally body part candidates d,d’ belong to the same person.</li></ul><p>The last statement can be used to partition pose belonging to different people. Clearly, the above statements can be formulated in terms of linear equations as functions of (x,y,z). In this way, the Integer Linear Program (ILP) is set up, and the pose of multiple persons can be estimated. For the exact set of equations and much more detailed analysis, you can check out their paper <a href="https://arxiv.org/pdf/1511.06645.pdf">here</a>.</p><h4>3. RMPE (AlphaPose)</h4><p><a href="https://arxiv.org/abs/1612.00137">RMPE</a> is a popular top-down method of Pose Estimation. The authors posit that top-down methods are usually dependent on the accuracy of the person detector, as pose estimation is performed on the region where the person is located. Hence, errors in localization and duplicate bounding box predictions can cause the pose extraction algorithm to perform sub-optimally.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/700/1*P9ZlPvIEohqpUTzrnwqv0g.png" /><figcaption>Effect of duplicate predictions (left) and low confidence bounding boxes (right). (<a href="https://arxiv.org/pdf/1612.00137.pdf">Source</a>)</figcaption></figure><p>To resolve this issue, the authors proposed the usage of Symmetric Spatial Transformer Network (SSTN) to extract a high-quality single person region from an inaccurate bounding box. A Single Person Pose Estimator (SPPE) is used in this extracted region to estimate the human pose skeleton for that person. A Spatial De-Transformer Network (SDTN) is used to remap the estimated human pose back to the original image coordinate system. Finally, a parametric pose Non-Maximum Suppression (NMS) technique is used to handle the issue of redundant pose deductions.</p><p>Furthermore, the authors introduce a Pose Guided Proposals Generator to augment training samples that can better help train the SPPE and SSTN networks. The salient feature of RMPE is that this technique can be extended to any combination of a person detection algorithm and an SPPE.</p><h4>4. Mask RCNN</h4><p><a href="https://arxiv.org/abs/1703.06870">Mask RCNN</a> is a popular architecture for performing semantic and instance segmentation. The model parallelly predicts both the bounding box locations of the various objects in the image and a mask that semantically segments the object. The basic architecture can be quite easily extended for human pose estimation.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/764/1*LskT_JGTVkw162xeRJ8cFg.png" /><figcaption>Flowchart describing the Mask RCNN Architecture. (<a href="https://medium.com/@jonathan_hui/image-segmentation-with-mask-r-cnn-ebe6d793272">Source</a>)</figcaption></figure><p>The basic architecture first extracts feature maps from an image using a CNN. These feature maps are used by a Region Proposal Network (RPN) to get bounding box candidates for the presence of objects. The bounding box candidates select an area (region) from the feature map extracted by the CNN. Since the bounding box candidates can be of various sizes, a layer called RoIAlign is used to reduce the size of the extracted feature such that they are all of the uniform size. Now, this extracted feature is passed into the parallel branches of CNNs for final prediction of the bounding boxes and the segmentation masks.</p><p>Let us focus on the branch that performs segmentation. Suppose an object in our image can belong to one among K classes. The segmentation branch outputs <strong>K</strong> binary masks of size <strong>m x m</strong>, where each binary mask represents all objects belonging to that class alone. We can extract keypoints belonging to every person in the image by modeling each type of keypoint as a distinct class and treating this like a segmentation problem.</p><p>Parallely, the objection detection algorithm can be trained to identify the location of the persons. By combining the information of the location of the person as well as their set of keypoints, we obtain the human pose skeleton for every person in the image.</p><p>This method nearly resembles the top-down approach, but the person detection stage is performed in parallel to the part detection stage. In other words, the keypoint detection stage and person detection stage are independent of each other.</p><h4>5. Other Methods</h4><p>Multi-Person Human Pose Estimation is a vast field with a plethora of approaches to tackle the problem. For brevity, only a select few approaches are explained here. For a more exhaustive list of approaches, you may check out the following links:</p><ul><li><a href="https://github.com/cbsudux/awesome-human-pose-estimation">Awesome Human Pose Estimation</a></li><li><a href="https://paperswithcode.com/sota/multi-person-pose-estimation-on-mpii-multi">Papers with Code</a></li></ul><h3>Applications</h3><p>Pose Estimation has applications in myriad fields, some of which are listed below.</p><h4>1. Activity Recognition</h4><p>Tracking the variations in the pose of a person over a period of time can also be used for activity, gesture and gait recognition. There are several use cases for the same, including:</p><ul><li>Applications to detect if a person has fallen down or is sick.</li><li>Applications that can autonomously teach proper work out regimes, sport techniques and dance activities.</li><li>Applications that can understand full-body sign language. (Ex: Airport runway signals, traffic policemen signals, etc.).</li><li>Applications that can enhance security and surveillance.</li></ul><figure><img alt="" src="https://cdn-images-1.medium.com/max/519/1*Y09ZWoCf_EiwtA34S85-6Q.png" /><figcaption>Tracking the gait of the person is useful for security and surveillance purposes. (<a href="http://www.ee.oulu.fi/~gyzhao/research/gait_recognition.htm">Image source</a>)</figcaption></figure><h4>2. Motion Capture and Augmented Reality</h4><p>An interesting application of human pose estimation is for CGI applications. Graphics, styles, fancy enhancements, equipment and artwork can be superimposed on the person if their human pose can be estimated. By tracking the variations of this human pose, the rendered graphics can “naturally fit” the person as they move.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/600/1*aOJl0KLejxpBcu2rAq1suw.jpeg" /><figcaption>Example of CGI Rendering. (<a href="https://i.kym-cdn.com/photos/images/facebook/001/012/571/0a4.jpg">Source</a>)</figcaption></figure><p>A good visual example of what is possible can be seen through <a href="https://www.wired.com/story/all-the-face-tracking-tech-behind-apples-animoji/">Animoji</a>. Even though the above only tracks the structure of a face, the idea can be extrapolated for the keypoints of a person. The same concepts can be leveraged to render Augmented Reality (AR) elements that can mimic the movements of a person.</p><h4>3. Training Robots</h4><p>Instead of manually programming robots to follow trajectories, robots can be made to follow the trajectories of a human pose skeleton that is performing an action. A human instructor can effectively teach the robot certain actions by just demonstrating the same. The robot can then calculate how to move its articulators to perform the same action.</p><h4>4. Motion Tracking for Consoles</h4><p>An interesting application of pose estimation is for tracking the motion of human subjects for interactive gaming. Popularly, Kinect used 3D pose estimation (using IR sensor data) to track the motion of the human players and to use it to render the actions of the virtual characters.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/610/1*OLazaVAiH1vlCKhSS6OR0g.png" /><figcaption>The Kinect sensor in action. (<a href="https://appleinsider.com/articles/14/07/11/apples-secret-plans-for-primesense-3d-tech-hinted-at-by-new-itseez3d-ipad-app">Source</a>)</figcaption></figure><h3>Conclusion</h3><p>Great strides have been made in the field of human pose estimation, which enables us to better serve the myriad applications that are possible with it. Moreover, research in related fields such as Pose Tracking can greatly enhance its productive utilization in several fields. The concepts listed in this blog are not exhaustive but rather strives to introduce some popular variants of these algorithms and their real-life applications.</p><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=d49eb656739b" width="1" height="1" alt=""><hr><p><a href="https://medium.com/beyondminds/an-overview-of-human-pose-estimation-with-deep-learning-d49eb656739b">An Overview of Human Pose Estimation with Deep Learning</a> was originally published in <a href="https://medium.com/beyondminds">BeyondMinds</a> on Medium, where people are continuing the conversation by highlighting and responding to this story.</p>]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[How To Easily Classify Food Using Deep Learning And TensorFlow]]></title>
            <link>https://medium.com/nanonets/how-to-easily-classify-food-using-deep-learning-and-tensorflow-cbe9b1dc302c?source=rss-7d6e83a807b8------2</link>
            <guid isPermaLink="false">https://medium.com/p/cbe9b1dc302c</guid>
            <category><![CDATA[artificial-intelligence]]></category>
            <category><![CDATA[neural-networks]]></category>
            <category><![CDATA[machine-learning]]></category>
            <category><![CDATA[tensorflow]]></category>
            <category><![CDATA[deep-learning]]></category>
            <dc:creator><![CDATA[Bharath Raj]]></dc:creator>
            <pubDate>Mon, 18 Mar 2019 09:33:01 GMT</pubDate>
            <atom:updated>2019-05-06T16:56:46.832Z</atom:updated>
            <content:encoded><![CDATA[<h4><em>An in-depth tutorial on creating Deep Learning models for Multi-Label Classification.</em></h4><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*371WToG5habYs4np4tJOZA.jpeg" /></figure><p>By now you would have heard about Convolutional Neural Networks (CNNs) and its efficacy in classifying images. The accuracy of CNNs in image classification is quite remarkable and its real-life applications through APIs quite profound.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*nR5QCdmqUnvU2JFBu2Xa-Q.png" /><figcaption>Examples of Classification, Localization, Object Detection and Instance Segmentation. (<a href="https://www.google.com/url?sa=i&amp;rct=j&amp;q=&amp;esrc=s&amp;source=images&amp;cd=&amp;cad=rja&amp;uact=8&amp;ved=2ahUKEwiR16LF1vzgAhWXfX0KHaVZCPkQjRx6BAgBEAU&amp;url=https%3A%2F%2Fwww.analyticsindiamag.com%2Ftop-5-image-classification-research-papers-every-data-scientist-should-know%2F&amp;psig=AOvVaw0dWw_kL93mm_VWvWVylrdE&amp;ust=1552482609158420">Source</a>)</figcaption></figure><p>But sometimes, this technique may not be adequate. An image may represent multiple attributes. For instance, all of the following tags are valid for the below image. A simple classifier would get confused on what label to provide in such a scenario.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/960/1*Wd-6gLJfo6mAHkUxigaN3g.jpeg" /><figcaption>An image with multiple possible correct labels. (<a href="https://pixabay.com/photos/scenery-lake-man-boy-male-looking-1183363/">Source</a>)</figcaption></figure><p>This problem is known as <strong>Multi-Label classification</strong>.</p><h3>Why Multi-Label Classification?</h3><p>There are many applications where assigning multiple attributes to an image is necessary. In fact, it is more natural to think of images as belonging to multiple classes rather than a single class. Below are some applications of Multi Label Classification.</p><h4>1. Scene Understanding</h4><p>Multi Label Classification provides an easy to calculate prior for complex Scene Understanding algorithms. Identifying various possible tags for an image can help the Scene Understanding algorithm to create multiple vivid descriptions for the image.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1010/1*zxGKvMlgMQKE-T1YRUHTqA.png" /><figcaption>Multiple descriptions can be created for a scene based on the labels identified from the image. (<a href="http://visualgenome.org/static/paper/Visual_Genome.pdf">Source</a>)</figcaption></figure><h4>2. Content-Based Retrieval</h4><p>Multi Label tags can enhance the ability of search engines to retrieve very specific queries of a given product. For instance, we could provide multiple tags for an image of a fashion model wearing branded attire. A search engine can retrieve this result when you search for any one of the tags. A Multi Label Classification engine can automatically build up a database for the search engine.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*chlpimcsWvhFRSIS2DE5iw.png" /><figcaption>Content Based Image Retrieval in action. The Multi Label classifier performs the function of the Feature Extraction module in the above flowchart. (<a href="https://www.google.com/url?sa=i&amp;rct=j&amp;q=&amp;esrc=s&amp;source=images&amp;cd=&amp;cad=rja&amp;uact=8&amp;ved=2ahUKEwjJ3vmB1_zgAhWWfn0KHRCOBCwQjRx6BAgBEAU&amp;url=https%3A%2F%2Fblog.sicara.com%2Fkeras-tutorial-content-based-image-retrieval-convolutional-denoising-autoencoder-dc91450cc511&amp;psig=AOvVaw18Cl8gNqkRuk541o9Q9mvA&amp;ust=1552482639525637">Source</a>)</figcaption></figure><p>Moreover, we can use the tags to recommend related products based on the user’s activity or preferences. For instance, you can recommend similar songs or movies based on the user’s activity. A Multi Label Classifier can be used to automatically index such songs and movies.</p><h3>How does it work?</h3><p>If you are familiar with Machine Learning algorithms for classification, some minor modifications are enough to make the same algorithm work for a multi label problem. In any case, let us do a small review of how classification works, and how it can be expanded to a multi label scenario. For the rest of this blog, we will focus on implementing the same for images.</p><h4>Single Label Classification</h4><p>Neural Networks are among the most powerful (and popular) algorithms used for classification. They take inputs in the form of a vector, perform some computations and then produce an output vector. The output vector is then compared with the ground truth labels and the computation process is tweaked (i.e. trained) to yield better results. To train the Neural Network, we feed our input data in the form of feature vectors that represent the important gist of the data.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/479/1*NIOcHiCiGejigjGvq1iuUQ.png" /><figcaption>A Multi Layer Perceptron. (<a href="https://medium.com/@curiousily/tensorflow-for-hackers-part-iv-neural-network-from-scratch-1a4f504dfa8">Source</a>)</figcaption></figure><p>One hurdle you might have noticed is the issue of encoding images into a feature vector. Convolutional Neural Networks (CNNs) are used for this purpose. Convolutions extract important features from the images and convert them into a vector representation for further processing. The rest of the processing in a CNN is similar to that of a Multi Layered Perceptron. This, in a nutshell, is how single label classification is performed.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/866/1*VMYAQF9SCqJDlRnUI4RZWQ.png" /><figcaption>A Convolutional Neural Network. (<a href="https://sds-platform-private.s3-us-east-2.amazonaws.com/uploads/35_blog_image_34.png">Source</a>)</figcaption></figure><h4>Multi Label Classification</h4><p>Now, how do we adapt this model for Multi Label Classification ? There are several strategies for doing the same.</p><h4>Method 1 — Problem Transformation</h4><p>In this case, we will transform the Multi Label problem into a Multi Class problem. One way of doing this is by training a separate classifier for each label. This method has the obvious downside of training too many classifiers. This also ignores possible correlation between each label.</p><p>Another method is by encoding each possible combination of labels as a separate class, thereby creating a label powerset. This method works well for a small number of label combinations, but they are hard to scale for large number of label combinations. For just 10 labels, we would have get a power set of size 1024 (2 raised to the power 10)!</p><h4>Method 2 — Adapting the Algorithm</h4><p>Sometimes, making some minor modifications to the algorithm would be enough for tackling a Multi Label Classification problem. For instance, in the case of a Neural Network, we can replace the final softmax layer with a Sigmoid layer and then use Binary Cross Entropy to optimize the model.</p><p>Clearly there are a lot of strategies that can be explored. Often, one strategy may not work best for all kinds of data and hence requires lots of experimentation.</p><h3>Multi Label Food Classification</h3><p>The theory sounds alright but, how do we implement it? In this section, we will build our own Multi Label Food Classification algorithm using Keras (with TensorFlow backend). We will modify a simple CNN model to enable multi label classification. We will then do a comparison with Nanonets Multi Label Classification API.</p><p>All the code is available on GitHub over <a href="https://github.com/thatbrguy/Multilabel-Classification">here</a>. You can follow the GitHub repository for an in-depth guide to replicate the experiments.</p><h4>Problem Description</h4><p>Let us work on a possible real life application of Multi Label Classification. Given a food item, we would like to identify possible tags for the image. For instance, given an image of a cake, we would like our model to provide tags such as “carbs” and “dessert”.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/744/1*YfYF6SC6MvjFwF2k5_md7w.png" /><figcaption>Sample images and their respective tags.</figcaption></figure><p>Such a model is extremely useful for Content Based Retrieval for businesses based on the food industry. For instance, we can create an automated dietary planar app based on the requirements of the user and retrieve relevant images and recipes for the appropriate food items.</p><h4>Part 1 — Data Collection</h4><p>The first step is to collect and clean the data. I sampled around 2000 images from the <a href="http://www.ub.edu/cvub/recipes5k/">Recipes5k</a> dataset and resized them to size 224 x 224. The original dataset had annotations of the ingredients of a food item. However, there were more than 1000 possible ingredients (i.e. labels) and this would created highly sparse label vectors. Hence, I created my own set of annotations for the same images.</p><p>In our case, an image can have at most 10 possible labels. The list of labels are: [“Soups”, “Mains”, “Appetizer”, “Dessert” ,”Protein”, “Fats”, “Carbs”, “Healthy”, “Junk”, “Meat”]. To encode the labels in a format that can be utilized by the neural network, we create a 10 dimensional vector such that there is a “1” if a label is present in the image and “0” if a label is absent.</p><p>To make the annotation process simpler, I made some bold assumptions such as: “All cake images are Desserts and have Carbs”. This greatly simplified the annotation process, and I wrote a simple python function to carry most of the heavy lifting. While this strategy makes the process simpler, it may create some noisy annotations (i.e. slightly wrong) and could impact the final accuracy. Nevertheless, for this toy experiment, we proceed as such. A sample annotation for a cake image and its label is shown below.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*2Q5cUnsA_-PXSzTwvEDe0Q.jpeg" /><figcaption>A sample image and its vector format.</figcaption></figure><p>Clearly, we are restricted by the quantity of data in hand. To better enhance the training ability of our CNN, we can perform <a href="https://medium.com/nanonets/how-to-use-deep-learning-when-you-have-limited-data-part-2-data-augmentation-c26971dc8ced">Data Augmentation</a> and <a href="https://medium.com/nanonets/nanonets-how-to-use-deep-learning-when-you-have-limited-data-f68c0b512cab">Transfer Learning</a>.</p><h4>Part 2 — Building the Model</h4><p>We will define the model using Keras as follows. The below model is a pretrained ResNet-50 with two Dense layers in the end. Notice that we used a sigmoid activation rather than softmax for the Dense Layer. We use Binary Cross Entropy as our loss function. To calculate the accuracy of the model, we use the F1 score averaged by samples (or similar) as the metric.</p><pre>clear_session()<br>img = Input(shape = (224, 224, 3))</pre><pre>model = ResNet50(<br>weights = &#39;imagenet&#39;,<br>include_top = False, <br>input_tensor = img, <br>input_shape = None, <br>pooling = &#39;avg&#39;<br>)</pre><pre>final_layer = model.layers[-1].output</pre><pre>dense_layer_1 = Dense(128, activation = &#39;relu&#39;)(final_layer)<br>output_layer = Dense(10, activation = &#39;sigmoid&#39;)(dense_layer_1)</pre><pre>model = Model(input = img, output = output_layer)<br>model.compile(optimizer = &#39;adam&#39;,metrics = [&#39;accuracy&#39;], <br>loss = &#39;binary_crossentropy&#39;)</pre><h4>Part 3 — Training</h4><p>The data was split into train, validation and test sets. The data is normalized channel-wise before being fed into the CNN. Since our dataset is relatively small, we can directly use model.fit() to train our model. This is shown is the following code snippet:</p><pre>model.fit(<br>trainX, trainY, <br>batch_size = 32, <br>epochs = 50, <br>validation_data = (valX, valY))</pre><h4>Part 4 — Inference</h4><p>Now that we have a trained model, we can visualize its performance using model.predict() . This will output an array with each element representing the probability of a tag (or label). We can obtain a binary vector by rounding the predicted array such that a 1 signifies the presence of a tag and a 0 signifies the absence of a tag. We can use this binary vector to decode the predicted tags as shown in the image below.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*HPWQgriX-0y6b2h6SxzVjw.png" /><figcaption>Decoding the output from the Neural Network</figcaption></figure><p>To analyze the performance, we repeat the experiment with different models pre-trained on the ImageNet dataset. Overall, the following pre-trained models were used:</p><ul><li>ResNet-50</li><li>DenseNet-121</li><li>Xception</li><li>MobileNet</li></ul><h3>That was great! But…</h3><p>The above example works pretty good. But there are some issues:</p><ul><li>As mentioned earlier, there are several strategies to perform Multi Label Classification. Lots of experimentation is required.</li><li>Need to perform a Hyper Parameter Search to optimize performance.</li><li>Need to manually handle transfer learning and data augmentation.</li><li>Requires a powerful GPU and lots of time to train.</li><li>Would take additional time and effort (and skill) to move this model to production.</li></ul><p>The above issues pose a great limitation to moving such models quickly into deployment. Luckily, there is an easy alternative.</p><h3>Nanonets to the rescue!</h3><p>Nanonets provides an easy to use API to train a Multi Label classifier. It takes care of all of the heavy lifting, including Data Augmentation, Transfer Learning and Hyper Parameter search on their GPU clusters. It does all of this within an hour, and provides a REST API to integrate the model with your services. They also provide an annotation service if required.</p><p>It is pretty easy to get started with the Nanonets API. This section gives an overview about the steps involved in setting up the API to perform the same Multi Label food classification experiment. For a more detailed set of instructions, check out the GitHub repository over <a href="https://github.com/thatbrguy/Multilabel-Classification">here</a>.</p><h4>Part 1 — Setup</h4><p>Clone the GitHub <a href="https://github.com/thatbrguy/Multilabel-Classification">repository</a>. Obtain a free API key from <a href="http://app.nanonets.com/user/api_key">Nanonets,</a> set the appropriate environment variables, and run create_model.py as explained in the <a href="https://github.com/thatbrguy/Multilabel-Classification">repository</a>.</p><p>Note: In create_model.py we have to specify the list of possible labels (in our case, 10 food categories). I have already specified the labels in the code so you can directly run the above step. If you are using it for any other application, edit the list of possible labels inside this file.</p><h4>Part 2 — Upload the Dataset</h4><p>Nanonets requires the dataset to be provided in the following directory structure:</p><pre>-multilabel_data<br>|-ImageSets<br>||-image1.jpg<br>||-image2.jpg<br>|-Annotations<br>||-image1.txt<br>||-image2.txt</pre><p>I have already created the dataset in this format and provided a download link (and some instructions) in the GitHub <a href="https://github.com/thatbrguy/Multilabel-Classification">repository</a>. By running upload_training.py , the data is automatically pushed to Nanonets.</p><h4>Part 3 — Training and Inference</h4><p>Once the dataset is uploaded, you can execute train_model.py to start the training process. The script model_state.py will keep you updated about the current state of the model. You can also check out the status of your model from your user page at Nanonets as shown below:</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/935/1*Fowed8k7LyEbZxER1n8anw.png" /><figcaption>Status of your model in Nanonets</figcaption></figure><p>Once your model is trained, you can run prediction.py to use the deployed model! You can also observe the sample JSON output from your user page as shown below:</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*mS4CMw7mo3i84j6luarh0g.png" /><figcaption>Sample JSON response as shown by Nanonets.</figcaption></figure><h4>Performance</h4><p>Let us first perform a rudimentary analysis of the training time of the various Keras models. The training time for 100 epochs in minutes is plotted in the below bar graph.</p><p>The MobileNet is the fastest to train owing to its efficient architecture. Unsurprisingly, the Xception network takes a lot of time as it is the most complex network among the ones we compared.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/623/1*Yfm-LuSX6zTdjnsksedrMA.png" /><figcaption>Training Time in Minutes.</figcaption></figure><p>Do note that the training time <strong>does not</strong> account for the time incurred for hyperparameter search, model tuning, and model deployment. These factors greatly add on to the time required to move a model to production. However, Nanonets provided a production ready model within 30 minutes, even after accounting for all of the above factors.</p><p>Without a doubt, Nanonets trained faster than the Keras models. But how does it fare performance wise? Below we plot the F1 score obtained by the various Keras models and Nanonets.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/627/1*kwhfKnRZvr7pwfoT34VJpA.png" /><figcaption>F1 Score of various models.</figcaption></figure><p>Nanonets clearly has a higher score than the Keras models. Surprisingly, the MobileNet model came very close to catching up. Due to its parameter efficient architecture, it can mitigate overfitting better compared to the other Keras models. The relatively lower score of all models can either be attributed to the complexity and limited size of the dataset, or to noisy annotations. Let do a visual observation of the output as well.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*mDGQtFKyoXteHp37-2SpVQ.png" /><figcaption>Predicted vs Actual labels</figcaption></figure><p>Looks like our training was pretty successful! By using a larger dataset we could achieve better performance. You can also further experiment by using different datasets for other innovative applications by applying the concepts discussed above.</p><p><em>Originally published at </em><a href="https://blog.nanonets.com/multi-label-classification-using-deep-learning/"><em>https://blog.nanonets.com</em></a><em> on March 18, 2019.</em></p><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=cbe9b1dc302c" width="1" height="1" alt=""><hr><p><a href="https://medium.com/nanonets/how-to-easily-classify-food-using-deep-learning-and-tensorflow-cbe9b1dc302c">How To Easily Classify Food Using Deep Learning And TensorFlow</a> was originally published in <a href="https://medium.com/nanonets">NanoNets</a> on Medium, where people are continuing the conversation by highlighting and responding to this story.</p>]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[A Simple Guide to Semantic Segmentation]]></title>
            <link>https://medium.com/beyondminds/a-simple-guide-to-semantic-segmentation-effcf83e7e54?source=rss-7d6e83a807b8------2</link>
            <guid isPermaLink="false">https://medium.com/p/effcf83e7e54</guid>
            <category><![CDATA[data-science]]></category>
            <category><![CDATA[artificial-intelligence]]></category>
            <category><![CDATA[deep-learning]]></category>
            <category><![CDATA[machine-learning]]></category>
            <category><![CDATA[neural-networks]]></category>
            <dc:creator><![CDATA[Bharath Raj]]></dc:creator>
            <pubDate>Mon, 04 Mar 2019 07:37:17 GMT</pubDate>
            <atom:updated>2019-03-04T07:37:17.365Z</atom:updated>
            <content:encoded><![CDATA[<h4>A comprehensive review of Classical and Deep Learning methods for Semantic Segmentation</h4><p><em>Written by </em><a href="https://medium.com/u/7d6e83a807b8"><em>Bharath Raj</em></a><em> with feedback from </em><a href="https://www.linkedin.com/in/noyshu/"><em>Noy Shulman</em></a><em> and </em><a href="https://www.linkedin.com/in/rotem-alaluf-b37509137/"><em>Rotem Alaluf</em></a><em>.</em></p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*NqVnXjHpYZk-BFJjOIFy3g.jpeg" /><figcaption>Photo by <a href="https://unsplash.com/photos/35sVnCCynWA?utm_source=unsplash&amp;utm_medium=referral&amp;utm_content=creditCopyText">JFL</a> on <a href="https://unsplash.com/search/photos/texture?utm_source=unsplash&amp;utm_medium=referral&amp;utm_content=creditCopyText">Unsplash</a></figcaption></figure><p>Semantic Segmentation is the process of assigning a label to every pixel in the image. This is in stark contrast to classification, where a single label is assigned to the entire picture. Semantic segmentation treats multiple objects of the same class as a single entity. On the other hand, instance segmentation treats multiple objects of the same class as distinct individual objects (or instances). Typically, instance segmentation is harder than semantic segmentation.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/795/1*USmkmfMq7C5mrrLpYCXxUA.png" /><figcaption>Comparison between semantic and instance segmentation. (<a href="http://www.robots.ox.ac.uk/~tvg/publications/2017/CRFMeetCNN4SemanticSegmentation.pdf">Source</a>)</figcaption></figure><p>This blog explores some methods to perform semantic segmentation using classical as well as deep learning based approaches. Moreover, popular loss function choices and applications are discussed.</p><h3>Classical Methods</h3><p>Before the deep learning era kicked in, a good number of image processing techniques were used to segment image into regions of interest. Some of the popular methods used are listed below.</p><h4>Gray Level Segmentation</h4><p>The simplest form of semantic segmentation involves assigning hard-coded rules or properties a region must satisfy for it to be assigned a particular label. The rules can be framed in terms of the pixel’s properties such as its gray level intensity. One such method that uses this technique is the <a href="https://en.wikipedia.org/wiki/Split_and_merge_segmentation">Split and Merge</a> algorithm. This algorithm recursively splits an image into sub-regions until a label can be assigned, and then combines adjacent sub-regions with the same label by merging them.</p><p>The problem with this method is that rules must be hard-coded. Moreover, it is extremely difficult to represent complex classes such as humans with just gray level information. Hence, feature extraction and optimization techniques are needed to properly learn the representations required for such complex classes.</p><h4>Conditional Random Fields</h4><p>Consider segmenting an image by training a model to assign a class per pixel. In case our model is not perfect, we may obtain noisy segmentation results that may be impossible in nature (such as dog pixels mixed with cat pixels, as shown in the image).</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*rMebznseZwQPzGu2OwUeiw.png" /><figcaption>Pixels with label dog mixed with pixels with label cat (image c). A more realistic segmentation is shown in image d. (<a href="http://www.robots.ox.ac.uk/~tvg/publications/2017/CRFMeetCNN4SemanticSegmentation.pdf">Source</a>)</figcaption></figure><p>These can be avoided by considering a prior relationship among pixels, such as the fact that objects are continuous and hence nearby pixels tend to have the same label. To model these relationships, we use Conditional Random Fields (CRFs).</p><p>CRFs are a class of statistical modelling methods used for structured prediction. Unlike discrete classifiers, CRFs can consider “neighboring context” such as relationship between pixels before making predictions. This makes it an ideal candidate for semantic segmentation. This section explores the usage of CRFs for semantic segmentation.</p><p>Each pixel in the image is associated with a finite set of possible states. In our case, the target labels are the set of possible states. The cost of assigning a state (or label, <strong>u</strong>) to a single pixel <strong>(x)</strong> is known as its unary cost. To model relationships between pixels, we also consider the cost of assigning a pair of labels <strong>(u,v)</strong> to a pair of pixels <strong>(x,y) </strong>known as the pairwise cost. We can consider pairs of pixels that are its immediate neighbors (Grid CRF) or we can consider all pairs of pixels in the image (Dense CRF)</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/960/1*_XexR4cVQU0ebeLqTV28jw.jpeg" /><figcaption>Dense vs Grid CRF. (<a href="https://slideplayer.com/slide/784090/3/images/2/Dense+CRF+construction.jpg">Source</a>)</figcaption></figure><p>The sum of the unary and pairwise cost of all pixels is known as the energy (or cost/loss) of the CRF. This value can be minimized to obtain a good segmentation output.</p><h3>Deep Learning Methods</h3><p>Deep Learning has greatly simplified the pipeline to perform semantic segmentation and is producing results of impressive quality. In this section we discuss popular model architectures and loss functions used to train these deep learning methods.</p><h4>1. Model Architectures</h4><p>One of the simplest and popular architecture used for semantic segmentation is the Fully Convolutional Network (FCN). In the paper <a href="https://people.eecs.berkeley.edu/~jonlong/long_shelhamer_fcn.pdf"><em>FCN for Semantic Segmentation</em></a>,the authors use the FCN to first downsample the input image to a smaller size (while gaining more channels) through a series of convolutions. This set of convolutions is typically called the <strong>encoder</strong>. The encoded output is then upsampled either through bilinear interpolation or a series of transpose-convolutions. This set of transposed-convolutions is typically called the <strong>decoder</strong>.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*edkNzGBBDBXtpZMq-pnSng.png" /><figcaption>Downsampling and Upsampling in an FCN. (<a href="https://people.eecs.berkeley.edu/~jonlong/long_shelhamer_fcn.pdf">Source</a>)</figcaption></figure><p>This basic architecture, despite being effective, has a number of drawbacks. One such drawback is the presence of checkerboard artifacts due to uneven overlap of the output of the transpose-convolution (or deconvolution) operation.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/995/1*yec82Kg1lwRiHbF8lTd-sA.png" /><figcaption>Formation of Checkerboard Artifacts. (<a href="https://distill.pub/2016/deconv-checkerboard/">Source</a>)</figcaption></figure><p>Another drawback is poor resolution at the boundaries due to loss of information from the process of encoding.</p><p>Several solutions were proposed to improve the performance quality of the basic FCN model. Below are some of the popular solutions that proved to be effective:</p><h4>U-Net</h4><p>The <a href="https://arxiv.org/abs/1505.04597">U-Net</a> is an upgrade to the simple FCN architecture. It has skip connections from the output of convolution blocks to the corresponding input of the transposed-convolution block at the same level.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/825/1*DxXHzO7JIZs24g-UQmZ8Hw.png" /><figcaption>U-Net. (<a href="https://arxiv.org/pdf/1505.04597.pdf">Source</a>)</figcaption></figure><p>This skip connections allows gradients to flow better and provides information from multiple scales of the image size. Information from larger scales (upper layers) can help the model classify better. Information from smaller scales (deeper layers) can help the model segment/localize better.</p><h4>Tiramisu Model</h4><p>The <a href="https://arxiv.org/abs/1611.09326">Tiramisu</a> Model is similar to the U-Net except for the fact that it uses Dense Blocks for convolution and transposed-convolutions as done in the <a href="https://arxiv.org/pdf/1608.06993.pdf">DenseNet</a> paper. A Dense Block consists of several layers of convolutions where the feature-maps of all preceding layers are used as inputs for all subsequent layers. The resultant network is extremely parameter efficient and can better access features from older layers.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/459/1*yX-Sgvyfn7izUKZjFO3BHA.png" /><figcaption>Tiramisu Network. (<a href="https://arxiv.org/abs/1611.09326">Source</a>)</figcaption></figure><p>A downside of this method is that due to the nature of the concatenation operations in several ML frameworks, it is not very memory efficient (requires a large GPU to run).</p><h4>MultiScale methods</h4><p>Some Deep Learning models explicitly introduce methods to incorporate information from multiple scales. For instance, the Pyramid Scene Parsing Network (<a href="https://arxiv.org/pdf/1612.01105.pdf">PSPNet</a>) performs the pooling operation (max or average) using four different kernel sizes and strides to the output feature map of a CNN such as the ResNet. It then upsamples the size of all the pooling outputs and the CNN output feature map using bilinear interpolation, and concatenates all of them along the channel axis. A final convolution is performed on this concatenated output to generate the prediction.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*SHicQ4LCjn04aHpuKIqC-Q.png" /><figcaption>PSPNet. (<a href="https://arxiv.org/pdf/1612.01105.pdf">Source</a>)</figcaption></figure><p>Atrous (Dilated) Convolutions present an efficient method to combine features from multiple scales without increasing the number of parameters by a large amount. By adjusting the dilation rate, the same filter has its weight values spread out farther in space. This enables it to learn more global context.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*_UXhPeEeeOP667o9PLihhA.png" /><figcaption>Cascaded Atrous Convolutions. (<a href="https://arxiv.org/pdf/1706.05587.pdf">Source</a>)</figcaption></figure><p>The <a href="https://arxiv.org/pdf/1706.05587.pdf">DeepLabv3</a> paper uses Atrous Convolutions with different dilation rates to capture information from multiple scales, without significant loss in image size. They experiment with using Atrous convolutions in a cascaded manner (as shown above) and also in a parallel manner in the form of Atrous Spatial Pyramid Pooling (as shown below).</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1008/1*WeIGBdZkYXzFUWicX8bueg.png" /><figcaption>Parallel Atrous Convolutions. (<a href="https://arxiv.org/pdf/1706.05587.pdf">Source</a>)</figcaption></figure><h4>Hybrid CNN-CRF methods</h4><p>Some methods use a CNN as a feature extractor and then use the features as unary cost (potential) input to a Dense CRF. This hybrid CNN-CRF method offers good results due to the ability of CRFs to model inter-pixel relationships.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*WnyZFykBL2s3Emn6JU0M_g.png" /><figcaption>Methods using combinations of CNN and CRF. (<a href="http://www.robots.ox.ac.uk/~tvg/publications/2017/CRFMeetCNN4SemanticSegmentation.pdf">Source</a>)</figcaption></figure><p>Certain methods incorporate the CRF within the neural network itself, as presented in <a href="https://www.robots.ox.ac.uk/~szheng/papers/CRFasRNN.pdf">CRF-as-RNN</a> where the Dense CRF is modelled as a Recurrent Neural Network. This enables end-to-end training, as illustrated in the above image.</p><h4>2. Loss Functions</h4><p>Unlike normal classifiers, a different loss function must be selected for semantic segmentation. Below are some of the popular loss functions used for semantic segmentation:</p><h4>Pixel-wise Softmax with Cross Entropy</h4><p>Labels for semantic segmentation are of the same size as of the original image. The label can be represented in one-hot encoded form as depicted below:</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/450/1*6H-CaeUZC-QExm0WfcX3jg.jpeg" /><figcaption>One-Hot format for semantic segmentation. (<a href="http://ronny.rest/media/tutorials/segmentation/ZZZ_IMAGES_DIR/label_formats.jpeg">Source</a>)</figcaption></figure><p>Since the label is in a convenient one-hot form, it can be directly used as the ground truth (target) for calculating cross-entropy. However, softmax must be applied pixel-wise on the predicted output before applying cross entropy, as each pixel can belong to any one our target classes.</p><h4>Focal Loss</h4><p>Focal Loss, introduced in the <a href="https://arxiv.org/pdf/1708.02002.pdf">RetinaNet</a> paper proposes an upgrade to the standard cross-entropy loss for usage in cases with extreme class imbalance.</p><p>Consider the plot of the standard cross entropy loss equation as shown below (Blue color). Even in the case where our model is pretty confident about a pixel’s class (say 80%), it has a tangible loss value (here, around 0.3). On the other hand, Focal Loss (Purple color, with gamma=2)does not penalize the model to such a large extent when the model is confident about a class (i.e. loss is nearly 0 for 80% confidence).</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/567/1*IHAAgRjtH4HZ_Lgu3OIbAg.png" /><figcaption>Standard Cross Entropy (Blue) vs Focal Loss with various values of gamma. (<a href="https://arxiv.org/pdf/1708.02002.pdf">Source</a>)</figcaption></figure><p>Let us explore why this is significant with an intuitive example. Assume we have an image with 10000 pixels, with only two classes: Background class (0 in one-hot form) and Target class (1 in one-hot form). Let us assume 97% of the image is the background and 3% of the image is the target. Now, say our model is 80% sure about pixels that are background, but only 30% sure about pixels that are the target class.</p><p>While using cross-entropy, loss due to background pixels is equal to <strong>(97% of 10000) * 0.3</strong> which equals <strong>2850 </strong>and loss due to target pixels is equal to <strong>(3% of 10000) * 1.2</strong> which equals <strong>360</strong>. Clearly, the loss due to the more confident class dominates, and there is very low incentive for the model to learn the target class. Comparatively, with focal loss, loss due to background pixels is equal to <strong>(97% of 10000) * 0</strong> which is 0. This allows the model to learn the target class better.</p><h4>Dice Loss</h4><p>Dice Loss is another popular loss function used for semantic segmentation problems with extreme class imbalance. Introduced in the <a href="https://arxiv.org/pdf/1606.04797.pdf">V-Net</a> paper, the Dice Loss is used to calculate the overlap between the predicted class and the ground truth class. The Dice Coefficient (D) is represented as follows:</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/257/1*ftK1SeMgOIG9FWjOcINGbw.png" /><figcaption>Dice Coefficient. (<a href="https://arxiv.org/pdf/1606.04797.pdf">Source</a>)</figcaption></figure><p>Our objective is to maximize the overlap between the predicted and ground truth class (i.e. to maximize the Dice Coefficient). Hence, we generally minimize <strong>(1-D) </strong>instead to obtain the same objective, as most ML libraries provide options for minimization only.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/534/1*HFLXmW2wMKB_xDN-HgEtrw.png" /><figcaption>Derivative of Dice Coefficient. (<a href="https://arxiv.org/pdf/1606.04797.pdf">Source</a>)</figcaption></figure><p>Even though Dice Loss works well for samples with class imbalance, the formula for calculating its derivative (shown above) has squared terms in the denominator. When those values are small, we could get large gradients, leading to training instability.</p><h3>Applications</h3><p>Semantic Segmentation is used in various real life applications. Following are some of the significant use cases of semantic segmentation.</p><h4>Autonomous Driving</h4><p>Semantic segmentation is used to identify lanes, vehicles, people and other objects of interest. The resultant is used to make intelligent decisions to guide the vehicle properly.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*QgHLw45KG7-LR_ZSkAqRsw.png" /><figcaption>Semantic segmentation for autonomous vehicles. (<a href="https://wiki.tum.de/download/attachments/23561833/sms.png?version=1&amp;modificationDate=1483619907233&amp;api=v2">Source</a>)</figcaption></figure><p>One constraint on autonomous vehicles is that performance must be real time. A solution to the above problem is to integrate a GPU locally along with the vehicle. To enhance performance of the above solution, lighter (low parameters) neural networks can be used or techniques to fit neural networks on the <a href="https://heartbeat.fritz.ai/how-to-fit-large-neural-networks-on-the-edge-eb621cdbb33">edge</a> can be implemented.</p><h4>Medical Image Segmentation</h4><p>Semantic Segmentation is used to identify salient elements in medical scans. It is especially useful to identify abnormalities such as tumors. The accuracy and low recall of algorithms are of high importance for these applications.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/800/1*Kyv4okvercqpYPh1fSPieA.png" /><figcaption>Segmentation of medical scans. (<a href="https://ai2-s2-public.s3.amazonaws.com/figures/2017-08-08/1b699b098ec7a5e539afd8370d71a82d41e3370d/3-Figure1-1.png">Source</a>)</figcaption></figure><p>We can also automate less critical operations such as estimating the volume of organs from 3D semantically segmented scans.</p><h4>Scene Understanding</h4><p>Semantic segmentation usually forms the base for more complex tasks such as Scene Understanding and Visual Question and Answer (VQA). A scene graph or a caption is usually the output of scene understanding algorithms</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/994/1*Q28zA8NBPPwTWmm8o2Lstw.png" /><figcaption>Scene Understanding in action. (<a href="https://arxiv.org/pdf/1606.04797.pdf">Source</a>)</figcaption></figure><h4>Fashion Industry</h4><p>Semantic Segmentation is used in the Fashion Industry to extract clothing items from an image to provide similar suggestions from retail shops. More advanced algorithms can “re-dress” particular items of clothing in an image.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*R7ZO8eLo240C9GCETFyS9g.png" /><figcaption>Semantic segmentation used as an intermediate step to redress a human based on text input. (<a href="https://arxiv.org/abs/1710.07346">Source</a>)</figcaption></figure><h4>Satellite (Or Aerial) Image Processing</h4><p>Semantic Segmentation is used to identify types of land from satellite imagery. Typical use cases involve segmenting water bodies to provide accurate map information. Other advanced uses cases involve mapping roads, identifying types of crops, identifying free parking space and so on.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/882/1*7eMYJ7vCZzE88bZcQdTkdw.png" /><figcaption>Semantic segmentation of satellite/aerial images. (<a href="https://ai2-s2-public.s3.amazonaws.com/figures/2017-08-08/59cbe15b43e6ca172fce40786be68340f50be541/12-Figure1.1-1.png">Source</a>)</figcaption></figure><h3>Conclusion</h3><p>Deep Learning greatly enhanced and simplified Semantic Segmentation algorithms and paved the way for greater adoption in real-life applications. The concepts listed in this blog are not exhaustive as research communities continuously strive to enhance the accuracy and real-time performance of these algorithms. Nevertheless, this blog introduces some popular variants of these algorithms and their real-life applications.</p><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=effcf83e7e54" width="1" height="1" alt=""><hr><p><a href="https://medium.com/beyondminds/a-simple-guide-to-semantic-segmentation-effcf83e7e54">A Simple Guide to Semantic Segmentation</a> was originally published in <a href="https://medium.com/beyondminds">BeyondMinds</a> on Medium, where people are continuing the conversation by highlighting and responding to this story.</p>]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[Depth Estimation]]></title>
            <link>https://medium.com/beyondminds/depth-estimation-cad24b0099f?source=rss-7d6e83a807b8------2</link>
            <guid isPermaLink="false">https://medium.com/p/cad24b0099f</guid>
            <category><![CDATA[artificial-intelligence]]></category>
            <category><![CDATA[neural-networks]]></category>
            <category><![CDATA[machine-learning]]></category>
            <category><![CDATA[deep-learning]]></category>
            <category><![CDATA[data-science]]></category>
            <dc:creator><![CDATA[Bharath Raj]]></dc:creator>
            <pubDate>Sat, 16 Feb 2019 14:05:21 GMT</pubDate>
            <atom:updated>2019-02-17T11:14:49.731Z</atom:updated>
            <content:encoded><![CDATA[<h4>A comprehensive review of techniques used to estimate depth using Machine Learning and classical methods.</h4><p><em>Written by </em><a href="https://medium.com/u/7d6e83a807b8"><em>Bharath Raj</em></a><em> with feedback from </em><a href="https://www.linkedin.com/in/rotem-alaluf-b37509137/"><em>Rotem Alaluf</em></a><em>.</em></p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*k15IG4yYYk_cgsmXMNpeBg.jpeg" /><figcaption>Photo by <a href="https://unsplash.com/photos/zjPasgivhcc?utm_source=unsplash&amp;utm_medium=referral&amp;utm_content=creditCopyText">Osman Rana</a> on <a href="https://unsplash.com/search/photos/far?utm_source=unsplash&amp;utm_medium=referral&amp;utm_content=creditCopyText">Unsplash</a></figcaption></figure><p>Conventional displays are two dimensional. A picture or a video of the three dimensional world is encoded to be stored in two dimensions. Needless to say, we lose information corresponding to the third dimension which has depth information.</p><p>2D representation is good enough for most applications. However, there are applications that require information to be provided in three dimensions. An important application is robotics, where information in three dimensions is required to accurately move the actuators. Clearly, some provisions have to made to incorporate the lost depth information, and this blog explores such concepts.</p><h4>How do we estimate depth?</h4><p>Our eyes estimate depth by comparing the image obtained by our left and right eye. The minor displacement between both viewpoints is enough to calculate an approximate depth map. We call the pair of images obtained by our eyes a stereo pair. This, combined with our lens with variable focal length, and general experience of “seeing things”, allows us to have seamless 3D vision.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/425/1*9vMU9qDgaqt67SdJU0o06g.jpeg" /><figcaption>Stereo image pair formed due to the different viewpoints with respect to the left eye and the right eye. (<a href="http://img.tomshardware.com/de/2005/05/18/dreidimensionales_sehen_ohne_brille_monster_springen_dich_an/wahrnehmung.jpg">Source</a>)</figcaption></figure><p>Engineers and Researchers have realized this concept and tried to emulate the same to extract depth information from the environment. There are numerous approaches to reach the same outcome. We will explore the hardware and software approaches separately.</p><h3>Hardware:</h3><h4>1. Dual camera technology</h4><p>Some devices have two cameras separated by a small distance (usually a few millimeters) to capture images from different viewpoints. These two images form a stereo pair, and is used to compute depth information.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/891/1*rK8OMRzOEBk9ZR0SnRFaIQ.jpeg" /><figcaption>Dual camera separated by a small distance on a mobile phone. (<a href="https://images.dazeinfo.com/wp-content/uploads/2017/11/dual-camera-smartphone-shipments-india-Q2-2017.jpg">Source</a>)</figcaption></figure><h4><strong>2. Dual pixel technology</strong></h4><p>An alternative solution to the Dual Camera technology is Dual Pixel Autofocus (<a href="https://www.usa.canon.com/internet/portal/us/home/learn/education/topics/article/2018/July/Intro-to-Dual-Pixel-Autofocus-(DPAF)/Intro-to-Dual-Pixel-Autofocus-(DPAF)">DPAF</a>) technology.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/400/1*Z-r1Vu8I5YlvAJgqrqX2JQ.png" /><figcaption>Calculation of depth using DPAF on the Google Pixel 2. (<a href="https://ai.googleblog.com/2017/10/portrait-mode-on-pixel-2-and-pixel-2-xl.html">Source</a>)</figcaption></figure><p>Each pixel is comprised of two photodiodes, which are separated by a very small distance (less than a millimeter). Each photodiode considers the image signals separately, and then analyzes it. This distance of separation is surprisingly sufficient for the images produced by the photodiodes to be considered as a stereo-image pair. Popularly, <a href="https://ai.googleblog.com/2017/10/portrait-mode-on-pixel-2-and-pixel-2-xl.html">Google Pixel 2</a> uses this technology to calculate depth information.</p><h4>3. Sensors</h4><p>A good alternative to multiple cameras is to use sensors that can infer distance. For instance, the first version of <a href="https://courses.engr.illinois.edu/cs498dh/fa2011/lectures/Lecture%2025%20-%20How%20the%20Kinect%20Works%20-%20CP%20Fall%202011.pdf">Kinect</a> used an Infra-Red (IR) projector to achieve this. A pattern of IR dots is projected on to the environment, and a monochrome CMOS sensor (placed a few centimeters apart) received the reflected rays. The difference between the expected and received IR dot positions is calculated to produce the depth information.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/610/1*ZcE9tqy6unvIxrrVtm6uUQ.png" /><figcaption>Kinect sensor in action. (<a href="https://appleinsider.com/articles/14/07/11/apples-secret-plans-for-primesense-3d-tech-hinted-at-by-new-itseez3d-ipad-app">Source</a>)</figcaption></figure><p>LIDAR systems fire laser pulses at the objects in the environment, and measures the time it takes for these pulses to get reflected back (also known as time of flight). They also additionally measure the change in wavelength of these laser pulses. This can give accurate depth information.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/616/1*P1bTz2TsAmAjjvienVxtIw.jpeg" /><figcaption>LIDAR in action. (<a href="https://img.newatlas.com/velodyne-lidar-vls-128-sensor-2.jpg?auto=format%2Ccompress&amp;ch=Width%2CDPR&amp;fit=crop&amp;h=347&amp;q=60&amp;rect=0%2C45%2C1000%2C562&amp;w=616&amp;s=8d952db4007819de462bb3464de5c5fc">Source</a>)</figcaption></figure><p>An alternative and inexpensive solution would be to use Ultrasonic sensors. These sensors usually include a transmitter that projects ultrasonic sound waves towards the target. The waves are reflected by the target back to the sensor. By measuring the time the waves take to return to the sensor, we can measure the distance to the target. However, sound based sensors may perform <a href="https://www.bannerengineering.com/in/en/company/expert-insights/ultrasonic-sensors-101.html">poorly</a> in noisy environments.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/300/1*NcYOIgf1FIeskIG1rqnfvQ.jpeg" /><figcaption>A typical low cost ultrasonic sensor. (<a href="https://www.makerlab-electronics.com/my_uploads/2016/05/ultrasonic-sensor-HCSR04-1.jpg">Source</a>)</figcaption></figure><h3>Software:</h3><p>Using additional hardware not only increases the cost of production, but also makes the depth estimation methods incompatible with other devices. Fortunately, methods to estimate depth by using software only techniques do exist, and is also an active research topic. Below are some of the popular methods to estimate depth using software:</p><h4>1. Multiple image methods</h4><p>The easiest way to calculate depth information without using additional hardware is to take multiple images of the same scene with slight displacements. By matching keypoints that are common with each image, we can reconstruct a 3D model of the scene. Algorithms such as Scale-Invariant Feature Transform (<a href="https://en.wikipedia.org/wiki/Scale-invariant_feature_transform">SIFT</a>) are excellent at this task.</p><p>To make this method more robust, we can measure the change in orientation of the device to calculate the physical distance between the two images. This can be done by measuring the accelerometer and gyroscope data of the device. For instance, Visual-Intertial Odometry is used in Apple’s ARKit to calculate the depth and other attributes of the scene. User experience is refined as even slight motions of the device is enough to create stereo image information.</p><h4>2. Single image methods</h4><p>There are several single-image depth estimation methods as well. These methods usually involve a neural network trained on pairs of images and their depth maps. Such methods are easy to interpret and construct, and provide decent accuracy. Below are examples of some popular learning based methods.</p><h4>A. Supervised Learning based methods</h4><p>Supervised methods require some sort of labels to be trained. Usually, the labels are pixel-wise RGB-D depth maps. In such cases, the trained model can directly output the depth map. Commonly used depth datasets include the <a href="https://cs.nyu.edu/~silberman/datasets/nyu_depth_v2.html">NYUv2</a> dataset, which contains RGB-D depth maps for indoor images, and the <a href="http://make3d.cs.cornell.edu/data.html">Make3D</a> dataset, which contains RGB-D depth maps for outdoor images. You can checkout this GitHub <a href="https://github.com/scott89/awesome-depth">repo</a> for information on more datasets.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/800/1*4PH2J5iGG1wgnIj4XzQEmg.jpeg" /><figcaption>Sample image (left) and its depth annotation in RGB-D (right). (<a href="https://cs.nyu.edu/~silberman/datasets/nyu_depth_v2.html">Source</a>)</figcaption></figure><p>Target labels need not necessarily be pure depth maps, but can also be a function of depth maps, such as hazy images. Hence, we can use hazy and haze-free image pairs for training the model, and then the depth can be extracted using a function that relates a hazy image with its depth value. For this discussion, we will only concentrate on methods that use depth maps as target labels.</p><p>Autoencoder are among the simplest type of networks used to extract depth information. Popular variants involve using <a href="https://arxiv.org/abs/1505.04597">U-Nets</a>, which are convolutional autoencoders with residual skip connections connecting feature maps from the downsampling (output of convolutions) and upsampling (output of transposed convolutions) arm.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*lvXoKMHoPJMKpKK7keZMEA.png" /><figcaption>Standard U-Net architecture. (<a href="https://lmb.informatik.uni-freiburg.de/people/ronneber/u-net/u-net-architecture.png">Source</a>)</figcaption></figure><p>Improvements can be made over the basic structure. For instance, in the <a href="https://arxiv.org/pdf/1411.4734v4.pdf">paper</a> “Predicting Depth, Surface Normals and Semantic Labels with a Common Multi-Scale Convolutional Architecture” multiple neural networks have been used, with each network operating on input in different scales. The parameters of each network such as kernel size and stride are different. The authors claim that extracting information from multiple scales yields a higher quality depth than single scale extraction.</p><p>An improvement over the above method is <a href="https://arxiv.org/abs/1803.11029">presented</a> in “Structured Attention Guided Convolutional Neural Fields for Monocular Depth Estimation”. Here they use a single end-to-end trainable model, but they fuse features maps of different scales using structured attention guided Conditional Random Fields (<a href="https://en.wikipedia.org/wiki/Conditional_random_field">CRFs</a>) before feeding it as input to the last convolution operation.</p><p>Other methods treat depth extraction as an image-to-image translation problem. Conventional image translation methods are based on the pix2pix <a href="https://phillipi.github.io/pix2pix/">paper</a>. These methods directly extract the depth map given an input image.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*Iw8XCmw7VccR_9V1HCgbcQ.jpeg" /><figcaption>Image translation in action. (<a href="https://phillipi.github.io/pix2pix/">Source</a>)</figcaption></figure><p>Similarly, improvements can be made over this structure as well. The performance can be enhanced by improving GAN stability and output quality, by using methods like <a href="https://arxiv.org/pdf/1704.00028.pdf">gradient penalty</a>, <a href="https://arxiv.org/abs/1805.08318">self-attention</a> and <a href="https://arxiv.org/abs/1603.08155">perceptual loss</a>.</p><h4>B. Unsupervised Learning based methods</h4><p>It is hard to obtain depth datasets of high quality that account for all possible background conditions. Unsurprisingly, enhancing performance of supervised methods beyond some point is difficult due to the lack of accurate data. Semi-supervised and Unsupervised methods remove the requirement of a target depth image, and hence are not limited by this constraint.</p><p>The <a href="https://arxiv.org/pdf/1603.04992.pdf">method</a> introduced by “Unsupervised CNN for Single View Depth Estimation: Geometry to the Rescue” involves generating the right image, for a given left image in a stereo image pair (or vice versa). This can be performed by training an autoencoder as in the supervised scenario. Our trained model can output right-side images for any left-side image. Now, we calculate the <a href="https://en.wikipedia.org/wiki/Binocular_disparity">disparity</a> between the two images, which in our case is the displacement of a pixel (or block) in the right-image with respect to its location in the left-image. Using the value of disparity, we can calculate the depth, given the focal length of the camera and the distance between the two images.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/728/1*AZ3E4tTcOtc1dhtafNGLrw.jpeg" /><figcaption>Calculation of depth using disparity. Baseline is the distance between the two cameras (right and left images). (<a href="https://image.slidesharecdn.com/lecture09-110524023509-phpapp02/95/lecture09-3-728.jpg?cb=1306204632">Source</a>)</figcaption></figure><p>The above method is considered to be truly unsupervised when our algorithm can adapt to non stereo image pairs as well. This can be done by keeping track of the distance between the two images by checking the sensor data on the device. Improvements can be made over this method, as done in this <a href="https://arxiv.org/pdf/1609.03677.pdf">work</a> “Unsupervised Monocular Depth Estimation with Left-Right Consistency” where the disparity is calculated both with respect to the left image and the right image, and then the depth is calculated by considering both values.</p><h4>Limitations</h4><p>The limitation of using learning based methods, especially that of supervised methods, is that they may not generalize well to all use-cases. Analytical methods may not have enough information to create a robust depth map from a single image. However, incorporating domain knowledge can aid extraction of depth information in some cases.</p><p>For instance, consider <a href="https://www.robots.ox.ac.uk/~vgg/rg/papers/hazeremoval.pdf">Dark Channel Prior</a> based haze removal. The authors observed that most local patches of hazy images have low intensity pixels in atleast one channel. Using this information, they created an analytical haze removal method. Since haze is a function of depth, by comparing the dehazed image with the original, the depth can be easily recovered.</p><p>A clear limitation of unsupervised methods is that they require additional domain information such as camera focal length and sensor data to measure image displacement. However, they do offer better generalization than supervised methods, atleast in theory.</p><h3>Applications of depth estimation</h3><h4>1. Augmented reality</h4><p>One of the key applications of depth estimation is Augmented Reality (AR). A fundamental problem in AR is to place an object in 3D space such that its orientation, scale and perspective are properly calibrated. Depth information is vital for such processes.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/796/1*6auQT4Sar0HmDyRVS5_9Ow.png" /><figcaption>An AR app that can measure the dimensions of objects. (<a href="https://cdn0.tnwcdn.com/wp-content/blogs.dir/1/files/2018/06/Screenshot_20180621-183426-796x450.png">Source</a>)</figcaption></figure><p>One impressive application is IKEA’s <a href="https://www.youtube.com/watch?v=vDNzTasuYEw">demo</a>, where you can visualize products in your home using an AR module before actually purchasing them. Using this method, we can visualize its dimensions, as well as view it from multiple scales.</p><h4>2. Robotics and object trajectory estimation</h4><p>Objects in real life move in 3D space. However, since our displays are limited to two dimensions, we cannot accurately calculate motion along the third dimension.</p><p>With depth information, we can estimate the trajectory along the third dimension. Moreover, knowing the scale values, we can calculate the distance, velocity and acceleration values of the object within a reasonable accuracy. This is especially useful for robots to reach or track objects in 3D space</p><h4>3. Haze and Fog removal</h4><p>Haze and Fog are natural phenomena that are a function of depth. Distant objects are obscured to a greater extent.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/520/1*HmwmvnbmxgjHpATZ-zDoZQ.png" /><figcaption>Example of haze removal. (<a href="https://github.com/thatbrguy/Dehaze-GAN">Source</a>)</figcaption></figure><p>Hence, image processing methods that aim to remove haze must estimate the depth information first. Haze removal is an active research topic, and there are several quantitative and learning based solutions proposed.</p><h4>4. Portrait mode</h4><p>Portrait mode on certain smart phone devices involve focusing on certain objects of interest, and blurring other regions. Blur applied as a function of depth creates a much more appealing image than using just uniform blur.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/640/1*SdgFNXID6Z1Ooh0wYOUD7A.jpeg" /><figcaption>Blurred image (right) created using portrait mode. (<a href="https://2.bp.blogspot.com/-1plbwPnt2vg/WeV-zkSr_AI/AAAAAAAACFI/zDWndZXuAp0QyPGVjygbzz7pTuYa7X6jACLcBGAs/s640/flower-comp-s.jpg">Source</a>)</figcaption></figure><h3>Conclusion</h3><p>Depth Estimation is a challenging problem with numerous applications. Through efforts taken by the research community, powerful and inexpensive solutions using Machine Learning are becoming more commonplace. These and many other related solutions would greatly pave the path for innovative applications using Depth Estimation in many domains.</p><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=cad24b0099f" width="1" height="1" alt=""><hr><p><a href="https://medium.com/beyondminds/depth-estimation-cad24b0099f">Depth Estimation</a> was originally published in <a href="https://medium.com/beyondminds">BeyondMinds</a> on Medium, where people are continuing the conversation by highlighting and responding to this story.</p>]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[Advances in Generative Adversarial Networks]]></title>
            <link>https://medium.com/beyondminds/advances-in-generative-adversarial-networks-7bad57028032?source=rss-7d6e83a807b8------2</link>
            <guid isPermaLink="false">https://medium.com/p/7bad57028032</guid>
            <category><![CDATA[data-science]]></category>
            <category><![CDATA[artificial-intelligence]]></category>
            <category><![CDATA[neural-networks]]></category>
            <category><![CDATA[machine-learning]]></category>
            <category><![CDATA[deep-learning]]></category>
            <dc:creator><![CDATA[Bharath Raj]]></dc:creator>
            <pubDate>Thu, 31 Jan 2019 09:32:03 GMT</pubDate>
            <atom:updated>2019-02-11T13:08:12.167Z</atom:updated>
            <content:encoded><![CDATA[<h3>Advances in Generative Adversarial Networks (GANs)</h3><h4>A summary of the latest advances in Generative Adversarial Networks</h4><p><em>Written by </em><a href="https://medium.com/u/7d6e83a807b8"><em>Bharath Raj</em></a><em> with feedback from </em><a href="https://www.linkedin.com/in/rotem-alaluf-b37509137/"><em>Rotem Alaluf</em></a></p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*ZfejbNRvN9qHI9de3ugEjQ.jpeg" /><figcaption><a href="https://unsplash.com/photos/gKlnwCvghTU?utm_source=unsplash&amp;utm_medium=referral&amp;utm_content=creditCopyText">Art by Lønfeldt</a> on <a href="https://unsplash.com/search/photos/abstract?utm_source=unsplash&amp;utm_medium=referral&amp;utm_content=creditCopyText">Unsplash</a></figcaption></figure><p>Generative Adversarial Networks are a powerful class of neural networks with remarkable applications. They essentially consist of a system of two neural networks — the <strong>Generator</strong> and the <strong>Discriminator </strong>— dueling each other.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/926/1*lhPwxtvyEntvCYnuRQd1nQ.png" /><figcaption>GANs in action. (<a href="https://leonardoaraujosantos.gitbooks.io/artificial-inteligence/content/generative_models.html">Source</a>)</figcaption></figure><p>Given a set of target samples, the <strong>Generator</strong> tries to produce samples that can <strong>fool</strong> the <strong>Discriminator</strong> into believing they are real. The <strong>Discriminator</strong> tries to <strong>resolve</strong> <strong>real</strong> (target) samples from <strong>fake</strong> (generated) samples. Using this iterative training approach, we eventually end up with a Generator that is really good at generating samples similar to the target samples.</p><p>GANs have a plethora of applications, as they can learn to mimic data distributions of almost any kind. Popularly, GANs are used for removing artefacts, super resolution, pose transfer, and literally any kind of image translation, as shown below:</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*aZTXGhMpdOGUf4Z60ZpNcA.png" /><figcaption>Image translation using GANs. (<a href="https://phillipi.github.io/pix2pix/">Source</a>)</figcaption></figure><p>However, they are <strong>excruciatingly difficult</strong> to work with, owing to its <strong>fickle stability</strong>. Needless to say, many researchers have proposed brilliant solutions to mitigate some of the problems involved with training GANs. However, the research in this area evolved so fast that, it became hard to keep track of interesting ideas. This blog makes an effort to list out some popular techniques that are commonly used to make GAN training stable.</p><h3>Drawbacks of using GANs — An Overview</h3><p>GANs are difficult to work with for a bunch of reasons. Some of them are listed below in this section.</p><h4>1. Mode collapse</h4><p><strong>Natural</strong> <strong>data</strong> distributions are highly complex and <strong>multimodal</strong>. That is, the data distribution has a lot of “peaks” or “modes”. Each mode represents a concentration of similar data samples, but are distinct from other modes.</p><p>During mode collapse, the generator produces samples that belong to a <strong>limited set of modes</strong>. This happens when the generator believes that it can fool the discriminator by locking on to a single mode. That is, the generator produces samples exclusively from this mode.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/841/1*cGfM4M9PGijW9pvg32BZzg.png" /><figcaption>The image at the top represents the output of a GAN without mode collapse. The image at the bottom represents the output of a GAN with mode collapse. (<a href="https://arxiv.org/pdf/1611.02163.pdf">Source</a>)</figcaption></figure><p>The discriminator eventually figures out that samples from this mode are fake. As a result, the generator simply locks on to another mode. This cycle repeats indefinitely, and this essentially limits the diversity of the generated samples. For a more detailed explanation, you can check out this <a href="http://aiden.nibali.org/blog/2017-01-18-mode-collapse-gans/">blog</a>.</p><h4>2. Convergence</h4><p>A common question in GAN training is “when do we stop training them?”. Since the Generator loss improves when the Discriminator loss degrades (and vice-versa), we can not judge convergence based on the value of the loss function. This is illustrated by the image below:</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/393/1*FlJ8ijfnwfpsy5GJGQaAkQ.png" /><figcaption>Plot of a typical GAN loss function. Note how convergence cannot be interpreted from this plot. (<a href="https://medium.com/@sanketgujar95/gans-in-tensorflow-261649d4f18d">Source</a>)</figcaption></figure><h4>3. Quality</h4><p>As with the previous problem, it is difficult to quantitatively tell when the generator produces high quality samples. Additional perceptual regularization added to the loss function can help mitigate the situation to some extent.</p><h4>4. Metrics</h4><p>The GAN objective function explains how well the Generator or the Discriminator is performing with respect to its opponent. It does not however represent the quality or the diversity of the output. Hence, we need distinct metrics that can measure the same.</p><h3>Terminologies</h3><p>Before we dive deep into techniques that can aid performance, let us review some terminologies. This will simplify explanations of the techniques presented in the next section.</p><h4>1. Infimum and Supremum</h4><p>Put simply, Infimum is the largest lower bound of a set. Supremum is the smallest upper bound of a set. They differ from minimum and maximum in the sense that the infimum and supremum need not belong to the set.</p><h4>2. Divergence Measures</h4><p>Divergence measures represent the distance between two distributions. Conventional GANs essentially minimize the <a href="https://en.wikipedia.org/wiki/Jensen%E2%80%93Shannon_divergence">Jensen Shannon divergence</a> between the real data distribution and the generated data distribution. GAN loss functions can be modified to minimize other divergence measures such as the <a href="https://en.wikipedia.org/wiki/Kullback%E2%80%93Leibler_divergence">Kulback Leibler divergence</a> or <a href="https://en.wikipedia.org/wiki/Total_variation_distance_of_probability_measures">Total Variation Distance</a>. Popularly, the Wasserstein GAN minimises the <a href="https://en.wikipedia.org/wiki/Earth_mover%27s_distance">Earth Mover distance</a>.</p><h4>3. Kantorovich Rubenstein Duality</h4><p>Some divergence measures are intractable to optimize in their naive form. However, their dual form (replacing infimum with supremum or vice-versa) may be tractable to optimize. The duality principle lays a framework for transforming one form to another. For a very detailed explanation about the same, you can check out this<a href="https://vincentherrmann.github.io/blog/wasserstein/"> blog post</a>.</p><h4>4. Lipschitz continuity</h4><p>A Lipschitz continuous function is limited in how fast it can change. For a function to be Lipschitz continuous, the absolute value of the slope of the function’s graph (for any pair of points) cannot be more than a real value K. Such functions are also known as K-Lipschitz continuous.</p><p>Lipschitz continuity is desired in GANs as they bound the gradients of the discriminator, essentially preventing the exploding gradient problem. Moreover, the Kantorovich-Rubinstein duality requires it for a Wasserstein GAN, as mentioned in this excellent <a href="https://christiancosgrove.com/blog/2018/01/04/spectral-normalization-explained.html">blog post</a>.</p><h3>Techniques for Improving Performance</h3><p>There are a plethora of tricks and techniques that can be used for making GANs more stable and powerful. To keep this blog concise I’ve only explained techniques that are either relatively new or complex. I’ve listed out other miscellaneous tricks and techniques at the end of this section.</p><h4>1. Alternative Loss Functions</h4><p>One of the most popular fixes to the shortcomings of GANs is the <a href="https://arxiv.org/abs/1701.07875"><strong>Wasserstein GAN</strong></a>. It essentially replaces the Jensen Shannon divergence of conventional GANs with the <strong>Earth Mover distance</strong> (Wasserstein-1 distance or EM distance). The original form of the EM distance is intractable, and hence we use its dual form (calculated by the Kantorovich Rubenstein Duality). This requires the discriminator to be <strong>1-Lipschitz</strong>, which is maintained by <strong>clipping the weights</strong> of the discriminator.</p><p>The advantage of using Earth Mover distance is that it is <strong>continuous</strong> even when the real and generated data distributions are disjoint, unlike JS or KL divergence. Also, there is a correlation between the generated image quality and the loss value (<a href="https://arxiv.org/pdf/1701.07875.pdf">Source</a>). The disadvantage is that, we need to perform several discriminator updates per generator update (as per the original implementation). Moreover, the authors claim that weight clipping is a terrible way to ensure 1-Lipschitz constraint.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/826/1*VlaZmJjPfi99qXtMAXWHNQ.png" /><figcaption>The earth mover distance (left) is continuous, even if the distributions are not continuous, unlike the Jensen Shannon divergence (right). Refer to this <a href="https://arxiv.org/pdf/1701.07875.pdf">paper</a> for a detailed explanation.</figcaption></figure><p>Another interesting solution is to use mean squared loss instead of log loss. The authors of the <a href="https://arxiv.org/abs/1611.04076"><strong>LSGAN</strong></a> argue that the conventional GAN loss function does not provide much incentive to “pull” the generated data distribution close to the real data distribution.</p><p>The log loss in the original GAN loss function does not bother about the distance of the generated data from the decision boundary (the decision boundary separates real and fake data). LSGAN on the other hand<strong> penalizes</strong> <strong>generated samples</strong> that are<strong> far away</strong> from the <strong>decision boundary</strong>, essentially “pulling” the generated data distribution closer to the real data distribution. It does this by replacing the log loss with mean squared loss. For a detailed explanation of the same, check out this <a href="https://wiseodd.github.io/techblog/2017/03/02/least-squares-gan/">blog</a>.</p><h4>2. Two Timescale Update Rule (TTUR)</h4><p>In this method, we use a <strong>different learning rate</strong> for the discriminator and the generator (<a href="https://arxiv.org/pdf/1706.08500.pdf">Source</a>). Typically, a slower update rule is used for the generator and a faster update rule is used for the discriminator. Using this method, we can perform generator and discriminator updates in 1:1 ratio, and just tinker with the learning rates. Notably, the <a href="https://arxiv.org/abs/1805.08318">SAGAN</a> implementation uses this method.</p><h4>3. Gradient Penalty</h4><p>In the paper <a href="https://arxiv.org/abs/1704.00028">Improved Training of WGANs</a>, the authors claim that <strong>weight clipping</strong> (as originally performed in WGANs) lead to <strong>optimization issues</strong>. They claim that weight clipping forces the neural network to learn “simpler approximations” to the optimal data distribution, leading to <strong>lower quality results</strong>. They also claim that weight clipping leads to the <strong>exploding or vanishing gradient problem</strong>, if the WGAN hyperparameter is not set properly. The author introduces a simple gradient penalty which is added to the loss function such that the above problems are mitigated. Moreover, <strong>1-Lipschitz </strong>continuity is maintained, as in the original WGAN implementation.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/617/1*413LI5UXQFbRp77q89Qpew.png" /><figcaption>Gradient penalty added as regularizer, as in the original WGAN-GP paper. (<a href="https://arxiv.org/pdf/1704.00028.pdf">Source</a>)</figcaption></figure><p>The authors of <a href="https://arxiv.org/abs/1705.07215"><strong>DRAGAN</strong></a> claim that mode collapse occurs when the game played by the GAN (i.e. discriminator and generator going against each other) reaches a “local equilibrium state”. They also claim that the gradients contributed by the discriminator around such states are “sharp”. Naturally, using a gradient penalty will help us circumvent these states, greatly enhancing stability and reducing mode collapse.</p><h4>4. Spectral Normalization</h4><p>Spectral normalization is a <strong>weight normalization technique</strong> that is typically used on the Discriminator to enhance the training process. This essentially ensures that the Discriminator is <strong>K-Lipschitz</strong> continuous.</p><p>Some implementations like the <a href="https://arxiv.org/abs/1805.08318">SAGAN</a> used spectral normalization on the Generator as well. It is also stated that this method is computationally more efficient than Gradient Penalty (<a href="https://christiancosgrove.com/blog/2018/01/04/spectral-normalization-explained.html">Source</a>).</p><h4>5. Unrolling and Packing</h4><p>As stated in this excellent <a href="http://aiden.nibali.org/blog/2017-01-18-mode-collapse-gans/">blog</a>, one way to prevent mode hopping is to peek into the future and <strong>anticipate counterplay </strong>when updating parameters. Unrolled GANs enables the Generator to fool the Discriminator, after the discriminator had a chance to respond (taking counterplay into account).</p><p>Another way of preventing mode collapse is to “pack” several samples belonging to the same class before passing it to the Discriminator. This method is incorporated in <a href="https://arxiv.org/abs/1712.04086"><strong>PacGAN</strong></a>, in which they have reported decent reduction of mode collapse.</p><h4>6. Stacking GANs</h4><p>A single GAN may not be powerful enough to handle a task effectively. We could instead use multiple GANs placed consecutively, where each GAN solves an easier version of the problem. For instance, <a href="https://www.cs.toronto.edu/~urtasun/publications/zhu_etal_iccv17.pdf"><strong>FashionGAN</strong></a> used two GANs to perform localized image translation.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*KXwyQG2HMQ8EvMqSNVnUYw.png" /><figcaption>FashionGAN used two GANs to perform localized image translation. (<a href="https://www.cs.toronto.edu/~urtasun/publications/zhu_etal_iccv17.pdf">Source</a>)</figcaption></figure><p>Taking this concept to the extreme, we can gradually increase the difficulty of the problem presented to our GANs. For instance, Progressive GANs (<a href="https://arxiv.org/abs/1710.10196">ProGANs</a>) can generate high quality images of excellent resolution.</p><h4>7. Relativistic GANs</h4><p>Conventional GANs measure the probability of the generated data being real. Relativistic GANs measure the probability of the generated data being “more realistic” than the real data. We can measure this “relative realism” using an appropriate distance measure, as mentioned in the <a href="https://arxiv.org/abs/1807.00734">RGAN paper</a>.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*INq5F_CDRUmZOo7ASt6a6g.png" /><figcaption>Output of the discriminator when using the standard GAN loss (image B). Image C represents how the output curve should actually look like. Image A represents the optimal solution to the JS divergence. (<a href="https://arxiv.org/abs/1807.00734">Source</a>)</figcaption></figure><p>The authors also mention that the discriminator output should converge to <strong>0.5</strong> when it has reached the optimal state. However, conventional GAN training algorithms force the discriminator to output “real” (i.e. <strong>1</strong>) for any image. This, in a way, prevents the discriminator from reaching its optimal value. The relativistic method solves this issue as well, and has pretty remarkable results, as shown below.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*nMzTMXmBoVcRcb0ey34Cvw.jpeg" /><figcaption>Output of a standard GAN (left) and a relativistic GAN (right) after 5000 iterations. (<a href="https://medium.com/@jonathan_hui/gan-rsgan-ragan-a-new-generation-of-cost-function-84c5374d3c6e">Source</a>)</figcaption></figure><h4>8. Self Attention Mechanism</h4><p>The authors of <a href="https://arxiv.org/abs/1805.08318">Self Attention GANs</a> claim that <strong>convolutions</strong> used for generating images look at <strong>information</strong> that are <strong>spread locally</strong>. That is, they <strong>miss out</strong> on <strong>relationships</strong> that <strong>span globally</strong> due to their restrictive receptive field.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*Vvu3U3aKgFMFMF2zBj0Byg.jpeg" /><figcaption>Adding the attention map (calculated in the yellow box) to the standard convolution operation. (<a href="https://arxiv.org/pdf/1805.08318.pdf">Source</a>)</figcaption></figure><p>Self-Attention Generative Adversarial Network allows attention-driven, long-range dependency modeling for image generation tasks. The <strong>self-attention</strong> mechanism is <strong>complementary</strong> to the normal convolution operation. The global information (long range dependencies) aid in generating images of higher quality. The network can <strong>choose to ignore</strong> the attention mechanism, or consider it along with normal convolutions. For a detailed explanation, you can check out their <a href="https://arxiv.org/pdf/1805.08318.pdf">paper</a>.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*tuIw6Iys9MYJPHa_XBTxYQ.png" /><figcaption>Visualization of the attention map for the location marked by the red dot. (<a href="https://medium.com/@jonathan_hui/gan-self-attention-generative-adversarial-networks-sagan-923fccde790c">Source</a>)</figcaption></figure><h4>9. Miscellaneous Techniques</h4><p>Here is a list of some additional techniques (not exhaustive!) that are used to improve GAN training:</p><ul><li>Feature Matching</li><li>Mini Batch Discrimination</li><li>Historical Averaging</li><li>One-sided Label Smoothing</li><li>Virtual Batch Normalization</li></ul><p>You can read up more about these techniques in this <a href="https://arxiv.org/pdf/1606.03498.pdf">paper</a>, and from this <a href="https://lilianweng.github.io/lil-log/2017/08/20/from-GAN-to-WGAN.html#improved-gan-training">blog post</a>. A lot more techniques are listed in this <a href="https://github.com/soumith/ganhacks">GitHub repository</a>.</p><h3>Metrics</h3><p>Now that we have established methods to improve training, we need to quantitatively prove it. The following metrics are often used to measure the performance of a GAN:</p><h4>1. Inception Score</h4><p>The inception score measures how “real” the generated data is.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/444/1*yDUeYnwIjJsLcaWHARKLbQ.png" /><figcaption>The Inception Score. (<a href="https://arxiv.org/pdf/1801.01973.pdf">Source</a>)</figcaption></figure><p>The equation has two components p(y|x) and p(y) . Here, x is the image that is produced by the Generator, and p(y|x) is the probability distribution obtained, when you pass image x through a pre-trained Inception Network (pretrained on the ImageNet dataset, as in the <a href="https://arxiv.org/pdf/1801.01973.pdf">original implementation</a>). Also, p(y) is the marginal probability distribution, which can be calculated by averaging p(y|x) over a few distinct samples of generated images (x). These two terms represent <strong>two different qualities</strong> that are desirable on real images:</p><ol><li>The generated image must have objects that are “<strong>meaningful</strong>” (objects are clear, and not blurry). This means that p(y|x) should have “<strong>low entropy</strong>”. In other words, our Inception Network must be strongly confident that the generated image belongs to a particular class.</li><li>The generated images should be “<strong>diverse</strong>”. This means that p(y) should have “<strong>high entropy</strong>”. In other words, generator should produce images such that each image represents a different class label (ideally).</li></ol><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*7qF9eTRu41frGGUDMK59sA.png" /><figcaption>Ideal plots of p(y|x) and p(y). Such a pair would have a really large KL divergence. (<a href="https://medium.com/@jonathan_hui/gan-how-to-measure-gan-performance-64b988c47732">Source</a>)</figcaption></figure><p>If a random variable is <strong>highly predictable</strong>, it has <strong>low entropy</strong> (i.e. p(y|x)must be a distribution with a sharp peak). On the contrary, if it is <strong>unpredictable</strong>, it has <strong>high entropy</strong> (i.e. p(y) must be a uniform distribution). If both these traits are satisfied, we should expect a <strong>large KL divergence</strong> between p(y|x) and p(y) . Naturally, a large Inception Score (IS) is better. For a deeper analysis on the Inception Score, you can checkout this <a href="https://arxiv.org/pdf/1801.01973.pdf">paper</a>.</p><h4>2. Fréchet Inception Distance (FID)</h4><p>A<strong> drawback</strong> of the Inception Score is that <strong>statistics</strong> of the real data are <strong>not compared</strong> with the statistics of the generated data (<a href="https://arxiv.org/pdf/1706.08500.pdf">Source</a>). Fréchet distance resolves the drawback by comparing the mean and covariance of the real and generated images. Fréchet Inception Distance (FID) performs the same analysis, but on the feature maps produced by passing the real and generated images through a pre-trained Inception-v3 Network (<a href="https://nealjean.com/ml/frechet-inception-distance/">Source</a>). The equation is described as follows:</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/535/1*Pz1TEP1UWByU0sQW7psnjQ.png" /><figcaption>FID compares the mean and covariance of the real and generated data distributions. Tr stands for Trace. (<a href="https://nealjean.com/ml/frechet-inception-distance/">Source</a>)</figcaption></figure><p>A <strong>lower FID score is better</strong>, as it explains that the statistics of the generated images are very similar to that of the real images.</p><h3>Conclusion</h3><p>The research community has produced numerous solutions and hacks to overcome the shortcomings of GAN training. However, it is difficult to keep track of significant contributions due to the sheer volume of new research. The details shared in this blog is not exhaustive for the same reason, and may become outdated in the near future. Nevertheless, I hope this blog serves as a guideline for people looking for methods to improve the performance of their GANs.</p><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=7bad57028032" width="1" height="1" alt=""><hr><p><a href="https://medium.com/beyondminds/advances-in-generative-adversarial-networks-7bad57028032">Advances in Generative Adversarial Networks</a> was originally published in <a href="https://medium.com/beyondminds">BeyondMinds</a> on Medium, where people are continuing the conversation by highlighting and responding to this story.</p>]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[How to Fit Large Neural Networks on the Edge]]></title>
            <link>https://heartbeat.comet.ml/how-to-fit-large-neural-networks-on-the-edge-eb621cdbb33?source=rss-7d6e83a807b8------2</link>
            <guid isPermaLink="false">https://medium.com/p/eb621cdbb33</guid>
            <category><![CDATA[machine-learning]]></category>
            <category><![CDATA[deep-learning]]></category>
            <category><![CDATA[heartbeat]]></category>
            <category><![CDATA[mlops]]></category>
            <category><![CDATA[neural-networks]]></category>
            <dc:creator><![CDATA[Bharath Raj]]></dc:creator>
            <pubDate>Tue, 21 Aug 2018 14:37:09 GMT</pubDate>
            <atom:updated>2021-09-23T14:23:15.776Z</atom:updated>
            <content:encoded><![CDATA[<h4>Exploring techniques used to fit neural networks in memory-constrained edge settings</h4><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*GKgHihXIRl3EN_Q4Xf_y2w.jpeg" /></figure><p>Deploying memory-hungry deep learning algorithms is a challenge for anyone who wants to create a scalable service. Cloud services are expensive in the long run. <a href="https://heartbeat.fritz.ai/machine-learning-on-ios-and-android-bd77f6e92c7b">Deploying models offline on edge devices</a> is cheaper, and has <a href="https://towardsdatascience.com/deep-learning-on-the-edge-9181693f466c">other benefits</a> as well. The only disadvantage is that they have a paucity of memory and compute power.</p><p>This blog explores a few techniques that can be used to fit neural networks in memory-constrained settings. Different techniques are used for the “training” and “inference” stages, and hence they are discussed separately.</p><h3>Training</h3><p>Certain applications require online learning. That is, the model improves based on feedback or additional data. Deploying such applications on the edge places a tangible resource constraint on your model. Here are 4 ways you can reduce the memory consumption of such models.</p><h4>1. Gradient Checkpointing</h4><p>Frameworks such as TensorFlow consume a lot of memory for training. During a forward pass, the value at every node in the graph is evaluated and saved in memory. This is required for calculating the gradient during backprop.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/541/1*Xko6SWaBYjGdCyUcuzCOOg.gif" /><figcaption>Value of every node is saved after a forward pass to calculate the gradient in a single backward pass. (<a href="https://github.com/openai/gradient-checkpointing">Source</a>)</figcaption></figure><p>Normally this is okay, but when models get deeper and more complex, the memory consumption increases drastically. A neat sidestep solution to this is to recompute the values of the node when needed, instead of saving them to memory.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/541/1*WfizUwplzHUMVQ9m5nWDAw.gif" /><figcaption>Recomputing the node values to calculate the gradient. Note that we need to do several partial forward passes to complete a single backward pass. (<a href="https://github.com/openai/gradient-checkpointing">Source</a>)</figcaption></figure><p>However, as shown above, the computational cost increases significantly. A good trade-off is to save only some nodes in memory while recomputing the others when needed. These saved nodes are called checkpoints. This drastically reduces deep neural network memory consumption. This is illustrated below:</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/541/1*cGCJWpGSW67XFaeKf2k2TQ.gif" /><figcaption>The second node from the left is a checkpoint node. It reduces memory consumption while providing a reasonable time penalty. (<a href="https://github.com/openai/gradient-checkpointing">Source</a>)</figcaption></figure><h4>2. Trade speed for memory (Recomputation)</h4><p>Extending on the above idea, we can recompute certain operations to save time. A good example for this is the <a href="https://arxiv.org/pdf/1707.06990.pdf">Memory Efficient DenseNet</a> implementation.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/427/1*ffeZyApPiJ_RCjCICeJyGg.jpeg" /><figcaption>A dense block in a DenseNet. (<a href="https://arxiv.org/abs/1608.06993">Source</a>)</figcaption></figure><p>DenseNets are very parameter efficient, but are also memory inefficient. The paradox arises because of the nature of the concatenation and batchnorm operations.</p><p>To make convolution efficient on the GPU, the values must be placed contiguously. Hence, after concatenation, cudNN arranges the values contiguously on the GPU. This involves a lot of redundant memory allocation. Similarly, batchnorm involves excess memory allocation, as explained in this <a href="https://arxiv.org/pdf/1707.06990.pdf">paper</a>. Both operations contribute to a quadratic growth in memory. DenseNets have have a large number of concatenations and batchnorms, and hence they are memory inefficient.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/976/1*Od0_xGWp_r_8tPYIALlgeg.png" /><figcaption>Comparing naive concat and batchnorm operations to their memory efficient counterparts. (<a href="https://arxiv.org/pdf/1707.06990.pdf">Source</a>)</figcaption></figure><p>A neat solution to the above involves two key observations.</p><p>Firstly, concatenation and batchnorm operations are not time intensive. Hence, we can just recompute the values when needed, instead of storing all the redundant memory. Secondly, instead of allocating “new” memory space for the output, we can use a “shared memory space” to dump the output.</p><p>We can overwrite this shared space to store output of other concatenation operations. We can recompute the concatenation operation for gradient calculation when needed. Similarly, we can extend this for the batchnorm operation. This simple trick saves a lot of GPU memory, in exchange for slightly increased compute time.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/952/1*JqY8-B1zJWMt9t54iB-JyQ.png" /></figure><h4>3. Reduce Precision</h4><p>In an excellent <a href="https://petewarden.com/2015/05/23/why-are-eight-bits-enough-for-deep-neural-networks/">blog</a>, Pete Warden explains how neural networks can be trained with 8-bit float values. There are a number of issues that accrue because of <a href="https://heartbeat.fritz.ai/8-bit-quantization-and-tensorflow-lite-speeding-up-mobile-inference-with-low-precision-a882dfcafbbd">reduction in precision</a>, some of which are listed below:</p><ul><li>As stated in this <a href="https://arxiv.org/pdf/1412.7024.pdf">paper</a>, “activations, gradients, and parameters” have very different ranges. A fixed-point representation would not be ideal. The paper a claims that a “dynamic fixed point” representation would be an excellent fit for low precision neural networks.</li><li>As stated in Pete Warden’s other <a href="https://petewarden.com/2017/06/22/what-ive-learned-about-neural-network-quantization/">blog</a>, lower precision implies a greater deviation from the exact value. Normally, if the errors are totally random, they have a good chance of canceling each other out. However, zeros are used extensively for padding, dropout, and ReLU. An exact representation of zero in the lower precision float format may not be possible, and hence might introduce an overall bias in the performance.</li></ul><h4>4. Architecture Engineering for Neural Networks</h4><p>Architecture engineering involves designing the neural network structure that best optimizes accuracy, memory, and speed. There are several ways by which convolutions can be optimized space-wise and time-wise.</p><ul><li>Factorize NxN convolutions into a combinations of Nx1 and 1xN convolutions. This conserves a lot of space while also boosting computational speed. This and several other optimization tricks were used in newer versions of the Inception network. For a more detailed discussion, check out this <a href="https://towardsdatascience.com/a-simple-guide-to-the-versions-of-the-inception-network-7fc52b863202">blog post</a>.</li><li>Use <a href="https://heartbeat.fritz.ai/building-an-image-recognition-model-for-mobile-using-depthwise-convolutions-643d70e0f7e2">Depthwise Separable convolutions</a> as in <a href="https://arxiv.org/pdf/1704.04861.pdf">MobileNet</a> and <a href="https://arxiv.org/abs/1610.02357">Xception Net</a>. For an elaborate discussion on the types of convolutions, check out this <a href="https://towardsdatascience.com/types-of-convolutions-in-deep-learning-717013397f4d">blog post</a>.</li><li>Use 1x1 convolutions as a bottleneck to reduce the number of incoming channels. This technique is used in several popular neural networks.</li></ul><figure><img alt="" src="https://cdn-images-1.medium.com/max/796/1*ayowbX4wpOAcZsN8gW5znQ.png" /><figcaption>Illustration of Google’s AutoML. (<a href="https://www.youtube.com/watch?v=Y2VF8tmLFHw">Source</a>)</figcaption></figure><p>An interesting solution is to <strong>let the machine decide the best architecture</strong> for a particular problem. <a href="https://arxiv.org/pdf/1707.07012.pdf">Neural Architecture Search</a> uses machine learning to find the best neural network architecture for a given classification problem. When used on ImageNet, the network formed as a result (NASNet) was among the best performing models created so far. Google’s <a href="https://ai.googleblog.com/2017/11/automl-for-large-scale-image.html">AutoML</a> works on the same principle.</p><blockquote>Deep learning — For experts, by experts. We’re using our decades of experience to deliver <a href="https://www.deeplearningweekly.com/?utm_campaign=dlweekly-newsletter-expertise4&amp;utm_source=heartbeat">the best deep learning resources to your inbox each week</a>.</blockquote><h3>Inference</h3><p>Fitting models for edge inference is relatively easier. This section covers techniques that can be used to optimize your neural network for such edge devices.</p><h4>1. Removing “Bloatware”</h4><p>Machine learning frameworks such as TensorFlow consume a lot of memory space for creating graphs. This additional space is useful for speeding up the training processes, but it isn’t used for inference. Hence, the part of the graph used exclusively for training can be pruned off. Let’s call this part of the graph <em>bloatware</em>.</p><p>For TensorFlow, it’s recommended to convert model checkpoints to frozen inference graphs. This process automatically removes the memory-hungry bloatware. Graphs from model checkpoints that throw <em>Resource Exhausted Error</em> can sometimes be fit into memory when converted to a frozen inference graph.</p><h4>2. Pruning Features</h4><p>Some machine learning models on Scikit-Learn (such as Random Forest and <a href="https://heartbeat.fritz.ai/boosting-your-machine-learning-models-using-xgboost-d2cabb3e948f">XGBoost</a>) output an attribute named feature_importances_. This attribute represents the significance of each feature for the classification or <a href="https://heartbeat.fritz.ai/5-regression-loss-functions-all-machine-learners-should-know-4fb140e9d4b0">regression</a> task. We can simply prune the features with the least significance. This can be extremely useful if your model has an excessively large number of features that you cannot reduce by any other method.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/800/1*8bg_EHw_ZJ5qzXuHRYuPEg.png" /><figcaption>Example of a feature importance plot. (<a href="https://machinelearningmastery.com/feature-importance-and-feature-selection-with-xgboost-in-python/">Source</a>)</figcaption></figure><p>Similarly, in neural networks, a lot of weight values are close to zero. We can simply prune those connections. However, removing individual connections between layers creates sparse matrices. There is work being done on creating <a href="https://arxiv.org/pdf/1602.01528.pdf">efficient inference engines</a> (hardware), which can handle sparse operations seamlessly. However, most machine learning frameworks convert sparse matrices to their dense form before sending them to the GPU.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/467/1*52TyqTAvDt2NiCU4913a-Q@2x.png" /><figcaption>Pruning an insignificant filter. (<a href="http://machinethink.net/blog/compressing-deep-neural-nets/">Source</a>)</figcaption></figure><p>Instead, we can remove insignificant neurons and slightly retrain the model. For <a href="https://heartbeat.fritz.ai/a-beginners-guide-to-convolutional-neural-networks-cnn-cf26c5ee17ed">CNNs</a>, we can remove entire filters, too. <a href="https://arxiv.org/pdf/1510.00149.pdf">Research</a> and <a href="http://machinethink.net/blog/compressing-deep-neural-nets/">experiments</a> have shown that we could retain most of the accuracy, while obtaining a massive reduction in size, by using this method.</p><h4>3. Weight Sharing</h4><p>To best illustrate weight sharing, consider the example given in this <a href="https://arxiv.org/pdf/1510.00149.pdf">Deep Compression paper</a>. Consider a 4x4 weight matrix. It has 16 32-bit float values. We require 512 bits (16 * 32) to represent the matrix.</p><p>Let us quantize the weight values to 4 levels, but let’s preserve their 32-bit nature. Now, the 4x4 weight matrix has only 4 unique values. The 4 unique values are stored in a separate (shared) memory space. We can give each of the 4 unique values a 2-bit address (Possible address values being 0, 1, 2, and 3).</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/392/1*HrNhTvX9JiP5SG5ikA6QvA.png" /><figcaption>Weight sharing illustrated. (<a href="https://arxiv.org/pdf/1510.00149.pdf">Source</a>)</figcaption></figure><p>We can reference the weight values by using the 2-bit addresses. Hence, we obtain a new 4x4 matrix with 2-bit addresses, with each location in the matrix referring to a location in the shared memory space. This method requires 160 bits (16 * 2 + 4 * 32) for the entire representation. We obtain a size reduction factor of 3.2.</p><p>Needless to say, this reduction in size comes with an increase in time complexity. However, the time to access shared memory would not be a severe time penalty.</p><h4>4. Quantization and Lower Precision (Inference)</h4><p>Recall that we covered reduction in precision in the training part of this blog. For inference, reduction in precision is not as cumbersome as for training. The weights can just be converted to a <a href="https://heartbeat.fritz.ai/8-bit-quantization-and-tensorflow-lite-speeding-up-mobile-inference-with-low-precision-a882dfcafbbd">lower precision</a> format and be shipped off to inference. However, a sharp decrease in precision might require a slight readjustment of weight values.</p><h4>5. Encoding</h4><p>The pruned and quantized weights can be size-optimized further by using encoding. <a href="https://www.cs.ucsb.edu/~franklin/20/assigns/prog6files/HuffmanEncoding.htm">Huffman encoding</a> can represent the most frequent weight values with a lower number of bits. Hence, at the bit level, a Huffman encoded string takes a smaller space than a normal string.</p><p>Deep compression explores encoding using lossless compression techniques such as Huffman. However, <a href="https://arxiv.org/abs/1711.04686">research</a> has explored the use of lossy compression techniques as well. The downside to either method is the overhead of translation.</p><h4>6. Inference Optimizers</h4><p>We’ve discussed some great ideas so far, but implementing them from scratch would take quite some time. This is where inference optimizers kick in. For instance, Nvidia’s <a href="https://developer.nvidia.com/tensorrt">TensorRT</a> incorporates all of these great ideas (and more) and provides an <em>optimized inference engine</em> given a trained neural network.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*asvCqn1JXuzL0dDaqDTVkw.png" /><figcaption>TensorRT. (<a href="https://developer.nvidia.com/tensorrt">Source</a>)</figcaption></figure><p>Moreover, TensorRT can optimize the model such that it can make better use of Nvidia’s hardware. Below is an example where a model optimized with TensorRT uses Nvidia’s V100 more efficiently.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*AhFT3awnyhzrou8zJZz3rA.png" /><figcaption>Using model optimized by TensorRT on Nvidia’s V100. (<a href="https://devblogs.nvidia.com/tensorrt-3-faster-tensorflow-inference/">Source</a>)</figcaption></figure><h4>7. Knowledge Distillation</h4><p>Instead of performing fancy optimization techniques, we can teach smaller models to mimic the performance of beefy, larger models. This technique is called knowledge distillation, and it’s an integral part of Google’s <a href="https://ai.googleblog.com/2018/05/custom-on-device-ml-models.html">Learn2Compress</a>.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/640/1*Id6ZQBu9VgANtd8frCQK-w.png" /><figcaption>Teacher-Student models. (<a href="https://ai.googleblog.com/2018/05/custom-on-device-ml-models.html">Source</a>)</figcaption></figure><p>By using this method, we can force smaller models that can fit on edge devices to reach the performance levels of larger models. The drop in accuracy is reported to be minimal. You can refer to Hinton’s <a href="https://arxiv.org/pdf/1503.02531.pdf">paper</a> on the same for more information.</p><blockquote>Thank you for reading this article! Hope you found it interesting. Hit the clap button if you did! If you have any questions, you could hit me up on <a href="https://thatbrguy.github.io/">social media</a> or send me an email (bharathrajn98[at]gmail[dot]com).</blockquote><p><strong>Discuss this post on </strong><a href="https://www.reddit.com/r/MachineLearning/comments/993yve/d_how_to_fit_large_neural_networks_on_the_edge/"><strong>Reddit</strong></a><strong> and </strong><a href="https://news.ycombinator.com/item?id=17810371"><strong>Hacker News</strong></a><strong>.</strong></p><p><em>Editor’s Note:</em><a href="http://heartbeat.fritz.ai/"><em> Heartbeat</em></a><em> is a contributor-driven online publication and community dedicated to providing premier educational resources for data science, machine learning, and deep learning practitioners. We’re committed to supporting and inspiring developers and engineers from all walks of life.</em></p><p><em>Editorially independent, Heartbeat is sponsored and published by </em><a href="http://comet.ml/?utm_campaign=heartbeat-statement&amp;utm_source=blog&amp;utm_medium=medium"><em>Comet</em></a><em>, an MLOps platform that enables data scientists &amp; ML teams to track, compare, explain, &amp; optimize their experiments. We pay our contributors, and we don’t sell ads.</em></p><p><em>If you’d like to contribute, head on over to our</em><a href="https://heartbeat.fritz.ai/call-for-contributors-october-2018-update-fee7f5b80f3e"><em> call for contributors</em></a><em>. You can also sign up to receive our weekly newsletters (</em><a href="https://www.deeplearningweekly.com/"><em>Deep Learning Weekly</em></a><em> and the </em><a href="https://info.comet.ml/newsletter-signup/"><em>Comet Newsletter</em></a><em>), join us on</em><a href="https://join.slack.com/t/fritz-ai-community/shared_invite/enQtNTY5NDM2MTQwMTgwLWU4ZDEwNTAxYWE2YjIxZDllMTcxMWE4MGFhNDk5Y2QwNTcxYzEyNWZmZWEwMzE4NTFkOWY2NTM0OGQwYjM5Y2U"><em> </em></a><a href="https://join.slack.com/t/cometml/shared_invite/zt-49v4zxxz-qHcTeyrMEzqZc5lQb9hgvw"><em>Slack</em></a><em>, and follow Comet on </em><a href="https://twitter.com/Cometml"><em>Twitter</em></a><em> and </em><a href="https://www.linkedin.com/company/comet-ml/"><em>LinkedIn</em></a><em> for resources, events, and much more that will help you build better ML models, faster.</em></p><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=eb621cdbb33" width="1" height="1" alt=""><hr><p><a href="https://heartbeat.comet.ml/how-to-fit-large-neural-networks-on-the-edge-eb621cdbb33">How to Fit Large Neural Networks on the Edge</a> was originally published in <a href="https://heartbeat.comet.ml">Heartbeat</a> on Medium, where people are continuing the conversation by highlighting and responding to this story.</p>]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[How to Automate Surveillance Easily with Deep Learning]]></title>
            <link>https://medium.com/nanonets/how-to-automate-surveillance-easily-with-deep-learning-4eb4fa0cd68d?source=rss-7d6e83a807b8------2</link>
            <guid isPermaLink="false">https://medium.com/p/4eb4fa0cd68d</guid>
            <category><![CDATA[surveillance]]></category>
            <category><![CDATA[machine-learning]]></category>
            <category><![CDATA[tensorflow]]></category>
            <category><![CDATA[deep-learning]]></category>
            <category><![CDATA[computer-vision]]></category>
            <dc:creator><![CDATA[Bharath Raj]]></dc:creator>
            <pubDate>Fri, 03 Aug 2018 08:23:14 GMT</pubDate>
            <atom:updated>2018-08-10T08:30:05.416Z</atom:updated>
            <content:encoded><![CDATA[<blockquote>This article is a quick tutorial for implementing a surveillance system using Object Detection based on Deep Learning. It also compares the performance of different Object Detection models using GPU multiprocessing for inference, on Pedestrian Detection.</blockquote><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*csWLch8bSk4ic_tp6WSPJw.jpeg" /></figure><p>Surveillance is an integral part of security and patrol. For the most part, the job entails extended periods of looking out for something undesirable to happen. It is crucial that we do this, but also it is a very mundane task.</p><p>Wouldn’t life be much simpler if there was something that could do the “watching and waiting” for us? Well, you’re in luck. With the advancements in technology over the past few years, we could write some scripts to automate the above tasks — and that too, rather easily. But, before we dive deeper, let us ask ourselves:</p><h4>Are machines are good as humans?</h4><p>Anyone familiar with Deep Learning would know that image classifiers have surpassed human level accuracy.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/800/1*Oejgc8IivM4ZRQHVEgjqcw.png" /><figcaption>Error rate on the ImageNet dataset over time, for Humans, Traditional Computer Vision (CV) and Deep Learning. (Image source: <a href="https://www.dsiac.org/resources/journals/dsiac/winter-2017-volume-4-number-1/real-time-situ-intelligent-video-analytics">Link</a>)</figcaption></figure><p>So yes, a machine can keep a lookout for objects at the same standard (or better) when compared to a human. With that being said, using technology to perform surveillance is much more efficient.</p><ul><li>Surveillance is a repetitive and mundane task. This may cause performance dips for us human beings. By letting technology do the surveillance, we could focus on taking action if something goes amiss.</li><li>To survey a large strip of land, you need lots of personnel. Stationary cameras also have a limited range of view. With mobile surveillance bots (such as micro drones) these problems can be mitigated.</li></ul><p>Moreover, the same technology can be used for a variety of applications which are not limited to security, such as baby monitors or automated product delivery.</p><h3>Fair enough. But how do we automate it?</h3><p>Before we contrive complicated theories, let us think about how surveillance works normally. We look at a video feed, and if we spot something abnormal, we take action. So in essence, our technology should peruse every frame of the video, hoping to spot something abnormal. Does this process ring a bell?</p><p>As you may have guessed, this is the very essence of <strong>Object Detection with Localization. </strong>It is slightly different from classification that, we need to know the exact location of the object. Moreover, we may have multiple objects in a single image.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/700/1*ObF6-zNVK-1-q6w63IM2ug.jpeg" /></figure><p>To find the exact location, our algorithm should inspect every portion of the image to find the existence of a class. It is harder than it sounds. But since 2014, continuous iterative research in Deep Learning has introduced heavily engineered neural networks that can detect objects in real time.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*Bfb2EoLQFGqa4gBrON98LA.png" /><figcaption>Look at how performance increased over just a span of 2 years!</figcaption></figure><p>There are several Deep Learning architectures, that use different methods internally, to perform the same task. The most popular variants are the Faster RCNN, YOLO and the SSD networks.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*sNH_XnRaFxGKBJbLEXgwuQ.png" /><figcaption>Speed vs accuracy trade-off. A higher mAP and a lower GPU Time is optimal.</figcaption></figure><p>Each model depends on a base classifier, which greatly affects the final accuracy and model size. Moreover, the choice of the object detector can heavily influence computational complexity and final accuracy.</p><blockquote>There is always a Speed vs Accuracy vs Size trade-off when choosing an Object Detection algorithm.</blockquote><p>In this blog post, we will learn how to build a a simple but effective surveillance system, using Object Detection. Let us first discuss the constraints we are bound to because of the nature of the surveillance task.</p><h3>Constraints for Deep Learning in Surveillance</h3><p>Often we would like to keep a look-out over a large stretch of land. This brings forth a couple of factors that we may need to consider before automating surveillance.</p><h4>1. Video Feed</h4><p>Naturally, to keep a look-out over a large area, we may require multiple cameras. Moreover, these cameras need to store this data somewhere; either locally, or to a remote location.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*dW9pMZ7kw0Qa8gU7PiS2kg.jpeg" /><figcaption>Typical surveillance cameras. (Photo by <a href="https://unsplash.com/photos/yekGLpc3vro?utm_source=unsplash&amp;utm_medium=referral&amp;utm_content=creditCopyText">Scott Webb</a> on <a href="https://unsplash.com/search/photos/surveillance?utm_source=unsplash&amp;utm_medium=referral&amp;utm_content=creditCopyText">Unsplash</a>)</figcaption></figure><p>A higher quality video will take a lot more memory than a lower quality one. Moreover, an RGB input stream is 3x larger than a BW input stream. Since we can only store a finite amount of the input stream, the quality is often lowered to maximize storage.</p><p>Therefore, a scalable surveillance system should be able to interpret low quality images. Hence, our Deep Learning algorithm must be trained on such low quality images as well.</p><h4>2. Processing Power</h4><p>Now that we have resolved the input constraint, we can answer a bigger question. Where do we process the data obtained from camera sources? There are two methods of doing this.</p><ul><li><strong>Processing on a centralized server:</strong></li></ul><p>The video streams from the cameras are processed frame by frame on a remote server or a cluster. This method is robust, and enables us to reap the benefits of complex models with high accuracies. The obvious problem is latency; you need a fast Internet connection for limited delay. Moreover, if you are not using a commerical API, the server setup and maintenance costs can be high.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/690/1*AQAuo7fY13C-5ywAeD4hPg.png" /><figcaption>Memory consumption vs Inference GPU Time (milliseconds). Most high performance models consume a lot of memory. (<a href="https://arxiv.org/pdf/1611.10012.pdf">Source</a>)</figcaption></figure><ul><li><strong>Processing on the edge:</strong></li></ul><p>By attaching a small microcontroller, we can perform realtime inference on the camera itself. There is no transmission delay, and abnormalities can be reported faster than the previous method. Moreover, this is an excellent add on for bots that are mobile, so that they need not be constrained by range of WiFi/Bluetooth available. (such as microdrones).</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*91IEBjndluej6k7wt17GFw.png" /><figcaption>FPS capability of various object detectors. (<a href="https://medium.com/@jonathan_hui/object-detection-speed-and-accuracy-comparison-faster-r-cnn-r-fcn-ssd-and-yolo-5425656ae359">Source</a>)</figcaption></figure><p>The disadvantage is that, microcontrollers aren’t as powerful as GPUs, and hence you may be forced to use models with lower accuracy. This issue can be circumvented by using onboard GPUs, but that is an expensive solution. An interesting solution would be to use software such as TensorRT, which can optimize your program for inference.</p><h3>Training a Surveillance System</h3><p>In this section, we will checkout how to identify pedestrians using Object Detection. We’ll use the TensorFlow Object Detection API to create our Object Detection module. We will explore in brief on how to set up the API and train it for our surveillance task. For a more detailed explanation, you can checkout this <a href="https://medium.freecodecamp.org/how-to-play-quidditch-using-the-tensorflow-object-detection-api-b0742b99065d">blog post</a>.</p><h4>The entire process can be summarized in three phases:</h4><ol><li>Data preparation</li><li>Training the model</li><li>Inference</li></ol><figure><img alt="" src="https://cdn-images-1.medium.com/max/700/1*D85zUhvj5u7dHecM0XlRFA.jpeg" /><figcaption>The workflow involved in training an Object Detection model.</figcaption></figure><p>If you feel like seeing the results would motivate you more to try it out, feel free to scroll down to Phase 3!</p><h3>Phase 1: Data Preparation</h3><h4>Step 1: Obtain the dataset</h4><p>Surveillance footage taken in the past is probably the most accurate dataset you can get. But, it’s often hard to obtain such surveillance footage for most cases. In that case, we can train our object detector to generally recognize our targets from normal images.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*dUiiquKeRQFRhZ82ix4ICw.jpeg" /><figcaption>Sample annotated image from our dataset.</figcaption></figure><p>As discussed before, the images in your camera feed maybe of lower quality. So you must train your model to work in such conditions. A very elegant way of doing that is by performing data augmentation, which is explained in detail <a href="https://medium.com/nanonets/how-to-use-deep-learning-when-you-have-limited-data-part-2-data-augmentation-c26971dc8ced">here</a>. Essentially, we have to add some noise to degrade the image quality of the dataset. We could also experiment with blur and erosion effects.</p><p>We’ll use the <a href="http://www.robots.ox.ac.uk/ActiveVision/Research/Projects/2009bbenfold_headpose/project.html#datasets">TownCentre Dataset</a> for our object detection task. We’ll use the first 3600 frames of the video for training and validation, and the remaining 900 for testing. You can use the scripts in my <a href="https://github.com/thatbrguy/Pedestrian-Detector">GitHub repo</a> to extract the dataset.</p><h4>Step 2: Annotate the dataset</h4><p>You could use a tool such as LabelImg to perform the annotations. This is a tedious task, but important all the same. The annotations are saved as XML files.</p><p>Luckily, the owners of the <a href="http://www.robots.ox.ac.uk/ActiveVision/Research/Projects/2009bbenfold_headpose/project.html#datasets">TownCentre Dataset</a> have provided annotations in csv format. I wrote a quick script to convert the annotations to the required XML format, which you can find in my <a href="https://github.com/thatbrguy/Pedestrian-Detector">GitHub repo</a>.</p><h4>Step 3: Clone the repository</h4><p>Clone the<a href="https://github.com/thatbrguy/Pedestrian-Detector"> repository</a>. Run the following commands to install requirements, compile some Protobuf libraries and set path variables</p><pre>pip install -r requirements.txt<br>sudo apt-get install protobuf-compiler<br>protoc object_detection/protos/*.proto --python_out=.<br>export PYTHONPATH=$PYTHONPATH:`pwd`:`pwd`/slim</pre><h4>Step 4: Prepare the supporting inputs</h4><p>We need to assign an ID to our target. We define the ID in file called label_map.pbtxt as follows</p><pre>item {<br> id: 1<br> name: ‘target’<br>}</pre><p>Next, you must create a text file with the names of the XML and image files. For instance, if you have img1.jpg, img2.jpg and img1.xml, img2.xml in your dataset, you trainval.txt file should look like this:</p><pre>img1<br>img2</pre><p>Separate your dataset into two folders, namely <strong>images</strong> and <strong>annotations</strong>. Place the <strong>label_map.pbtxt</strong> and <strong>trainval.txt </strong>inside your annotations folder. Create a folder named <strong>xmls </strong>inside the annotations folder and place all your XMLs inside that. Your directory hierarchy should look something like this:</p><pre>-base_directory<br>|-images<br>|-annotations<br>||-xmls<br>||-label_map.pbtxt<br>||-trainval.txt</pre><h4>Step 5: Create TF Records</h4><p>The API accepts inputs in the <strong>TFRecords</strong> file format. Use the <strong>create_tf_record.py </strong>file provided in my <a href="https://github.com/thatbrguy/Pedestrian-Detector">repo</a> to convert your dataset into TFRecords. You should execute the following command in your base directory:</p><pre>python create_tf_record.py \<br>    --data_dir=`pwd` \<br>    --output_dir=`pwd`</pre><p>You will find two files, <strong>train.record</strong> and <strong>val.record</strong>, after the program finishes its execution.</p><h3>Phase 2: Training the model</h3><h4>Step 1: Model Selection</h4><p>As mentioned before, there is a trade off between speed and accuracy. Also, building and training an object detector from scratch would be extremely time consuming. So, the TensorFlow Object Detection API provides a bunch of pre-trained models, which you can fine tune to your use case. This process is known as <a href="https://medium.com/nanonets/nanonets-how-to-use-deep-learning-when-you-have-limited-data-f68c0b512cab">Transfer Learning</a>, and it speeds up your training process by an enormous amount.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*YfELRLCcGoNYCI-tV260zg.png" /><figcaption>A bunch of models pre-trained on the MS COCO Dataset</figcaption></figure><p>Download one of these models, and extract the contents into your base directory. You will receive the model checkpoints, a frozen inference graph, and a pipeline.config file.</p><h4>Step 2: Defining the training job</h4><p>You have to define the “training job” in the <strong>pipeline.config</strong> file. Place the file in the base directory. What really matters is the last few lines of the file — you only need to set the highlighted values to your respective file locations.</p><pre>gradient_clipping_by_norm: 10.0<br>  fine_tune_checkpoint: &quot;<strong>model.ckpt</strong>&quot;<br>  from_detection_checkpoint: true<br>  num_steps: 200000<br>}<br>train_input_reader {<br>  label_map_path: &quot;<strong>annotations/label_map.pbtxt</strong>&quot;<br>  tf_record_input_reader {<br>    input_path: &quot;<strong>train.record</strong>&quot;<br>  }<br>}<br>eval_config {<br>  num_examples: 8000<br>  max_evals: 10<br>  use_moving_averages: false<br>}<br>eval_input_reader {<br>  label_map_path: &quot;<strong>annotations/label_map.pbtxt</strong>&quot;<br>  shuffle: false<br>  num_epochs: 1<br>  num_readers: 1<br>  tf_record_input_reader {<br>    input_path: &quot;<strong>val.record</strong>&quot;<br>  }<br>}</pre><h4>Step 3: Commence training</h4><p>Execute the below command to start the training job. It’s recommended to use a machine with a large enough GPU (provided you installed the gpu version of tensorflow) to accelerate the training process.</p><pre>python object_detection/train.py \<br>--logtostderr \<br>--pipeline_config_path=pipeline.config \<br>--train_dir=train</pre><h3>Phase 3: Inference</h3><h4>Step 1: Export the trained model</h4><p>Before you can use the model, you need to export the trained checkpoint files to a frozen inference graph. It’s actually easier done than said — just execute the code below (Replace ‘xxxxx’ with the checkpoint number):</p><pre>python object_detection/export_inference_graph.py \<br>--input_type=image_tensor \<br>--pipeline_config_path=pipeline.config \<br>--trained_checkpoint_prefix=train/model.ckpt-<strong>xxxxx</strong> \<br>--output_directory=output</pre><p>You will obtain a file named <strong>frozen_inference_graph.pb</strong>, along with a bunch of checkpoint files.</p><h4>Step 2: Use it on a video stream</h4><p>We need to extract individual frames from our video source. It can done by using OpenCV’s VideoCapture method, as follows:</p><pre>cap = cv2.VideoCapture()<br>flag = True</pre><pre>while(flag):<br>    flag, frame = cap.read()<br>    ## -- Object Detection Code --</pre><p>The data extraction code used in Phase 1 automatically creates a folder ‘test_images’ with our test set images. We can run our model on the test set by executing the following:</p><pre>python object_detection/inference.py \<br>--input_dir=<strong>{PATH}</strong> \<br>--output_dir=<strong>{PATH}</strong> \<br>--label_map=<strong>{PATH}</strong> \<br>--frozen_graph=<strong>{PATH}</strong> \<br>--num_output_classes=1<strong> \<br></strong>--n_jobs=1 \<br>--delay=0</pre><h3>Experiments</h3><p>As mentioned earlier, there is trade off between speed and accuracy while choosing an object detection model. I ran some experiments which measured the FPS and count accuracy of the people detected using three different models. Moreover, the experiments were run on different resource constraints (GPU parallelism constraints) . The outcome of these experiments can give you some valuable insights while selecting an object detection model.</p><h4>Setup</h4><p>The following models were selected for our experiment. These are available in the TensorFlow Object Detection API’s Model Zoo.</p><ul><li>Faster RCNN with ResNet 50</li><li>SSD with MobileNet v1</li><li>SSD with InceptionNet v2</li></ul><p>All models were trained on Google Colab for 10k steps (or until their loss saturated). For inference, an AWS p2.8xlarge instance was used. The count accuracy was measured by comparing the number of people detected by the model and the ground truth. The inference speed in Frames per Second (FPS) was tested under the following constraints:</p><ul><li>Single GPU</li><li>Two GPUs in parallel</li><li>Four GPUs in parallel</li><li>Eight GPUs in parallel</li></ul><h3>Results</h3><p>Here’s an excerpt from the output produced by using FasterRCNN on our test set. I’ve also attached a video comparing the output produced by each model near the end of this blog. Feel free to scroll down and check it out!</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/480/1*-WkySYuR7koWY3g_Ikec2A.gif" /></figure><h4>Training Time</h4><p>The plot below shows the time needed to train each model for 10k steps(in hours). This is excluding the time required for a hyperparameter search.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*PonvbFYwkzO_b2op8j7m8w.png" /></figure><p>When your application is very different from the pretrained model you use for transfer learning, you may need to heavily adjust the hyperparameters. However, when your application is similar, you wouldn’t need to do an extensive search. Nonetheless, you may still require to experiment with training parameters such as the learning rate and choice of optimizer.</p><h4>Speed (Frames per Second)</h4><p>This was the most interesting part of our experiment. As stated earlier, we measured the FPS performance of our three models on five different resource constraints. The results are shown below:</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*DDoaea3tiL_hjVYQieQneA.png" /></figure><p>SSDs are extremely fast, easily beating Faster RCNN’s speed when we use a single GPU. However, Faster RCNN quickly catches up with SSD when we increase the number of GPUs (working in parallel). Needless to say, SSD with MobileNet is much faster than SSD with InceptionNet at a low GPU environment.</p><p>One notable feature from the above graph is that, FPS slightly decreases when we increase the number of GPUs for SSD with MobileNet. There’s actually a simple answer to this apparent paradox. It turns out that our setup processed the images faster than they were being supplied by the image read function!</p><blockquote>Speed of your video processing system can not be greater than the speed at which images are fed to the system.</blockquote><p>To prove my hypothesis, I gave the image read function a head-start. The plot below shows the improvement in FPS for SSD with MobileNet when a delay was added. The slight reduction in FPS in the earlier graph is because of the overhead involved due to multiple GPUs requesting for input.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*jft44ZvgB4TLm5wsta0OKQ.png" /></figure><p>Needless to say, we observe a sharp increase in FPS if we introduce delays. The bottom line is, we need to have an optimized image transfer pipeline to prevent a bottleneck for speed. But since our intended use case is surveillance, we have an additional bottleneck. The FPS of the surveillance camera sets the upper limit for the FPS of our system.</p><h4>Count Accuracy</h4><p>We define count accuracy as the percentage of people correctly recognized by our object detection system. I felt like it’s more apt with respect to surveillance. Here’s how each of our models performed:</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*QW7jFFQTIke5SwmBBY2quA.png" /></figure><p>Needless to say, Faster RCNN is the most accurate model. Also surprisingly MobileNet performs better than InceptionNet.</p><p>Based on the experiments, it is evident that there is indeed a speed vs accuracy trade-off. However, we can use a model with high accuracy at a good FPS rate if we have enough resources. We observe that Faster RCNN with ResNet-50 offers the best accuracy, and a very good FPS rating when deployed on 4+ GPUs in parallel.</p><h3>That was a lot of steps!</h3><p>Well.. I wouldn’t argue. It is indeed a lot of steps. Moreover, setting a up cloud instance for this model to work in real time would be burdensome and expensive.</p><p>A better solution would be to use an API service that is already deployed on servers so that you can just worry about developing your product. That’s where <a href="https://nanonets.com/object-detection-api/?utm_source=Medium&amp;utm_campaign=surveillance%20blog/"><strong>Nanonets</strong></a> kicks in. They have their API deployed on quality hardware with GPUs such that you get insane performance with none of the hassle!</p><p>I converted my existing XML annotations to JSON format and fed it to the Nanonets API. As a matter of fact, if you dont want to manually annotate your dataset, you can request them to annotate it for you. Here’s the reduced workflow when Nanonets takes care of the heavy lifting.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/700/1*Yv4isduxmtLunpSZbBl_Ag.jpeg" /><figcaption>Reduced workflow with Nanonets</figcaption></figure><p>Earlier, I mentioned how mobile surveillance units such as micro drones can greatly enhance efficiency. We can create such drones quite easily using micro controllers such the Raspberry Pi, and we can use API calls to perform inference.</p><p>It’s pretty simple to get started with the Nanonets API for Object Detection, but for a well explained guide, you can checkout this <a href="https://medium.com/nanonets/how-to-easily-detect-objects-with-deep-learning-on-raspberrypi-225f29635c74">blog post</a>.</p><h3>Results with Nanonets</h3><p>It took about 2 hours for Nanonets to finish the training process. This is including the time required for hyperparameter search. In terms of time taken for training, Nanonets is the clear winner. Nanonets also defeated FasterRCNN in terms of count accuracy.</p><pre>FasterRCNN Count Accuracy = 88.77%<br>Nanonets Count Accuracy = <strong>89.66%</strong></pre><p>Here is the performance of all four models on our test dataset. It is evident that both SSD models are a bit unstable and have lower accuracy. Moreover, even though FasterRCNN and Nanonets have comparable accuracies, the latter has bounding boxes that are more stable.</p><iframe src="https://cdn.embedly.com/widgets/media.html?src=https%3A%2F%2Fwww.youtube.com%2Fembed%2F0hWW6FVcFAo%3Ffeature%3Doembed&amp;url=http%3A%2F%2Fwww.youtube.com%2Fwatch%3Fv%3D0hWW6FVcFAo&amp;image=https%3A%2F%2Fi.ytimg.com%2Fvi%2F0hWW6FVcFAo%2Fhqdefault.jpg&amp;key=a19fcc184b9711e1b4764040d3dc5c07&amp;type=text%2Fhtml&amp;schema=youtube" width="854" height="480" frameborder="0" scrolling="no"><a href="https://medium.com/media/ae27df7c6c53eeb6e98272efaab42b77/href">https://medium.com/media/ae27df7c6c53eeb6e98272efaab42b77/href</a></iframe><h3>Is automated surveillance accountable?</h3><p>Deep learning is an amazing tool that provides exemplary results with ease. But, to what extent can we trust our surveillance system to act on its own? There are a few instances where automation is questionable.</p><blockquote><strong>Update:</strong> In light of GDPR and the reasons stated below, it is <strong>imperative</strong> that we ponder about the legality and ethical issues concerning automation of surveillance. This blog is for educational purposes only, and it used a publicly available dataset. It is your responsibility to make sure that your automated system complies with the law in your region.</blockquote><h4>1. Dubious Conclusions</h4><p>We do not know how a deep learning algorithm arrives at a conclusion. Even if the data feeding process is impeccable, there may be a lot of spurious hits. For instance, this AI profanity filter used by British cops kept removing pictures of <a href="https://gizmodo.com/british-cops-want-to-use-ai-to-spot-porn-but-it-keeps-m-1821384511?utm_campaign=socialflow_gizmodo_twitter&amp;utm_source=gizmodo_twitter&amp;utm_medium=socialflow">sand dunes thinking they were obscene images</a>. Techniques such as <a href="http://www.cs.toronto.edu/~guerzhoy/321/lec/W07/HowConvNetsSee.pdf">guided backpropagation</a> can explain decisions to some extent, but we still have a long way to go.</p><h4>2. Adversarial Attacks</h4><p>Deep Learning systems are fragile. <a href="https://blog.openai.com/adversarial-example-research/">Adversarial attacks</a> are akin to optical illusions for image classifiers. But the scary part is, a calculated unnoticeable perturbation can force a deep learning model to mis-classify. Using the same principle, researchers have been able to circumvent surveillance systems based on deep learning by using “<a href="https://www.digitaltrends.com/cool-tech/facial-recognition-glasses-security/">adversarial glasses</a>”.</p><h4>3. False positives</h4><p>Another problem is, what do we do in the event of false positives. The severity of the issue depends on the application itself. For instance, a false positive on a border patrol system may be more significant than a garden monitoring system. There should be some amount of human intervention to avoid mishaps.</p><h4>4. Similar faces</h4><p>Sadly, your look is not as unique as your fingerprint. It is possible for two people (or more) to look very similar. Identical twins are one of the prime examples. It was reported that, Apple Face ID <a href="https://www.mirror.co.uk/tech/apple-accused-racism-after-face-11735152">failed to distinguish</a> two unrelated Chinese coworkers. This could make surveillance and identifying people harder.</p><h4>5. Lack of diversity in datasets</h4><p>Deep Learning algorithms are only as good as the data your provide it. Most popular datasets of human faces, only have samples of white people. While it may seem obvious to a child that humans can exist in various colors, Deep Learning algorithms are sort of dumb. In fact, Google got into trouble because it classified a black person <a href="https://www.wired.com/story/when-it-comes-to-gorillas-google-photos-remains-blind/">incorrectly as a gorilla</a>.</p><blockquote><strong>About Nanonets: </strong>Nanonets is building APIs to simplify deep learning for developers. Visit us at<a href="https://nanonets.com/object-detection-api/?utm_source=Medium&amp;utm_campaign=surveillance%20blog/"> https://www.nanonets.com</a> for more)</blockquote><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=4eb4fa0cd68d" width="1" height="1" alt=""><hr><p><a href="https://medium.com/nanonets/how-to-automate-surveillance-easily-with-deep-learning-4eb4fa0cd68d">How to Automate Surveillance Easily with Deep Learning</a> was originally published in <a href="https://medium.com/nanonets">NanoNets</a> on Medium, where people are continuing the conversation by highlighting and responding to this story.</p>]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[Deep Learning on the Edge]]></title>
            <link>https://medium.com/data-science/deep-learning-on-the-edge-9181693f466c?source=rss-7d6e83a807b8------2</link>
            <guid isPermaLink="false">https://medium.com/p/9181693f466c</guid>
            <category><![CDATA[data-science]]></category>
            <category><![CDATA[towards-data-science]]></category>
            <category><![CDATA[artificial-intelligence]]></category>
            <category><![CDATA[deep-learning]]></category>
            <category><![CDATA[machine-learning]]></category>
            <dc:creator><![CDATA[Bharath Raj]]></dc:creator>
            <pubDate>Sun, 24 Jun 2018 17:28:24 GMT</pubDate>
            <atom:updated>2018-12-03T14:29:01.983Z</atom:updated>
            <content:encoded><![CDATA[<h4>An overview of performing Deep Learning on mobile and edge devices.</h4><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*iuSKK3d30UFIb_vNPdftjQ.jpeg" /><figcaption>Photo by <a href="https://unsplash.com/photos/FO7JIlwjOtU?utm_source=unsplash&amp;utm_medium=referral&amp;utm_content=creditCopyText">Alexandre Debiève</a> on <a href="https://unsplash.com/search/photos/electronics?utm_source=unsplash&amp;utm_medium=referral&amp;utm_content=creditCopyText">Unsplash</a></figcaption></figure><p>Scalable Deep Learning services are contingent on several constraints. Depending on your target application, you may require low latency, enhanced security or long-term cost effectiveness. Hosting your Deep Learning model on the cloud may not be the best solution in such cases.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/950/1*In6L9g43W0RmYOXASC1vtA.jpeg" /><figcaption>Computing on the Edge (<a href="https://www.ptgrey.com/edge-computing">Source</a>)</figcaption></figure><p><strong>Deep Learning on the edge</strong> alleviates the above issues, and provides other benefits. Edge here refers to the computation that is performed locally on the consumer’s products. This blog explores the <strong>benefits</strong> of using edge computing for Deep Learning, and the<strong> problems</strong> associated with it.</p><h3>Why edge? Why not use the cloud?</h3><p>There is a plethora of compelling reasons to favor edge computing over cloud computing.</p><h4>1. Bandwidth and Latency</h4><p>It’s no doubt that there’s a tangible Round Trip Time (RTT) associated with API calls to a remote server. Applications that demand near instantaneous inference can not function properly with the latency.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*WIqaQsKbqWTPlClBqWzHNQ.jpeg" /><figcaption>Latency and Power consumption stats for Object Detection (DET), Tracking (TRA) and Localization (LOC) on four different edge devices (<a href="https://blog.acolyer.org/2018/04/20/the-architectural-implications-of-autonomous-driving-constraints-and-acceleration/">Source</a>)</figcaption></figure><p>Take <strong>self driving cars</strong> for example. A large enough <strong>latency</strong> could significantly increase the <strong>risk </strong>of accidents. Moreover, unexpected events such as animal crossing or jay walking can happen over just a few frames. In these cases, response time is extremely critical. This is why Nvidia has their custom <a href="https://www.nvidia.com/en-us/self-driving-cars/drive-platform/">on-board compute devices</a> to perform inference on the edge.</p><p>Moreover, when you have a large number of devices connected to the same network, the effective bandwidth is reduced. This is because of the inherent competition to use the communication channel. This can be significantly reduced if computation is done on the edge.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/947/1*KX645CSfemBCM6mi5xfV1A.png" /><figcaption>Bandwidth requirement for various applications. (<a href="https://siliconupdates.blogspot.com/2017/07/augmented-reality-and-virtual-reality.html">Source</a>)</figcaption></figure><p>Take the case of processing 4K HD videos on multiple devices. Processing them locally would heavily save bandwidth usage. This is because we do not need to upload data to the cloud for inference. Due to this, we can scale this network relatively easily.</p><h4>2. Security and Decentralization</h4><p>Commercial servers are prone to attacks and hacks. Of course, the risk is negligible if you use a trusted vendor. But, you are required to trust a third party for the security of the data you collect and your intellectual property (IP). Having devices on the edge gives you <strong>absolute control</strong> over your IP.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/767/1*VwgFhNj-vmbd6VZx-NyKIA.png" /><figcaption>Centralized vs Decentralized vs Distributed. (<a href="https://blog.ethfinex.com/the-significance-of-decentralisation-b7f72655484e">Source</a>)</figcaption></figure><p>If you’ve heard about blockchain, decentralization or distribution may be familiar to you. Nonetheless, having several devices on the edge reaps all the benefits of decentralization. It’s <strong>harder</strong> to bring down an entire network of hidden devices using a <strong>single DDoS attack</strong>, than a centralized server. This is especially useful for applications such as using drones for border patrol.</p><h4>3. Job Specific Usage (Customization)</h4><p>Imagine you have a factory that produces toys. It has a couple hundred work stations. You require an image classification service at every work station. Problem is, each work station has a different set of objects, and training a single classifier may not be effective. Moreover, hosting <strong>multiple classifiers</strong> on the <strong>cloud</strong> would be <strong>expensive</strong>.</p><p>The cost effective solution is to train classifiers specific to each part on the cloud, and ship the <strong>trained models</strong> to the <strong>edge devices</strong>. Now, these devices are customized to their work station. They would have better performance than a classifier predicting across all work stations.</p><h4>4. Swarm Intelligence</h4><p>Continuing with the idea mentioned above, edge devices can aid in training machine learning models too. This is especially useful for <strong>Reinforcement Learning</strong>, for which you could simulate a large number of “episodes” in <strong>parallel</strong>.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/700/1*KYomzpKV5Ub3zjVB6hNqAg.jpeg" /><figcaption>Multiple agents trying to grasp objects. (<a href="http://robohub.org/deep-learning-in-robotics/">Source</a>)</figcaption></figure><p>Moreover, edge devices can be used to collect data for <strong>Online Learning</strong> (or <strong>Continuous Learning</strong>). For instance, we can use multiple drones to survey an area for classification. Using optimization techniques such as Asynchronous SGD, a single model can be <strong>trained in parallel</strong> among all edge devices. It can also be merely used for aggregating and processing data from various sources.</p><h4>5. Redundancy</h4><p>Redundancy is extremely vital for robust memory and network architectures. Failure of one node in a network could have serious impacts on the other nodes. In our case, edge devices can provide a good level of redundancy. If one of the our edge devices (here, a node) fail, its neighbor can take over temporarily. This greatly ensures reliability and heavily reduces downtime.</p><h4>6. Cost effective in the long run</h4><p>In the long run, cloud services will turn out to be more expensive than having a dedicated set of inference devices. This is especially true if your devices have a large duty cycle (that is, they are working most of the time). Moreover, edge devices are much cheaper if they’re fabricated in bulk, reducing the cost significantly.</p><h3>Constraints for Deep Learning on the Edge</h3><p><strong>Deep Learning </strong>models are known for being <strong>large</strong> and <strong>computationally expensive</strong>. It’s a challenge to fit these models into <strong>edge devices</strong> which usually have <strong>frugal memory</strong>. There are a number of ways by which we can approach these problems.</p><h4>1. Parameter Efficient Neural Networks</h4><p>A striking feature about neural networks is their enormous size. Edge devices typically can not handle large neural networks. This motivated researchers to minimize the size of the neural networks, while maintaining accuracy. Two popular parameter efficient neural networks are the <a href="https://arxiv.org/abs/1704.04861">MobileNet</a> and the <a href="https://arxiv.org/abs/1602.07360">SqueezeNet</a>.</p><p>The <strong>SqueezeNet</strong> incorporates a lot of strategies such as late down-sampling and filter count reduction, to get high performance at a low parameter count. They introduce “Fire modules” that have “squeeze” and “expand” layers that optimize the parameter efficiency of the network.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/628/1*c5ZTXzakIVkDjC5DGlBhyQ.png" /><figcaption>Fire module in the SqueezeNet. (<a href="https://arxiv.org/pdf/1602.07360.pdf">Source</a>)</figcaption></figure><p>The <strong>MobileNet</strong> factorizes normal convolutions into a combination of depth wise convolutions and 1x1 convolutions. This arrangement greatly reduces the number of parameters involved.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/712/1*7EJDG7ypufhx14nIu1Vw9Q.jpeg" /><figcaption>Top 1 accuracy in the ImageNet dataset with respect to number of Multiply-Accumulates (MACs). (<a href="https://ai.googleblog.com/2017/06/mobilenets-open-source-models-for.html">Source</a>)</figcaption></figure><h4>2. Pruning and Truncation</h4><p>A large number of neurons in trained networks are <strong>benign</strong> and do not contribute to the final accuracy. In this case, we can <strong>prune</strong> such neurons to save some space. Google’s <a href="https://ai.googleblog.com/2018/05/custom-on-device-ml-models.html">Learn2Compress</a> has found that we can obtain a<strong> size</strong> <strong>reduction by factor of 2</strong>, while retaining 97% of the accuracy.</p><p>Moreover, most neural network parameters are 32 bit float values. Edge devices on the other hand can be designed to work on 8 bit values, or less. Reducing precision can significantly reduce the model size. For instance, reducing a <strong>32 bit model</strong> to <strong>8 bit model</strong> ideally reduces model size by a <strong>factor of 4</strong>.</p><h4>3. Distillation</h4><p>Distillation is the process of teaching smaller networks using a larger “teacher” network. Google’s <a href="https://ai.googleblog.com/2018/05/custom-on-device-ml-models.html">Learn2Compress</a> incorporates this in their size reduction process. Combined with transfer learning, this becomes a powerful method to reduce model size without losing much accuracy.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/640/1*Id6ZQBu9VgANtd8frCQK-w.png" /><figcaption>Joint training and distillation approach to learn compact student models. (<a href="https://ai.googleblog.com/2018/05/custom-on-device-ml-models.html">Source</a>)</figcaption></figure><h4>4. Optimized Microprocessor Designs</h4><p>So far we have discussed way to scale down neural networks to fit in our edge devices. An alternate (or complementary) method would be to scale up the performance of the microprocessor.</p><p>The simplest solution would be to have a GPU on a microprocessor, such as the popular <a href="https://developer.nvidia.com/embedded/buy/jetson-tx2">Nvidia Jetson</a>. However, these devices may not be cost effective when deployed on a large scale.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/676/1*KlSkL6KOtxml6s5jgqA7Ag.png" /><figcaption>Nvidia Jetson (<a href="https://developer.nvidia.com/embedded/buy/jetson-tx2">Source</a>)</figcaption></figure><p>A more interesting solution would be to use Vision Processing Units (VPUs). Intel claims that their Movidius VPUs have “high speed performance at an ultra low power consumption”. Google’s <a href="https://www.movidius.com/news/google-launches-aiy-vision-kit-featuring-intel-movidius-vpu">AIY kits</a> and Intel’s <a href="https://www.movidius.com/news/intel-movidius-neural-compute-stick-honored-with-ces-best-of-innovation-award-2018">Neural Compute Stick </a>internally use this VPU.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/770/1*KSItXzlVVbP37XZ7WW-SJw.jpeg" /><figcaption>Google AIY’s Vision Bonnet using a Movidius VPU. (<a href="https://www.zdnet.com/article/google-offers-raspberry-pi-owners-this-new-ai-vision-kit-to-spot-cats-people-emotions/">Source</a>)</figcaption></figure><p>Alternatively, we could use FPGAs. They have low power consumption than GPUs and can accommodate lower bit (&lt; 32 bit) architectures. However, there could be a slight drop in performance compared to GPUs owing to their lower FLOPs rating.</p><p>For large scale deployment, custom ASICs would be the best solution. Fabricating micro-architectures similar to Nvidia’s V100 to accelerate matrix multiplications could greatly boost performance.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/560/1*gzozPNb4SFcWPNkOZeNDZw.png" /><figcaption>Pascal vs Volta architecture; Nvidia. (<a href="https://www.nvidia.com/en-us/data-center/tensorcore/">Source</a>)</figcaption></figure><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=9181693f466c" width="1" height="1" alt=""><hr><p><a href="https://medium.com/data-science/deep-learning-on-the-edge-9181693f466c">Deep Learning on the Edge</a> was originally published in <a href="https://medium.com/data-science">TDS Archive</a> on Medium, where people are continuing the conversation by highlighting and responding to this story.</p>]]></content:encoded>
        </item>
    </channel>
</rss>