<?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: Rose Umutesi</title>
    <description>The latest articles on DEV Community by Rose Umutesi (@rose_umutesi_).</description>
    <link>https://dev.to/rose_umutesi_</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%2F4142754%2F4fe4e7d2-4a7e-45c7-95f2-5e82b00414e4.png</url>
      <title>DEV Community: Rose Umutesi</title>
      <link>https://dev.to/rose_umutesi_</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/rose_umutesi_"/>
    <language>en</language>
    <item>
      <title># Understanding Computer Vision: From Pixels to Object Detection</title>
      <dc:creator>Rose Umutesi</dc:creator>
      <pubDate>Tue, 13 Oct 2026 14:25:36 +0000</pubDate>
      <link>https://dev.to/rose_umutesi_/-understanding-computer-vision-from-pixels-to-object-detection-26i3</link>
      <guid>https://dev.to/rose_umutesi_/-understanding-computer-vision-from-pixels-to-object-detection-26i3</guid>
      <description>&lt;h2&gt;
  
  
  Introduction
&lt;/h2&gt;

&lt;p&gt;Computer vision is a field of artificial intelligence that enables computers to process and understand images and videos. It can be used in different areas, such as detecting vehicles, analyzing medical images, and identifying plant diseases.&lt;/p&gt;

&lt;p&gt;During the &lt;em&gt;Introduction to Computer Vision — Live Demo&lt;/em&gt; in the kLab TekHer AI Program, Cohort 2, I explored how computer vision works through practical experiments using Python and pretrained YOLO models. I worked with a sample bus image and my own photo to explore image processing, classification, object detection, and segmentation. I also tested how changes in brightness and image resolution affected the model's predictions.&lt;/p&gt;

&lt;p&gt;In this blog, I explain what I did, the results I observed, and what I learned from the experiment.&lt;/p&gt;

&lt;h2&gt;
  
  
  1. How does a computer see an image?
&lt;/h2&gt;

&lt;p&gt;When we look at a photograph, we can easily recognize objects such as people, buses, and buildings. A computer processes an image differently. A digital image is represented by numbers stored in an array, and a computer vision model uses patterns learned from data to make predictions.&lt;/p&gt;

&lt;p&gt;For example, an RGB image has three color channels: red, green, and blue. Each pixel contains a value for each channel.&lt;/p&gt;

&lt;p&gt;I used Python to load the bus image and inspect its numerical values.&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;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;from&lt;/span&gt; &lt;span class="n"&gt;PIL&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;Image&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;np&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;array&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;open&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;IMAGE_PATH&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;convert&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;RGB&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;

&lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Image shape:&lt;/span&gt;&lt;span class="sh"&gt;"&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="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Data type:&lt;/span&gt;&lt;span class="sh"&gt;"&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;dtype&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Minimum value:&lt;/span&gt;&lt;span class="sh"&gt;"&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="nf"&gt;min&lt;/span&gt;&lt;span class="p"&gt;())&lt;/span&gt;
&lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Maximum value:&lt;/span&gt;&lt;span class="sh"&gt;"&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="nf"&gt;max&lt;/span&gt;&lt;span class="p"&gt;())&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;My output was:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Image shape: (1080, 810, 3)
Data type: uint8
Minimum value: 0
Maximum value: 255
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This means the image had 1080 rows, 810 columns, and three color channels. The data type &lt;code&gt;uint8&lt;/code&gt; stores integer values between 0 and 255 for each channel.&lt;/p&gt;

&lt;p&gt;For example, a pixel with values &lt;code&gt;[197, 184, 168]&lt;/code&gt; represents a color formed by combining its red, green, and blue values.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;What I learned:&lt;/strong&gt; An image is not just a photograph to a computer. It is numerical data that can be inspected and processed using Python. Understanding this helped me see how computers can work with images.&lt;/p&gt;

&lt;h2&gt;
  
  
  2. Applying filters to images
&lt;/h2&gt;

&lt;p&gt;After exploring how images are represented, I tested how filters can change them. A filter applies a mathematical operation to image pixels to create an effect, such as smoothing an image or highlighting its edges.&lt;/p&gt;

&lt;h3&gt;
  
  
  Grayscale
&lt;/h3&gt;

&lt;p&gt;Grayscale removes the original color information and represents the image using shades of gray. I created a simple grayscale image by averaging the three color channels.&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;gray&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;img&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;mean&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;axis&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;span class="n"&gt;plt&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;imshow&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;gray&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;cmap&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;gray&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="n"&gt;plt&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;title&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Grayscale Image&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="n"&gt;plt&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;axis&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;off&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="n"&gt;plt&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;show&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Blur
&lt;/h3&gt;

&lt;p&gt;A blur filter smooths an image by averaging nearby pixel values. I used a 5 × 5 kernel for this experiment.&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;blur_kernel&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="nf"&gt;ones&lt;/span&gt;&lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="mi"&gt;5&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;5&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt; &lt;span class="o"&gt;/&lt;/span&gt; &lt;span class="mi"&gt;25&lt;/span&gt;
&lt;span class="n"&gt;blurred&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;convolve&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;gray&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;blur_kernel&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="n"&gt;plt&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;imshow&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;blurred&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;cmap&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;gray&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="n"&gt;plt&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;title&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Blurred Image&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="n"&gt;plt&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;axis&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;off&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="n"&gt;plt&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;show&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The kernel is a small matrix that moves across the image and combines neighboring pixel values.&lt;/p&gt;

&lt;h3&gt;
  
  
  Edge detection
&lt;/h3&gt;

&lt;p&gt;Edges are areas where brightness changes sharply. I used Sobel filters to highlight changes in horizontal and vertical directions.&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;sobel_x&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="nf"&gt;array&lt;/span&gt;&lt;span class="p"&gt;([&lt;/span&gt;
    &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mi"&gt;1&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="p"&gt;[&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;span class="mi"&gt;0&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="p"&gt;[&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mi"&gt;1&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="p"&gt;])&lt;/span&gt;

&lt;span class="n"&gt;sobel_y&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;sobel_x&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;T&lt;/span&gt;

&lt;span class="n"&gt;edges&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="nf"&gt;hypot&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="nf"&gt;convolve&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;gray&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;sobel_x&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
    &lt;span class="nf"&gt;convolve&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;gray&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;sobel_y&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="n"&gt;plt&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;imshow&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;edges&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;cmap&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;gray&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="n"&gt;plt&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;title&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Detected Edges&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="n"&gt;plt&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;axis&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;off&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="n"&gt;plt&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;show&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;I also tested sharpening, which emphasizes differences between neighboring pixels and can make details appear clearer.&lt;/p&gt;

&lt;p&gt;These operations relate to image enhancement, where image properties are adjusted to change the visual result. The Pillow documentation explains how enhancement factors can be used to modify properties such as brightness and sharpness. &lt;a href="https://pillow.readthedocs.io/en/stable/reference/ImageEnhance.html" rel="noopener noreferrer"&gt;Pillow ImageEnhance documentation&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;What I learned:&lt;/strong&gt; Different filters highlight different information. Grayscale removes color, blur smooths details, edge detection highlights boundaries, and sharpening emphasizes details. This helped me understand some of the basic operations used in image processing. &lt;/p&gt;
&lt;br&gt;&lt;br&gt;&lt;br&gt;&lt;br&gt;&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;&lt;tbody&gt;
&lt;tr&gt;
    &lt;td&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%2F51shj7ho3vvkhdc3aeyr.png" alt="Computer vision experiment screenshot 1" width="357" height="485"&gt;&lt;/td&gt;
    &lt;td&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%2F0qadb6rjfxjpne7942k0.png" alt="Computer vision experiment screenshot 3" width="361" height="490"&gt;&lt;/td&gt;
  &lt;/tr&gt;
&lt;/tbody&gt;&lt;/table&gt;&lt;/div&gt;
&lt;br&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%2Fqe79mdgshgptexredui6.png" alt="Computer vision experiment screenshot 2" width="800" height="239"&gt;
&lt;h2&gt;
  
  
  3. Image classification: What is in the image?
&lt;/h2&gt;

&lt;p&gt;Image classification assigns a category to an entire image. It answers a question such as, “What does this picture most likely contain?”&lt;/p&gt;

&lt;p&gt;The Ultralytics documentation describes classification as categorizing an image based on its content. This is different from identifying the exact location of each object in the image. &lt;a href="https://docs.ultralytics.com/tasks/" rel="noopener noreferrer"&gt;Ultralytics YOLO tasks documentation&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;I used a pretrained YOLO classification model:&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="n"&gt;ultralytics&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;YOLO&lt;/span&gt;

&lt;span class="n"&gt;classifier&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;YOLO&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;yolo11n-cls.pt&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="n"&gt;results&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;classifier&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;IMAGE_PATH&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;verbose&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="bp"&gt;False&lt;/span&gt;&lt;span class="p"&gt;)&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;results&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;probs&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;top5&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;When I tested the bus image, the top predictions were:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Predicted label&lt;/th&gt;
&lt;th&gt;Confidence&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Minibus&lt;/td&gt;
&lt;td&gt;57.1%&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Police van&lt;/td&gt;
&lt;td&gt;33.7%&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Trolleybus&lt;/td&gt;
&lt;td&gt;4.2%&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Recreational vehicle&lt;/td&gt;
&lt;td&gt;1.4%&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Streetcar&lt;/td&gt;
&lt;td&gt;0.6%&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;The model predicted &lt;em&gt;minibus&lt;/em&gt; with the highest confidence, followed by &lt;em&gt;police van&lt;/em&gt;.&lt;/p&gt;

&lt;p&gt;I also tested my own photo. The top predictions included &lt;code&gt;grocery_store&lt;/code&gt; at 16.6%, &lt;code&gt;French_horn&lt;/code&gt; at 16.4%, and &lt;code&gt;restaurant&lt;/code&gt; at 8.6%. These labels did not clearly describe my photo, and the confidence scores were low.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;What I learned:&lt;/strong&gt; Classification can provide useful predictions, but it does not always produce the correct or most meaningful label. I learned to examine the model's predictions and confidence scores instead of automatically accepting its first answer.&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%2Fskc9b5nxtjcojhvsy9m6.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%2Fskc9b5nxtjcojhvsy9m6.png" alt="Computer vision experiment screenshot" width="523" height="337"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;h2&gt;
  
  
  4. Object detection: What is in the image, and where?
&lt;/h2&gt;

&lt;p&gt;Object detection goes a step further than classification. It identifies objects and shows their locations using rectangular boxes called &lt;em&gt;bounding boxes&lt;/em&gt;. The model can return a label, a confidence score, and coordinates for each detected object.&lt;/p&gt;

&lt;p&gt;According to the Ultralytics documentation, object detection identifies and locates objects in images or video frames using bounding boxes. This makes it useful when we need to know both what an object is and where it appears. &lt;a href="https://docs.ultralytics.com/tasks/" rel="noopener noreferrer"&gt;Ultralytics YOLO tasks documentation&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;I loaded a pretrained YOLO detection model and tested it on the bus image.&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;detector&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;YOLO&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;yolo11n.pt&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="n"&gt;results&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;detector&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;IMAGE_PATH&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;conf&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mf"&gt;0.4&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;verbose&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="bp"&gt;False&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="n"&gt;annotated_image&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;results&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;plot&lt;/span&gt;&lt;span class="p"&gt;()[:,&lt;/span&gt; &lt;span class="p"&gt;:,&lt;/span&gt; &lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="o"&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;plt&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;imshow&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;annotated_image&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="n"&gt;plt&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;title&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Object Detection&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="n"&gt;plt&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;axis&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;off&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="n"&gt;plt&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;show&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The model detected one bus at 94% confidence and four people at confidence scores of 89%, 88%, 86%, and 62%.&lt;/p&gt;

&lt;p&gt;This was more informative than classification because I could see the locations of the detected objects.&lt;/p&gt;

&lt;h3&gt;
  
  
  Testing different confidence thresholds
&lt;/h3&gt;

&lt;p&gt;I changed the confidence threshold to see how the results changed.&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Confidence threshold&lt;/th&gt;
&lt;th&gt;What I observed&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;0.1 (10%)&lt;/td&gt;
&lt;td&gt;The bus and people were detected, along with a skateboard at 12% confidence.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;0.4 (40%)&lt;/td&gt;
&lt;td&gt;The model detected the bus and four people.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;0.9 (90%)&lt;/td&gt;
&lt;td&gt;Only the bus at 94% confidence remained.&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;A lower threshold allows more possible detections, including predictions that may be incorrect. A higher threshold removes lower-confidence predictions but may also exclude real objects.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;What I learned:&lt;/strong&gt; The confidence threshold affects which predictions are kept. Choosing a threshold involves balancing the possibility of missing real objects against the possibility of accepting incorrect detections.&lt;/p&gt;

&lt;h2&gt;
  
  
  5. Image segmentation: Understanding object shapes
&lt;/h2&gt;

&lt;p&gt;Image segmentation provides more detailed information about the pixels belonging to an object. Instead of drawing only a rectangle around a person or bus, a segmentation model produces a mask that follows the object's visible shape.&lt;/p&gt;

&lt;p&gt;Ultralytics explains that instance segmentation extends detection by producing pixel-level masks for individual objects. This detail can be useful in applications such as agricultural analysis and medical imaging. &lt;a href="https://docs.ultralytics.com/tasks/" rel="noopener noreferrer"&gt;Ultralytics YOLO tasks documentation&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;I used a pretrained YOLO segmentation model:&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;segmenter&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;YOLO&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;yolo11n-seg.pt&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="n"&gt;results&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;segmenter&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;IMAGE_PATH&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;conf&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mf"&gt;0.4&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;verbose&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="bp"&gt;False&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="n"&gt;annotated_image&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;results&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;plot&lt;/span&gt;&lt;span class="p"&gt;()[:,&lt;/span&gt; &lt;span class="p"&gt;:,&lt;/span&gt; &lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="o"&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;plt&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;imshow&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;annotated_image&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="n"&gt;plt&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;title&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Image Segmentation&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="n"&gt;plt&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;axis&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;off&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="n"&gt;plt&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;show&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;In my experiment, the notebook reported approximately 44% mask coverage for the bus image. It also produced masks for objects including the bus and several people.&lt;/p&gt;

&lt;p&gt;The 44% value came from the mask calculation in my notebook. It should not be treated as an exact measurement of the real-world area occupied by the objects.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;What I learned:&lt;/strong&gt; Classification, detection, and segmentation solve different problems. Classification predicts what an image may contain, detection shows where objects are located, and segmentation provides more detail about their visible shapes. The right task depends on what information we need.&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%2Fultm77m0gxiyphn7cptt.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%2Fultm77m0gxiyphn7cptt.png" alt="Computer vision experiment screenshot" width="524" height="553"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  6. Testing the models on my own photo
&lt;/h2&gt;

&lt;p&gt;One of the most interesting parts of the experiment was testing the models on my own photo instead of only using the sample images.&lt;/p&gt;

&lt;p&gt;At a confidence threshold of 0.4, the detection model returned six person boxes. However, some boxes overlapped, so six detections did not necessarily mean six different people.&lt;/p&gt;

&lt;p&gt;The classification model also returned unexpected labels, including &lt;code&gt;grocery_store&lt;/code&gt; and &lt;code&gt;French_horn&lt;/code&gt;. This helped me compare the output of classification with the output of object detection and segmentation.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;What I learned:&lt;/strong&gt; Testing a model on new images is important because its predictions may differ from what we expect. I also learned that detection counts need to be interpreted carefully, especially when bounding boxes overlap.&lt;/p&gt;

&lt;h2&gt;
  
  
  7. How brightness and resolution affected detection
&lt;/h2&gt;

&lt;p&gt;I wanted to understand whether changing image quality would affect the model's predictions. I therefore tested different brightness levels and image resolutions.&lt;/p&gt;

&lt;h3&gt;
  
  
  Brightness experiment
&lt;/h3&gt;

&lt;p&gt;I tested brightness factors of 0.3, 0.7, 1.0, and 1.5. A factor of 1.0 represented the original brightness, while lower and higher factors made the image darker and brighter.&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Brightness factor&lt;/th&gt;
&lt;th&gt;Person detections&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;0.3&lt;/td&gt;
&lt;td&gt;4&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;0.7&lt;/td&gt;
&lt;td&gt;6&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;1.0&lt;/td&gt;
&lt;td&gt;6&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;1.5&lt;/td&gt;
&lt;td&gt;5&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;The number of person detections changed when I adjusted the brightness. This showed that a change to the input image could affect the model's output.&lt;/p&gt;

&lt;h3&gt;
  
  
  Resolution experiment
&lt;/h3&gt;

&lt;p&gt;I also resized my photo to different widths and ran the detection model again.&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Image width&lt;/th&gt;
&lt;th&gt;Observed result&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;48 pixels&lt;/td&gt;
&lt;td&gt;1 person detection&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;128 pixels&lt;/td&gt;
&lt;td&gt;4 person detections&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;320 pixels&lt;/td&gt;
&lt;td&gt;3 person detections, plus two unexpected &lt;code&gt;pizza&lt;/code&gt; predictions&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;640 pixels&lt;/td&gt;
&lt;td&gt;6 person detections&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;The smallest image contained much less visual detail, and the model detected fewer people. The unexpected predictions at 320 pixels also showed that a model can make incorrect predictions.&lt;/p&gt;

&lt;p&gt;These results describe my experiment. They do not mean that every small or bright image will produce the same results.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;What I learned:&lt;/strong&gt; Image quality can influence computer vision predictions. Changes in brightness may make objects harder to recognize, while reducing resolution can remove useful details. Increasing resolution does not guarantee that every prediction will be correct.&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
  &lt;tbody&gt;
&lt;tr&gt;
    &lt;td&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%2F7c3xhr8es65q0iue6vae.png" alt="Computer vision result 1" width="704" height="655"&gt;&lt;/td&gt;
    &lt;td&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%2Fdygnmbtoezy52ekmykq1.png" alt="Computer vision result 2" width="693" height="645"&gt;&lt;/td&gt;
    &lt;td&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%2Fnj3cbp23p2mujhvnxr9c.png" alt="Computer vision result 3" width="685" height="636"&gt;&lt;/td&gt;
  &lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;&lt;strong&gt;Result 1&lt;/strong&gt;&lt;/p&gt;

&lt;pre&gt;person 90% box=(1096,857)-(1674,2446)
person 84% box=(153,976)-(706,2440)
person 64% box=(687,1290)-(1200,2445)
person 48% box=(654,996)-(1139,2442)
person 47% box=(1455,1073)-(1517,1171)
person 43% box=(2,1150)-(85,1359)&lt;/pre&gt;

&lt;p&gt;&lt;strong&gt;Result 2&lt;/strong&gt;&lt;/p&gt;

&lt;pre&gt;person 91% box=(1104,857)-(1672,2446)
person 86% box=(152,981)-(703,2441)
person 58% box=(716,1454)-(1202,2446)
person 55% box=(677,1093)-(1195,2446)&lt;/pre&gt;

&lt;p&gt;&lt;strong&gt;Result 3&lt;/strong&gt;&lt;/p&gt;

&lt;pre&gt;person 91% box=(1105,860)-(1675,2445)
person 82% box=(151,976)-(727,2441)
person 66% box=(655,999)-(1150,2442)
person 42% box=(1455,1075)-(1517,1172)
person 41% box=(0,1147)-(84,1360)&lt;/pre&gt;




&lt;h2&gt;
  
  
  8. Testing model robustness
&lt;/h2&gt;

&lt;p&gt;Model robustness refers to how well a model continues to perform when its input changes.&lt;/p&gt;

&lt;p&gt;The notebook also included tests involving a very dark image, an image rotated upside down, a low-resolution image, and a blurred image. These conditions represent challenges that may occur when images are captured in real life.&lt;/p&gt;

&lt;p&gt;My brightness and resolution experiments already showed that the number of detections could change when the input changed. I would need to compare the actual results from the rotation and blur tests before deciding which condition affected the model most.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;What I learned:&lt;/strong&gt; A model that performs well on one clear image may not perform equally well on every image. Testing different conditions helps us identify weaknesses and better understand the limits of a model.&lt;/p&gt;

&lt;h2&gt;
  
  
  9. My main lessons from the experiment
&lt;/h2&gt;

&lt;p&gt;This practical session helped me connect computer vision concepts with actual code and model predictions. My main lessons were:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Images contain numerical data.&lt;/strong&gt; I learned how pixels and RGB channels represent colors.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Filters change image information.&lt;/strong&gt; Grayscale, blur, edge detection, and sharpening helped me understand basic image processing.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Classification and detection are different.&lt;/strong&gt; Classification predicts a label for an image, while detection identifies objects and their locations.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Segmentation gives more detail.&lt;/strong&gt; It produces masks that show the visible shapes of objects.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Confidence scores need interpretation.&lt;/strong&gt; A model can produce uncertain or incorrect predictions.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Image quality matters.&lt;/strong&gt; Changes in brightness and resolution affected the detections in my experiments.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Testing is important.&lt;/strong&gt; Examining the outputs helped me notice unexpected predictions and overlapping boxes rather than assuming that the model was always right.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;The most valuable part for me was testing the models on my own photo and observing how their predictions changed. It made the concepts easier to understand because I could compare what I expected with what the models actually produced.&lt;/p&gt;

&lt;h2&gt;
  
  
  Conclusion
&lt;/h2&gt;

&lt;p&gt;This experiment gave me a practical introduction to computer vision. I started by examining an image as numerical data, then applied filters and explored classification, object detection, and segmentation. Finally, I tested how changes in brightness and resolution affected the model's predictions.&lt;/p&gt;

&lt;p&gt;I learned that computer vision involves more than identifying objects in a photograph. We also need to understand the task we are solving, examine the results, and test how a model behaves when the input changes.&lt;/p&gt;

&lt;p&gt;As I continue learning artificial intelligence and machine learning, I want to build on this knowledge by exploring how computer vision can be applied to practical problems, including identifying plant diseases in agriculture.&lt;/p&gt;

&lt;h2&gt;
  
  
  Resources
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;1. Ultralytics — YOLO Tasks Documentation&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://docs.ultralytics.com/tasks/" rel="noopener noreferrer"&gt;https://docs.ultralytics.com/tasks/&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;2. Pillow — ImageEnhance Documentation&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://pillow.readthedocs.io/en/stable/reference/ImageEnhance.html" rel="noopener noreferrer"&gt;https://pillow.readthedocs.io/en/stable/reference/ImageEnhance.html&lt;/a&gt;&lt;/p&gt;

</description>
      <category>computervision</category>
      <category>ai</category>
      <category>machinelearning</category>
      <category>python</category>
    </item>
    <item>
      <title>Understanding Word Embeddings: How Machines Learn the Meaning of Words</title>
      <dc:creator>Rose Umutesi</dc:creator>
      <pubDate>Wed, 30 Sep 2026 12:35:20 +0000</pubDate>
      <link>https://dev.to/rose_umutesi_/understanding-word-embeddings-how-machines-learn-the-meaning-of-words-33be</link>
      <guid>https://dev.to/rose_umutesi_/understanding-word-embeddings-how-machines-learn-the-meaning-of-words-33be</guid>
      <description>&lt;p&gt;When I started learning Natural Language Processing (NLP), one question kept coming back to me: How can a computer understand words when words are just text?&lt;/p&gt;

&lt;p&gt;A computer does not naturally understand that king and queen are related, or that cat and dog are more similar than cat and car. To a computer, these are simply sequences of characters.&lt;/p&gt;

&lt;p&gt;This is where word embeddings become important.&lt;/p&gt;

&lt;h2&gt;
  
  
  What are word embeddings?
&lt;/h2&gt;

&lt;p&gt;Word embeddings are a way of representing words as numerical vectors.&lt;/p&gt;

&lt;p&gt;Instead of giving a machine the word:&lt;/p&gt;

&lt;p&gt;"coffee"&lt;/p&gt;

&lt;p&gt;we can represent it as something like:&lt;/p&gt;

&lt;p&gt;[0.21, -0.43, 0.87, 0.12, ...]&lt;/p&gt;

&lt;p&gt;The actual vectors usually have many more dimensions than this example. The important idea is that words with similar meanings or similar uses can have similar positions in a mathematical space.&lt;/p&gt;

&lt;p&gt;This is based on a useful idea in linguistics: words that appear in similar contexts tend to have related meanings.&lt;/p&gt;

&lt;p&gt;For example, consider:&lt;/p&gt;

&lt;p&gt;I drank coffee in the morning.&lt;/p&gt;

&lt;p&gt;and:&lt;/p&gt;

&lt;p&gt;I drank tea in the morning.&lt;/p&gt;

&lt;p&gt;Because coffee and tea appear in similar contexts, an embedding model can learn that they are related.&lt;/p&gt;

&lt;p&gt;This is one reason embeddings are useful for NLP tasks such as text classification, recommendation systems, search, sentiment analysis, and information retrieval.&lt;/p&gt;

&lt;h2&gt;
  
  
  Word2Vec
&lt;/h2&gt;

&lt;p&gt;One embedding method I studied is Word2Vec.&lt;/p&gt;

&lt;p&gt;Word2Vec was introduced by researchers at Google and is designed to learn vector representations of words from text. Two important Word2Vec approaches are Continuous Bag of Words (CBOW) and Skip-gram.&lt;/p&gt;

&lt;p&gt;The basic idea is surprisingly simple.&lt;/p&gt;

&lt;p&gt;CBOW&lt;/p&gt;

&lt;p&gt;CBOW tries to predict a word from the words surrounding it.&lt;/p&gt;

&lt;p&gt;For example:&lt;/p&gt;

&lt;p&gt;The farmer planted potatoes in the ___.&lt;/p&gt;

&lt;p&gt;The surrounding words can help the model predict a word such as field.&lt;/p&gt;

&lt;p&gt;Skip-gram&lt;/p&gt;

&lt;p&gt;Skip-gram works in the opposite direction. It starts with a target word and tries to predict the words that appear around it.&lt;/p&gt;

&lt;p&gt;For example:&lt;/p&gt;

&lt;p&gt;The farmer planted potatoes in the field.&lt;/p&gt;

&lt;p&gt;If the target word is potatoes, the model learns from words appearing around it, such as planted, farmer, and field.&lt;/p&gt;

&lt;p&gt;After seeing many examples, the model adjusts its numerical representations so that words appearing in similar contexts develop related vectors.&lt;/p&gt;

&lt;h2&gt;
  
  
  A small Python example
&lt;/h2&gt;

&lt;p&gt;We can experiment with Word2Vec using the &lt;code&gt;gensim&lt;/code&gt; library.&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="n"&gt;gensim.models&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;Word2Vec&lt;/span&gt;

&lt;span class="n"&gt;sentences&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;
    &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;the&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;farmer&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;plants&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;potatoes&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;
    &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;the&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;farmer&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;grows&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;crops&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;
    &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;potatoes&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;are&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;important&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;crops&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;
    &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;farmers&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;grow&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;maize&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;and&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;potatoes&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;
    &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;the&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;farmer&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;harvests&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;crops&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
&lt;span class="p"&gt;]&lt;/span&gt;

&lt;span class="n"&gt;model&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;Word2Vec&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="n"&gt;sentences&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;vector_size&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;50&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;window&lt;/span&gt;&lt;span class="o"&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;min_count&lt;/span&gt;&lt;span class="o"&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;workers&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;4&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;seed&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;42&lt;/span&gt;
&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="n"&gt;similar_words&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;model&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;wv&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;most_similar&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;potatoes&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;topn&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="p"&gt;)&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;similar_words&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The output from my experiment was:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;[('plants', 0.3308681547641754),
 ('the', 0.20481298863887787),
 ('are', 0.10614515095949173)]
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The &lt;code&gt;most_similar()&lt;/code&gt; method compares the vector for &lt;code&gt;potatoes&lt;/code&gt; with the other word vectors and returns the words that are closest to it in the learned vector space.&lt;/p&gt;

&lt;p&gt;In this experiment, &lt;code&gt;plants&lt;/code&gt; had the highest similarity score among the three returned words. The scores indicate how close the word vectors are, with higher values representing greater similarity.&lt;/p&gt;

&lt;p&gt;However, there is an important limitation. This example uses only five sentences, so the results should not be interpreted as meaningful knowledge about the English language. The model has very little data to learn from. A real Word2Vec model would normally be trained on a much larger and more representative corpus.&lt;/p&gt;

&lt;p&gt;This experiment helped me understand an important point about word embeddings: the model is not learning dictionary definitions. Instead, it is learning patterns from how words appear in relation to other words.&lt;/p&gt;

&lt;h2&gt;
  
  
  What surprised me?
&lt;/h2&gt;

&lt;p&gt;The most interesting thing I learned is that we can represent something as complicated as language using numbers.&lt;/p&gt;

&lt;p&gt;At first, seeing a word represented by hundreds of numbers felt strange. I wondered how those numbers could possibly represent meaning.&lt;/p&gt;

&lt;p&gt;The key realization was that one number does not represent one specific meaning. Instead, the entire vector represents a position in a learned mathematical space. Relationships between vectors can then capture useful patterns between words.&lt;/p&gt;

&lt;p&gt;This also explains why word embeddings can perform interesting similarity tasks. If two words frequently occur in similar contexts, their vectors can end up relatively close together.&lt;/p&gt;

&lt;p&gt;However, embeddings are not perfect. They can learn biases and patterns from the data used to train them. They also depend heavily on the quality and size of the training corpus.&lt;/p&gt;

&lt;h2&gt;
  
  
  What I struggled with
&lt;/h2&gt;

&lt;p&gt;My biggest challenge was understanding the difference between text processing and meaning representation.&lt;/p&gt;

&lt;p&gt;Techniques such as tokenization and TF-IDF are useful for converting text into numbers, but embeddings go a step further by learning relationships between words based on context.&lt;/p&gt;

&lt;p&gt;I initially thought that an embedding was simply another way of encoding words. Now I understand that the important part is the relationship between the vectors, not just the individual numbers.&lt;/p&gt;

&lt;h2&gt;
  
  
  Final thoughts
&lt;/h2&gt;

&lt;p&gt;Word embeddings helped me understand an important idea in NLP: computers do not need to understand language exactly like humans do in order to find useful patterns in text.&lt;/p&gt;

&lt;p&gt;By representing words as vectors and learning from their contexts, models such as Word2Vec can capture relationships between words mathematically.&lt;/p&gt;

&lt;p&gt;There are also other embedding approaches, including GloVe and FastText, each with different ways of learning word representations. Modern NLP has gone further with contextual representations from models such as BERT and transformer-based systems.&lt;/p&gt;

&lt;p&gt;For me, learning word embeddings was a good reminder that machine learning often works by turning things that seem difficult to quantify—such as language—into representations that algorithms can process.&lt;/p&gt;

&lt;p&gt;And that is what makes embeddings so interesting: words become numbers, but the relationships between those numbers can carry information about language.&lt;/p&gt;

&lt;h2&gt;
  
  
  References
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Mikolov et al., &lt;a href="https://arxiv.org/abs/1301.3781" rel="noopener noreferrer"&gt;Efficient Estimation of Word Representations in Vector Space&lt;/a&gt; (2013).&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Mikolov et al., &lt;a href="https://arxiv.org/abs/1310.4546" rel="noopener noreferrer"&gt;Distributed Representations of Words and Phrases and their Compositionality&lt;/a&gt; (2013).&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Goldberg &amp;amp; Levy, &lt;a href="https://arxiv.org/abs/1402.3722" rel="noopener noreferrer"&gt;word2vec Explained: Deriving Mikolov et al.'s Negative-Sampling Word-Embedding Method&lt;/a&gt; (2014).&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>nlp</category>
      <category>machinelearning</category>
      <category>python</category>
    </item>
    <item>
      <title>From Deep Learning Model to a Deployed Potato Disease Classifier 🥔</title>
      <dc:creator>Rose Umutesi</dc:creator>
      <pubDate>Fri, 25 Sep 2026 12:07:14 +0000</pubDate>
      <link>https://dev.to/rose_umutesi_/from-deep-learning-model-to-a-deployed-potato-disease-classifier-3p6f</link>
      <guid>https://dev.to/rose_umutesi_/from-deep-learning-model-to-a-deployed-potato-disease-classifier-3p6f</guid>
      <description>&lt;h1&gt;
  
  
  From Deep Learning Model to a Deployed Potato Disease Classifier 🥔
&lt;/h1&gt;

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

&lt;p&gt;Potato diseases can significantly affect crop production and farmers' livelihoods. Early identification of diseases can help farmers take action before infections spread and cause greater losses.&lt;/p&gt;

&lt;p&gt;As part of my AI and Machine Learning training, I worked on a deep learning project to build an image classification system that can identify three potato leaf conditions:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;🌱 Healthy&lt;/li&gt;
&lt;li&gt;🟤 Early Blight&lt;/li&gt;
&lt;li&gt;🟤 Late Blight&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The goal was not only to train a model, but to take the project from &lt;strong&gt;dataset preparation and model training to model export, application development, and online deployment&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;The final application allows a user to upload a potato leaf image and receive a predicted class together with the model's confidence.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Dataset
&lt;/h2&gt;

&lt;p&gt;For this project, I used the &lt;strong&gt;PlantVillage dataset&lt;/strong&gt; available through Kaggle.&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%2Fyfaie8ri8xs544voygdz.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%2Fyfaie8ri8xs544voygdz.png" alt="Potato leaf dataset samples" width="799" height="190"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;I focused on three potato categories:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;code&gt;Potato___Early_blight&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;Potato___Late_blight&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;Potato___healthy&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The selected dataset contained &lt;strong&gt;2,152 potato leaf images&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;Before training, I verified the images to make sure that the dataset did not contain corrupted files.&lt;/p&gt;

&lt;p&gt;I then created a data pipeline using &lt;strong&gt;fastai&lt;/strong&gt;. The images were resized to &lt;strong&gt;224 × 224 pixels&lt;/strong&gt; and divided into training and validation sets.&lt;/p&gt;

&lt;h2&gt;
  
  
  Choosing the Model
&lt;/h2&gt;

&lt;p&gt;For the classification task, I used &lt;strong&gt;ResNet18&lt;/strong&gt;, a convolutional neural network architecture commonly used for image classification.&lt;/p&gt;

&lt;p&gt;I used &lt;strong&gt;transfer learning&lt;/strong&gt; rather than training the network completely from scratch. This allowed me to fine-tune a pretrained model for the three potato disease classes.&lt;/p&gt;

&lt;p&gt;The model was implemented using &lt;strong&gt;fastai and PyTorch&lt;/strong&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  Baseline Model
&lt;/h2&gt;

&lt;p&gt;I first trained a baseline ResNet18 model using four fine-tuning epochs.&lt;/p&gt;

&lt;p&gt;The baseline achieved a validation accuracy of:&lt;/p&gt;

&lt;h3&gt;
  
  
  &lt;strong&gt;98.37%&lt;/strong&gt;
&lt;/h3&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%2Fg5qob7rc4159ctxratup.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%2Fg5qob7rc4159ctxratup.png" alt=" " width="799" height="216"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;This provided a strong starting point. I then investigated whether changing the training configuration could improve the validation performance.&lt;/p&gt;

&lt;h2&gt;
  
  
  Experiment: Improving the Training Configuration
&lt;/h2&gt;

&lt;p&gt;For my second experiment, I kept the &lt;strong&gt;ResNet18 architecture unchanged&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;Instead, I changed the fine-tuning configuration:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Configuration&lt;/th&gt;
&lt;th&gt;Baseline&lt;/th&gt;
&lt;th&gt;Experiment 2&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Architecture&lt;/td&gt;
&lt;td&gt;ResNet18&lt;/td&gt;
&lt;td&gt;ResNet18&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Fine-tuning epochs&lt;/td&gt;
&lt;td&gt;4&lt;/td&gt;
&lt;td&gt;6&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Learning rate&lt;/td&gt;
&lt;td&gt;Default&lt;/td&gt;
&lt;td&gt;0.001&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Validation accuracy&lt;/td&gt;
&lt;td&gt;98.37%&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;98.84%&lt;/strong&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;Experiment 2 achieved a validation accuracy of &lt;strong&gt;99.07%&lt;/strong&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%2Fpnf8048ectrwjbfloj39.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%2Fpnf8048ectrwjbfloj39.png" alt=" " width="800" height="213"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;This showed how changing the training configuration could affect validation performance without changing the underlying model architecture.&lt;/p&gt;

&lt;h2&gt;
  
  
  Error Analysis
&lt;/h2&gt;

&lt;p&gt;After training, I performed error analysis using fastai's classification interpretation tools.&lt;/p&gt;

&lt;p&gt;I examined the &lt;strong&gt;confusion matrix&lt;/strong&gt; and examples associated with the model's highest-loss predictions.&lt;/p&gt;

&lt;p&gt;This helped me look beyond a single accuracy number and understand where the model could still make mistakes.&lt;/p&gt;

&lt;p&gt;I also tested the model using images outside the original dataset. This showed an important practical consideration: a model can perform very well on images from the same dataset while finding images from different environments more challenging.&lt;/p&gt;

&lt;p&gt;Differences in lighting, background, camera quality, leaf position, and image conditions can affect predictions.&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%2Fhmh4g19jwhdcyobpcyaw.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%2Fhmh4g19jwhdcyobpcyaw.png" alt=" " width="800" height="571"&gt;&lt;/a&gt;&lt;br&gt;
Confusion matrix showing the model's classification performance across Healthy, Early Blight, and Late Blight classes.&lt;/p&gt;

&lt;h2&gt;
  
  
  Exporting the Model
&lt;/h2&gt;

&lt;p&gt;After training and analysis, I exported the trained PyTorch model so that it could be used outside the notebook environment.&lt;/p&gt;

&lt;p&gt;I exported the model to &lt;strong&gt;TorchScript&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;This allowed me to load the model in a separate Python application without depending on the original training notebook.&lt;/p&gt;

&lt;p&gt;I then uploaded the exported model to &lt;strong&gt;Hugging Face&lt;/strong&gt;, where it could be accessed by my deployed application.&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%2Fayqodsbb7d5o1gke785k.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%2Fayqodsbb7d5o1gke785k.png" alt=" " width="794" height="559"&gt;&lt;/a&gt;&lt;br&gt;
Local verification of the exported TorchScript model using test images from the PlantVillage dataset.&lt;/p&gt;

&lt;h2&gt;
  
  
  Building the Application
&lt;/h2&gt;

&lt;p&gt;The next step was to turn the trained model into an application.&lt;/p&gt;

&lt;p&gt;I initially explored a Gradio implementation, but I encountered an inference compatibility issue when loading the exported fastai model locally.&lt;/p&gt;

&lt;p&gt;Instead of stopping there, I changed the model export and inference approach by using &lt;strong&gt;TorchScript&lt;/strong&gt; and built the final application with &lt;strong&gt;Streamlit&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;The application allows a user to:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Upload a potato leaf image.&lt;/li&gt;
&lt;li&gt;Process the image using the trained model.&lt;/li&gt;
&lt;li&gt;Receive a predicted disease class.&lt;/li&gt;
&lt;li&gt;View the probability for each class.&lt;/li&gt;
&lt;/ol&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%2F613tdgxtssullonjl02i.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%2F613tdgxtssullonjl02i.png" alt=" " width="800" height="326"&gt;&lt;/a&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%2Ffmje7kukirppzi7nciz1.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%2Ffmje7kukirppzi7nciz1.png" alt=" " width="800" height="446"&gt;&lt;/a&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%2F5qsp7ma1l0kz2c946que.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%2F5qsp7ma1l0kz2c946que.png" alt=" " width="800" height="433"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The three possible predictions are:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Healthy | Early Blight | Late Blight&lt;/strong&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Deploying the Application
&lt;/h2&gt;

&lt;p&gt;The exported model was hosted on &lt;strong&gt;Hugging Face&lt;/strong&gt;, while the Streamlit application was deployed using &lt;strong&gt;Streamlit Community Cloud&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;The application code was stored in GitHub, while the larger model file was stored separately on Hugging Face.&lt;/p&gt;

&lt;p&gt;This allowed the Streamlit application to download the model when it starts.&lt;/p&gt;

&lt;p&gt;The final application is publicly available here:&lt;/p&gt;

&lt;p&gt;👉 &lt;strong&gt;&lt;a href="https://potato-disease-classifier-lyiuksv5xfmhfrhrygcxxu.streamlit.app/" rel="noopener noreferrer"&gt;Potato Disease Classifier — Live Demo&lt;/a&gt;&lt;/strong&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Challenges I Encountered
&lt;/h2&gt;

&lt;p&gt;One of the most important lessons from this project was that training a model successfully is only one part of machine learning development.&lt;/p&gt;

&lt;h3&gt;
  
  
  1. Model inference compatibility
&lt;/h3&gt;

&lt;p&gt;The first application approach using the exported fastai model encountered an inference compatibility issue.&lt;/p&gt;

&lt;p&gt;I investigated the problem and changed the model export and inference approach by using TorchScript.&lt;/p&gt;

&lt;h3&gt;
  
  
  2. Large model file
&lt;/h3&gt;

&lt;p&gt;The exported model was approximately &lt;strong&gt;47 MB&lt;/strong&gt;, which was too large to upload directly through GitHub's browser interface.&lt;/p&gt;

&lt;p&gt;I therefore hosted the model separately on Hugging Face.&lt;/p&gt;

&lt;h3&gt;
  
  
  3. Deployment
&lt;/h3&gt;

&lt;p&gt;I initially explored deploying the application through Hugging Face Spaces. However, the available free option did not provide the type of Python compute environment required for the application.&lt;/p&gt;

&lt;p&gt;I therefore deployed the Streamlit application using &lt;strong&gt;Streamlit Community Cloud&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;These challenges taught me that deploying machine learning models involves more than model accuracy. Model serialization, dependencies, file size, hosting, and the inference environment all matter.&lt;/p&gt;

&lt;h2&gt;
  
  
  What I Learned
&lt;/h2&gt;

&lt;p&gt;This project helped me understand the complete workflow of taking a deep learning model beyond a notebook.&lt;/p&gt;

&lt;p&gt;I learned how to:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Work with an image classification dataset.&lt;/li&gt;
&lt;li&gt;Build a data pipeline using fastai.&lt;/li&gt;
&lt;li&gt;Use transfer learning with ResNet18.&lt;/li&gt;
&lt;li&gt;Fine-tune a pretrained model.&lt;/li&gt;
&lt;li&gt;Compare different training configurations.&lt;/li&gt;
&lt;li&gt;Perform error analysis.&lt;/li&gt;
&lt;li&gt;Export a trained PyTorch model to TorchScript.&lt;/li&gt;
&lt;li&gt;Host a model on Hugging Face.&lt;/li&gt;
&lt;li&gt;Build an interactive Streamlit application.&lt;/li&gt;
&lt;li&gt;Connect an application to a remotely hosted model.&lt;/li&gt;
&lt;li&gt;Deploy a machine learning application online.&lt;/li&gt;
&lt;li&gt;Troubleshoot model inference and deployment problems.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Most importantly, I learned that &lt;strong&gt;a machine learning project does not end when the model reaches a high accuracy&lt;/strong&gt;. Turning a model into something that another person can use requires additional engineering, testing, and deployment work.&lt;/p&gt;

&lt;h2&gt;
  
  
  Conclusion
&lt;/h2&gt;

&lt;p&gt;This project took a potato disease classifier from a training notebook to a publicly accessible web application.&lt;/p&gt;

&lt;p&gt;The final experiment using ResNet18 achieved &lt;strong&gt;99.07% validation accuracy&lt;/strong&gt;. The model was then exported to TorchScript, hosted on Hugging Face, integrated into a Streamlit application, and deployed online.&lt;/p&gt;

&lt;p&gt;The project gave me practical experience across the machine learning lifecycle—from data preparation and model training to deployment and troubleshooting.&lt;/p&gt;

&lt;h2&gt;
  
  
  Project Links
&lt;/h2&gt;

&lt;p&gt;You can explore the project and try the deployed application below:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;🥔 &lt;a href="https://potato-disease-classifier-lyiuksv5xfmhfrhrygcxxu.streamlit.app/" rel="noopener noreferrer"&gt;Live Streamlit App&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;🤗 &lt;a href="https://huggingface.co/Rose-30/potato-disease-classifier" rel="noopener noreferrer"&gt;Hugging Face Model&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;💻 &lt;a href="https://github.com/Hoga30/potato-disease-classifier" rel="noopener noreferrer"&gt;GitHub Repository&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Thank you for reading!&lt;/p&gt;

</description>
      <category>machinelearning</category>
      <category>deeplearning</category>
      <category>python</category>
      <category>ai</category>
    </item>
  </channel>
</rss>
