<?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: Levente Slajcho</title>
    <description>The latest articles on DEV Community by Levente Slajcho (@levente-slajcho).</description>
    <link>https://dev.to/levente-slajcho</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.us-east-2.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F3996309%2F0cab2b40-e105-4fe6-81fe-9c1b0df7c7b8.jpg</url>
      <title>DEV Community: Levente Slajcho</title>
      <link>https://dev.to/levente-slajcho</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/levente-slajcho"/>
    <language>en</language>
    <item>
      <title>Image Segmentation - Part 1: Data Exploration and Baseline Model (S1E1)</title>
      <dc:creator>Levente Slajcho</dc:creator>
      <pubDate>Thu, 25 Jun 2026 16:09:30 +0000</pubDate>
      <link>https://dev.to/levente-slajcho/image-segmentation-with-u-net-computer-vision-code-along-series-s1e1-hmo</link>
      <guid>https://dev.to/levente-slajcho/image-segmentation-with-u-net-computer-vision-code-along-series-s1e1-hmo</guid>
      <description>&lt;h1&gt;
  
  
  Table of contents
&lt;/h1&gt;



&lt;ul&gt;
&lt;li&gt;
Foreword

&lt;ul&gt;
&lt;li&gt;Prerequisites&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;GitHub Repository&lt;/li&gt;
&lt;li&gt;
Let's Dive In

&lt;ul&gt;
&lt;li&gt;Loading the Dataset&lt;/li&gt;
&lt;li&gt;Building the Model&lt;/li&gt;
&lt;li&gt;Training the Model&lt;/li&gt;
&lt;li&gt;Exploration&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Summary&lt;/li&gt;
&lt;li&gt;Foreshadowing&lt;/li&gt;
&lt;li&gt;Afterword&lt;/li&gt;
&lt;/ul&gt;




&lt;h1&gt;
  
  
  Foreword
&lt;/h1&gt;

&lt;p&gt;&lt;br&gt;&lt;em&gt;Don't worry if you have never created a single model before.&lt;/em&gt;&lt;br&gt;&lt;/p&gt;

&lt;p&gt;This post is written for beginners with some theoretical knowledge, aiming to explain concepts in the practical way I wish I had found when I started going deeper with neural networks. That being said: your feedback means the world to me - especially if you are an expert in this field, reading this.&lt;/p&gt;

&lt;p&gt;As mentioned in the &lt;a href="https://dev.to/levente-slajcho/cva-computer-vision-adventure-series-s1e0-intro-3pjn"&gt;Intro&lt;/a&gt;, we start our series with a Kaggle competition, solving an image segmentation problem, labeling cars on a Birds-Eye View (BEV) LiDAR map.&lt;/p&gt;

&lt;p&gt;This project consists of 3 parts. By the end of this one, Part 1, you will build an intuition about:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;U-Net Structure&lt;/li&gt;
&lt;li&gt;Encoders and Decoders&lt;/li&gt;
&lt;li&gt;Skip connections&lt;/li&gt;
&lt;li&gt;IoU metric for evaluating segmentation masks&lt;/li&gt;
&lt;li&gt;Understand what's COCO-style dataset&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;*&lt;em&gt;This is intentionally a simple baseline model. The goal of Part 1 is not maximum accuracy, but understanding the full pipeline.&lt;br&gt;
*&lt;/em&gt;&lt;br&gt;
&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F1cdxlteko3l6bid08iwn.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F1cdxlteko3l6bid08iwn.png" alt="Example inference" width="800" height="268"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;h3&gt;
  
  
  Prerequisites
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;Theoretical:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Basic information about how neural networks work. &lt;a href="https://www.coursera.org/specializations/deep-learning" rel="noopener noreferrer"&gt;This course&lt;/a&gt; is recommended, alternatively the corresponding videos on the &lt;a href="https://www.youtube.com/@Deeplearningai/playlists" rel="noopener noreferrer"&gt;DeepLearningAI Youtube channel&lt;/a&gt; for the theory.&lt;/li&gt;
&lt;li&gt;Understand how image filters work. You can read about it &lt;a href="https://saaisudarsanan.medium.com/filters-and-operations-on-an-image-da31054db734" rel="noopener noreferrer"&gt;here&lt;/a&gt;, or try it out yourself using this simple Jupyter Notebook I created for the Intro of this series: &lt;a href="https://github.com/slelo/CVCA-S0E0-OpenCV-Playground" rel="noopener noreferrer"&gt;https://github.com/slelo/CVCA-S0E0-OpenCV-Playground&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Technical:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://www.kaggle.com/competitions/segment-vehicle-lidar/data" rel="noopener noreferrer"&gt;Download the dataset for this example from Kaggle&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;Basic Python programming skills&lt;/li&gt;
&lt;li&gt;Python &amp;gt;=3.10, preferably 3.10 or 3.11. Newer version sometimes have compability issues.&lt;/li&gt;
&lt;li&gt;Jupyter Notebook (run &lt;code&gt;jupyter --version&lt;/code&gt; from your Python venv to check)&lt;/li&gt;
&lt;li&gt;PyTorch with CUDA (&lt;a href="https://pytorch.org/get-started/locally/" rel="noopener noreferrer"&gt;see hardware and software requirements here&lt;/a&gt;) To check, this running this snippet should return &lt;code&gt;True&lt;/code&gt;:
&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;torch&lt;/span&gt;
&lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;torch&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;cuda&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;is_available&lt;/span&gt;&lt;span class="p"&gt;())&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;If &lt;code&gt;False&lt;/code&gt;, run this: &lt;code&gt;pip install torch torchvision torchaudio --index-url https://download.pytorch.org/whl/cu121&lt;/code&gt;&lt;/p&gt;


&lt;h1&gt;
  
  
  GitHub Repository
&lt;/h1&gt;

&lt;p&gt;&lt;a href="https://github.com/slelo/CVCA-S1E1-UNet-Image-Segmentation/tree/part-01-baseline-model" class="crayons-btn crayons-btn--primary" rel="noopener noreferrer"&gt;🤖 Use this repository for this project&lt;/a&gt;
&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Make sure you're on the &lt;code&gt;part-01-baseline-model&lt;/code&gt; branch.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;For the best learning experience, I kindly ask you to copy the code &lt;strong&gt;by typing&lt;/strong&gt;, preferably even without ML full-line autocomplete extensions. There are no shortcuts for understanding concepts and building intuition, your brain will thank you a lot for actively thinking while typing.&lt;/p&gt;




&lt;h1&gt;
  
  
  Let's Dive In
&lt;/h1&gt;

&lt;ol&gt;
&lt;li&gt;Project Structure&lt;/li&gt;
&lt;li&gt;Loading the Dataset&lt;/li&gt;
&lt;li&gt;Building the Model&lt;/li&gt;
&lt;li&gt;Training the Model&lt;/li&gt;
&lt;li&gt;
Exploration

&lt;/li&gt;
&lt;/ol&gt;

&lt;h3&gt;
  
  
  Project Structure
&lt;/h3&gt;

&lt;p&gt;&lt;br&gt;In the first step, create the following project structure:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;segment-vehicle-lidar/
|
├── data/
├── notebooks/
│   ├── 01_exploration.ipynb
|   └── 02_training_baseline.ipnyb
├── src/
│   ├── dataset.py
│   ├── model.py
│   └── train.py
├── checkpoints/
└── README.md
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Next:&lt;br&gt;
&lt;a href="https://www.kaggle.com/competitions/segment-vehicle-lidar/data" class="crayons-btn crayons-btn--primary" rel="noopener noreferrer"&gt;🤖 Download the dataset from Kaggle&lt;/a&gt;
&lt;/p&gt;

&lt;p&gt;After extracting the file copy the &lt;code&gt;test/&lt;/code&gt; and &lt;code&gt;train/&lt;/code&gt; folders into the &lt;code&gt;data/&lt;/code&gt; folder.&lt;/p&gt;

&lt;h3&gt;
  
  
  Loading the Dataset
&lt;/h3&gt;

&lt;p&gt;Open &lt;code&gt;dataset.py&lt;/code&gt;.&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;import&lt;/span&gt; &lt;span class="n"&gt;os&lt;/span&gt; &lt;span class="c1"&gt;#handles paths
&lt;/span&gt;&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;json&lt;/span&gt; &lt;span class="c1"&gt;#handles train.json
&lt;/span&gt;&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;numpy&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="n"&gt;np&lt;/span&gt; 
&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;cv2&lt;/span&gt; &lt;span class="c1"&gt;#for loading and converting images and for handling polygons
&lt;/span&gt;&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;torch&lt;/span&gt; &lt;span class="c1"&gt;#does neural network stuff
&lt;/span&gt;&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="n"&gt;torch.utils.data&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;Dataset&lt;/span&gt; &lt;span class="c1"&gt;#handles data for neural network stuff
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Let's take a look at the code from the repository. In this file, you can see a class named &lt;code&gt;CocoSegDataset(Dataset)&lt;/code&gt;. This class tells us how and from where the COCO-style dataset should be loaded. Luckily, we don't have to implement the whole COCO format ourselves. For this project, our custom CocoSegDataset class reads the parts we need and turns the segmentation polygons into masks.&lt;/p&gt;

&lt;p&gt;The COCO-style format is a standardized JSON-based format for training models for diverse tasks where we don't only want to know &lt;strong&gt;what&lt;/strong&gt; we see in the image, but more importantly &lt;strong&gt;where&lt;/strong&gt; we see it. A few examples are 2D human pose estimation, image labeling, and object detection.&lt;/p&gt;

&lt;p&gt;Open the &lt;code&gt;train.json&lt;/code&gt; annotation file. First you see a list of the metadata of the images and an assigned &lt;code&gt;id&lt;/code&gt;. Then, when you scroll down, among some other information, you'll find the &lt;code&gt;image_id&lt;/code&gt;, &lt;code&gt;segmentation&lt;/code&gt;, &lt;code&gt;bbox&lt;/code&gt; and &lt;code&gt;area&lt;/code&gt;. &lt;/p&gt;

&lt;p&gt;As you can see in the image of whatever I managed to draw below (let's call it Myrtle the Cat), &lt;code&gt;segmentation&lt;/code&gt; (black) denotes a polygon in &lt;code&gt;x1, y1, x2, y2, ...&lt;/code&gt; format. The &lt;code&gt;area&lt;/code&gt; of the labelled data and &lt;code&gt;bbox&lt;/code&gt; (blue) that contains &lt;code&gt;[x, y, width, height]&lt;/code&gt; for the bounding box.&lt;/p&gt;

&lt;p&gt;In the &lt;code&gt;for&lt;/code&gt; loop of CocoSegDataset class's &lt;code&gt;__getitem__&lt;/code&gt; method, you can see how OpenCV is capable of turning these polygons into a 2D matrix mask.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F71y9ucol6ex7cwnhv51e.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F71y9ucol6ex7cwnhv51e.png" width="800" height="374"&gt;&lt;/a&gt;&lt;/p&gt;&lt;br&gt;COCO-style data annotation consisting of Myrtle the Cat and a polygon, bounding box and area
  &lt;p&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="" class="article-body-image-wrapper"&gt;&lt;img alt=" "&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;After reading the images, the last important step happens in these lines:&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="n"&gt;image&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;torch&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;from_numpy&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;image&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;permute&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="mi"&gt;0&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="nf"&gt;float&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;span class="n"&gt;mask&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;torch&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;from_numpy&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;mask&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;float&lt;/span&gt;&lt;span class="p"&gt;().&lt;/span&gt;&lt;span class="nf"&gt;unsqueeze&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="nf"&gt;float&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The first line's purpose is to change the order of dimensions in a way &lt;a href="https://docs.pytorch.org/docs/2.12/generated/torch.nn.Conv2d.html#torch.nn.Conv2d" rel="noopener noreferrer"&gt;PyTorch likes it&lt;/a&gt;. It expects the input channels (RGB) first, then the height and width of the image.&lt;/p&gt;

&lt;p&gt;The second operation simply turns a 2D mask into a 3D array by using &lt;a href="https://docs.pytorch.org/docs/2.12/generated/torch.unsqueeze.html" rel="noopener noreferrer"&gt;&lt;code&gt;.unsqueeze(0)&lt;/code&gt;&lt;/a&gt; where &lt;code&gt;0&lt;/code&gt; specifies the position of the newly added dimension. This dimension is needed to make &lt;code&gt;mask&lt;/code&gt; have a channel dimension and match the number of dimensions of &lt;code&gt;image&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F0l86z4ljx5hb136cjmtv.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F0l86z4ljx5hb136cjmtv.png" alt=" " width="800" height="384"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;em&gt;&lt;strong&gt;Intuition Hook&lt;/strong&gt;&lt;/em&gt;&lt;br&gt;
&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fcqryvu0gqz10tecj65mq.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fcqryvu0gqz10tecj65mq.png" alt=" " width="352" height="162"&gt;&lt;/a&gt;&lt;br&gt;
In the beginning, after reading tons of sophisticated and very mathematic description of tensors, I realized that in Computer Science, a tensor is just a one-dimensional or multidimensional array. Nothing more, nothing less. Frameworks like PyTorch and TensorFlow mainly work with tensors.&lt;br&gt;
Flat Jerry is a matrix, 3D Jerry is a tensor PyTorch likes.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;.squeeze(d)&lt;/code&gt; flattens Jerry by removing its dimension &lt;code&gt;d&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;.unsqueeze(p)&lt;/code&gt; inflates Jerry by adding a new dimension to the array at position &lt;code&gt;p&lt;/code&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/blockquote&gt;

&lt;h3&gt;
  
  
  Building the Model
&lt;/h3&gt;

&lt;p&gt;Time to build our model! &lt;br&gt;
We are going to implement this network,&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fgsd4fzuyd1lu0kh03wao.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fgsd4fzuyd1lu0kh03wao.png" alt=" " width="800" height="495"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Here, the Encoder - consisting of 3 EncloderBlocks - extracts the features in the image, and the Decoder - consisting of 3 DecoderBlocks - upsamples the intermediate features and creates the output - the yellow label over Myrtle the Cat.&lt;/p&gt;

&lt;p&gt;Open &lt;code&gt;model.py&lt;/code&gt; and copy the code into your project. You will see 4 classes defined, ordered by level of abstraction in the models structure:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;code&gt;DoubleConv(nn.Module)&lt;/code&gt;: Implements a &lt;a href="https://docs.pytorch.org/docs/2.12/generated/torch.nn.Module.html" rel="noopener noreferrer"&gt;Module&lt;/a&gt;, which is the base class for all neural network modules, a fundamental building block for neural networks. For our baseline model in Part 1, we start building our model with &lt;a href="https://docs.pytorch.org/docs/2.12/generated/torch.nn.Conv2d.html" rel="noopener noreferrer"&gt;Conv2d layers&lt;/a&gt;, each followed by a &lt;a href="https://docs.pytorch.org/docs/2.12/generated/torch.nn.ReLU.html" rel="noopener noreferrer"&gt;ReLU&lt;/a&gt; activation function.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;The Encoder and the Decoder:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;The &lt;code&gt;EncoderBlock&lt;/code&gt; (marked red) consists of one DoubleConv module for feature extraction and a &lt;a href="https://docs.pytorch.org/docs/2.12/generated/torch.nn.MaxPool2d.html" rel="noopener noreferrer"&gt;MaxPool2d&lt;/a&gt; for downsampling. In our project, these blocks learn increasingly abstract features that help the model identify which pixels belong to cars.&lt;/li&gt;
&lt;li&gt;The &lt;code&gt;DecoderBlock&lt;/code&gt; (marked blue) upsamples the feature maps using transposed 2D convolution, &lt;a href="https://docs.pytorch.org/docs/2.12/generated/torch.nn.ConvTranspose2d.html" rel="noopener noreferrer"&gt;ConvTranspose2d&lt;/a&gt; (often incorrectly called &lt;strong&gt;deconvolution&lt;/strong&gt;), followed by a previously defined DoubleConv module. &lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Finally &lt;code&gt;UNet&lt;/code&gt;, the highest level PyTorch module in our model. It assembles the model using 3 EncoderBlocks, a Bottleneck (DoubleConv) in the middle, 3 DecoderBlocks, and a &lt;a href="https://docs.pytorch.org/docs/2.12/generated/torch.nn.Conv2d.html" rel="noopener noreferrer"&gt;&lt;code&gt;Conv2d&lt;/code&gt;&lt;/a&gt; output layer. In this project we won't use an activation function - e.g. a sigmoid - as the output layer, because we are going to use a loss function that works with raw logits: &lt;a href="https://docs.pytorch.org/docs/2.12/generated/torch.nn.BCEWithLogitsLoss.html" rel="noopener noreferrer"&gt;BCEWithLogitsLoss&lt;/a&gt;. For that, we need the unprocessed output information. Logits are the raw output values of the model before converting them into probabilities with a sigmoid function. Since we only predict whether each pixel is car or background, this is a binary segmentation problem, so one output channel with &lt;code&gt;BCEWithLogitsLoss&lt;/code&gt; is enough.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Now take a break and spot an important difference between the &lt;code&gt;forward&lt;/code&gt; methods of the EncoderBlock and the DecoderBlock. &lt;/p&gt;

&lt;p&gt;The DecoderBlock has two inputs: &lt;code&gt;x&lt;/code&gt; and &lt;code&gt;skip&lt;/code&gt;. The second one denotes the Skip Connections marked with gray lines in the figure above. &lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;&lt;em&gt;Intuition Hook&lt;/em&gt;&lt;/strong&gt;&lt;br&gt;
&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fdh805ksgd90gps9qa916.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fdh805ksgd90gps9qa916.png" alt=" " width="557" height="372"&gt;&lt;/a&gt;&lt;br&gt;
You can think of a skip connection as a sort of IKEA assembly instruction.&lt;/p&gt;

&lt;p&gt;The first DecoderBlock gets the parts (features) from the Bottleneck layer, but doesn't really know what to do with them. &lt;/p&gt;

&lt;p&gt;In our project, the EncoderBlock from the same level gives the instructions using the &lt;em&gt;skip connection&lt;/em&gt; saying, "I can provide this kind of image structure to fit the parts into", but it can't help further. Therefore, the first DecoderBlock assembles the parts based on the information it has, and hands it to the second DecoderBlock.&lt;/p&gt;

&lt;p&gt;The second DecoderBlock has the assembly from the first DecoderBlock as one part, but has to build it in a bigger assembly now. To do this, it gets the assembly instructions from the EncoderBlock on the same level using the &lt;em&gt;skip connection&lt;/em&gt;, and so on.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;That's it! We just built a baseline model!&lt;/p&gt;

&lt;h3&gt;
  
  
  Training the Model
&lt;/h3&gt;

&lt;p&gt;In the next step, open and copy the code of &lt;code&gt;train.py&lt;/code&gt;.&lt;br&gt;
In this file we will prepare our training and validation sets using the images in &lt;code&gt;data/train/images&lt;/code&gt; and specify how to run a training and validation for each epoch.&lt;/p&gt;

&lt;p&gt;The code in this file is pretty easy to follow. Start the coding part with the &lt;code&gt;main&lt;/code&gt; function and refer to the comments for the explanation of the code. Don't forget about the &lt;code&gt;if __name__ == "__main__": [...]&lt;/code&gt; part, otherwise in the next step, the training won't work as expected.&lt;/p&gt;

&lt;p&gt;About the IoU metric: practically we won't use the &lt;code&gt;compute_iou(...)&lt;/code&gt; (&lt;a href="https://pyimagesearch.com/2016/11/07/intersection-over-union-iou-for-object-detection/" rel="noopener noreferrer"&gt;Intersection over Union&lt;/a&gt;) metric for anything. It's only there to see the training progress, and to have a better understanding about what's happening. &lt;/p&gt;

&lt;p&gt;We won't use it as a loss function, because it returns discrete values and therefore it isn't differentiable. Backward propagation only works with differentiable functions. However, this is something we luckily don't have to do manually: frameworks like Tensorflow and PyTorch automatically do the calculations for us for those (see the &lt;code&gt;#backward propagation&lt;/code&gt; part in the &lt;code&gt;train_one_epoch(...)&lt;/code&gt; method).&lt;/p&gt;




&lt;h1&gt;
  
  
  Exploration
&lt;/h1&gt;

&lt;p&gt;From now on, you will see some exciting results.&lt;br&gt;
Simply follow the instructions of the two notebooks, &lt;code&gt;01_exploration.ipnyb&lt;/code&gt; and &lt;code&gt;02_training_baseline.ipnyb&lt;/code&gt; and try to write the code yourself for practice. They will guide you through the training and evaluation part.&lt;/p&gt;

&lt;p&gt;For the &lt;code&gt;01_exploration.ipnyb&lt;/code&gt;, expected result should look something like this:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fw8b03fu8bii90fa4x96i.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fw8b03fu8bii90fa4x96i.png" alt=" " width="799" height="259"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;and for &lt;code&gt;02_training_baseline.ipnyb&lt;/code&gt;, something like this:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F1bpvo7mwz4bihqvczzyh.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F1bpvo7mwz4bihqvczzyh.png" alt=" " width="800" height="556"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;For better understanding of the numbers in the results, here is some rule of thumb:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;High &lt;code&gt;train_loss&lt;/code&gt; and High &lt;code&gt;val_loss&lt;/code&gt; means high bias. This means that the model is underfitted, failing to recognise patterns.&lt;/li&gt;
&lt;li&gt;Low  &lt;code&gt;train_loss&lt;/code&gt; and High &lt;code&gt;val_loss&lt;/code&gt; means high variance/overfitting. The model is learned the training data "by heart". It can't recognize new data, it's too sensitive to the noise in the training data.&lt;/li&gt;
&lt;li&gt;Low &lt;code&gt;train_loss&lt;/code&gt; and Low &lt;code&gt;val_loss&lt;/code&gt; normally means a good fit. The model learned to recognise the patterns, but immune to the noise.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;If you'd like to see Part 2 of Image Segmentation in the next episode, please &lt;/p&gt;

&lt;h1&gt;
  
  
  Summary
&lt;/h1&gt;

&lt;p&gt;In this part we learned how to read the a COCO-style dataset and handle it with PyTorch. We built a simple model with BCEWithLogitsLoss loss function (criterion). After a quick sanity check by overfitting 1 and then 10 images, we were able to train our first U-Net model. &lt;/p&gt;

&lt;p&gt;Most importantly, we now hopefully have an intuition about the basic concepts of a neural networks and can apply them in real life.&lt;/p&gt;

&lt;h1&gt;
  
  
  Foreshadowing
&lt;/h1&gt;

&lt;p&gt;In the next episode, Part 2 of Image Segmentation project we will focus on making our model even better. &lt;/p&gt;

&lt;p&gt;We will use a great tool to curate the dataset, learn how to tune hyperparameters and build a better model architecture that can also be trained more consistently.&lt;/p&gt;

&lt;p&gt;Follow if you'd like to join!&lt;/p&gt;

&lt;h1&gt;
  
  
  Afterword
&lt;/h1&gt;

&lt;p&gt;Thank you for following this series and for coding along with this project. I appreciate it.&lt;/p&gt;

&lt;p&gt;If you are someone learning Computer Vision, please leave a feedback in the comments and share your experience. It will help me imrpoving the quality of my work and it will help others to get better.&lt;/p&gt;

&lt;p&gt;If you are an expert in the field, your constructive feedback means the world to me. I started this series to showcase concepts through interesting projects and help others to understand concepts the way I did. This means that my projects can have mistakes or missing information. &lt;/p&gt;

</description>
      <category>ai</category>
      <category>pytorch</category>
      <category>computervision</category>
      <category>python</category>
    </item>
    <item>
      <title>Intro to Computer Vision Code-Along series - S1E0</title>
      <dc:creator>Levente Slajcho</dc:creator>
      <pubDate>Mon, 22 Jun 2026 11:34:38 +0000</pubDate>
      <link>https://dev.to/levente-slajcho/cva-computer-vision-adventure-series-s1e0-intro-3pjn</link>
      <guid>https://dev.to/levente-slajcho/cva-computer-vision-adventure-series-s1e0-intro-3pjn</guid>
      <description>&lt;h1&gt;
  
  
  Motivation
&lt;/h1&gt;

&lt;p&gt;Let me start with a very short story.&lt;/p&gt;

&lt;p&gt;I did my first project involving Computer Vision when I was 15 years old, completely fascinated by technology and by creative solutions to all kinds of problems.&lt;/p&gt;

&lt;p&gt;At the time, I thought it would be cool to turn my PC into a touchscreen device, so I took the naked LCD panel and diffuser layer from an old screen and built them into a cardboard box. I also disassembled my webcam and replaced its RGB filter with a makeshift infrared filter made from the black disk of an old floppy disk. The sketchy IR camera, together with a few IR LEDs, was placed inside the box, and whenever I touched the diffuser, it reflected the IR light back to the camera sensor.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fbaqhx8gqujo5o2fucmwg.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fbaqhx8gqujo5o2fucmwg.png" width="640" height="360"&gt;&lt;/a&gt;&lt;/p&gt;&lt;br&gt;I had something like this in mind. Ended up with an 8 inch screen of an old multimedia station for cars | Image source: &lt;a href="https://prototypinginterfaces.com/5-5/" rel="noopener noreferrer"&gt;https://prototypinginterfaces.com/5-5/&lt;/a&gt;
  &lt;p&gt;&lt;/p&gt;

&lt;p&gt;Using CCV from the since then vanished company NUi Group (&lt;a href="https://github.com/nuigroup/ccv2" rel="noopener noreferrer"&gt;https://github.com/nuigroup/ccv2&lt;/a&gt;), I calibrated the four corners of the screen, and together with the TUIO mouse driver, that was enough to track my fingers and use them as multi-touch input.&lt;/p&gt;

&lt;p&gt;I can't really describe what it feels like as a teenager to build a touchscreen PC for exactly $0. That small project opened a huge window for me. It showed me that cameras are not only for recording fun and memorable moments - they can also be used to build things, solve problems, and interact with the world in completely different ways.&lt;/p&gt;

&lt;h3&gt;
  
  
  Fast forward to 2026
&lt;/h3&gt;

&lt;p&gt;A little over a decade later, I graduated in Media Informatics and Visual Computing, and I now have almost 8 years of combined professional experience in 3D design, product development, and Java development. The first satisfied my love for DIY projects, the latter my love for IT.&lt;/p&gt;

&lt;p&gt;In a way, Computer Vision as my ultimate career goal feels like the combination of those two worlds. Cameras and image processing have a very strong connection to the real world, especially if you consider Computer Vision as part of robotics - and that is exactly the field I am absolutely in love with.&lt;/p&gt;

&lt;p&gt;However, having experience only from my studies is a turn-off for companies looking to hire a Computer Vision Engineer. &lt;/p&gt;

&lt;p&gt;9 years ago I managed to get a 3D designer job with Solidworks just by sitting down to practice all day and all night for only 2 weeks, turning my hobby and personal interest into a profession. Computer Vision is of course a more complex topic, but I am convinced that with the same amount of motivation and enthusiasm the same thing will happen again.&lt;/p&gt;




&lt;h1&gt;
  
  
  About the Computer Vision Code-Along series
&lt;/h1&gt;

&lt;p&gt;Let's climb this mountain together, and follow me if you're interested.&lt;/p&gt;

&lt;p&gt;If you are in a similar situation and looking forward to working in this field and helping the world with your own vision and your computer's vision, stick with me. In this series, I'll be working on three kinds of projects: Kaggle competitions, real-life problems, and totally made-up problems that nobody ever asked a solution for - let’s call those fun projects.&lt;/p&gt;

&lt;p&gt;The focus of every project is to learn something new, gain experience, and overcome problems, whether they are skill issue kind of problems or technical ones.&lt;/p&gt;

&lt;h3&gt;
  
  
  What to expect and what not to expect
&lt;/h3&gt;

&lt;p&gt;This series is about modern Computer Vision using neural networks in the first season and vision transformers (ViT) in the second season. Some basic, but stable knowledge about traditional Computer Vision methods is required to keep up.&lt;/p&gt;

&lt;p&gt;It is not a shortcut to expertise in modern Computer Vision. Expect a rather slow pace, and don't expect to find the best possible solutions here. That is exactly the point of this series: you're learning with me, but more importantly for yourself. Think, code, debug, experiment, and let others know in the comments if you came up with a different solution.&lt;/p&gt;

&lt;p&gt;Over the next few months - roughly with weekly or bi-weekly episodes, depending on my available free time -, we'll go through different Computer Vision techniques and work on projects related to them in a learning-by-doing manner. If your learning style is very theory-first, then this series might not be the perfect fit for you - although I still recommend following along, because we'll talk about theory as well.&lt;/p&gt;

&lt;p&gt;You'll also get full transparency into my technical struggles. At first glance, some parts may feel redundant, but these insights are part of this journey. This is not a course, this is a series of blog posts aimed at exploring, learning, trying different paths, and gaining experience in this field. &lt;/p&gt;

&lt;p&gt;If you stay with me until the end, you'll hopefully become the proud owner of a beautiful GitHub repo and gain insight and experience in modern Computer Vision.&lt;/p&gt;

&lt;h3&gt;
  
  
  Where to start
&lt;/h3&gt;

&lt;p&gt;Depending on your learning style and your starting point, there are different ways to begin, but most importantly, absolutely get familiar with OpenCV.&lt;/p&gt;

&lt;p&gt;If you are completely new to Computer Vision, I strongly recommend building solid foundations in traditional Computer Vision first.&lt;br&gt;
For complete beginners, I also made a small Jupyter Notebook as an appetizer that showcases OpenCV filters using nothing but your webcam, you can find it here: &lt;/p&gt;


&lt;div class="ltag-github-readme-tag"&gt;
  &lt;div class="readme-overview"&gt;
    &lt;h2&gt;
      &lt;img src="https://assets.dev.to/assets/github-logo-5a155e1f9a670af7944dd5e12375bc76ed542ea80224905ecaf878b9157cdefc.svg" alt="GitHub logo"&gt;
      &lt;a href="https://github.com/slelo" rel="noopener noreferrer"&gt;
        slelo
      &lt;/a&gt; / &lt;a href="https://github.com/slelo/CVCA-S1E0-Mini-OpenCV-Playground" rel="noopener noreferrer"&gt;
        CVCA-S1E0-Mini-OpenCV-Playground
      &lt;/a&gt;
    &lt;/h2&gt;
    &lt;h3&gt;
      Computer Vision Appetizer for complete beginners
    &lt;/h3&gt;
  &lt;/div&gt;
  &lt;div class="ltag-github-body"&gt;
    
&lt;div id="readme" class="md"&gt;&lt;div class="markdown-heading"&gt;
&lt;h1 class="heading-element"&gt;About&lt;/h1&gt;

&lt;/div&gt;
&lt;p&gt;This repository is part of the first episode of my newly started Computer Vision Code-Along blog post series. &lt;br&gt;&lt;/p&gt;
&lt;p&gt;&lt;a href="https://dev.to/levente-slajcho/cva-computer-vision-adventure-series-s1e0-intro-3pjn" rel="nofollow"&gt;&lt;img src="https://camo.githubusercontent.com/0b90b95355fe854da0231021755cba147476c7512c3bc525442359ae1afcee43/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f526561642532306d6f72652532306f6e2d6465762e746f2d3041304130413f7374796c653d666f722d7468652d6261646765266c6f676f3d646576646f74746f266c6f676f436f6c6f723d7768697465" alt="Read more on dev.to"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;div class="markdown-heading"&gt;
&lt;h1 class="heading-element"&gt;OpenCV-Filters&lt;/h1&gt;

&lt;/div&gt;
&lt;p&gt;Computer Vision Appetizer for beginners: Simple code with OpenCV filters.
Feel free to explore, experiment, change parameters, and learn by doing.&lt;/p&gt;
&lt;p&gt;Disclaimer: this repo will be updated from time to time&lt;/p&gt;
&lt;a rel="noopener noreferrer" href="https://private-user-images.githubusercontent.com/45306730/611169919-14860987-ded7-43fe-8799-4065793e70ae.png?jwt=eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJpc3MiOiJnaXRodWIuY29tIiwiYXVkIjoicmF3LmdpdGh1YnVzZXJjb250ZW50LmNvbSIsImtleSI6ImtleTUiLCJleHAiOjE3ODQxMTgyMDIsIm5iZiI6MTc4NDExNzkwMiwicGF0aCI6Ii80NTMwNjczMC82MTExNjk5MTktMTQ4NjA5ODctZGVkNy00M2ZlLTg3OTktNDA2NTc5M2U3MGFlLnBuZz9YLUFtei1BbGdvcml0aG09QVdTNC1ITUFDLVNIQTI1NiZYLUFtei1DcmVkZW50aWFsPUFLSUFWQ09EWUxTQTUzUFFLNFpBJTJGMjAyNjA3MTUlMkZ1cy1lYXN0LTElMkZzMyUyRmF3czRfcmVxdWVzdCZYLUFtei1EYXRlPTIwMjYwNzE1VDEyMTgyMlomWC1BbXotRXhwaXJlcz0zMDAmWC1BbXotU2lnbmF0dXJlPTNmZWU1YzA4MzcxMDc1MDRiZDBmMjQyMmM3NjU2NWRhYWY1YjcxMTBiOWVhZjViOTU2MzJmM2MxM2MxY2FjNjgmWC1BbXotU2lnbmVkSGVhZGVycz1ob3N0JnJlc3BvbnNlLWNvbnRlbnQtdHlwZT1pbWFnZSUyRnBuZyJ9.KAFfnel16gzYElJxSgz0464jKQDO3Qgk8i0kIK0Xu0U"&gt;&lt;img width="800" height="512" alt="image" src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fprivate-user-images.githubusercontent.com%2F45306730%2F611169919-14860987-ded7-43fe-8799-4065793e70ae.png%3Fjwt%3DeyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJpc3MiOiJnaXRodWIuY29tIiwiYXVkIjoicmF3LmdpdGh1YnVzZXJjb250ZW50LmNvbSIsImtleSI6ImtleTUiLCJleHAiOjE3ODQxMTgyMDIsIm5iZiI6MTc4NDExNzkwMiwicGF0aCI6Ii80NTMwNjczMC82MTExNjk5MTktMTQ4NjA5ODctZGVkNy00M2ZlLTg3OTktNDA2NTc5M2U3MGFlLnBuZz9YLUFtei1BbGdvcml0aG09QVdTNC1ITUFDLVNIQTI1NiZYLUFtei1DcmVkZW50aWFsPUFLSUFWQ09EWUxTQTUzUFFLNFpBJTJGMjAyNjA3MTUlMkZ1cy1lYXN0LTElMkZzMyUyRmF3czRfcmVxdWVzdCZYLUFtei1EYXRlPTIwMjYwNzE1VDEyMTgyMlomWC1BbXotRXhwaXJlcz0zMDAmWC1BbXotU2lnbmF0dXJlPTNmZWU1YzA4MzcxMDc1MDRiZDBmMjQyMmM3NjU2NWRhYWY1YjcxMTBiOWVhZjViOTU2MzJmM2MxM2MxY2FjNjgmWC1BbXotU2lnbmVkSGVhZGVycz1ob3N0JnJlc3BvbnNlLWNvbnRlbnQtdHlwZT1pbWFnZSUyRnBuZyJ9.KAFfnel16gzYElJxSgz0464jKQDO3Qgk8i0kIK0Xu0U" class="js-gh-image-fallback"&gt;&lt;/a&gt;
&lt;div class="markdown-heading"&gt;
&lt;h2 class="heading-element"&gt;Requirements&lt;/h2&gt;

&lt;/div&gt;
&lt;ul&gt;
&lt;li&gt;Python 3.10 or higher&lt;/li&gt;
&lt;li&gt;OpenCV&lt;/li&gt;
&lt;li&gt;Jupyter Notebook&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="markdown-heading"&gt;
&lt;h2 class="heading-element"&gt;Installation&lt;/h2&gt;

&lt;/div&gt;
&lt;p&gt;This one isn't gonna be too long, just run:&lt;/p&gt;
&lt;div class="highlight highlight-source-shell notranslate position-relative overflow-auto js-code-highlight"&gt;
&lt;pre&gt;pip install -r requirements.txt&lt;/pre&gt;

&lt;/div&gt;
&lt;/div&gt;



&lt;/div&gt;
&lt;br&gt;
  &lt;div class="gh-btn-container"&gt;&lt;a class="gh-btn" href="https://github.com/slelo/CVCA-S1E0-Mini-OpenCV-Playground" rel="noopener noreferrer"&gt;View on GitHub&lt;/a&gt;&lt;/div&gt;
&lt;br&gt;
&lt;/div&gt;
&lt;br&gt;





&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F4f6dwa4vihqqt4hw2xci.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F4f6dwa4vihqqt4hw2xci.png" width="800" height="512"&gt;&lt;/a&gt;&lt;/p&gt;&lt;br&gt;Example with Canny filter
  &lt;p&gt;&lt;/p&gt;

&lt;p&gt;If you're familiar with this, I wholeheartedly recommend - and kind of require - completing the Deep Learning Specialization by Andrew Ng on Coursera (&lt;a href="https://www.coursera.org/specializations/deep-learning" rel="noopener noreferrer"&gt;https://www.coursera.org/specializations/deep-learning&lt;/a&gt;). It gives you a lot of understanding of what is happening under the hood, and the assignments also make you implement many of those ideas yourself.&lt;/p&gt;

&lt;p&gt;I'll be using PyCharm as a development environment and Python 3.10 and 3.11 by default for compatibility reasons. If we use other tools in later projects, I'll let you know.&lt;/p&gt;




&lt;h1&gt;
  
  
  Foreshadowing
&lt;/h1&gt;

&lt;p&gt;In the next episode, we'll use U-Nets for image segmentation for an inactive Kaggle competition. Until then, you can read more about them here: &lt;a href="https://towardsdatascience.com/understanding-u-net-61276b10f360/" rel="noopener noreferrer"&gt;https://towardsdatascience.com/understanding-u-net-61276b10f360/&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Please make sure you have a basic understanding of Convolutional Neural Networks. To build better intuition, I also recommend reading about AlexNet, ResNet, and MobileNet, and learning how they work and why they became so popular (This video and the following ones in the playlist will help: &lt;a href="https://www.youtube.com/watch?v=-bvTzZCEOdM&amp;amp;list=PLkDaE6sCZn6Gl29AoE31iwdVwSG-KnDzF&amp;amp;index=12" rel="noopener noreferrer"&gt;https://www.youtube.com/watch?v=-bvTzZCEOdM&amp;amp;list=PLkDaE6sCZn6Gl29AoE31iwdVwSG-KnDzF&amp;amp;index=12&lt;/a&gt;)&lt;/p&gt;

&lt;p&gt;The next episode will be linked here when it's ready.&lt;/p&gt;

&lt;p&gt;Thank you for reading, and your thoughts are more than welcome in the comments.&lt;/p&gt;

</description>
      <category>computervision</category>
      <category>machinelearning</category>
      <category>tensorflow</category>
      <category>pytorch</category>
    </item>
  </channel>
</rss>
