<?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_86f0d45baef9).</description>
    <link>https://dev.to/rose_umutesi_86f0d45baef9</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_86f0d45baef9</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/rose_umutesi_86f0d45baef9"/>
    <language>en</language>
    <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_86f0d45baef9/from-deep-learning-model-to-a-deployed-potato-disease-classifier-3p6f</link>
      <guid>https://dev.to/rose_umutesi_86f0d45baef9/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>
