<?xml version="1.0" encoding="utf-8"?><feed xmlns="http://www.w3.org/2005/Atom" ><generator uri="https://jekyllrb.com/" version="3.10.0">Jekyll</generator><link href="https://sazid-uddin.github.io/feed.xml" rel="self" type="application/atom+xml" /><link href="https://sazid-uddin.github.io/" rel="alternate" type="text/html" /><updated>2026-07-27T15:05:38+00:00</updated><id>https://sazid-uddin.github.io/feed.xml</id><title type="html">Md. Sazid Uddin</title><subtitle>AI researcher and software engineer — computer vision, reinforcement learning, generative models, and formal verification of mechanistic interpretability interventions.</subtitle><author><name>Md. Sazid Uddin</name><email>sazid.uddin@aiub.edu</email></author><entry><title type="html">Cauli-Det, in Full: Problem, Architecture, and the Ablations Behind the 91.1% mAP</title><link href="https://sazid-uddin.github.io/cauli-det-full-writeup/" rel="alternate" type="text/html" title="Cauli-Det, in Full: Problem, Architecture, and the Ablations Behind the 91.1% mAP" /><published>2026-07-27T00:00:00+00:00</published><updated>2026-07-27T00:00:00+00:00</updated><id>https://sazid-uddin.github.io/cauli-det-full-writeup</id><content type="html" xml:base="https://sazid-uddin.github.io/cauli-det-full-writeup/"><![CDATA[<p><img src="/images/cauli-det.jpg" alt="Cauli-Det" /></p>

<p><strong>Cauli-Det</strong> is a fine-tuned, architecturally modified YOLOv8 model that detects and localizes three cauliflower diseases from ordinary smartphone photos — 91.1% mAP, published in <em>Frontiers in Plant Science</em> (2024).</p>

<p><a href="https://github.com/manchitro/cauli-det">Code</a> · <a href="https://doi.org/10.3389/fpls.2024.1373590">Paper (DOI: 10.3389/fpls.2024.1373590)</a></p>

<h2 id="problem">Problem</h2>

<p>Cauliflower is economically significant in agricultural economies like Bangladesh, which produced 283 kilotons in 2020 — but crop disease can devastate yield, and the standard defense is manual visual inspection, which is laborious, error-prone, and can miss early disease. Smallholder farmers, especially in remote areas, typically can’t afford expert agricultural consultation. Automated detection from an ordinary phone camera is the alternative — but it has to actually run on cheap hardware and actually tell you <em>where</em> the disease is, not just <em>that</em> the plant is sick.</p>

<p>That second point is the actual gap this project targets. Prior cauliflower-disease research — K-means clustering plus Random Forest, K-means plus GLCM features and logistic regression, transfer-learning approaches like EfficientNetB1 and InceptionV3 — is uniformly <strong>classification-only</strong>: “is this plant diseased, and with what,” not <strong>localization</strong>. For an actual field intervention (spot-treating, isolating one plant, flagging a specific area for closer inspection) you need to know <em>where</em> on the plant the disease is, which means object detection, not classification. That’s what motivates using YOLOv8 — a detector, not a classifier — as the base model.</p>

<h2 id="diseases-covered">Diseases covered</h2>

<p>Three classes, drawn from field images collected in Manikganj, Bangladesh (Dec 2021 – Jan 2022):</p>

<ul>
  <li><strong>Downy Mildew</strong> (fungal) — white, yellow, or brownish patches with downy gray mold on leaf undersides, progressing to leaf death.</li>
  <li><strong>Black Rot</strong> (bacterial, <em>Xanthomonas campestris</em>) — dull, irregular yellow spots progressing to V-shaped patches; renders produce unsaleable.</li>
  <li><strong>Bacterial Spot Rot</strong> (<em>Alternaria brassicicola</em>) — water-soaked lesions on flower heads forming rotting masses, browning to black.</li>
</ul>

<h2 id="architecture">Architecture</h2>

<p>Starting point: stock YOLOv8, which has three parts — a <strong>backbone</strong> (progressive downsampling convolutions extracting high-level features), a <strong>neck</strong> (C2f cross-stage-partial-fusion modules plus an SPPF spatial-pyramid-pooling module, fusing multi-scale features), and dual <strong>heads</strong> (detection, outputting bounding boxes; classification, outputting per-class probabilities).</p>

<p>Three deliberate, empirically-justified modifications on top of that:</p>

<ol>
  <li><strong>Extra Conv blocks in both heads</strong> (kernel size 1, inserted before the output convolution) — adds depth without much parameter growth. Landed on 3 extra blocks after testing 1 through 5.</li>
  <li><strong>Hard Swish activation</strong>, replacing the default SiLU — a clipped-linear approximation that trades a small amount of non-linearity for real compute savings, and happened to also win on accuracy.</li>
  <li><strong>Full (unfrozen) fine-tuning</strong> with a uniform learning rate across the whole network, rather than freezing the backbone or using differential learning rates. This was the single most consequential finding of the four ablations below.</li>
</ol>

<h2 id="dataset">Dataset</h2>

<p>656 images total (VegNet dataset), split 70/15/15 train/val/test, resized to 256×256. Bounding boxes hand-annotated using Makesense.ai — the original dataset only had image-level labels, so this annotation work is itself part of the contribution.</p>

<table>
  <thead>
    <tr>
      <th>Class</th>
      <th>Share</th>
      <th>Train</th>
      <th>Val</th>
      <th>Test</th>
      <th>Total</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <td>Healthy</td>
      <td>31.4%</td>
      <td>144</td>
      <td>31</td>
      <td>31</td>
      <td>206</td>
    </tr>
    <tr>
      <td>Downy Mildew</td>
      <td>27.0%</td>
      <td>125</td>
      <td>26</td>
      <td>26</td>
      <td>177</td>
    </tr>
    <tr>
      <td>Bacterial Spot Rot</td>
      <td>26.4%</td>
      <td>121</td>
      <td>26</td>
      <td>26</td>
      <td>173</td>
    </tr>
    <tr>
      <td>Black Rot</td>
      <td>15.2%</td>
      <td>70</td>
      <td>15</td>
      <td>15</td>
      <td>100</td>
    </tr>
  </tbody>
</table>

<h2 id="experiments--four-questions-tested-empirically">Experiments — four questions, tested empirically</h2>

<p><strong>1. Which YOLO to start from?</strong></p>

<table>
  <thead>
    <tr>
      <th>Model</th>
      <th>Test Precision</th>
      <th>Test Recall</th>
      <th>Test mAP50</th>
      <th>Test mAP50-95</th>
      <th>Params</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <td>YOLOv7</td>
      <td>97.8%</td>
      <td>88.9%</td>
      <td>92.6%</td>
      <td>71.8%</td>
      <td>37.21M</td>
    </tr>
    <tr>
      <td>YOLOv8n</td>
      <td>91.0%</td>
      <td>82.8%</td>
      <td>82.1%</td>
      <td>57.7%</td>
      <td>3.01M</td>
    </tr>
    <tr>
      <td>YOLOv8s</td>
      <td>91.4%</td>
      <td>83.2%</td>
      <td>84.1%</td>
      <td>66.1%</td>
      <td>11.14M</td>
    </tr>
    <tr>
      <td>YOLOv8m</td>
      <td>91.2%</td>
      <td>86.8%</td>
      <td>91.6%</td>
      <td>72.1%</td>
      <td>25.86M</td>
    </tr>
    <tr>
      <td>YOLOv8l</td>
      <td>90.4%</td>
      <td>87.5%</td>
      <td>91.5%</td>
      <td>71.1%</td>
      <td>43.63M</td>
    </tr>
    <tr>
      <td>YOLOv8x</td>
      <td>91.8%</td>
      <td>84.7%</td>
      <td>91.0%</td>
      <td>72.3%</td>
      <td>68.16M</td>
    </tr>
  </tbody>
</table>

<p>YOLOv8s doesn’t win this table outright — YOLOv7 and YOLOv8m both post higher raw mAP. It was picked anyway on a deployability argument: under a third the parameters of YOLOv7, and the larger YOLOv8 variants show diminishing returns for a problem this size. The gap closes further once the head modifications below are applied.</p>

<p><strong>2. How many extra Conv blocks?</strong></p>

<table>
  <thead>
    <tr>
      <th>Config</th>
      <th>Test Precision</th>
      <th>Test Recall</th>
      <th>Test mAP50</th>
      <th>Test mAP50-95</th>
      <th>Params</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <td>YOLOv8s (base)</td>
      <td>91.4%</td>
      <td>83.2%</td>
      <td>84.1%</td>
      <td>66.1%</td>
      <td>11.14M</td>
    </tr>
    <tr>
      <td>+1 Conv</td>
      <td>95.5%</td>
      <td>83.7%</td>
      <td>90.5%</td>
      <td>68.8%</td>
      <td>11.20M</td>
    </tr>
    <tr>
      <td>+2 Conv</td>
      <td>90.1%</td>
      <td>85.2%</td>
      <td>89.4%</td>
      <td>69.4%</td>
      <td>11.26M</td>
    </tr>
    <tr>
      <td>+3 Conv</td>
      <td>93.1%</td>
      <td>82.9%</td>
      <td>90.6%</td>
      <td>69.4%</td>
      <td>11.32M</td>
    </tr>
    <tr>
      <td>+4 Conv</td>
      <td>93.6%</td>
      <td>85.9%</td>
      <td>90.3%</td>
      <td>68.6%</td>
      <td>11.38M</td>
    </tr>
    <tr>
      <td>+5 Conv</td>
      <td>94.6%</td>
      <td>85.7%</td>
      <td>90.4%</td>
      <td>68.8%</td>
      <td>11.45M</td>
    </tr>
  </tbody>
</table>

<p>+3 Conv blocks hits the best test mAP50 (90.6%) for near-minimal parameter cost; going further adds parameters without a corresponding gain — likely overfitting on a dataset this size.</p>

<p><strong>3. Freeze the backbone, or fine-tune everything?</strong></p>

<table>
  <thead>
    <tr>
      <th>Strategy</th>
      <th>Test Precision</th>
      <th>Test Recall</th>
      <th>Test mAP50</th>
      <th>Test mAP50-95</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <td>Default (uniform, unfrozen)</td>
      <td>93.1%</td>
      <td>82.9%</td>
      <td>90.6%</td>
      <td>69.4%</td>
    </tr>
    <tr>
      <td>Freeze non-extra-Conv layers</td>
      <td>29.9%</td>
      <td>35.2%</td>
      <td>27.2%</td>
      <td>13.6%</td>
    </tr>
    <tr>
      <td>Freeze backbone</td>
      <td>56.6%</td>
      <td>46.1%</td>
      <td>51.1%</td>
      <td>28.0%</td>
    </tr>
    <tr>
      <td>Fast extra-Conv (differential LR)</td>
      <td>90.6%</td>
      <td>76.5%</td>
      <td>83.9%</td>
      <td>60.3%</td>
    </tr>
    <tr>
      <td>Fast head (differential LR)</td>
      <td>92.0%</td>
      <td>77.8%</td>
      <td>84.6%</td>
      <td>61.5%</td>
    </tr>
    <tr>
      <td>Fast head+neck (differential LR)</td>
      <td>95.5%</td>
      <td>83.7%</td>
      <td>90.5%</td>
      <td>68.8%</td>
    </tr>
  </tbody>
</table>

<p>This is the sharpest result in the whole study. Freezing the backbone doesn’t just underperform — it collapses the model (mAP50 drops from 90.6% to as low as 27.2%). The pretrained COCO features aren’t close enough to cauliflower-field imagery for a frozen backbone to be a usable starting point; the domain shift is too large. Full fine-tuning was a necessity here, not a stylistic choice.</p>

<p><strong>4. Which activation function?</strong></p>

<table>
  <thead>
    <tr>
      <th>Function</th>
      <th>Test Precision</th>
      <th>Test Recall</th>
      <th>Test mAP50</th>
      <th>Test mAP50-95</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <td>SiLU (default)</td>
      <td>93.1%</td>
      <td>82.9%</td>
      <td>90.6%</td>
      <td>69.4%</td>
    </tr>
    <tr>
      <td>ReLU</td>
      <td>90.6%</td>
      <td>82.9%</td>
      <td>87.5%</td>
      <td>66.8%</td>
    </tr>
    <tr>
      <td>LeakyReLU</td>
      <td>94.2%</td>
      <td>84.0%</td>
      <td>90.0%</td>
      <td>67.7%</td>
    </tr>
    <tr>
      <td>Tanh</td>
      <td>90.6%</td>
      <td>70.2%</td>
      <td>77.1%</td>
      <td>50.2%</td>
    </tr>
    <tr>
      <td>Hard Swish</td>
      <td>93.2%</td>
      <td>82.6%</td>
      <td>91.1%</td>
      <td>70.1%</td>
    </tr>
  </tbody>
</table>

<p>Hard Swish wins on both axes that matter — best test mAP50 (91.1%) <em>and</em> cheaper to compute than SiLU — so it replaced the framework default.</p>

<h2 id="final-results">Final results</h2>

<p><strong>Validation set</strong> — Precision 91.9%, Recall 85.1%, mAP50 92.0%, mAP50-95 67.7%</p>

<table>
  <thead>
    <tr>
      <th>Class</th>
      <th>Images</th>
      <th>Instances</th>
      <th>Precision</th>
      <th>Recall</th>
      <th>AP50</th>
      <th>AP50-95</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <td>Downy Mildew</td>
      <td>26</td>
      <td>77</td>
      <td>91.9%</td>
      <td>84.4%</td>
      <td>94.1%</td>
      <td>70.3%</td>
    </tr>
    <tr>
      <td>Black Rot</td>
      <td>15</td>
      <td>215</td>
      <td>85.2%</td>
      <td>75.8%</td>
      <td>84.5%</td>
      <td>53.2%</td>
    </tr>
    <tr>
      <td>Bacterial Spot Rot</td>
      <td>26</td>
      <td>40</td>
      <td>98.7%</td>
      <td>95.0%</td>
      <td>97.4%</td>
      <td>79.7%</td>
    </tr>
  </tbody>
</table>

<p><strong>Test set</strong> — Precision 93.2%, Recall 82.6%, mAP50 91.1%, mAP50-95 70.1%</p>

<table>
  <thead>
    <tr>
      <th>Class</th>
      <th>Images</th>
      <th>Instances</th>
      <th>Precision</th>
      <th>Recall</th>
      <th>AP50</th>
      <th>AP50-95</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <td>Downy Mildew</td>
      <td>26</td>
      <td>50</td>
      <td>90.1%</td>
      <td>84.0%</td>
      <td>92.5%</td>
      <td>68.6%</td>
    </tr>
    <tr>
      <td>Black Rot</td>
      <td>15</td>
      <td>225</td>
      <td>92.6%</td>
      <td>66.7%</td>
      <td>82.6%</td>
      <td>55.2%</td>
    </tr>
    <tr>
      <td>Bacterial Spot Rot</td>
      <td>26</td>
      <td>34</td>
      <td>96.8%</td>
      <td>97.1%</td>
      <td>98.3%</td>
      <td>86.4%</td>
    </tr>
  </tbody>
</table>

<p>The weak point in both splits is <strong>Black Rot recall</strong> (66.7% on test) — the model catches Downy Mildew and Bacterial Spot Rot reliably but misses roughly a third of Black Rot instances. Worth naming explicitly rather than only quoting the headline mAP.</p>

<h2 id="honest-limitations">Honest limitations</h2>

<ol>
  <li><strong>Only three disease types</strong> — real cauliflower cultivation faces more than this; a dataset-scope limit, not a model-scope one.</li>
  <li><strong>No cross-device evaluation</strong> — all images from one camera; performance on typical farmer smartphone cameras is untested.</li>
  <li><strong>No real-time/field testing</strong> — evaluation is offline, on curated images; live video inference under field conditions hasn’t been tried.</li>
  <li><strong>Small dataset</strong> — 656 images total is small by detection-model standards, which limits generalization claims.</li>
</ol>

<p>Full code, training scripts, and the complete README (including this same ablation detail) are on <a href="https://github.com/manchitro/cauli-det">GitHub</a>.</p>]]></content><author><name>Md. Sazid Uddin</name><email>sazid.uddin@aiub.edu</email></author><category term="Research" /><category term="Computer Vision" /><summary type="html"><![CDATA[The full write-up behind the Cauli-Det portfolio entry — problem motivation, architecture, all four ablation studies, and the honest per-class weak spot the headline number hides.]]></summary></entry><entry><title type="html">Cooperative MARL for Mammogram ROI Classification, in Full</title><link href="https://sazid-uddin.github.io/marl-mammogram-full-writeup/" rel="alternate" type="text/html" title="Cooperative MARL for Mammogram ROI Classification, in Full" /><published>2026-07-27T00:00:00+00:00</published><updated>2026-07-27T00:00:00+00:00</updated><id>https://sazid-uddin.github.io/marl-mammogram-full-writeup</id><content type="html" xml:base="https://sazid-uddin.github.io/marl-mammogram-full-writeup/"><![CDATA[<p><img src="/images/mammo.png" alt="MARL mammogram ROI classification" /></p>

<p>Sixteen reinforcement-learning agents independently scan small patches of a mammogram region of interest, communicate, and reach a consensus classification (benign/malignant) — without any single agent ever seeing the whole image. 82.45% accuracy on CBIS-DDSM. Published at IEEE ICDABI 2023, presented virtually.</p>

<p><a href="https://github.com/manchitro/marl-cbis-ddsm">Code</a> · <a href="https://doi.org/10.1109/ICDABI60145.2023.10629500">Paper (DOI: 10.1109/ICDABI60145.2023.10629500)</a></p>

<h2 id="problem">Problem</h2>

<p>Breast carcinoma caused roughly 685,000 deaths in 2020 — 25% of that year’s 2.26 million new cases — and about 13% of women face a lifetime risk of developing it. Mammography is the standard screening tool, but reading mammograms is resource-intensive and requires expert radiologists, which is a bottleneck on early detection. Decades of computer-aided detection research have targeted this, but almost all of it — from classical ML through modern deep CNNs (state-of-the-art methods on CBIS-DDSM reach 95%+ accuracy) — processes the <strong>whole image at once</strong>. Parameter counts for these models scale with image resolution, an increasingly real cost as medical imaging resolution keeps climbing.</p>

<p>Reinforcement learning for this specific problem was, at the time, relatively unexplored. The question this project asks: what if, instead of one large model consuming the whole image, many small agents each look at a tiny local patch, share what they see with each other, and reach a <em>decentralized</em> consensus — does that reduce the computational burden of scaling with image size, while staying accurate enough to be useful? The architecture is adapted from prior multi-agent image classification work demonstrated on MNIST — this project’s contribution is extending that general framework to the harder, real task of mammogram ROI classification.</p>

<h2 id="architecture">Architecture</h2>

<p>The task is framed as a partially observable Markov Decision Process (POMDP): an 8-tuple ⟨I, N, S, A, P, π, O, γ⟩ — the image, agent count, state space (agent positions), action space (<code class="language-plaintext highlighter-rouge">{up, down, left, right}</code>), position-transition function, action policy, local-observation function, and discount factor. Each of the 16 agents runs five modules per timestep:</p>

<ol>
  <li><strong>Feature Extraction</strong> — a 4-layer CNN turns the agent’s local 24×24px window into a 128-dimensional feature vector.</li>
  <li><strong>Position Encoding</strong> — the agent’s (x, y) coordinates pass through a fully-connected layer, GELU activation, and batch normalization.</li>
  <li><strong>Decision</strong> — an LSTM aggregates the agent’s full observation history (its own features, position encoding, and the averaged messages received from other agents), then a small policy network outputs a probability distribution over the four move directions.</li>
  <li><strong>Prediction</strong> — a second, separate LSTM tracks a running benign/malignant belief from the same inputs, independent of the movement decision.</li>
  <li><strong>Communication</strong> — each agent generates a message from its prediction-LSTM hidden state, broadcasts it, and every other agent decodes and averages all incoming messages, feeding that average back into both LSTMs next timestep.</li>
</ol>

<p>After a fixed episode length (32 steps by default), each agent emits a raw prediction vector; the system’s final classification is the argmax of the softmax-averaged predictions across all 16 agents. Training uses REINFORCE (policy-gradient) with an Adam optimizer — the reward for a sampled trajectory is the cross-entropy loss between that trajectory’s predicted and true label.</p>

<p>The key idea worth stating plainly: <strong>no agent ever sees the whole image, and there’s no central controller</strong> — classification emerges from many small, partial, locally-informed views reaching agreement through message-passing. That’s a genuinely different shape of solution than “bigger CNN, more parameters,” even though it doesn’t currently win on raw accuracy (see Results).</p>

<h2 id="dataset">Dataset</h2>

<p>CBIS-DDSM (Curated Breast Imaging Subset of DDSM), <strong>mass images only</strong> — calcification images were explicitly out of scope, left as future work. ROIs (professionally radiologist-annotated) resized to 224×224, retaining full aspect information.</p>

<table>
  <thead>
    <tr>
      <th> </th>
      <th>Benign</th>
      <th>Malignant</th>
      <th>Total</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <td>Train</td>
      <td>681</td>
      <td>637</td>
      <td>1,318</td>
    </tr>
    <tr>
      <td>Test</td>
      <td>231</td>
      <td>147</td>
      <td>378</td>
    </tr>
    <tr>
      <td><strong>Total</strong></td>
      <td><strong>912</strong></td>
      <td><strong>784</strong></td>
      <td><strong>1,696</strong></td>
    </tr>
  </tbody>
</table>

<p>Augmentation (horizontal flip, vertical flip, 90°/180°/270° rotation, and combinations) produced 12 copies per training image, expanding the training set to 15,816 images.</p>

<h2 id="training-setup">Training setup</h2>

<p>100 epochs, mini-batch size 32, LSTM hidden size 256, message size 64, 16 agents with a 24×24px observation window, 32 steps per episode, discount factor γ=0.99, learning rate 1e-4, Adam optimizer.</p>

<h2 id="results">Results</h2>

<table>
  <thead>
    <tr>
      <th>Metric</th>
      <th>Train (top-1)</th>
      <th>Eval</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <td>F1</td>
      <td>0.916</td>
      <td>0.81</td>
    </tr>
    <tr>
      <td>Accuracy</td>
      <td>—</td>
      <td>82.45%</td>
    </tr>
    <tr>
      <td>Precision</td>
      <td>—</td>
      <td>81.73%</td>
    </tr>
    <tr>
      <td>Recall</td>
      <td>—</td>
      <td>81.00%</td>
    </tr>
  </tbody>
</table>

<p><strong>Comparison against other published methods on the same dataset (CBIS-DDSM, mass images):</strong></p>

<table>
  <thead>
    <tr>
      <th>Method</th>
      <th>Year</th>
      <th>Accuracy</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <td>Jabeen et al.</td>
      <td>2023</td>
      <td>95.40%</td>
    </tr>
    <tr>
      <td>Baccouche et al.</td>
      <td>2022</td>
      <td>95.13%</td>
    </tr>
    <tr>
      <td>Muduli et al.</td>
      <td>2022</td>
      <td>90.68%</td>
    </tr>
    <tr>
      <td>Ragab et al.</td>
      <td>2019</td>
      <td>87.20%</td>
    </tr>
    <tr>
      <td><strong>This method</strong></td>
      <td>2023</td>
      <td><strong>82.45%</strong></td>
    </tr>
    <tr>
      <td>Khan et al.</td>
      <td>2019</td>
      <td>77.66%</td>
    </tr>
  </tbody>
</table>

<p>The honest framing: this doesn’t beat CNN-based state of the art on raw accuracy — it lands in the middle of a six-method comparison table, behind four CNN-based methods and ahead of one. The paper’s own conclusion is blunt about this: the model is described as far from being useful in the field in its current form. The contribution being claimed is architectural and methodological — a decentralized, partial-observation approach that scales differently with image resolution than whole-image CNN classifiers — not a leaderboard win. That framing is worth keeping intact rather than softened; overstating a result like this is exactly what undermines credibility with a technical reviewer.</p>

<h2 id="honest-limitations">Honest limitations</h2>

<ol>
  <li><strong>Single dataset</strong> — evaluated only on CBIS-DDSM; generalization to other mammogram datasets untested.</li>
  <li><strong>Single abnormality type</strong> — trained only on mass images, not calcifications, which look visually distinct and would need separate evaluation.</li>
  <li><strong>Accuracy trails CNN competitors</strong> — see table above.</li>
  <li><strong>Requires pre-annotated ROIs</strong> — the system classifies a given ROI, it doesn’t locate the ROI on a raw, unmarked mammogram itself. Full automation would need an ROI-localization step on top of this.</li>
</ol>

<p>Full code, training scripts, and the complete README are on <a href="https://github.com/manchitro/marl-cbis-ddsm">GitHub</a>.</p>]]></content><author><name>Md. Sazid Uddin</name><email>sazid.uddin@aiub.edu</email></author><category term="Research" /><category term="Reinforcement Learning" /><summary type="html"><![CDATA[The full write-up behind the MARL portfolio entry — POMDP formulation, the five-module agent architecture, and an honest read of a result that doesn't beat CNN baselines.]]></summary></entry></feed>