joakes90's picture
Add static informational Space: model card summary, performance table, example clips
fe31efd verified
Raw
History Blame Contribute Delete
10.4 kB
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1" />
<title>Engine Sound Classifier</title>
<style>
:root {
color-scheme: light;
--page: #f9f9f7;
--surface-1: #fcfcfb;
--text-primary: #0b0b0b;
--text-secondary: #52514e;
--text-muted: #898781;
--grid: #e1e0d9;
--baseline: #c3c2b7;
--border: rgba(11,11,11,0.10);
--series-1: #2a78d6;
--series-1-wash: rgba(42,120,214,0.10);
--link: #1c5cab;
}
@media (prefers-color-scheme: dark) {
:root:where(:not([data-theme="light"])) {
color-scheme: dark;
--page: #0d0d0d;
--surface-1: #1a1a19;
--text-primary: #ffffff;
--text-secondary: #c3c2b7;
--text-muted: #898781;
--grid: #2c2c2a;
--baseline: #383835;
--border: rgba(255,255,255,0.10);
--series-1: #3987e5;
--series-1-wash: rgba(57,135,229,0.14);
--link: #86b6ef;
}
}
:root[data-theme="dark"] {
color-scheme: dark;
--page: #0d0d0d;
--surface-1: #1a1a19;
--text-primary: #ffffff;
--text-secondary: #c3c2b7;
--text-muted: #898781;
--grid: #2c2c2a;
--baseline: #383835;
--border: rgba(255,255,255,0.10);
--series-1: #3987e5;
--series-1-wash: rgba(57,135,229,0.14);
--link: #86b6ef;
}
* { box-sizing: border-box; }
body {
margin: 0;
background: var(--page);
color: var(--text-primary);
font: 16px/1.55 system-ui, -apple-system, "Segoe UI", sans-serif;
}
main {
max-width: 760px;
margin: 0 auto;
padding: 48px 20px 80px;
}
h1 { font-size: 1.7rem; margin: 0 0 6px; }
h2 { font-size: 1.15rem; margin: 40px 0 12px; }
.tagline { color: var(--text-secondary); margin: 0 0 20px; }
.status {
display: inline-block;
font-size: 0.85rem;
color: var(--text-secondary);
background: var(--series-1-wash);
border: 1px solid var(--border);
border-radius: 6px;
padding: 4px 10px;
margin-bottom: 20px;
}
p { color: var(--text-secondary); }
a { color: var(--link); }
code {
background: var(--surface-1);
border: 1px solid var(--border);
border-radius: 4px;
padding: 1px 5px;
font-size: 0.9em;
}
.card {
background: var(--surface-1);
border: 1px solid var(--border);
border-radius: 10px;
padding: 20px;
}
.samples { display: grid; gap: 12px; }
.sample-row {
display: flex;
align-items: center;
gap: 14px;
flex-wrap: wrap;
}
.sample-label { min-width: 170px; font-size: 0.95rem; color: var(--text-primary); }
audio { flex: 1; min-width: 220px; height: 36px; }
/* --- bar chart --- */
.chart { padding: 4px 4px 0; }
.bar-row {
display: grid;
grid-template-columns: 90px 1fr 56px;
align-items: center;
gap: 10px;
height: 40px;
position: relative;
}
.bar-row + .bar-row { border-top: 1px solid var(--grid); }
.bar-cat { font-size: 0.9rem; color: var(--text-secondary); }
.bar-track { position: relative; height: 24px; }
.bar-fill {
position: absolute;
left: 0; top: 0;
height: 24px;
border-radius: 4px;
background: var(--series-1);
transition: filter 0.1s ease;
}
.bar-fill.best { background: var(--series-1); }
.bar-fill:hover { filter: brightness(1.08); }
.bar-value { font-size: 0.9rem; color: var(--text-primary); text-align: right; font-variant-numeric: tabular-nums; }
.chart-axis {
display: grid;
grid-template-columns: 90px 1fr 56px;
gap: 10px;
margin-top: 6px;
border-top: 1px solid var(--baseline);
padding-top: 4px;
}
.chart-axis span { font-size: 0.75rem; color: var(--text-muted); }
.chart-axis .ticks { position: relative; height: 14px; }
.chart-axis .ticks i { position: absolute; top: 0; font-style: normal; }
.tooltip {
position: absolute;
pointer-events: none;
background: var(--text-primary);
color: var(--page);
font-size: 0.78rem;
padding: 5px 8px;
border-radius: 5px;
white-space: nowrap;
transform: translate(-50%, -130%);
opacity: 0;
transition: opacity 0.1s ease;
z-index: 5;
}
.bar-row:hover .tooltip { opacity: 1; }
table.perf {
width: 100%;
border-collapse: collapse;
font-size: 0.88rem;
margin-top: 14px;
}
table.perf caption { text-align: left; color: var(--text-muted); font-size: 0.78rem; margin-bottom: 6px; }
table.perf th, table.perf td {
text-align: left;
padding: 6px 8px;
border-bottom: 1px solid var(--grid);
color: var(--text-secondary);
}
table.perf th { color: var(--text-primary); font-weight: 600; }
table.perf td.num, table.perf th.num { text-align: right; font-variant-numeric: tabular-nums; }
ul.weak { color: var(--text-secondary); padding-left: 20px; }
ul.weak li { margin-bottom: 6px; }
.links { display: flex; flex-wrap: wrap; gap: 10px 24px; margin-top: 8px; }
.links a { font-size: 0.95rem; }
footer {
margin-top: 48px;
padding-top: 16px;
border-top: 1px solid var(--grid);
color: var(--text-muted);
font-size: 0.82rem;
}
</style>
</head>
<body>
<main>
<h1>Engine Sound Classifier</h1>
<p class="tagline">
A fine-tuned <a href="https://github.com/qiuqiangkong/audioset_tagging_cnn" target="_blank" rel="noopener">PANNs CNN14</a>
(pretrained on AudioSet) that classifies short engine-audio clips into one of
34 configurations — cylinder count, layout, and stroke type (e.g. <code>i4</code>,
<code>v8_cross</code>, <code>single_two_stroke</code>, <code>2_rotor</code>).
</p>
<span class="status">Early checkpoint · ~0.33 balanced accuracy · 34 classes</span>
<p>
This is a static, informational Space — it doesn't run the model. It exists
so you can hear a few labeled example clips and see how the model is doing
without needing to spin up compute. To actually run inference, download the
checkpoint from the model repo linked below.
</p>
<h2>Example clips</h2>
<div class="card samples">
<div class="sample-row">
<span class="sample-label"><code>i2_360</code></span>
<audio controls preload="none" src="audio/i2_360.wav"></audio>
</div>
<div class="sample-row">
<span class="sample-label"><code>v2_45</code></span>
<audio controls preload="none" src="audio/v2_45.wav"></audio>
</div>
<div class="sample-row">
<span class="sample-label"><code>single_two_stroke</code></span>
<audio controls preload="none" src="audio/single_two_stroke.wav"></audio>
</div>
</div>
<h2>Performance by run</h2>
<div class="card">
<div class="chart" id="chart">
<div class="bar-row">
<span class="bar-cat">Run A</span>
<div class="bar-track">
<span style="font-size: 0.82rem; color: var(--text-muted);">balanced accuracy not tracked this run (micro 0.380, overfit)</span>
</div>
<span class="bar-value"></span>
</div>
<div class="bar-row">
<span class="bar-cat">Run B</span>
<div class="bar-track">
<div class="bar-fill" style="width: 74.25%"></div>
<div class="tooltip" style="left: 74.25%">0.297 balanced · 0.311 micro</div>
</div>
<span class="bar-value">0.297</span>
</div>
<div class="bar-row">
<span class="bar-cat">Run C</span>
<div class="bar-track">
<div class="bar-fill" style="width: 80.75%"></div>
<div class="tooltip" style="left: 80.75%">0.323 balanced · 0.343 micro</div>
</div>
<span class="bar-value">0.323</span>
</div>
<div class="bar-row">
<span class="bar-cat">Run D</span>
<div class="bar-track">
<div class="bar-fill best" style="width: 82.5%"></div>
<div class="tooltip" style="left: 82.5%">0.330 balanced · 0.376 micro (best)</div>
</div>
<span class="bar-value"><strong>0.330</strong></span>
</div>
<div class="chart-axis">
<span></span>
<div class="ticks">
<i style="left: 0%">0.0</i>
<i style="left: 50%">0.2</i>
<i style="right: 0%">0.4</i>
</div>
<span></span>
</div>
</div>
<table class="perf">
<caption>Recording-level balanced accuracy is the headline metric; random guessing over 34 classes is ~0.03.</caption>
<thead>
<tr><th>Run</th><th>Change</th><th class="num">Balanced acc</th><th class="num">Micro acc</th></tr>
</thead>
<tbody>
<tr><td>A</td><td>baseline (no regularization)</td><td class="num"></td><td class="num">0.380 (overfit)</td></tr>
<tr><td>B</td><td>+ SpecAugment / noise / mixup</td><td class="num">0.297</td><td class="num">0.311 (underfit)</td></tr>
<tr><td>C</td><td>fixed SpecAugment time-mask scale</td><td class="num">0.323</td><td class="num">0.343</td></tr>
<tr><td>D</td><td>+ softened class weights (counts⁻⁰·⁵)</td><td class="num"><strong>0.330</strong></td><td class="num"><strong>0.376</strong></td></tr>
</tbody>
</table>
</div>
<h2>Known weak spots</h2>
<ul class="weak">
<li>Engines with many cylinders (8/12) are confused with close siblings far
more than 1–2 cylinder engines, which have more distinctive, widely-spaced
firing pulses.</li>
<li>A couple of classes (<code>v12</code>, <code>2_rotor</code>) remain
poorly calibrated even after two rounds of fixes.</li>
<li>Cylinder-family accuracy (does it at least get the cylinder count
right) is meaningfully higher than exact-class accuracy — most confusion
is between siblings in the same family, not wild misfires.</li>
</ul>
<h2>Links</h2>
<div class="links">
<a href="https://huggingface.co/joakes90/engine_sound_cassifier" target="_blank" rel="noopener">Model repo (checkpoint + card)</a>
<a href="https://github.com/joakes90/auto_sound_train" target="_blank" rel="noopener">Training code + notebook (GitHub)</a>
<a href="https://github.com/joakes90/auto_sound_train/blob/master/FINDINGS.md" target="_blank" rel="noopener">Full diagnostic write-up</a>
</div>
<footer>
CC BY-SA 4.0. This Space is static — no inference runs here.
</footer>
</main>
</body>
</html>