<?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: Amandha Panagoda</title>
    <description>The latest articles on DEV Community by Amandha Panagoda (@its_amandha).</description>
    <link>https://dev.to/its_amandha</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F2614275%2F5dc2ed90-b77d-4c61-9420-433b054b17a8.png</url>
      <title>DEV Community: Amandha Panagoda</title>
      <link>https://dev.to/its_amandha</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/its_amandha"/>
    <language>en</language>
    <item>
      <title>MediatR + CQRS</title>
      <dc:creator>Amandha Panagoda</dc:creator>
      <pubDate>Thu, 15 May 2025 17:57:18 +0000</pubDate>
      <link>https://dev.to/its_amandha/mediatr-cqrs-57cp</link>
      <guid>https://dev.to/its_amandha/mediatr-cqrs-57cp</guid>
      <description>&lt;p&gt;You’ve probably seen it in many “clean architecture” diagrams: arrows pointing from Controllers to Handlers, from Handlers to Repositories, and this thing in the middle....MediatR. Paired with a buzzing acronym CQRS (Command Query Responsibility Segregation), it can feel like you’re building the next NASA control system when you just want to create a To-Do app.&lt;/p&gt;

&lt;p&gt;But before you throw it all away as overengineering, let’s actually break it down. Because when used correctly, MediatR + CQRS can give your code: clear separation, testability, and fewer "what does this method even do?" moments.&lt;/p&gt;

&lt;h2&gt;
  
  
  What Is MediatR?
&lt;/h2&gt;

&lt;p&gt;MediatR is a simple in-process messaging library for .NET, created by Jimmy Bogard. It helps you decouple your logic by acting as a &lt;strong&gt;mediator&lt;/strong&gt; (get it?) between the request and the handler. Instead of calling a service directly, you send a request and let the handler &lt;em&gt;handle&lt;/em&gt; it.&lt;/p&gt;

&lt;p&gt;So instead of:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;var result = _orderService.PlaceOrder(request);
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;You do:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;var result = await _mediator.Send(new PlaceOrderCommand(request));
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The MediatR tells the right handler to take over.&lt;/p&gt;

&lt;h2&gt;
  
  
  What Is CQRS?
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;CQRS&lt;/strong&gt; stands for Command Query Responsibility Segregation. In simple terms: separate your read logic from your write logic. That’s it.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Commands&lt;/strong&gt; mutate state. (PlaceOrderCommand, DeleteUserCommand)&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Queries&lt;/strong&gt; return data. (GetOrderByIdQuery, GetUsersListQuery)&lt;/p&gt;

&lt;p&gt;In traditional CRUD apps, you have services like:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;UserService.CreateUser();
UserService.GetUsers();
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;And when paired with MediatR, you get a smooth flow:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;await _mediator.Send(new RegisterUserCommand(...));
var users = await _mediator.Send(new GetUsersQuery());
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The benefit? You can optimize them independently. Queries can hit fast read replicas or return DTOs tailored for UI. Commands can enforce strict validation and business rules.&lt;/p&gt;

&lt;h2&gt;
  
  
  MediatR + CQRS
&lt;/h2&gt;

&lt;p&gt;These two patterns play really well together. MediatR routes your commands and queries to the right handler. You end up with a codebase where:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;The controller doesn’t know the details of business logic.&lt;/li&gt;
&lt;li&gt;The logic is easily testable (you just test the handler).&lt;/li&gt;
&lt;li&gt;The code is predictable and scalable.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  But Do You &lt;em&gt;Need&lt;/em&gt; It?
&lt;/h3&gt;

&lt;p&gt;Here’s the catch: this combo isn’t free. You’ll be creating lots of files - commands, queries, handlers. Don’t use CQRS and MediatR unless you really need them.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;When it makes sense:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;You have complex domains with deep business logic.&lt;/li&gt;
&lt;li&gt;You need clear audit trails, validations, and handler pipelines.&lt;/li&gt;
&lt;li&gt;Your system is growing fast, and maintainability is key.&lt;/li&gt;
&lt;li&gt;You’re writing unit-test-heavy applications and value isolation.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;When it’s overkill:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;It’s a simple CRUD app.&lt;/li&gt;
&lt;li&gt;You have a tight deadline and limited devs.&lt;/li&gt;
&lt;li&gt;You’re building a proof of concept or internal tool.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;There’s no shame in keeping things simple. &lt;/p&gt;

&lt;h2&gt;
  
  
  Creating a Simple Project
&lt;/h2&gt;

&lt;p&gt;Let’s walk through how to structure a simple .NET Web API project using CQRS with MediatR. We'll build a small app that manages Pokémon data.&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.amazonaws.com%2Fuploads%2Farticles%2Fn4z6vlt5y0y9k8lrmwxl.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.amazonaws.com%2Fuploads%2Farticles%2Fn4z6vlt5y0y9k8lrmwxl.png" alt="File and Folder Structure" width="503" height="675"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Model
&lt;/h3&gt;

&lt;p&gt;We start with a basic model to represent Pokémon data:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;public class PokemonModel
{
    public int Id { get; set; }
    public string Name { get; set; }
    public string Generation { get; set; }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Data Access
&lt;/h3&gt;

&lt;p&gt;We create an interface and its implementation to simulate a data store. This acts as our data access abstraction:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;public interface IDemoDataAccess
{
    List&amp;lt;PokemonModel&amp;gt; GetPokemons();
    PokemonModel InsertPokemon(string name, string generation);
}

public class DemoDataAccess : IDemoDataAccess
{
    private List&amp;lt;PokemonModel&amp;gt; pokemons = new()
    {
        new PokemonModel { Id = 1, Name = "Bulbasaur", Generation = "Kanto" },
        new PokemonModel { Id = 2, Name = "Azurill", Generation = "Hoenn" }
    };

    public List&amp;lt;PokemonModel&amp;gt; GetPokemons() =&amp;gt; pokemons;

    public PokemonModel InsertPokemon(string name, string generation)
    {
        int newId = pokemons.Max(p =&amp;gt; p.Id) + 1;
        var pokemon = new PokemonModel { Id = newId, Name = name, Generation = generation };
        pokemons.Add(pokemon);
        return pokemon;
    }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Queries
&lt;/h3&gt;

&lt;p&gt;In CQRS, we separate reads (queries) from writes (commands).&lt;/p&gt;

&lt;p&gt;And Queries are used for reading data only — no changes allowed.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;public record GetPokemonListQuery : IRequest&amp;lt;List&amp;lt;PokemonModel&amp;gt;&amp;gt; { }

public record GetPokemonByIdQuery(int id) : IRequest&amp;lt;PokemonModel&amp;gt; { }
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Commands
&lt;/h3&gt;

&lt;p&gt;Used for write operations like creating or updating data.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;public record InsertPokemonCommand(string Name, string Generation) : IRequest&amp;lt;PokemonModel&amp;gt; { }
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Handlers
&lt;/h3&gt;

&lt;p&gt;Handlers are where the real logic happens. MediatR finds the right handler based on the request sent.&lt;/p&gt;

&lt;h4&gt;
  
  
  Get List
&lt;/h4&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;public class GetPokemonListHandler : IRequestHandler&amp;lt;GetPokemonListQuery, List&amp;lt;PokemonModel&amp;gt;&amp;gt;
{
    private readonly IDemoDataAccess _data;

    public GetPokemonListHandler(IDemoDataAccess data)
    {
        _data = data;
    }

    public Task&amp;lt;List&amp;lt;PokemonModel&amp;gt;&amp;gt; Handle(GetPokemonListQuery request, CancellationToken cancellationToken)
    {
        return Task.FromResult(_data.GetPokemons());
    }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h4&gt;
  
  
  Get By Id
&lt;/h4&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;public class GetPokemonByIdHandler : IRequestHandler&amp;lt;GetPokemonByIdQuery, PokemonModel&amp;gt;
{
    private readonly IMediator _mediator;

    public GetPokemonByIdHandler(IMediator mediator)
    {
        _mediator = mediator;
    }

    public async Task&amp;lt;PokemonModel&amp;gt; Handle(GetPokemonByIdQuery request, CancellationToken cancellationToken)
    {
        var pokemons = await _mediator.Send(new GetPokemonListQuery());
        return pokemons.FirstOrDefault(x =&amp;gt; x.Id == request.id);
    }
}

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h4&gt;
  
  
  Insert
&lt;/h4&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;public class InsertPokemonHandler : IRequestHandler&amp;lt;InsertPokemonCommand, PokemonModel&amp;gt;
{
    private readonly IDemoDataAccess _data;

    public InsertPokemonHandler(IDemoDataAccess data)
    {
        _data = data;
    }

    public Task&amp;lt;PokemonModel&amp;gt; Handle(InsertPokemonCommand request, CancellationToken cancellationToken)
    {
        return Task.FromResult(_data.InsertPokemon(request.Name, request.Generation));
    }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  API Layer
&lt;/h3&gt;

&lt;p&gt;The controller sends requests to MediatR, which then delegates to the appropriate handler.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;[ApiController]
[Route("api/[controller]")]
public class PokemonController : ControllerBase
{
    private readonly IMediator _mediator;

    public PokemonController(IMediator mediator)
    {
        _mediator = mediator;
    }

    [HttpGet]
    public async Task&amp;lt;List&amp;lt;PokemonModel&amp;gt;&amp;gt; GetPokemon()
    {
        return await _mediator.Send(new GetPokemonListQuery());
    }

    [HttpGet("{id}")]
    public async Task&amp;lt;PokemonModel&amp;gt; GetPokemonById(int id)
    {
        return await _mediator.Send(new GetPokemonByIdQuery(id));
    }

    [HttpPost]
    public async Task&amp;lt;PokemonModel&amp;gt; Post([FromBody] PokemonModel pokemon)
    {
        return await _mediator.Send(new InsertPokemonCommand(pokemon.Name, pokemon.Generation));
    }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h4&gt;
  
  
  How CQRS and MediatR Work Together
&lt;/h4&gt;

&lt;ul&gt;
&lt;li&gt;Separation of Concerns: Queries (&lt;code&gt;GetPokemonListQuery&lt;/code&gt;) are for reading. Commands (&lt;code&gt;InsertPokemonCommand&lt;/code&gt;) are for writing.&lt;/li&gt;
&lt;li&gt;Request/Response Pattern: Each query or command implements &lt;code&gt;IRequest&amp;lt;T&amp;gt;&lt;/code&gt;, and is handled by &lt;code&gt;IRequestHandler&amp;lt;TRequest, TResponse&amp;gt;&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;MediatR Acts as a Mediator: &lt;code&gt;IMediator.Send()&lt;/code&gt; sends requests to their correct handlers. The controller doesn’t need to know who handles what, it just sends the request.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Final Thoughts
&lt;/h2&gt;

&lt;p&gt;MediatR and CQRS are amazing tools. Used right, they bring order to the chaos of growing applications. But like any tool, they’re not a requirement.&lt;/p&gt;

&lt;p&gt;Don’t feel pressured to adopt them just because it looks cleaner.&lt;/p&gt;

&lt;p&gt;Yes, clean code is great. But &lt;em&gt;pragmatic&lt;/em&gt; code is even better.&lt;/p&gt;

&lt;p&gt;Start simple. Let your architecture evolve with your app. Reach for CQRS and MediatR when your business logic cries out for structure, not just because the latest YouTube video told you so.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;The best architecture is the one you understand, maintain, and scale comfortably.&lt;/strong&gt;&lt;/p&gt;

</description>
      <category>csharp</category>
      <category>dotnet</category>
      <category>designpatterns</category>
      <category>cqrs</category>
    </item>
    <item>
      <title>How to Train Your Model When Data Lies</title>
      <dc:creator>Amandha Panagoda</dc:creator>
      <pubDate>Fri, 28 Feb 2025 15:37:54 +0000</pubDate>
      <link>https://dev.to/its_amandha/how-to-train-your-model-when-data-lies-c0b</link>
      <guid>https://dev.to/its_amandha/how-to-train-your-model-when-data-lies-c0b</guid>
      <description>&lt;p&gt;Imagine you're learning to tell dog breeds apart, but your teacher occasionally tells you the wrong information. They sometimes mistakenly call a Labrador a Golden Retriever. They also call a Husky a Malamute at times. When this keeps happening, you'll start doubting yourself, or worse....learn the wrong things altogether.&lt;/p&gt;

&lt;p&gt;This is exactly what happens when you train machine learning models on noisy labels. Labels that are erroneous in the data. The model gets confused, learns the incorrect patterns, and does not predict well.&lt;/p&gt;

&lt;p&gt;So, how do you make a model smart enough to handle these errors? That's what we will explore in this article.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;You can find the code snippets I've used here in my colab notebook:&lt;/em&gt; &lt;a href="https://colab.research.google.com/drive/1JKFNi81AcHcmlyI31LWifHmHkmPM_0TQ?usp=sharing" rel="noopener noreferrer"&gt;Colab Notebook&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  What Are Noisy Labels?
&lt;/h2&gt;

&lt;p&gt;A &lt;strong&gt;label&lt;/strong&gt; is the correct answer for a data point. So, if you have a data set of pictures of cats and dogs, each picture will have a label of "cat" or "dog."&lt;/p&gt;

&lt;p&gt;But sometimes, labels are &lt;strong&gt;wrong&lt;/strong&gt;. This can happen because:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Humans make errors: Someone manually labeled a picture of a Husky as a Wolf.&lt;/li&gt;
&lt;li&gt;Data can be unclear: Some flowers are nearly identical to each other.&lt;/li&gt;
&lt;li&gt;Automatic labeling goes wrong: A weak system can incorrectly classify objects.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;These types of errors in labels are what are called &lt;strong&gt;noisy labels&lt;/strong&gt;. And if you train a model with too much noise, it may end up memorizing the mistakes instead of learning from correct patterns.&lt;/p&gt;

&lt;h2&gt;
  
  
  Let’s Create a Noisy Dataset in Python
&lt;/h2&gt;

&lt;p&gt;First, let’s generate a clean dataset, then introduce some noise.&lt;/p&gt;

&lt;h3&gt;
  
  
  Step 1: Generate a Clean Dataset
&lt;/h3&gt;

&lt;p&gt;We’ll create a simple dataset with two classes (0 and 1) using &lt;code&gt;sklearn.datasets.make_classification&lt;/code&gt;.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;import numpy as np
import matplotlib.pyplot as plt
from sklearn.datasets import make_classification
from sklearn.model_selection import train_test_split

# Create a classification dataset with 1000 samples (data points) and 2 features (columns)
# n_informative=2 means the two features are useful for the classification task
# n_redundant=0 means no extra, redundant features are added
X, y = make_classification(n_samples=1000, n_features=2, n_informative=2, 
                           n_redundant=0, n_clusters_per_class=1, random_state=42)


X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2, random_state=42)

plt.scatter(X_train[:, 0], X_train[:, 1], c=y_train, cmap="coolwarm", alpha=0.7)
plt.title("Clean Dataset")
plt.show()
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&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.amazonaws.com%2Fuploads%2Farticles%2Fwljk0m0x2p8qreqnx3gs.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.amazonaws.com%2Fuploads%2Farticles%2Fwljk0m0x2p8qreqnx3gs.png" alt="Image description" width="546" height="435"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Step 2: Add Noisy Labels
&lt;/h3&gt;

&lt;p&gt;Now, we introduce &lt;strong&gt;20% label noise&lt;/strong&gt; by flipping some labels randomly.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;def add_label_noise(y, noise_rate=0.2):
    np.random.seed(42)
    num_noisy = int(len(y) * noise_rate)
    noisy_indices = np.random.choice(len(y), num_noisy, replace=False)
    y_noisy = y.copy()

    y_noisy[noisy_indices] = 1 - y_noisy[noisy_indices] # flip the labels :)
    return y_noisy

# Introduce noise into labels
y_train_noisy = add_label_noise(y_train, noise_rate=0.2)

plt.scatter(X_train[:, 0], X_train[:, 1], c=y_train_noisy, cmap="coolwarm", alpha=0.7)
plt.title("Dataset with Noisy Labels (20% incorrect)")
plt.show()
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&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.amazonaws.com%2Fuploads%2Farticles%2Fzkb4ha1uub5d5sgih2d6.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.amazonaws.com%2Fuploads%2Farticles%2Fzkb4ha1uub5d5sgih2d6.png" alt="Image description" width="546" height="435"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;🔴 Notice the difference? Some red points are mixed into the blue area and vice versa. That’s the &lt;em&gt;noise&lt;/em&gt;!&lt;/p&gt;

&lt;h2&gt;
  
  
  Why Are Noisy Labels Bad?
&lt;/h2&gt;

&lt;p&gt;To understand why it can be a problem, let’s train a Random Forest model on both clean and noisy datasets to compare how noise affects accuracy.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;from sklearn.ensemble import RandomForestClassifier
from sklearn.metrics import accuracy_score

# Train on the clean labels
clf_clean = RandomForestClassifier(random_state=42)
clf_clean.fit(X_train, y_train)
acc_clean = accuracy_score(y_test, clf_clean.predict(X_test))

# Train on noisy labels
clf_noisy = RandomForestClassifier(random_state=42)
clf_noisy.fit(X_train, y_train_noisy)
acc_noisy = accuracy_score(y_test, clf_noisy.predict(X_test))

print(f"Accuracy with Clean Labels: {acc_clean * 100:.2f}%")
print(f"Accuracy with Noisy Labels: {acc_noisy * 100:.2f}%")
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Accuracy with Clean Labels: 93.00%&lt;br&gt;
Accuracy with Noisy Labels: 86.00%&lt;/strong&gt; 😧&lt;/p&gt;

&lt;p&gt;📉 On clean labels, the model was 93% accurate, yet when noisy labels were introduced, the accuracy dropped to 86%. This demonstrates the extent to which incorrect data can confuse a model during training.&lt;/p&gt;

&lt;p&gt;This may not seem like a lot, but even a small proportion of noisy data (20% in this case) can lead to an apparent degradation in performance. This is because the model starts memorizing the incorrect labels instead of learning real patterns. &lt;/p&gt;
&lt;h2&gt;
  
  
  How to Handle Noisy Labels?
&lt;/h2&gt;
&lt;h3&gt;
  
  
  Method 1: Use a Smarter Loss Function (MAE Instead of Cross-Entropy)
&lt;/h3&gt;

&lt;p&gt;As per my research in Google and ChatGPT, the most common loss function for classification is &lt;strong&gt;cross-entropy loss&lt;/strong&gt;, but it overreacts to wrong labels. A better option is &lt;strong&gt;Mean Absolute Error (MAE)&lt;/strong&gt;, which is more resistant to noise.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;import tensorflow as tf
from tensorflow.keras.models import Sequential
from tensorflow.keras.layers import Dense

model = Sequential([
    Dense(16, activation="relu", input_shape=(2,)),
    Dense(16, activation="relu"),
    Dense(1, activation="sigmoid")
])

model.compile(optimizer="adam", loss="mean_absolute_error", metrics=["accuracy"])

model.fit(X_train, y_train_noisy, epochs=20, batch_size=16, verbose=0, validation_data=(X_test, y_test))

_, acc = model.evaluate(X_test, y_test)
print(f"Accuracy with MAE loss: {acc:.4f}")
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;MAE gives less importance to extreme errors, making the model less likely to overfit to noisy labels.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Accuracy with MAE loss: 0.9150&lt;/strong&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Method 2: Co-Teaching (Two Models Teach Each Other)
&lt;/h3&gt;

&lt;p&gt;Instead of using one model, we can train two models and let them filter out the noisy data for each other.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;from sklearn.linear_model import LogisticRegression

model1 = LogisticRegression() 
model2 = LogisticRegression()

# Identify "trusted" samples (least noisy)
trusted_samples = np.abs(y_train - y_train_noisy) &amp;lt; 0.5

model1.fit(X_train[trusted_samples], y_train_noisy[trusted_samples])
model2.fit(X_train[trusted_samples], y_train_noisy[trusted_samples])

# Combine predictions
preds1 = model1.predict(X_test)
preds2 = model2.predict(X_test)
final_preds = (preds1 + preds2) // 2  # Majority voting

acc_coteach = accuracy_score(y_test, final_preds)
print(f"Accuracy with Co-Teaching: {acc_coteach:.4f}")
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Each model trains only on "trusted" data, preventing them from memorizing noise.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Accuracy with Co-Teaching: 0.9000&lt;/strong&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Method 3: Semi-Supervised Learning (Train on Clean Data First)
&lt;/h3&gt;

&lt;p&gt;If we have some clean data, we can train the model on it first, then use it to fix noisy labels.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;# Train model on clean samples
model_clean = RandomForestClassifier()
model_clean.fit(X_train[trusted_samples], y_train_noisy[trusted_samples])

y_train_fixed = model_clean.predict(X_train)

final_model = RandomForestClassifier()
final_model.fit(X_train, y_train_fixed)

acc_fixed = accuracy_score(y_test, final_model.predict(X_test))
print(f"Accuracy after Semi-Supervised Learning: {acc_fixed:.4f}")
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The model learns correct patterns first, then refines its understanding with the full dataset.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Accuracy after Semi-Supervised Learning: 0.9050&lt;/strong&gt;&lt;/p&gt;

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

&lt;p&gt;While noisy labels cause a noticeable drop in performance, techniques like Semi-Supervised Learning and MAE loss can help recover some of the lost accuracy, though nothing quite matches the performance of clean data.&lt;/p&gt;

</description>
      <category>machinelearning</category>
      <category>python</category>
      <category>datascience</category>
    </item>
    <item>
      <title>[Boost]</title>
      <dc:creator>Amandha Panagoda</dc:creator>
      <pubDate>Thu, 26 Dec 2024 06:46:48 +0000</pubDate>
      <link>https://dev.to/its_amandha/-4pgi</link>
      <guid>https://dev.to/its_amandha/-4pgi</guid>
      <description>&lt;div class="ltag__link"&gt;
  &lt;a href="/its_amandha" class="ltag__link__link"&gt;
    &lt;div class="ltag__link__pic"&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.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F2614275%2F5dc2ed90-b77d-4c61-9420-433b054b17a8.png" alt="its_amandha"&gt;
    &lt;/div&gt;
  &lt;/a&gt;
  &lt;a href="/its_amandha/the-art-of-game-testing-2ii5" class="ltag__link__link"&gt;
    &lt;div class="ltag__link__content"&gt;
      &lt;h2&gt;The Art of Game Testing&lt;/h2&gt;
      &lt;h3&gt;Amandha Panagoda ・ Dec 26&lt;/h3&gt;
      &lt;div class="ltag__link__taglist"&gt;
        &lt;span class="ltag__link__tag"&gt;#gamedev&lt;/span&gt;
        &lt;span class="ltag__link__tag"&gt;#testing&lt;/span&gt;
      &lt;/div&gt;
    &lt;/div&gt;
  &lt;/a&gt;
&lt;/div&gt;


</description>
      <category>gamedev</category>
      <category>testing</category>
    </item>
    <item>
      <title>The Art of Game Testing</title>
      <dc:creator>Amandha Panagoda</dc:creator>
      <pubDate>Thu, 26 Dec 2024 05:50:50 +0000</pubDate>
      <link>https://dev.to/its_amandha/the-art-of-game-testing-2ii5</link>
      <guid>https://dev.to/its_amandha/the-art-of-game-testing-2ii5</guid>
      <description>&lt;p&gt;When we think of software quality assurance, the image that comes to mind often includes endless test cases, defect logs, and late-night debugging. At its core, QA ensures that a product fulfills its purpose without compromise. While this principle applies universally, game testing elevates QA to a whole new level. Because games are more than just software; they’re &lt;em&gt;immersive experiences&lt;/em&gt; crafted to &lt;em&gt;captivate, challenge, and entertain&lt;/em&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.amazonaws.com%2Fuploads%2Farticles%2Fmvc6gnwdz4w3immx02be.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.amazonaws.com%2Fuploads%2Farticles%2Fmvc6gnwdz4w3immx02be.png" alt="Buff Doge vs. Cheems meme. WHAT IT'S ACTUALLY LIKE; WHAT WE THOUGHT GAME TESTING WAS LIKE; They are making me jump 10000 times over a log just to make sure I don't go out of bounds of the game; I get to play the newest, most exciting games before anyone else" width="800" height="603"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Understanding Game Components
&lt;/h2&gt;

&lt;p&gt;Before diving into testing, it’s essential to understand the intricate anatomy of a game. Games are like fine tuned machine; every part must work in harmony. &lt;/p&gt;

&lt;p&gt;&lt;strong&gt;1. Menu and UI&lt;/strong&gt;&lt;br&gt;
Testing menus isn’t just about clicking buttons; it’s about usability, responsiveness, and accessibility. Can players navigate seamlessly using a controller, keyboard, or mouse?&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;2. Art and Animation&lt;/strong&gt;&lt;br&gt;
From textures to character movement, visuals need to render flawlessly across all supported platforms. Testers test edge cases, like extreme camera angles or lag spikes during animations.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;3. Sound Design&lt;/strong&gt;&lt;br&gt;
Audio must sync perfectly with in-game actions. A gunshot sound should fire instantly, not 2 seconds later.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;4. Music&lt;/strong&gt;&lt;br&gt;
Dynamic background music must transition seamlessly between scenarios. Abrupt stops and loops in audio will disrupt immersion.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;5. Camera Controls&lt;/strong&gt;&lt;br&gt;
Ensure intuitive control while maintaining immersion, whether it’s a cinematic zoom or a free-roaming camera.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;6. Player and Action Attributes&lt;/strong&gt;&lt;br&gt;
Character stats, weapon mechanics, and physics all need precise tuning. Have you ever seen a character unintentionally fly due to a physics glitch? Exactly.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;7. World/Level/Scene&lt;/strong&gt;&lt;br&gt;
Test the boundaries of the game world. Can players walk through walls? Are there “invisible death traps”? &lt;/p&gt;

&lt;p&gt;&lt;strong&gt;8. Triggers and Events&lt;/strong&gt;&lt;br&gt;
Ensure environmental interactions (like opening doors or triggering puzzles) function as intended. Misfires can ruin the gameplay flow.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;9. Scoring and Progression&lt;/strong&gt;&lt;br&gt;
Gameplay progression, such as leveling up or unlocking items, must be error-free and balanced. Testers often collaborate closely with designers here.&lt;/p&gt;




&lt;h2&gt;
  
  
  Types of Game Testing
&lt;/h2&gt;

&lt;p&gt;Game QA involves a variety of testing approaches, each tailored to ensure every component works flawlessly.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;1. Combinatorial Testing&lt;/strong&gt;&lt;br&gt;
This involves testing different combinations of game settings (e.g., resolutions, hardware configurations, or gameplay paths).&lt;br&gt;
Usually done using automation tools.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;2. Functionality Testing&lt;/strong&gt;&lt;br&gt;
The bread-and-butter of QA. Verify mechanics, ensure controls are responsive, and document every test scenario with expected vs. actual behavior.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;3. Compatibility Testing&lt;/strong&gt;&lt;br&gt;
Games must perform well across multiple platforms (PC, console, mobile). Testing isn’t just about resolution but also input methods like controllers, keyboards, and touchscreens.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;4. Regression Testing&lt;/strong&gt;&lt;br&gt;
Fixing a bug might inadvertently break other areas. Testers must meticulously re-check related functionalities.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;5. Ad Hoc Testing&lt;/strong&gt;&lt;br&gt;
Sometimes, the best bugs are discovered through unscripted exploration. Play like an over-curious player trying to break the game.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;6. Load Testing&lt;/strong&gt;&lt;br&gt;
Can the game’s servers handle 10,000 players? What about 50,000? Simulated load tests measure server thresholds.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;7. Play Testing&lt;/strong&gt;&lt;br&gt;
Focus on gameplay balance, difficulty levels, and overall player experience.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;8. Soak Testing&lt;/strong&gt;&lt;br&gt;
Leave the game running for hours (or even days) to identify long-term stability issues like memory leaks or crashes.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;9. Alpha and Beta Testing&lt;/strong&gt;&lt;br&gt;
Alpha tests involve internal testers, while beta tests allow external players to catch bugs and provide valuable feedback.&lt;/p&gt;




&lt;h2&gt;
  
  
  Game Testing Practices
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;1. Boundary and Glitch Explorations&lt;/strong&gt;&lt;br&gt;
Players love pushing limits. This is why testers explore:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Jumping off high points with unusual combos.&lt;/li&gt;
&lt;li&gt;Walking along map edges or corners.&lt;/li&gt;
&lt;li&gt;Opening multiple menus mid-action to trigger unexpected behaviors.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;2. Latency Testing for Controls&lt;/strong&gt;&lt;br&gt;
In fast-paced games like first-person shooters, every millisecond counts. Use tools to measure input-to-action latency, ensuring not just functionality but speed.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;3. Save and Load Exploits&lt;/strong&gt;&lt;br&gt;
Games often fail due to improper handling of save/load mechanics:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Save mid-action (e.g., mid-jump) and reload.&lt;/li&gt;
&lt;li&gt;Corrupt save files to test error handling.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;4. AI Behavior Analysis&lt;/strong&gt; (edge cases are critical here)&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;How AI responds to erratic player behavior (e.g., running in circles).&lt;/li&gt;
&lt;li&gt;Situations where multiple AI units get stuck in confined spaces.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;5. Environment Manipulation&lt;/strong&gt;&lt;br&gt;
For destructible environments, verify chain reactions. For example, does breaking one object affect others nearby? Sync damage effects with animations.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;6. Peripheral Testing&lt;/strong&gt;&lt;br&gt;
Console games need to support various controllers, steering wheels, VR headsets, and even third-party devices.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;7. Localization Testing&lt;/strong&gt;&lt;br&gt;
For global audiences, text rendering must be spot-on:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Does German text (typically longer) fit in menus?&lt;/li&gt;
&lt;li&gt;Do right-to-left scripts (like Arabic) render correctly?&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  The Human Touch in Game Testing
&lt;/h2&gt;

&lt;p&gt;Games are about more than just technical precision; they’re about fun. While rigorous testing ensures functionality, testers must also assess emotional responses:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Is the game intuitive?&lt;/strong&gt;&lt;br&gt;
&lt;em&gt;Does it feel rewarding to progress?&lt;br&gt;
Are players likely to get frustrated by specific mechanics?&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;Sometimes, the best QA isn’t about catching bugs; it’s about making sure the game &lt;em&gt;feels right.&lt;/em&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Conclusion
&lt;/h3&gt;

&lt;p&gt;Game testing is a blend of technical rigor and creative exploration. It demands the mindset of both a developer and a player. Beyond ensuring flawless execution, it’s about enabling players to immerse themselves in uninterrupted joy.&lt;/p&gt;

&lt;p&gt;So, the next time you boot up a game and enjoy a seamless experience, remember the testers who meticulously checked every jump, trigger, and sound bite to make that moment possible.🙂‍↕️&lt;/p&gt;

</description>
      <category>gamedev</category>
      <category>testing</category>
    </item>
  </channel>
</rss>
