<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Seri Lee</title>
    <description>The latest articles on DEV Community by Seri Lee (@sally20921).</description>
    <link>https://dev.to/sally20921</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F685201%2F47fb77cf-7b33-47b9-b939-15c315afcab6.png</url>
      <title>DEV Community: Seri Lee</title>
      <link>https://dev.to/sally20921</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/sally20921"/>
    <language>en</language>
    <item>
      <title>Advanced Object Detection </title>
      <dc:creator>Seri Lee</dc:creator>
      <pubDate>Tue, 24 Aug 2021 09:04:32 +0000</pubDate>
      <link>https://dev.to/sally20921/advanced-object-detection-25db</link>
      <guid>https://dev.to/sally20921/advanced-object-detection-25db</guid>
      <description>&lt;p&gt;&lt;em&gt;This article is originally from the book "Computer Vision with PyTorch"&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;In the previous chapter, we learned about R-CNN and Fast R-CNN techniques, which leveraged region proposals to generate predictions of the locations of objects in an image along with the classes corresponding to objects in the image. Furthermore, we learned about the bottleneck of the speed of inference, which happens because of having two different models-one for region proposal generation and another for object detection. In this chapter, we will learn about different modern techniques, such as Faster R-CNN, YOLO, and Single-Shot Detector (SSD), that overcomes slow inference time by employing a single model to make predictions for both the class of objects and the bounding box in a single shot. We will start by learning about anchor boxes and then proceed to learn about how each of the techniques works and how to implement them to detect objects in an image. &lt;/p&gt;

&lt;h2&gt;
  
  
  Components of modern object detection algorithms
&lt;/h2&gt;

&lt;p&gt;The drawback of the R-CNN and Fast R-CNN techniques is that they have two disjointed networks-one to identify the regions that likely contain an object and the other to make corrections to the bounding box where an object is identified. Furthermore, both the models require as many forward propagations as there are region proposals. Modern object detection algorithms focus heavily on training a single neural network and have the capability to detect all objects in one forward pass. In the subsequent sections, we will learn about the various components of a typical modern object detection algorithm:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Anchor Boxes &lt;/li&gt;
&lt;li&gt;Region Proposal Network (RPN)&lt;/li&gt;
&lt;li&gt;Region of Interest Pooling (RoI)&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Anchor boxes
&lt;/h3&gt;

&lt;p&gt;So far, we have region proposals coming from the selective search method. Anchor boxes come in as handy replacement for selective search-we will learn how they replace selective search-based region proposals in this section.&lt;/p&gt;

&lt;p&gt;Typically, a majority of objects have a similar shape-for example, in a majority of cases, a bounding box corresponding to an image of a person will have a greater height than width, and a bounding box corresponding to the image of a truck will have a greater width than height. Thus, we will have a decent idea of the height and width of the objects present in an image even before training the model (by inspecting the ground truths of bounding boxes corresponding to objects of various classes). &lt;/p&gt;

&lt;p&gt;Furthermore, in some images, the objects of interest might be scaled-resulting in a much smaller or much greater height and width than average-while still maintaining the aspect ratio (that is, 

&lt;span class="katex-element"&gt;
  &lt;span class="katex"&gt;&lt;span class="katex-mathml"&gt;heightwidth\frac{height}{width} &lt;/span&gt;&lt;span class="katex-html"&gt;&lt;span class="base"&gt;&lt;span class="strut"&gt;&lt;/span&gt;&lt;span class="mord"&gt;&lt;span class="mopen nulldelimiter"&gt;&lt;/span&gt;&lt;span class="mfrac"&gt;&lt;span class="vlist-t vlist-t2"&gt;&lt;span class="vlist-r"&gt;&lt;span class="vlist"&gt;&lt;span&gt;&lt;span class="pstrut"&gt;&lt;/span&gt;&lt;span class="sizing reset-size6 size3 mtight"&gt;&lt;span class="mord mtight"&gt;&lt;span class="mord mathnormal mtight"&gt;w&lt;/span&gt;&lt;span class="mord mathnormal mtight"&gt;i&lt;/span&gt;&lt;span class="mord mathnormal mtight"&gt;d&lt;/span&gt;&lt;span class="mord mathnormal mtight"&gt;t&lt;/span&gt;&lt;span class="mord mathnormal mtight"&gt;h&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span&gt;&lt;span class="pstrut"&gt;&lt;/span&gt;&lt;span class="frac-line"&gt;&lt;/span&gt;&lt;/span&gt;&lt;span&gt;&lt;span class="pstrut"&gt;&lt;/span&gt;&lt;span class="sizing reset-size6 size3 mtight"&gt;&lt;span class="mord mtight"&gt;&lt;span class="mord mathnormal mtight"&gt;h&lt;/span&gt;&lt;span class="mord mathnormal mtight"&gt;e&lt;/span&gt;&lt;span class="mord mathnormal mtight"&gt;i&lt;/span&gt;&lt;span class="mord mathnormal mtight"&gt;g&lt;/span&gt;&lt;span class="mord mathnormal mtight"&gt;h&lt;/span&gt;&lt;span class="mord mathnormal mtight"&gt;t&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="vlist-s"&gt;​&lt;/span&gt;&lt;/span&gt;&lt;span class="vlist-r"&gt;&lt;span class="vlist"&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="mclose nulldelimiter"&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;/span&gt;
). &lt;/p&gt;

&lt;p&gt;Once we have a decent idea of the aspect ratio and the height and width of objects (which can be obtained from ground truth values in the dataset) present in our images, we define the anchor boxes with heights and widths representing the majority of objects' bounding boxes within our dataset. &lt;/p&gt;

&lt;p&gt;Typically, this is obtained by employing K-means clustering on top of the ground truth bounding boxes of objects present in images. &lt;/p&gt;

&lt;p&gt;Now that we understand how anchor boxes' heights and widths are obtained, we will learn about how to leverage them in the process:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Slide each anchor box over an image from top left to bottom right&lt;/li&gt;
&lt;li&gt;The anchor box that has a high intersection over union (IoU) with the object will have a label that it contains an object, and the others will be labeled 0.

&lt;ul&gt;
&lt;li&gt;We can modify the threshold of the IoU by mentioning that if the IoU is greater than a certain threshold, the object class is 1; if it is less than another threshold, the object class is 0, and it is unknown otherwise. Once we obtain the ground truths as defined here, we can build a model that can predict the location of an object and also the offset corresponding to the anchor box to match it with ground truth. Let's understand how anchor boxes are represented in the following image:
&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--auFvw_sI--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/rftwf3b69fy5yjirk95s.png" alt="Screen Shot 2021-08-22 at 3.58.37 AM"&gt; In the preceding image, we have two anchor boxes, one that has a greater height than width and the other with a greater width than height, to correspond to the objects (classes) in the image-a person and a car. &lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;We slide the two anchor boxes over the image and note the locations where the IoU of the anchor box with the ground truth is the highest and denote that this particular location contains an object while the rest of the locations do not contain an object.&lt;/p&gt;

&lt;p&gt;In addition to the preceding two anchor boxes, we would also create anchor boxes with varying scales so that we accommodate the different scales at which an object can be presented within an image. An example of how the different scales of anchor boxes look follows: &lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--RvlcMunG--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/3n7o147s5cxiwrlcnp1g.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--RvlcMunG--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/3n7o147s5cxiwrlcnp1g.png" alt="Screen Shot 2021-08-22 at 4.02.33 AM"&gt;&lt;/a&gt; Note that all the anchor boxes have the same center but different aspect ratios or scales.&lt;/p&gt;

&lt;p&gt;Now that we understand anchor boxes, in the next section, we will learn about the RPN, which leverages anchor boxes to come up with predictions of regions that are likely to contain an object. &lt;/p&gt;

&lt;h3&gt;
  
  
  Region Proposal Network
&lt;/h3&gt;

&lt;p&gt;Imagine a scenario where we have a &lt;em&gt;224x224x3&lt;/em&gt; image. Furthermore, let's say that the anchor box is of shape &lt;em&gt;8x8&lt;/em&gt; for this example. If we have a stride of 8 pixels, we are fetching &lt;em&gt;224/8 = 28&lt;/em&gt; crops of a picture for every row-essentially 
&lt;span class="katex-element"&gt;
  &lt;span class="katex"&gt;&lt;span class="katex-mathml"&gt;28×28=57628 \times 28 = 576 &lt;/span&gt;&lt;span class="katex-html"&gt;&lt;span class="base"&gt;&lt;span class="strut"&gt;&lt;/span&gt;&lt;span class="mord"&gt;28&lt;/span&gt;&lt;span class="mspace"&gt;&lt;/span&gt;&lt;span class="mbin"&gt;×&lt;/span&gt;&lt;span class="mspace"&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="base"&gt;&lt;span class="strut"&gt;&lt;/span&gt;&lt;span class="mord"&gt;28&lt;/span&gt;&lt;span class="mspace"&gt;&lt;/span&gt;&lt;span class="mrel"&gt;=&lt;/span&gt;&lt;span class="mspace"&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="base"&gt;&lt;span class="strut"&gt;&lt;/span&gt;&lt;span class="mord"&gt;576&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;/span&gt;
 crops from a picture. We then take each of these crops and pass through a Region Proposal Network (RPN) model that indicates whether the crop contains an image. Essentially, an RPN suggests the likelihood of a crop containing an object. &lt;/p&gt;

&lt;p&gt;Let's compare the output of &lt;code&gt;selectivesearch&lt;/code&gt; and the output of an RPN. &lt;/p&gt;

&lt;p&gt;&lt;code&gt;selectivesearch&lt;/code&gt; gives a region candidates based on a set of computations on top of pixel values. However, an RPN generates region candidates based on the anchor boxes and strides with which anchor boxes are slid over the image. Once we obtain the region candidates using either of these two methods, we identify the candidates that are most likely to contain an object.&lt;/p&gt;

&lt;p&gt;While region proposal generation based on &lt;code&gt;selectivesearch&lt;/code&gt; is done outside of the neural network, we can build an RPN that is part of the object detection network. Using an RPN, we are now in a position where we don't have to perform unnecessary computations to calculate region proposals outside of the network. This way, we have a single model to identify regions, identify classes of objects in image, and identify their corresponding bounding box locations. &lt;/p&gt;

&lt;p&gt;Next, we will learn how an RPN identifies whether a region candidate (a crop obtained after sliding an anchor box) contains an object or not. In our training data, we would have the ground truth correspond to objects. We now take each region candidate and compare with the ground truth bounding boxes of objects in an image to identify whether the IoU between a region candidate and a ground truth bounding box is greater than a certain threshold (say, 0.5). If the IoU is greater than a certain threshold, the region candidate contains an object, and if the IoU is less than a threshold (say 0.1), the region candidate does not contain an object and all the candidates that have an IoU between the two thresholds (0.1-0.5) are ignored while training. &lt;/p&gt;

&lt;p&gt;Once we train a model to predict if the region candidate contains an object, we then perform non-max suppression, as multiple overlapping regions can contain an object.&lt;/p&gt;

&lt;p&gt;In summary, an RPN trains a model to enable it to identify region proposals with a high likelihood of containing an object by performing the following steps:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Slide anchor boxes of different aspect ratios and sizes across the image to fetch crops of an image.&lt;/li&gt;
&lt;li&gt;Calculate the IoU between the ground truth bounding boxes of objects in the image and the crops obtained in the previous step. &lt;/li&gt;
&lt;li&gt;Prepare the training dataset in such a way that crops with an IoU greater than a threshold contain an object and crops with an IoU less than a threshold do not contain an object. &lt;/li&gt;
&lt;li&gt;Train the model to identify the regions that contain an object.&lt;/li&gt;
&lt;li&gt;Perform non-max suppression to identify the region candidate that has the highest probability of containing an object and eliminate other region candidates that have a high overlap with it. &lt;/li&gt;
&lt;/ol&gt;

&lt;h3&gt;
  
  
  Classification and regression
&lt;/h3&gt;

&lt;p&gt;So far, we have learned about the following steps in order to identify objects and perform offsets to bounding boxes:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Identify the regions that contain objects.&lt;/li&gt;
&lt;li&gt;Ensure that all the feature maps of regions, irrespective of the regions' shape, are exactly the same using Region of Interest (RoI) pooling.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Two issues with these steps are as follows:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;The region proposals do not correspond tightly over the object (IoU&amp;gt;0.5 is the threshold we had in the RPN).&lt;/li&gt;
&lt;li&gt;We identified whether the region contains an object or not, but not the class of the object located in the region.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;We address these two issues in this section, where we take the uniformly shape feature map obtained previously and pass it through a network. We expect the network to predict the class of the object contained within the region and also the offsets corresponding to the region to ensure that the bounding box is as tight as possible around the object in the image. &lt;/p&gt;

&lt;p&gt;Let's understand this through the following diagram: &lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--BjZN5UUv--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/oohv6q89y595m641fyh2.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--BjZN5UUv--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/oohv6q89y595m641fyh2.png" alt="Screen Shot 2021-08-22 at 4.29.18 AM"&gt;&lt;/a&gt; In the preceding diagram, we are taking the output of RoI pooling as input (the &lt;em&gt;7x7x5x12&lt;/em&gt; shape), flattening it, and connecting to a dense layer before predicting two aspects:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Class of object in the region&lt;/li&gt;
&lt;li&gt;Amount of offset to be done on the predicted bounding boxes of the region to maximize the IoU with the ground truth&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Hence, if there are 20 classes in the data, the output of the neural network contains a total of 25 outputs-21 classes (including the background class) and the 4 offsets to be applied to the height, width, and two center coordinates of the bounding box. &lt;/p&gt;

&lt;p&gt;Now that we have learned the different components of an object detection pipeline, let's summarize it with the following diagram:&lt;br&gt;
&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--Ju9CEaXY--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/es6wcqd4296guqk98skq.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--Ju9CEaXY--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/es6wcqd4296guqk98skq.png" alt="Screen Shot 2021-08-22 at 5.37.51 AM"&gt;&lt;/a&gt; &lt;/p&gt;

&lt;h2&gt;
  
  
  Working details of YOLO
&lt;/h2&gt;

&lt;p&gt;You Only Look Once (YOLO) and its variants are one of the prominent object detection algorithms. In this section, we will understand at a high level how YOLO works and the potential limitations of R-CNN-based object detection frameworks that YOLO overcomes. &lt;/p&gt;

&lt;p&gt;First, let's learn about the possible limitations of R-CNN-based detection algorithms. In Faster R-CNN, we slide over the image using anchor boxes and identify the regions that are likely to contain an object, and then we make the bounding box corrections. However, in the fully connected layer, where only the detected region's RoI pooling output is passed as input, in the case of regions that do not fully encompass the object (where the object is beyond the boundaries of the bounding box of region proposal), the network has to guess the real boundaries of object, as it has not seen the full image (but has seen only the region proposal). &lt;/p&gt;

&lt;p&gt;YOLO comes in handy in such scenarios, as it looks at the whole image while predicting the bounding box corresponding to an image. &lt;/p&gt;

&lt;p&gt;Furthermore, Faster R-CNN is still slow, as we have two networks: the RPN and the final network that predicts classes and bounding boxes around objects.&lt;/p&gt;

&lt;p&gt;Here, we will understand how YOLO overcomes the limitations of Faster R-CNN, both by looking at the whole image at once as well as by having a single network to make predictions. &lt;/p&gt;

&lt;p&gt;We will look at how data is prepared for YOLO through the following example:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Create ground truth to train a model for a given image:

&lt;ul&gt;
&lt;li&gt;Let's consider an image with the given ground truth of bounding boxes in red:
&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--efS0_JAC--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/5asytnz6gvw0yl85m4z6.png" alt="Screen Shot 2021-08-24 at 5.58.42 PM"&gt;
&lt;/li&gt;
&lt;li&gt;Divide the image into &lt;em&gt;NxN&lt;/em&gt; grid cells-for now, let's say &lt;em&gt;N=3&lt;/em&gt;:
&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--WsjRiVMS--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/8w25i680el9u9lo40a16.png" alt="Screen Shot 2021-08-24 at 5.59.19 PM"&gt;
&lt;/li&gt;
&lt;li&gt;Identify those grid cells that contain the center of at least one ground truth bounding box. In our case, they are cells &lt;em&gt;b1&lt;/em&gt; and &lt;em&gt;b3&lt;/em&gt; of our &lt;em&gt;3x3&lt;/em&gt; grid image. &lt;/li&gt;
&lt;li&gt;The cell(s) where the middle point of ground truth bounding box falls is/are responsible for predicting the bounding box of the object. Let's create the ground truth corresponding to each cell. &lt;/li&gt;
&lt;li&gt;The output ground truth corresponding to each cell is as follows: 
&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--_Mcl2ZYq--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/v2cizjupac9w1xyfdqbz.png" alt="Screen Shot 2021-08-24 at 6.02.05 PM"&gt;
Here, &lt;em&gt;pc&lt;/em&gt; (the objectness score) is the probability of the cell containing an object.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Let's understand how to calculate &lt;em&gt;bx&lt;/em&gt;, &lt;em&gt;by&lt;/em&gt;, &lt;em&gt;bw&lt;/em&gt; and &lt;em&gt;bh&lt;/em&gt;. &lt;/p&gt;

&lt;p&gt;First, we consider the grid cell (let's consider the &lt;em&gt;b1&lt;/em&gt; grid cell) as our universe, and normalize it to a scale between 0 and 1, as follows:&lt;br&gt;
&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--8Bp99BZy--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/a3uwelfmvggabpqil0ik.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--8Bp99BZy--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/a3uwelfmvggabpqil0ik.png" alt="Screen Shot 2021-08-24 at 6.03.32 PM"&gt;&lt;/a&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--kKzsv1j2--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/ekybpo128jsf8zpirtfj.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--kKzsv1j2--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/ekybpo128jsf8zpirtfj.png" alt="Screen Shot 2021-08-26 at 3.17.10 AM"&gt;&lt;/a&gt;&lt;br&gt;
&lt;em&gt;bx&lt;/em&gt; and &lt;em&gt;by&lt;/em&gt; are the locations of the mid-point of the ground truth bounding with respect to the image (of the grid cell), as defined previously. In our case, &lt;em&gt;bx = 0.5&lt;/em&gt;, as the mid-point of the ground truth is at a distance of &lt;em&gt;0.5&lt;/em&gt; unit from the origin. Similarly, &lt;em&gt;by = 0.5&lt;/em&gt;.&lt;/p&gt;

&lt;p&gt;So far, we have calculated offsets from the grid cell center to the ground truth center corresponding to the object in the image. Now, let's understand how &lt;em&gt;bw&lt;/em&gt; and &lt;em&gt;bh&lt;/em&gt; are calculated. &lt;/p&gt;

&lt;p&gt;&lt;em&gt;bw&lt;/em&gt; is the ratio of the width of the bounding box with respect to the width of the grid cell.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;bh&lt;/em&gt; is the ratio of the height of the bounding box with respect to the height of the grid cell.&lt;/p&gt;

&lt;p&gt;Next, we will predict the class corresponding to the grid cell. If we have three classes, we will predict the probability of the cell containing an object among any of the three classes. Note that we do not need a background class here, as &lt;em&gt;pc&lt;/em&gt; corresponds to whether the grid cell contains an object. &lt;/p&gt;

&lt;p&gt;Now that we understand how to represent the output layer of each cell, let's understand how we construct the output of our &lt;em&gt;3x3&lt;/em&gt; grid cells. &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Let's consider the output of the grid cell &lt;em&gt;a3&lt;/em&gt;:&lt;br&gt;
&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--YXlLm_Xq--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/e3dytbitx3ba58kv8lmw.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--YXlLm_Xq--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/e3dytbitx3ba58kv8lmw.png" alt="Screen Shot 2021-08-26 at 3.25.03 AM"&gt;&lt;/a&gt;&lt;br&gt;
The output of cell &lt;em&gt;a3&lt;/em&gt; is as shown in the preceding screenshot. As the grid cell does not contain an object, the first output (&lt;em&gt;pc&lt;/em&gt;-objectness score) is 0 and the remaining values do not matter as the cell do not contain the center of any ground truth bounding box of an object. &lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Let's consider the output corresponding to grid cell &lt;em&gt;b1&lt;/em&gt;:&lt;br&gt;&lt;br&gt;
&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--W4KpPvje--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/4741u5yijrdrannravh6.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--W4KpPvje--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/4741u5yijrdrannravh6.png" alt="Screen Shot 2021-08-26 at 3.26.40 AM"&gt;&lt;/a&gt;&lt;br&gt;
The preceding output is the way it is because the grid cell contains an object with the &lt;em&gt;bx&lt;/em&gt;, &lt;em&gt;by&lt;/em&gt;, &lt;em&gt;bw&lt;/em&gt;, and &lt;em&gt;bh&lt;/em&gt; values that were obtained in the same way as we went through earlier (in the bullet point before last), and finally the class being &lt;em&gt;car&lt;/em&gt; resulting in &lt;em&gt;c2&lt;/em&gt; being 1 while &lt;em&gt;c1&lt;/em&gt; and &lt;em&gt;c3&lt;/em&gt; are 0.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Note that for each cell, we are able to fetch 8 outputs. Hence, for &lt;em&gt;3x3&lt;/em&gt; grid of cells, we fetch &lt;em&gt;3x3x8&lt;/em&gt; outputs. &lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;Define a model where the input is an image and the output is &lt;em&gt;3x3x8&lt;/em&gt; with the ground truth being as defined in the previous step.&lt;br&gt;
&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--qVSfWH9e--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/2k1wxr7ofzlbtf1bmxb9.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--qVSfWH9e--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/2k1wxr7ofzlbtf1bmxb9.png" alt="Screen Shot 2021-08-26 at 3.29.25 AM"&gt;&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Define the ground truth by considering the anchor boxes. &lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;So far, we have been building for a scenario where the expectation is that there is only one object within a grid cell. However, in reality, there can be scenarios where there are multiple objects within the same grid cell. This would result in creating ground truths that are incorrect. Let's understand this phenomenon through the following example image:&lt;br&gt;
&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--JkUf7-GN--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/5a8mlsj8l1bqa7vlhir1.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--JkUf7-GN--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/5a8mlsj8l1bqa7vlhir1.png" alt="Screen Shot 2021-08-26 at 3.33.55 AM"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;In the preceding example, the mid-point of the ground truth bounding boxes for both the car and the person fall in the same cell-cell &lt;em&gt;b1&lt;/em&gt;.&lt;/p&gt;

&lt;p&gt;One way to avoid such a scenario is by having a grid that has more rows and columns-for example, a &lt;em&gt;19x19&lt;/em&gt; grid. However, there can be still a scenario where an increase in the number of grid cells does not help. Anchor boxes come in handy in such a scenario. Let's say we have two anchor boxes-one that has a greater height than width (corresponding to the person) and another that has a greater width than height (corresponding to the car):&lt;br&gt;
&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--z8CV5Eg4--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/jbctd62w9kcvvv7n8xkp.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--z8CV5Eg4--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/jbctd62w9kcvvv7n8xkp.png" alt="Screen Shot 2021-08-26 at 3.36.18 AM"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Typically the anchor boxes would have the grid cell center as their centers. The output for each cell in a scenario where we have two anchor boxes is represented as a concatenation of the output expected of the two anchor boxes:&lt;br&gt;
&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--N-lVFybJ--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/him66hxrdlj5xkw6v8nm.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--N-lVFybJ--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/him66hxrdlj5xkw6v8nm.png" alt="Screen Shot 2021-08-26 at 3.37.12 AM"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Here, &lt;em&gt;bx, by, bw&lt;/em&gt; and &lt;em&gt;bh&lt;/em&gt; represent the offset from the anchor box (which is the universe in this scenario as seen in the image instead of the grid cell). &lt;/p&gt;

&lt;p&gt;From the preceding screenshot, we see we have an output that is &lt;em&gt;3x3x16&lt;/em&gt;, as we have two anchors. The expected output is of the shape &lt;em&gt;NxNx(num_classes+1)x(num_anchor_boxes), where *NxN&lt;/em&gt; is the number of cells in the grid, &lt;em&gt;num_classes&lt;/em&gt; is the number of classes in the dataset, and &lt;em&gt;num_anchor_boxes&lt;/em&gt; is the number of anchor boxes.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Now we define the loss function to train the model. &lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;When calculating the loss associated with the model, we need to ensure that we do not calculate the regression loss and classification loss when the objectness score is less than a certain threshold (this corresponds to the cells that do not contain an object).  &lt;/p&gt;

&lt;p&gt;Next, if the cell contains an object, we need to ensure that the classification across different classes is as accurate as possible. &lt;/p&gt;

&lt;p&gt;Finally, if the cell contains an object, the bounding box offsets should be as close to expected as possible. However, since the offsets of width and height can be much higher when compared to the offset of the center (as offsets of the center range between 0 and 1, while the offsets of width and height need not), we give a lower weightage to offsets of width and height by fetching a square root value.   &lt;/p&gt;

&lt;p&gt;Calculate the loss of localization and classification as follows: &lt;br&gt;
&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--b7zUGAHH--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/ikn7tga28mgamfzxv0he.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--b7zUGAHH--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/ikn7tga28mgamfzxv0he.png" alt="image"&gt;&lt;/a&gt;&lt;br&gt;
&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--3ThSuKuz--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/5aupv42v3xsrarb97abp.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--3ThSuKuz--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/5aupv42v3xsrarb97abp.png" alt="image"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Here, we observe the following:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;em&gt;lambda_coordinate&lt;/em&gt; is the weightage associate with regression loss. &lt;/li&gt;
&lt;li&gt;
&lt;em&gt;object_ij&lt;/em&gt; represents whether the cell contains an object. &lt;/li&gt;
&lt;li&gt;
&lt;em&gt;hat_p_i(c)&lt;/em&gt; corresponds to the predicted class probability, and &lt;em&gt;C_ij&lt;/em&gt; represents the objectness score. &lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The overall loss is a sum of classification and regression loss values. &lt;/p&gt;

&lt;h2&gt;
  
  
  Working details of SSD
&lt;/h2&gt;

&lt;p&gt;So far, we have seen a scenario where we made predictions after gradually convolving and pooling the output from the previous layer. However, we know that different layers have different receptive fields to the original image. For example, the initial layers have a smaller receptive field when compared to the final layers, which have a larger receptive field. Here, we will learn how SSD leverages this phenomenon to come up with a prediction of bounding boxes for images. &lt;/p&gt;

&lt;p&gt;The workings behind how SSD helps overcome the issue of detecting objects with different scales is as follows:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;We leverage the pre-trained VGG network and extend it with a few additional layers until we obtain a &lt;em&gt;1x1&lt;/em&gt; block. &lt;/li&gt;
&lt;li&gt;Instead of leveraging only the final layer for bounding box and class predictions, we will leverage all of the last few layers to make class and bounding box predictions. &lt;/li&gt;
&lt;li&gt;In place of anchor boxes, we will come up with default boxes that have a specific set of scales and aspect ratios.&lt;/li&gt;
&lt;li&gt;Each of the default boxes should predict the object and bounding box offset just like how anchor boxes are expected to predict classes and offsets in YOLO. &lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Now that we understand the main ways in which SSD differs from YOLO (which is that default boxes in SSD replace anchor boxes in YOLO and multiple layers are connected to the final layer in SSD, instead of gradual convolution pooling in YOLO), let's learn about the following:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;The network architecture of SSD&lt;/li&gt;
&lt;li&gt;How to leverage different layers for bounding box and class predictions &lt;/li&gt;
&lt;li&gt;How to assign scale and aspect ratios for default boxes in different layers&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>deeplearning</category>
    </item>
    <item>
      <title>Basics of Object Detection (Part 2)</title>
      <dc:creator>Seri Lee</dc:creator>
      <pubDate>Tue, 17 Aug 2021 21:40:00 +0000</pubDate>
      <link>https://dev.to/sally20921/basics-of-object-detection-part-2-5325</link>
      <guid>https://dev.to/sally20921/basics-of-object-detection-part-2-5325</guid>
      <description>&lt;p&gt;&lt;em&gt;This article is originally from the book "Modern Computer Vision with PyTorch"&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;We will hold off on building a model until the forthcoming sections as training a model is more involved and we would also have to learn a few more components before we train it. In the next section, we will learn about non-max suppression, which helps in shortlisting from the different possible predicted bounding boxes around an object when inferring using the trained model on a new image.&lt;/p&gt;

&lt;h2&gt;
  
  
  Non-max suppression
&lt;/h2&gt;

&lt;p&gt;Imagine a scenario where multiple region proposals are generated and significantly overlap one another. Essentially, all the predicted bounding box coordinates (offsets to region proposals) significantly overlap one another. For example, let's consider the following image, where multiple region proposals are generated for the person in the image:&lt;br&gt;
&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--2jMCxxL_--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/zpf3s955obq2vn1hm3u4.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--2jMCxxL_--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/zpf3s955obq2vn1hm3u4.png" alt="Screen Shot 2021-08-16 at 3.26.02 PM"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;In the preceding image, I ask you to identify the box among the many region proposals that we will consider as the one containing an object and the boxes that we will discard. Non-max suppression comes in handy in such a scenario. Let's unpack the term "Non-max suppression".&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Non-max&lt;/strong&gt; refers to the boxes that do not contain the highest probability of containing an object, and &lt;strong&gt;suppression&lt;/strong&gt; refers to us discarding those boxes that do not contain the highest probability of containing an object. In non-max suppression, we identify the bounding box that has the highest probability and discard all the other bounding boxes that have an IoU greater than a certain threshold with the box containing the highest probability of containing an object. &lt;/p&gt;

&lt;p&gt;In PyTorch, non-max suppression is performed using the &lt;em&gt;nms&lt;/em&gt; function in the &lt;em&gt;torchvision.ops&lt;/em&gt; module. The &lt;em&gt;nms&lt;/em&gt; function takes the bounding box coordinates, the confidence of the object in the bounding box, and the threshold of IoU across bounding boxes, to identify the bounding boxes to be retained. You will be leveraging the &lt;em&gt;nms&lt;/em&gt; function when predicting object classes and bounding boxes of objects in a new imagein both the &lt;em&gt;Training R-CNN-based custom object detectors&lt;/em&gt; and &lt;em&gt;Training Fast R-CNN-based custom object detectors&lt;/em&gt; sections. &lt;/p&gt;
&lt;h2&gt;
  
  
  Mean average precision
&lt;/h2&gt;

&lt;p&gt;So far, we have looked at getting an output that comprises a bounding box around each object within the image and the class corresponding to the object within the bounding box. Now comes the next question: How do we quantify the accuracy of the predictions coming from our model?&lt;/p&gt;

&lt;p&gt;mAP comes to the rescue in such a scenario. Before we try to understand mAP, let's first understand precision, then average precision, and finally, mAP: &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Typically we calculate precision as&lt;br&gt;
&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--4FZiTsuJ--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/ezcr7ic7tyfprxjh36g4.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--4FZiTsuJ--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/ezcr7ic7tyfprxjh36g4.png" alt="Screen Shot 2021-08-16 at 5.20.32 PM"&gt;&lt;/a&gt;&lt;br&gt;
A true positive refers to the bounding boxes that predicted the correct class of objects and that have an IoU with the ground truth that is greater than a certain threshold. A false positive refers to the bounding boxes that predicted the class incorrectly or have an overlap that is less than the defined threshold with the ground truth. Furthermore, if there are multiple bounding boxes that are identified for the same ground truth bounding box, only one box can get into a true positive, and everything else gets into a false negative.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Average precision is the average of precision values calculated at various IoU thresholds. &lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;mAP is the average of precision values calculated at various IoU threshold values across all the classes of objects present within the dataset. &lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;So far, we have learned about preparing a training dataset for our model, performing non-max suppression on the model's predictions, and calculating its accuracies. In the following sections, we will learn about training a model (R-CNN-based and Fast R-CNN-based) to detect objects in new images.&lt;/p&gt;
&lt;h2&gt;
  
  
  Training R-CNN-based custom object detectors
&lt;/h2&gt;

&lt;p&gt;R-CNN stands for Region-based Convolutional Neural Network. Region-based within R-CNN stands for the region proposals. Region proposals are used to identify objects within an image. Note that R-CNN assists in identifying both the object present in the image and the location of objects present in the image and the location of objects within the image. &lt;/p&gt;

&lt;p&gt;In the following sections, we will learn about the working details of R-CNN before training it on our custom dataset. &lt;/p&gt;
&lt;h3&gt;
  
  
  Working details of R-CNN
&lt;/h3&gt;

&lt;p&gt;Let's get an idea of R-CNN-based object detection at a high level using the following diagram:&lt;br&gt;
&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--8DfsV_vJ--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/5p9v429m2a71ue72mmwh.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--8DfsV_vJ--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/5p9v429m2a71ue72mmwh.png" alt="Screen Shot 2021-08-16 at 5.34.26 PM"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;We perform the following steps when leveraging the R-CNN technique for object detection:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Extract region proposals from an image: ensure that we extract a high number of proposals to not miss out on any potential object within the image. &lt;/li&gt;
&lt;li&gt;Resize (warp) all the extracted regions to get images of the same size.&lt;/li&gt;
&lt;li&gt;Pass the resized region proposals through a network: typically we pass the resized region proposals through a pretrained model such as VGG16 or ResNet50 and extract the features in a fully connected layer. &lt;/li&gt;
&lt;li&gt;Create data for model training, where the input is features extracted by passing the region proposals through a pretrained model, and the outputs are the class corresponding to each region proposal and the offset of the region proposal from the ground truth corresponding to the image. If a region proposal has an IoU greater than a certain threshold with the object, we prepare training data in such a way that the region is responsible for predicting the class of object it is overlapping with and also the offset of region proposal with the ground truth bounding box that contains the object of interest.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;A sample as a result of creating a bounding box offset and a ground truth class for a region proposal is as follows:&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--725ip7ov--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/4yxfk45vadn3525yaw06.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--725ip7ov--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/4yxfk45vadn3525yaw06.png" alt="Screen Shot 2021-08-17 at 9.59.48 AM"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;In the preceding image, o (in red) represents the center of region proposal (dotted bounding box) and x represents the center of the ground truth bounding box (solid bounding box) corresponding to cat class. We calculate the offset between the region proposal bounding box and the ground truth bounding box as the difference between center coordinates of the two bounding boxes ($dx, dy$) and the difference between the height and width of the bounding boxes ($dw, dh$).  &lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;Connect two output heads, one corresponding to the class of image and the other corresponding to the offset of region proposal with the ground truth bounding box to extract the fine bounding box on the object. &lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Train the model post, writing a custom loss function that minimizes both object classification error and the bounding box offset error. &lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Note that the loss function that we will minimize differs from the loss function that is optimized in the original paper. We are doing this to reduce the complexity associated with building R-CNN and Fast R-CNN from scratch. Once the reader is familiar with how the model works and can build a model using the following code, we highly encourage them to implement the original paper from scratch.&lt;/p&gt;

&lt;p&gt;In the next section, we will learn about fetching datasets and creating data for training. In the section after that, we will learn about designing the model and training it before predicting the class of objects present and their bounding boxes in a new image.&lt;/p&gt;
&lt;h3&gt;
  
  
  Implementing R-CNN for object detection on a custom dataset
&lt;/h3&gt;

&lt;p&gt;Implementing R-CNN involves the following steps:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;downloading the dataset&lt;/li&gt;
&lt;li&gt;preparing the dataset&lt;/li&gt;
&lt;li&gt;defining the region proposals extraction and IoU calculation functions&lt;/li&gt;
&lt;li&gt;creating input data for the model, resizing the region proposals, passing them through a pretrained model to fetch the fully connected layer values&lt;/li&gt;
&lt;li&gt;labelling each region proposal with a class or background label, defining the offset of the region proposal from the ground truth if the region proposal corresponds to an object and not background&lt;/li&gt;
&lt;li&gt;defining and training the model&lt;/li&gt;
&lt;li&gt;predicting on new images&lt;/li&gt;
&lt;/ol&gt;
&lt;h4&gt;
  
  
  Downloading the dataset
&lt;/h4&gt;

&lt;p&gt;We will download the data from the &lt;a href="https://storage.googleapis.com/openimages/v5/test-annotations-bbox.csv"&gt;Google Open Images v6 dataset&lt;/a&gt;. In code, we will work on only those images that are of a bus or a truck to ensure that we can train the images (as you will shortly notice the memory issues associated with using &lt;em&gt;selectivesearch&lt;/em&gt;).&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;pip &lt;span class="nb"&gt;install&lt;/span&gt; &lt;span class="nt"&gt;-q&lt;/span&gt; &lt;span class="nt"&gt;--upgrade&lt;/span&gt; selectivesearch torch_snippets
&lt;span class="nb"&gt;mkdir&lt;/span&gt; &lt;span class="nt"&gt;-p&lt;/span&gt; ~/.kaggle
&lt;span class="nb"&gt;mv &lt;/span&gt;kaggle.json ~/.kaggle
&lt;span class="nb"&gt;ls&lt;/span&gt; ~/.kaggle
&lt;span class="nb"&gt;chmod &lt;/span&gt;600 /root/.kaggle/kaggle.json
kaggle datasets download &lt;span class="nt"&gt;-d&lt;/span&gt; sixhky/open-images-bus-trucks/
unzip &lt;span class="nt"&gt;-qq&lt;/span&gt; open-images-bus-trucks.zip
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;div class="ltag_gist-liquid-tag"&gt;
  
&lt;/div&gt;



&lt;p&gt;By now, we have defined all the functions necessary to prepare data and initialize data loaders. In the next section, we will fetch region proposals (input regions to the model) and the ground truth of the bounding box offset along with the class of object (expected output).&lt;/p&gt;

&lt;h3&gt;
  
  
  Fetching region proposals and the ground truth of offset
&lt;/h3&gt;

&lt;p&gt;In this section, we will learn about creating the input and output values corresponding to our model. The input constitutes the candidates that are extracted using the &lt;em&gt;selectivesearch&lt;/em&gt; method and the output constitutes the class corresponding to candidates and the offset of the candidate with respect to the bounding box it overlaps the most with if the candidate contains an object.&lt;/p&gt;


&lt;div class="ltag_gist-liquid-tag"&gt;
  
&lt;/div&gt;


&lt;h3&gt;
  
  
  R-CNN network architecture
&lt;/h3&gt;

&lt;p&gt;In this section, we will learn about building a model that can predict both the class of region proposal and the offset corresponding to it in order to draw a tight bounding box around the object in the image. &lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Define a VGG backbone.&lt;/li&gt;
&lt;li&gt;Fetch the features post passing the normalized crop through a pretrained model.&lt;/li&gt;
&lt;li&gt;Attach a linear layer with sigmoid activation to the VGG backbone to predict the class corresponding to the region proposal. &lt;/li&gt;
&lt;li&gt;Attach an additional linear layer to predict the four bounding box offsets. &lt;/li&gt;
&lt;li&gt;Define the loss calculations for each of the two outputs (one to predict class and the other to predict the four bounding box offsets)&lt;/li&gt;
&lt;li&gt;Train the model that predicts both the class of region proposals and the four bounding box offsets.&lt;/li&gt;
&lt;/ol&gt;

&lt;h3&gt;
  
  
  Predict on a new image
&lt;/h3&gt;

&lt;p&gt;In this section, we will leverage the model trained so far to predict and draw bounding boxes around objects and the corresponding class of object within the predicted bounding box in new images.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Extract region proposals from the new image.&lt;/li&gt;
&lt;li&gt;Resize and normalize each crop.&lt;/li&gt;
&lt;li&gt;Feed-forward the preprocessed crops to make predictions of class and the offsets.&lt;/li&gt;
&lt;li&gt;Perform non-max suppression to fetch only those boxes that have the highest confidence of containing an object.&lt;/li&gt;
&lt;/ol&gt;

</description>
      <category>deeplearning</category>
    </item>
    <item>
      <title>Basics of Object Detection (Part 1)</title>
      <dc:creator>Seri Lee</dc:creator>
      <pubDate>Mon, 16 Aug 2021 06:20:38 +0000</pubDate>
      <link>https://dev.to/sally20921/basics-of-object-detection-part-1-1i52</link>
      <guid>https://dev.to/sally20921/basics-of-object-detection-part-1-1i52</guid>
      <description>&lt;p&gt;&lt;em&gt;This article is originally from the book "Modern Computer Vision with PyTorch"&lt;/em&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Introduction
&lt;/h2&gt;

&lt;p&gt;Imagine a scenario where we are leveraging computer vision for a self-driving car. It is not only necessary to detect whether the image of a road contains the images of vehicles, a sidewalk, and pedestrians, but it is also important to identify &lt;em&gt;where&lt;/em&gt; those objects are located. Various techniques of object detection that we will study in this article will come in handy in such a scenario.&lt;/p&gt;

&lt;p&gt;With the rise of autonomous cars, facial detection, smart video surveillence, and people-counting solutions, fast and accurate object detection systems are in great demand. These systems include not only object classification from an image, but also location of each one of the objects by drawing appropriate bounding boxes around them. This (drawing bounding boxes and classification) makes object detection a harder task than its traditional computer vision predecessor, image classification. &lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--JhcLAK3U--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/7qgc1cav8ch27bdqxo9n.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--JhcLAK3U--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/7qgc1cav8ch27bdqxo9n.png" alt="Screen Shot 2021-08-16 at 2.10.18 PM"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;To understand what the output of object detection looks like, let's go through the following diagram. In the preceding diagram, we can see that, while a typical object classification merely mentions the class of object present in the image, object localization draws a bounding box around the objects present in the image. Object detection, on the other hand, would involve drawing the bounding boxes around individual objects in the image, along with identifying the class of object within a bounding box across multiple objects present in the image. &lt;/p&gt;

&lt;p&gt;Training a typical object detection model involves the following steps:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Creating ground truth data that contains labels of the bounding box and class corresponding to various objects present in the image.&lt;/li&gt;
&lt;li&gt;Coming up with mechanisms that scan through the image to identify regions (region proposals) that are likely to contain objects. In this article, we will learn about leveraging region proposals generated by a method named &lt;em&gt;selective search&lt;/em&gt;. Also, we will learn about leveraging anchor boxes to identify regions containing objects. Moreover, we will learn about leveraging positional embeddings in transformers to aid in identifying the regions containing an object.&lt;/li&gt;
&lt;li&gt;Creating the target class variable by using the IoU metric. &lt;/li&gt;
&lt;li&gt;Creating the target bounding box offset variable to make corrections to the location of region proposal coming in the second step.&lt;/li&gt;
&lt;li&gt;Building a model that can predict the class of object along with the target bounding box offset corresponding to the region proposal. &lt;/li&gt;
&lt;li&gt;Measuring the accuracy of object detection using mean Average Precision (mAP).&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  Creating a bounding box ground truth for training
&lt;/h2&gt;

&lt;p&gt;We have learned that object detection gives us the output where a bounding box surrounds the object of interest in an image. For us  to build an algorithm that detects the bounding box surrounding the object in an image, we would have to create the input-output combinations, where the input is the image and the output is the bounding boxes surrounding the objects in the given image, and the classes corresponding to the objects. &lt;/p&gt;

&lt;p&gt;To train a model that provides the bounding box, we need the image, and also the corresponding bounding box coordinates of all the objects in an image. In this section, we will learn about one way to create the training dataset, where the image is the input and the corresponding bounding boxes and classes of objects are stored in an XML file as output. We will use the &lt;em&gt;ybat&lt;/em&gt; tool to annotate the bounding boxes and the corresponding classes.&lt;/p&gt;

&lt;p&gt;Let's understand about installing and using &lt;em&gt;ybat&lt;/em&gt; to create (annotate) bounding boxes around objects in the image. Furthermore, we will also be inspecting the XML files that contain the annotated class and bounding box information. &lt;/p&gt;

&lt;h3&gt;
  
  
  Installing the image annotation tool
&lt;/h3&gt;

&lt;p&gt;Let's start by downloading &lt;em&gt;ybat-master.zip&lt;/em&gt; from the following &lt;a href="https://github.com/drainingsun/ybat"&gt;github&lt;/a&gt; and unzip it. Post unzipping, store it in a folder of your choice. Open &lt;em&gt;ybat.html&lt;/em&gt; using a browser of your choice and you will see an empty page. The following screenshot shows a sample of what the folders looks like and how to open the &lt;em&gt;ybat.html&lt;/em&gt; file. &lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--esScc7EH--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/4tjwg8i3fj893vvv9xz5.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--esScc7EH--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/4tjwg8i3fj893vvv9xz5.png" alt="Screen Shot 2021-08-16 at 2.25.01 PM"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Before we start creating the ground truth corresponding to an image, let's specify all the possible classes that we want to label across images and store in the &lt;em&gt;classes.txt&lt;/em&gt; file as follows:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--Qxdna4if--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/o8nryuirlg2m9dvrm28u.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--Qxdna4if--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/o8nryuirlg2m9dvrm28u.png" alt="Screen Shot 2021-08-16 at 2.25.58 PM"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Now, let's prepare the ground truth corresponding to an image. This involves drawing a bounding box  around objects and assigning labels/classes to the object present in the image in the following steps:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Upload all the images you want to annotate &lt;/li&gt;
&lt;li&gt;Upload the &lt;em&gt;classes.txt&lt;/em&gt; file.&lt;/li&gt;
&lt;li&gt;Label each image by first selecting the filename and then drawing a crosshair around each object you want to label. Before drawing a crosshair, ensure you select the correct class in the classes region. &lt;/li&gt;
&lt;li&gt;Save the data dump in the desired format. Each format was independently developed by a different research team, and all are equally valid. Based on their popularity and convenience, every implementation prefers a different format. &lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;For example, when we downlaod the PASCAL VOC format, it downloads a zip of XML files. A snapshot of the XML files after drawing the rectangular bounding box is as follows: &lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--LegDokCp--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/nggc8hy4aapsip1dodbh.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--LegDokCp--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/nggc8hy4aapsip1dodbh.png" alt="Screen Shot 2021-08-16 at 2.33.05 PM"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;From the preceding screenshot, note that the &lt;em&gt;bndbox&lt;/em&gt; field contains the coordinates of the minimum and maximum values of the &lt;em&gt;x&lt;/em&gt; and &lt;em&gt;y&lt;/em&gt; coordinates corresponding to the object of interest in the image. We should also be able to extract the classes corresponding to the objects in the image using the &lt;em&gt;name&lt;/em&gt; field.&lt;/p&gt;

&lt;p&gt;Now that we understand how to create a ground truth of objects (class labels and bounding box) present in an image, in the following sections, we will dive into the building blocks of recognizing objects in an image. First, we will talk about region proposals that help in highlighting the portions of the image that are most likely to contain an object. &lt;/p&gt;

&lt;h2&gt;
  
  
  Understanding region proposals
&lt;/h2&gt;

&lt;p&gt;Imagine a hypothetical scenario where the image of interest contains a person and sky in the background. Furthermore, for this scenario, let's assume that there is little change in pixel intensity of the background and that there is considerable change in pixel intensity of the foreground. &lt;/p&gt;

&lt;p&gt;Just from the preceding description itself, we can conclude that there are two primary regions here-one is of the person and the other is of the sky. Furthermore, within the region of the image of a person, the pixels corresponding to hair will have a different intensity to the pixels corresponding to the face, establishing that there can be multiple sub-regions within a region. &lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Region proposal&lt;/strong&gt; is a technique that helps in identifying islands of regions where the pixels are similar to one another. &lt;/p&gt;

&lt;p&gt;Generating a region proposal comes in handy for object detection where we have to identify the locations of objects present in the image. Furthermore, given a region proposal generates a proposal for each region, it aids in object localization where the task is to identify a bounding box that fits exactly around the object in the image. We will learn how region proposals assist in object localization and detection in a later section on &lt;em&gt;Training R-CNN based custom object detectors&lt;/em&gt;, but let's first understand how to generate region proposals from an image. &lt;/p&gt;

&lt;h3&gt;
  
  
  Leveraging Selective Search to generate region proposals
&lt;/h3&gt;

&lt;p&gt;Selective Search is a region proposal algorithm used for object localization where it generates proposals of regions that are likely to be ground together based on their pixel intensities. Selective Search groups pixels based on the hierarchical grouping of similar pixels, which, in turn, leverages the color, texture, size and shape compatibility of content within an image. &lt;/p&gt;

&lt;p&gt;Initially, Selective Search over-segments an image by grouping pixels based on the preceding attributes. Next, it iterates through these over-segmented groups and groups them based on similarity. At each iteration, it combines smaller regions to form a larger region. &lt;/p&gt;

&lt;p&gt;Let's understand the &lt;em&gt;selective search&lt;/em&gt; process through the following example:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;## dependencies &lt;/span&gt;
pip &lt;span class="nb"&gt;install &lt;/span&gt;selectivesearch
pip &lt;span class="nb"&gt;install &lt;/span&gt;torch_snippets
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="nn"&gt;torch_snippets&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt;
&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;selectivesearch&lt;/span&gt;
&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="nn"&gt;skimage.segmentation&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;felzenszwalb&lt;/span&gt;

&lt;span class="n"&gt;img&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;read&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;'Hemanvi.jpeg'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="c1"&gt;## extract the felzenszwalb segments (which are obtained based on the color, texture, size and shape compatibility of content within an image) from the image
&lt;/span&gt;&lt;span class="n"&gt;segments_fz&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;felzenszwalb&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;img&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;scale&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;200&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="c1"&gt;## scale represents the number of clusters that can be formed within the segments of the image. The higher the value of scale, the greater the detail of the original image that is preserved.
&lt;/span&gt;
&lt;span class="n"&gt;subplots&lt;/span&gt;&lt;span class="p"&gt;([&lt;/span&gt;&lt;span class="n"&gt;img&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;segments_fz&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt; &lt;span class="n"&gt;titles&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s"&gt;'Original Image'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;'Image post &lt;/span&gt;&lt;span class="se"&gt;\n&lt;/span&gt;&lt;span class="s"&gt;felzenszwalb segmentation'&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt; &lt;span class="n"&gt;sz&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;10&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;nc&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The preceding code results in the following output: &lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s---pvaZRKs--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/t722n9ve56fny0b72fs9.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s---pvaZRKs--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/t722n9ve56fny0b72fs9.png" alt="Screen Shot 2021-08-16 at 2.51.38 PM"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;From the preceding output, note that pixels that belong to the same group have similar pixel values. &lt;/p&gt;

&lt;h3&gt;
  
  
  Implementing Selective Search to generate region proposals
&lt;/h3&gt;

&lt;p&gt;In this section, we will define the &lt;em&gt;extract_candidates&lt;/em&gt; function using &lt;em&gt;selectivesearch&lt;/em&gt; so that it can be leveraged in the subsequent sections on training R-CNN and Fast R-CNN-based custom object detectors:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="nn"&gt;torch_snippets&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt;
&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;selectivesearch&lt;/span&gt; 

&lt;span class="c1"&gt;# define the function that takes an image as the input parameter
&lt;/span&gt;&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;extract_candidates&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;img&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
 &lt;span class="c1"&gt;# fetch the candidate regions within the image using the selective_search method available in the selectivesearch package
&lt;/span&gt; &lt;span class="n"&gt;img_lbl&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;regions&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;selectivesearch&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;selectivesearch&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;img&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;scale&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;200&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;min_size&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;100&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

 &lt;span class="c1"&gt;# calculate the image area and initialize a list (candidates) that we will use to store the candidates that pass a defined threshold
&lt;/span&gt; &lt;span class="n"&gt;img_area&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;np&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;prod&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;img&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;shape&lt;/span&gt;&lt;span class="p"&gt;[:&lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;])&lt;/span&gt;
 &lt;span class="n"&gt;candidates&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[]&lt;/span&gt;

 &lt;span class="c1"&gt;# fetch only those candidates (regions) that are over 5% of the total image area and less than or equal to 100% of the image area and return them
&lt;/span&gt; &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;r&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="n"&gt;regions&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
  &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;r&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s"&gt;'rect'&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="n"&gt;candidates&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
   &lt;span class="k"&gt;continue&lt;/span&gt;
  &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;r&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s"&gt;'size'&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mf"&gt;0.05&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="n"&gt;img_area&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
   &lt;span class="k"&gt;continue&lt;/span&gt;
  &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;r&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s"&gt;'size'&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="n"&gt;img_area&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt; 
   &lt;span class="k"&gt;continue&lt;/span&gt;
  &lt;span class="n"&gt;x&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;y&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;w&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;h&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;r&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s"&gt;'rect'&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
  &lt;span class="n"&gt;candidates&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;append&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;list&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;r&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s"&gt;'rect'&lt;/span&gt;&lt;span class="p"&gt;]))&lt;/span&gt;
 &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;candidates&lt;/span&gt; 

&lt;span class="n"&gt;img&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;read&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;'Hemanvi.jpeg'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="n"&gt;candidates&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;extract_candidates&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;img&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="n"&gt;show&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;img&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;bbs&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;candidates&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The preceding code generates the following output:&lt;br&gt;
&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--NQdYPFBV--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/nl7cz9ccrvtsnu4cco0o.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--NQdYPFBV--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/nl7cz9ccrvtsnu4cco0o.png" alt="Screen Shot 2021-08-16 at 3.01.11 PM"&gt;&lt;/a&gt;&lt;br&gt;
The grid in the preceding diagram represent the candidate regions (region proposals) coming from the &lt;em&gt;selective_search&lt;/em&gt; method.&lt;/p&gt;

&lt;p&gt;Now that we understand region proposal generation, one question remains unanswered. How do we leverage region proposals for object detection and localization?&lt;/p&gt;

&lt;p&gt;A region proposal that has a high intersection with the location (ground truth) of an object in the image of interest is labeled as the one that contains the object, and a region proposal with a low intersection is labeled as background.&lt;/p&gt;

&lt;p&gt;In the next section, we will learn about how to calculate the intersection of a region proposal candidate with a ground truth bounding box in our journey to understand the various techniques that form the backbone of building an object detection model.&lt;/p&gt;
&lt;h3&gt;
  
  
  Understanding IoU
&lt;/h3&gt;

&lt;p&gt;Imagine a scenario where we came up with a prediction of a bounding box for an object. How do we measure the accuracy of our prediction? The concept &lt;strong&gt;Intersection over Union (IoU)&lt;/strong&gt; comes in handy in such a scenario.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Intersection&lt;/em&gt; measures how overlapping the predicted and actual bounding boxes are, while &lt;em&gt;Union&lt;/em&gt; measures the overall space possible for overlap. IoU is the ratio of the overlapping region between the two bounding boxes over the combined region of both the bounding boxes. &lt;/p&gt;

&lt;p&gt;This can be represented in a diagram as follows: &lt;br&gt;
&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--P-UbSa2X--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/d0d0zn6d8j85okg7jf5p.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--P-UbSa2X--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/d0d0zn6d8j85okg7jf5p.png" alt="Screen Shot 2021-08-16 at 3.07.25 PM"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;In the preceding diagram of two bounding boxes (rectangles), let's consider the left bounding box as the ground truth and the right bounding box as the prediction location of the object. IoU as a metric is the ratio of the overlapping region over the combined region between the two bounding boxes. &lt;/p&gt;

&lt;p&gt;In the following diagram, you can observe the variation in the IoU metric as the overlap between bounding boxes varies:&lt;br&gt;
&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--XfJB292B--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/ynbi6rt8yj18j1hm59ba.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--XfJB292B--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/ynbi6rt8yj18j1hm59ba.png" alt="Screen Shot 2021-08-16 at 3.09.26 PM"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;From the preceding diagram, we can see that as the overlap decreases, IoU decreases and, in the final one, where there is no overlap, the IoU metric is 0.&lt;/p&gt;

&lt;p&gt;Now that we have an intuition of measuring IoU, let's implement it in code and create a function to calculate IoU as we will leverage it in the sections of training R-CNN and training Fast R-CNN.&lt;/p&gt;

&lt;p&gt;Let's define a function that takes two bounding boxes as input and returns IoU as the output:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="c1"&gt;# specify the get_iou function that takes boxA and boxB as inputs where boxA and boxB are two different bounding boxes
&lt;/span&gt;&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;get_iou&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;boxA&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;boxB&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;epsilon&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mf"&gt;1e-5&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
 &lt;span class="c1"&gt;# we define the epsilon parameter to address the rare scenario when the union between the two boxes is 0, resulting in a division by zero error. 
&lt;/span&gt; &lt;span class="c1"&gt;# note that in each of the bounding boxes, there will be four values corresponding to the four corners of the bounding box
&lt;/span&gt;
 &lt;span class="c1"&gt;# calculate the coordinates of the intersection box
&lt;/span&gt; &lt;span class="n"&gt;x1&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nb"&gt;max&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;boxA&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt; &lt;span class="n"&gt;boxB&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;])&lt;/span&gt;
 &lt;span class="n"&gt;y1&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nb"&gt;max&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;boxA&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt; &lt;span class="n"&gt;boxB&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;])&lt;/span&gt;
 &lt;span class="n"&gt;x2&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nb"&gt;min&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;boxA&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt; &lt;span class="n"&gt;boxB&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;])&lt;/span&gt;
 &lt;span class="n"&gt;y2&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nb"&gt;min&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;boxA&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt; &lt;span class="n"&gt;boxB&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="p"&gt;])&lt;/span&gt;

 &lt;span class="c1"&gt;# note that x1 is storing the maximum value of the left-most x-value between the two bounding boxes. y1 is storing the topmost y-value and x2 and y2 are storing the right-most x-value and bottom-most y-value, respectively, corresponding to the intersection part.
&lt;/span&gt;
 &lt;span class="c1"&gt;# calculate the width and height corresponding to the intersection area (overlapping region):
&lt;/span&gt; &lt;span class="n"&gt;width&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;x2&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="n"&gt;x1&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
 &lt;span class="n"&gt;height&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;y2&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="n"&gt;y1&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

 &lt;span class="c1"&gt;# calculate the area of overlap
&lt;/span&gt; &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;width&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="ow"&gt;or&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;height&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="mf"&gt;0.0&lt;/span&gt;
 &lt;span class="n"&gt;area_overlap&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;width&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="n"&gt;height&lt;/span&gt;

 &lt;span class="c1"&gt;# if we specify that if the width or height corresponding to the overlapping region is less than 0, the area of intersection is 0. Otherwise, we calculate the area of overlap (intersection) similar to the way a rectangular's area is calculated. 
&lt;/span&gt;
 &lt;span class="c1"&gt;# calculate the combined area corresponding to the two bounding boxes
&lt;/span&gt; &lt;span class="n"&gt;area_a&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;boxA&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="n"&gt;boxA&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;])&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;boxA&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="n"&gt;boxA&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;])&lt;/span&gt;
 &lt;span class="n"&gt;area_b&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;boxB&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="n"&gt;boxB&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;])&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;boxB&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="n"&gt;boxB&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;])&lt;/span&gt;
 &lt;span class="n"&gt;area_combined&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;area_a&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="n"&gt;area_b&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="n"&gt;area_overlap&lt;/span&gt;

 &lt;span class="n"&gt;iou&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;area_overlap&lt;/span&gt; &lt;span class="o"&gt;/&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;area_combined&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="n"&gt;epsilon&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
 &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;iou&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



</description>
      <category>deeplearning</category>
    </item>
    <item>
      <title>Padding in Neural Network</title>
      <dc:creator>Seri Lee</dc:creator>
      <pubDate>Fri, 13 Aug 2021 05:50:15 +0000</pubDate>
      <link>https://dev.to/sally20921/padding-in-neural-network-o8m</link>
      <guid>https://dev.to/sally20921/padding-in-neural-network-o8m</guid>
      <description>&lt;p&gt;&lt;em&gt;this post is originally from &lt;a href="https://www.machinecurve.com/index.php/2020/02/07/what-is-padding-in-a-neural-network/"&gt;https://www.machinecurve.com/index.php/2020/02/07/what-is-padding-in-a-neural-network/&lt;/a&gt;&lt;/em&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  What is padding and why do we need it?
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--bPWzBbR2--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/yfk5meh3lavt1ie1awk9.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--bPWzBbR2--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/yfk5meh3lavt1ie1awk9.png" alt="image"&gt;&lt;/a&gt;&lt;br&gt;
What you see on the left is an RGB input image-width

&lt;span class="katex-element"&gt;
  &lt;span class="katex"&gt;&lt;span class="katex-mathml"&gt;WW&lt;/span&gt;&lt;span class="katex-html"&gt;&lt;span class="base"&gt;&lt;span class="strut"&gt;&lt;/span&gt;&lt;span class="mord mathnormal"&gt;W&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;/span&gt;
, height 
&lt;span class="katex-element"&gt;
  &lt;span class="katex"&gt;&lt;span class="katex-mathml"&gt;HH&lt;/span&gt;&lt;span class="katex-html"&gt;&lt;span class="base"&gt;&lt;span class="strut"&gt;&lt;/span&gt;&lt;span class="mord mathnormal"&gt;H&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;/span&gt;
 and three channels. Hence, this layer is likely the first layer in your model, in any other scenario, you'd have feature maps as the input to your layer.&lt;/p&gt;

&lt;p&gt;Now, what is a feature map? That's the yellow block in the image. It's a collection of 
&lt;span class="katex-element"&gt;
  &lt;span class="katex"&gt;&lt;span class="katex-mathml"&gt;NN&lt;/span&gt;&lt;span class="katex-html"&gt;&lt;span class="base"&gt;&lt;span class="strut"&gt;&lt;/span&gt;&lt;span class="mord mathnormal"&gt;N&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;/span&gt;
 one-dimensional maps that each represent a particular feature that the model has spotted within the image. This is why convolutional layers are known as feature extractors.&lt;/p&gt;

&lt;p&gt;Now, this is very nice-but how do we get from input (whether image or feature map) to a feature map? This is through &lt;em&gt;kernels&lt;/em&gt; or &lt;em&gt;filters&lt;/em&gt;, actually. These filters-you configure some number 
&lt;span class="katex-element"&gt;
  &lt;span class="katex"&gt;&lt;span class="katex-mathml"&gt;NN&lt;/span&gt;&lt;span class="katex-html"&gt;&lt;span class="base"&gt;&lt;span class="strut"&gt;&lt;/span&gt;&lt;span class="mord mathnormal"&gt;N&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;/span&gt;
 per convolutional layer-"slide"(strictly, convolve) over your input data, and have the same number of "channel" dimensions as your input data, but have much smaller widths and heights. For example, for the scenario above, a filter maybe 3x3 pixels wide and high, but always has 3 channels as our input has 3 channels, too. &lt;/p&gt;

&lt;p&gt;Now, when they slide over the input-from left to right horizontally, then moving down vertically after a row has been captured-they perform element-wise multiplications between what's currently under investigation within the input data and the weights present within the filter. These weights are equal to the weights fo a "classic" neural network, but are structured in a different way. Hence, optimizing a ConvNet involves computing a loss value for the model and subsequently using an optimizer to change the weights. &lt;/p&gt;

&lt;p&gt;Through these weights, as you may guess, the model learns to detect the presence of particular features-which once again, are represented by the feature maps. &lt;/p&gt;

&lt;h2&gt;
  
  
  Conv layers might induce spatial hierarchy
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s---qiXh0Bt--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/7mbrlzyacs7ao7lhdggk.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s---qiXh0Bt--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/7mbrlzyacs7ao7lhdggk.png" alt="image"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;If the width and/or height of your kernels is above 1, you'll see that the width and height of the feature map (being the output) getting smaller. This occurs due to the fact that the feature maps slides over the input and computes element-wise multiplications, but is too large in order to inspect the "edges" of the input. This is illustrated in the image, where "red" position is impossible to take and the "green" ones is part of the path of the convolution operation. &lt;/p&gt;

&lt;p&gt;As it cannot capture the edges, it won't be able to effectively "end" at the final position of your row, resulting in a smaller output width and/or height. &lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--oKqjNCMU--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/oisqs844ibs8iylbk241.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--oKqjNCMU--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/oisqs844ibs8iylbk241.png" alt="image"&gt;&lt;/a&gt; &lt;/p&gt;

&lt;p&gt;We call this a spatial hierarchy. Indeed, convolutional layers may cause a "hierarchy"-like flow of data through the model. Here, you have a schematic representation of a substantial hierarchy and a less substantial one-which is often considered to be less efficient. &lt;/p&gt;

&lt;h2&gt;
  
  
  Padding avoids the loss of spatial dimensions
&lt;/h2&gt;

&lt;p&gt;Sometimes, however, you need to apply filters of a fixed size, but you don't want to lose width and/or height dimensions in your feature maps. For example, this is the case when you're training an autoencoder. You need the outptut images to be of the same size as the input, yet need an activation function like Sigmoid in order to generate them.&lt;/p&gt;

&lt;p&gt;If you do so with a Conv layer, this would be problematic, as you'd reduce the size of your feature maps-and hence would produce outputs unequal in size as your inputs. &lt;/p&gt;

&lt;p&gt;That's not what we want when we create an autoencder. We want the original output and the original output only.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--6ruJUPSk--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/pn9zlb45b6j56w1rsv96.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--6ruJUPSk--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/pn9zlb45b6j56w1rsv96.png" alt="image"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Padding helps you solve this problem. Applying it effectively adds space around your input data or your feature map-or more precisely, "extra rows and columns". &lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--5zE4GoKI--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/tqzb6ie1gjl20qrfvb87.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--5zE4GoKI--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/tqzb6ie1gjl20qrfvb87.png" alt="image"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The consequence of this fact are rather pleasurable, as we can see in the example above. Adding "extra space" now allows us to capture the position we previously couldn't capture, and allows us to detect features in the edges of your input. &lt;/p&gt;

&lt;h2&gt;
  
  
  Types of padding
&lt;/h2&gt;

&lt;p&gt;Now, unfortunately, padding is not a binary option-i.e. it cannot simply be turned on and off. Rather, you can choose which padding you use. &lt;/p&gt;

&lt;h3&gt;
  
  
  Valid padding/no padding
&lt;/h3&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--56tTcBga--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/aft3yq6pezdainqmyhs2.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--56tTcBga--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/aft3yq6pezdainqmyhs2.png" alt="image"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Valid padding simply means "no padding". This equals the scenario where capturing edges only is not possible.  &lt;/p&gt;

&lt;p&gt;It may seem strange to you that frameworks include an option for valid padding/no padding, as you could simply omit the padding as well. However, this is not strange at all: if you specify some &lt;em&gt;padding&lt;/em&gt; attribute, there must be a default value. &lt;/p&gt;

&lt;h2&gt;
  
  
  Same padding/zero padding
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--YmWgKj0V--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/46n68s58zhyee1kzb5r0.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--YmWgKj0V--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/46n68s58zhyee1kzb5r0.png" alt="image"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Another option would be "same padding" also known as "zero padding". Here, the padding ensures that the output has the same shape as the input data. It is achieved by adding "zeros" at the edge of your layer output, e.g. the white space on the right of the image. &lt;/p&gt;

&lt;h2&gt;
  
  
  Casual Padding
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--3vf2Unp9--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/57qoj8s07hdqb18ce4sh.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--3vf2Unp9--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/57qoj8s07hdqb18ce4sh.png" alt="image"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Suppose that you have a time series dataset, where two inputs together determine an output, in a causal fashion. It's possible to create a model that can handle this by means of a &lt;em&gt;Conv1D&lt;/em&gt; layer with a kernel size of 2-the learnt kernel will be able to map the inputs to the outputs successfully. &lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--WQrr5Cfd--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/fd87ac807qhr2elca845.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--WQrr5Cfd--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/fd87ac807qhr2elca845.png" alt="image"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;But what about the first two targets? Although they are valid targets, the input are incomplete-that is, there is insufficient input data available in order to successfully use them in the training process. For the second target, one input-visible in gray-is missing (whereas the second is actually there), while for the first target both aren't there. &lt;/p&gt;

&lt;p&gt;For the first target, there is no real hope for success (as we don't have any input at all and hence do not know which values produce the target values), but for the second, we have a partial picture: we've got half the inputs that produce the target. &lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--vlXItmae--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/12c17lpuk1010470tw0d.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--vlXItmae--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/12c17lpuk1010470tw0d.png" alt="image"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Causal padding on the &lt;em&gt;Conv1D&lt;/em&gt; layer allows you to include the partial information in your training process. By padding your input dataset with zeros at the front, a causal mapping to the first, missed-out targets can be made. While the first target will be useless for training, the second can now be used based on the partial information that we have. &lt;/p&gt;

&lt;h3&gt;
  
  
  Reflection padding
&lt;/h3&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--ENjk_7PR--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/16zxbk5x7jegfof422bk.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--ENjk_7PR--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/16zxbk5x7jegfof422bk.png" alt="image"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Another type of padding is "reflection padding". As you can see, it pads the values with the "reflection" or "mirror" of the values directly in the opposite direction of the edge of your to be padded shape. &lt;/p&gt;

&lt;p&gt;For example, if you look at the image above, for the first row of the yellow box: if you go to the right, you'll see a 1. Now you need to fill the padding element directly to the right. What do you find when you move in the opposite direction of the edge? Indeed, a 5. Hence, your first padding value is a 5. When you move further, it's a 3, so the next padding value following the 5 is 3. And so one. In the opposite direction, you get a mirrored effect. Having a 3 at the edge, you'll once again find 5 (as it's the center value) but the second value for the padding will be a 1. and so on. &lt;/p&gt;

&lt;p&gt;Reflective padding seems to improve the empirical performance of your model. Possibly, this occurs because of how "zero" based padding (i.e. the "same" padding) and "constant" based padding alter the distribution of your dataset. This becomes clear when we actually visualize the padding when it is applied:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s---aFm-cLa--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/lwx4fxqmdol3abxug82p.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s---aFm-cLa--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/lwx4fxqmdol3abxug82p.png" alt="image"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Replication Padding/Symmetric Padding
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--ZepxDJqJ--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/7k6ri6ibzgn5pd1mv1gi.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--ZepxDJqJ--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/7k6ri6ibzgn5pd1mv1gi.png" alt="image"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Replication padding looks like reflection padding, but is slightly different. Rather than reflecting like a mirror, you simply take a copy and mirror it. Like this: You're at the first row again, at the right. You find a 1. What is the next value? Simple: you copy the entire row, mirror it, and start adding it as padding values horizontally. As you can see, since we only pad 2 elements in width, there are 1 and 5, but 3 falls off the padding. &lt;/p&gt;

&lt;p&gt;As with reflection padding, replication padding attempts to reduce the impact of "zero" and "constant" padding on the quality of your data by using "plausible" data values re-using what is along the borders of the input. &lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--ATJ9QkBk--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/sswemg4r58mbai40ilo2.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--ATJ9QkBk--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/sswemg4r58mbai40ilo2.png" alt="image"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Which padding to use when?
&lt;/h2&gt;

&lt;p&gt;There are no hard criteria that prescribe when to use which type of padding. Rather, it's important to understand that padding is pretty much important all the time-because it allows you to preserve information that is present at the borders of your input data, and present there only.  &lt;/p&gt;

</description>
      <category>deeplearning</category>
    </item>
  </channel>
</rss>
