dbv4-full-ranklist / index.html
narugo1992's picture
Squash 'spaces/animetimm/dbv4-full-ranklist/.'
eb47f75 verified
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Model Performance Leaderboard</title>
<style>
* {
margin: 0;
padding: 0;
box-sizing: border-box;
}
body {
font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif;
background: linear-gradient(135deg, #f5f7fa 0%, #c3cfe2 100%);
min-height: 100vh;
padding: 20px;
}
.container {
max-width: 1400px;
margin: 0 auto;
background: white;
border-radius: 12px;
box-shadow: 0 10px 30px rgba(0, 0, 0, 0.1);
overflow: hidden;
}
.header {
background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
color: white;
padding: 30px;
text-align: center;
}
.header h1 {
font-size: 2.5em;
margin-bottom: 15px;
font-weight: 300;
}
.dataset-info {
padding: 15px;
background: rgba(255, 255, 255, 0.1);
border-radius: 8px;
backdrop-filter: blur(10px);
font-size: 1.1em;
display: flex;
justify-content: center;
align-items: center;
flex-wrap: wrap;
gap: 20px;
}
.dataset-link {
color: #ffd700;
text-decoration: none;
font-weight: 500;
border-bottom: 2px solid transparent;
transition: all 0.3s ease;
}
.dataset-link:hover {
border-bottom-color: #ffd700;
}
.info-item {
display: flex;
align-items: center;
gap: 8px;
}
.table-container {
overflow-x: auto;
padding: 30px;
}
table {
width: 100%;
border-collapse: collapse;
background: white;
border-radius: 8px;
overflow: hidden;
box-shadow: 0 4px 6px rgba(0, 0, 0, 0.07);
}
th {
background: linear-gradient(135deg, #4facfe 0%, #00f2fe 100%);
color: white;
padding: 18px 15px;
text-align: center;
font-weight: 600;
font-size: 0.95em;
letter-spacing: 0.5px;
position: relative;
cursor: pointer;
user-select: none;
transition: background 0.3s ease;
}
th:hover {
background: linear-gradient(135deg, #43a3f5 0%, #00e5f5 100%);
}
th.sortable::after {
content: '↕️';
position: absolute;
right: 8px;
font-size: 0.8em;
opacity: 0.7;
}
th.sort-asc::after {
content: '↑';
opacity: 1;
}
th.sort-desc::after {
content: '↓';
opacity: 1;
}
td {
padding: 16px 15px;
border-bottom: 1px solid #e8ecf4;
font-size: 0.9em;
transition: background-color 0.2s ease;
text-align: center;
}
tr:hover {
background-color: #f8faff;
}
tr:nth-child(even) {
background-color: #fafbff;
}
tr:nth-child(even):hover {
background-color: #f0f4ff;
}
.model-link {
color: #667eea;
text-decoration: none;
font-weight: 500;
border-bottom: 2px solid transparent;
transition: all 0.3s ease;
display: inline-block;
}
.model-link:hover {
color: #5a67d8;
border-bottom-color: #5a67d8;
transform: translateY(-1px);
}
.number-cell {
font-family: 'Courier New', monospace;
font-weight: 500;
text-align: center;
}
/* Model Size Categories */
.model-tiny {
background: linear-gradient(90deg, #e8f5e8, #f0fff0);
border-left: 4px solid #4caf50;
}
.model-small {
background: linear-gradient(90deg, #e3f2fd, #f1f8ff);
border-left: 4px solid #2196f3;
}
.model-medium {
background: linear-gradient(90deg, #fff3e0, #fef7f0);
border-left: 4px solid #ff9800;
}
.model-large {
background: linear-gradient(90deg, #f3e5f5, #faf5ff);
border-left: 4px solid #9c27b0;
}
.model-xlarge {
background: linear-gradient(90deg, #ffebee, #fff5f5);
border-left: 4px solid #f44336;
}
.model-xxlarge {
background: linear-gradient(90deg, #fce4ec, #fff0f5);
border-left: 4px solid #e91e63;
}
/* F1 Score Categories */
.f1-score {
color: #2d3748;
font-weight: 600;
padding: 4px 8px;
border-radius: 4px;
}
.legend {
padding: 30px;
background: #f8fafc;
border-top: 1px solid #e2e8f0;
}
.legend h3 {
color: #2d3748;
margin-bottom: 20px;
font-size: 1.2em;
}
.legend-section {
margin-bottom: 25px;
}
.legend-title {
font-weight: 600;
color: #4a5568;
margin-bottom: 10px;
}
.legend-items {
display: flex;
flex-wrap: wrap;
gap: 15px;
}
.legend-item {
display: flex;
align-items: center;
gap: 8px;
padding: 8px 12px;
border-radius: 6px;
background: white;
box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1);
}
.legend-color {
width: 20px;
height: 20px;
border-radius: 3px;
border: 2px solid #e2e8f0;
}
.legend-color.tiny {
background: linear-gradient(90deg, #e8f5e8, #f0fff0);
border-color: #4caf50;
}
.legend-color.small {
background: linear-gradient(90deg, #e3f2fd, #f1f8ff);
border-color: #2196f3;
}
.legend-color.medium {
background: linear-gradient(90deg, #fff3e0, #fef7f0);
border-color: #ff9800;
}
.legend-color.large {
background: linear-gradient(90deg, #f3e5f5, #faf5ff);
border-color: #9c27b0;
}
.legend-color.xlarge {
background: linear-gradient(90deg, #ffebee, #fff5f5);
border-color: #f44336;
}
.legend-color.xxlarge {
background: linear-gradient(90deg, #fce4ec, #fff0f5);
border-color: #e91e63;
}
@media (max-width: 768px) {
.container {
margin: 10px;
border-radius: 8px;
}
.header {
padding: 20px;
}
.header h1 {
font-size: 2em;
}
.dataset-info {
flex-direction: column;
gap: 10px;
}
.table-container {
padding: 15px;
}
th, td {
padding: 12px 8px;
font-size: 0.85em;
}
.legend-items {
flex-direction: column;
}
}
</style>
</head>
<body>
<div class="container">
<div class="header">
<h1>Model Performance Leaderboard</h1>
<div class="dataset-info">
<div class="info-item">
<strong>Dataset:</strong>
<a href="#" id="datasetLink" class="dataset-link" target="_blank"></a>
</div>
<div class="info-item">
<strong>Task:</strong>
<span id="taskTag"></span>
</div>
<div class="info-item">
<strong>Models:</strong>
<span id="totalModels">0</span>
</div>
</div>
</div>
<div class="table-container">
<table id="modelTable">
<thead>
<tr>
<th>Model</th>
<th>Architecture</th>
<th class="sortable" data-column="input_size">Input Size</th>
<th class="sortable" data-column="params">Parameters</th>
<th class="sortable" data-column="flops">FLOPs</th>
<th class="sortable" data-column="macro_f1">Macro F1</th>
<th class="sortable" data-column="micro_f1">Micro F1</th>
</tr>
</thead>
<tbody id="tableBody">
</tbody>
</table>
</div>
<div class="legend" id="legend">
<h3>Legend</h3>
</div>
</div>
<script>
// Configuration - Modify these values
const dataset_repo_id = "animetimm/danbooru-wdtagger-v4-w640-ws-full";
const pretrained_tag = "dbv4-full";
// F1 Score grading criteria - customize these (will be sorted automatically)
const macro_f1_grades = [{"name": "SOTA", "min": 0.55, "max": 1.0}, {"name": "Premium", "min": 0.5, "max": 0.55}, {"name": "Production", "min": 0.45, "max": 0.5}, {"name": "Acceptable", "min": 0.35, "max": 0.45}, {"name": "Limited", "min": 0.25, "max": 0.35}, {"name": "Poor", "min": 0.0, "max": 0.25}];
const micro_f1_grades = [{"name": "Excellent", "min": 0.65, "max": 1.0}, {"name": "Good", "min": 0.55, "max": 0.65}, {"name": "Fair", "min": 0.45, "max": 0.55}, {"name": "Poor", "min": 0.0, "max": 0.45}];
// Model data - All numeric values should be integers
const modelData = [{"hf_repo": "animetimm/mobilenetv3_large_150d.dbv4-full", "architecture": "mobilenetv3_large_150d", "input_size": 384, "params": 29323076, "flops": 4624605304, "macro_f1": 0.39986178278923035, "micro_f1": 0.6051648259162903}, {"hf_repo": "animetimm/swinv2_base_window8_256.dbv4-full", "architecture": "swinv2_base_window8_256", "input_size": 448, "params": 99681716, "flops": 121619540992, "macro_f1": 0.5412678718566895, "micro_f1": 0.6831042170524597}, {"hf_repo": "animetimm/caformer_b36.dbv4-full", "architecture": "caformer_b36", "input_size": 384, "params": 134019362, "flops": 132216862464, "macro_f1": 0.546269953250885, "micro_f1": 0.6886452436447144}, {"hf_repo": "animetimm/caformer_s36.dbv4-full", "architecture": "caformer_s36", "input_size": 384, "params": 62811426, "flops": 44387998208, "macro_f1": 0.5037783980369568, "micro_f1": 0.6700260043144226}, {"hf_repo": "animetimm/mobilenetv3_large_100.dbv4-full.r224", "architecture": "mobilenetv3_large_100", "input_size": 224, "params": 20183788, "flops": 473726488, "macro_f1": 0.22153329849243164, "micro_f1": 0.46757057309150696}, {"hf_repo": "animetimm/mobilenetv4_conv_aa_large.dbv4-full", "architecture": "mobilenetv4_conv_aa_large", "input_size": 448, "params": 47291620, "flops": 19236604672, "macro_f1": 0.4578114449977875, "micro_f1": 0.6412474513053894}, {"hf_repo": "animetimm/mobilenetv3_large_100.dbv4-full", "architecture": "mobilenetv3_large_100", "input_size": 384, "params": 20183788, "flops": 1319630808, "macro_f1": 0.31062445044517517, "micro_f1": 0.5330070853233337}, {"hf_repo": "animetimm/caformer_m36.dbv4-full", "architecture": "caformer_m36", "input_size": 384, "params": 82657058, "flops": 74891684160, "macro_f1": 0.5149331092834473, "micro_f1": 0.6760287284851074}, {"hf_repo": "animetimm/mobilenetv4_conv_small.dbv4-full", "architecture": "mobilenetv4_conv_small", "input_size": 384, "params": 18474780, "flops": 1129638656, "macro_f1": 0.31232455372810364, "micro_f1": 0.5285327434539795}, {"hf_repo": "animetimm/eva02_large_patch14_448.dbv4-full", "architecture": "eva02_large_patch14_448", "input_size": 448, "params": 316843132, "flops": 620893090720, "macro_f1": 0.5694285035133362, "micro_f1": 0.6934136152267456}, {"hf_repo": "animetimm/convnext_base.dbv4-full", "architecture": "convnext_base", "input_size": 448, "params": 100354364, "flops": 123085808640, "macro_f1": 0.5211434960365295, "micro_f1": 0.6690741181373596}, {"hf_repo": "animetimm/vit_base_patch16_224.dbv4-full", "architecture": "vit_base_patch16_224", "input_size": 448, "params": 95842748, "flops": 134226315264, "macro_f1": 0.5003648996353149, "micro_f1": 0.6635887622833252}, {"hf_repo": "animetimm/caformer_s18.dbv4-full", "architecture": "caformer_s18", "input_size": 384, "params": 49855980, "flops": 22908156416, "macro_f1": 0.46389710903167725, "micro_f1": 0.6472342610359192}, {"hf_repo": "animetimm/mobilenetv4_conv_small_050.dbv4-full", "architecture": "mobilenetv4_conv_small_050", "input_size": 384, "params": 16939708, "flops": 412690688, "macro_f1": 0.1943172812461853, "micro_f1": 0.42909061908721924}, {"hf_repo": "animetimm/resnet50.dbv4-full", "architecture": "resnet50", "input_size": 384, "params": 49071356, "flops": 24169668608, "macro_f1": 0.3815140128135681, "micro_f1": 0.5716947913169861}, {"hf_repo": "animetimm/resnet152.dbv4-full", "architecture": "resnet152", "input_size": 384, "params": 83707132, "flops": 67908067328, "macro_f1": 0.44751423597335815, "micro_f1": 0.6240524649620056}, {"hf_repo": "animetimm/resnet101.dbv4-full", "architecture": "resnet101", "input_size": 384, "params": 68063484, "flops": 46033559552, "macro_f1": 0.4368686378002167, "micro_f1": 0.621998131275177}, {"hf_repo": "animetimm/resnet34.dbv4-full", "architecture": "resnet34", "input_size": 384, "params": 27684860, "flops": 21578584064, "macro_f1": 0.29000505805015564, "micro_f1": 0.5299346446990967}, {"hf_repo": "animetimm/resnet18.dbv4-full", "architecture": "resnet18", "input_size": 384, "params": 17576700, "flops": 10695888896, "macro_f1": 0.2587496340274811, "micro_f1": 0.4992590844631195}, {"hf_repo": "animetimm/convnextv2_huge.dbv4-full", "architecture": "convnextv2_huge", "input_size": 512, "params": 692617532, "flops": 1201620803328, "macro_f1": 0.5797423720359802, "micro_f1": 0.6970885992050171}, {"hf_repo": "animetimm/mobilevitv2_200.dbv4-full", "architecture": "mobilevitv2_200", "input_size": 384, "params": 30212229, "flops": 32430201184, "macro_f1": 0.4009774625301361, "micro_f1": 0.6083968877792358}];
let currentSort = {column: 'macro_f1', direction: 'desc'};
let f1Colors = {};
let sortedMacroGrades = [];
let sortedMicroGrades = [];
// Generate colors with green-blue-yellow gradient (high to low performance)
// Avoiding green-like colors in the blue-to-yellow transition
function generateColors(count) {
const colors = [];
if (count === 1) {
colors.push('hsl(120, 60%, 85%)'); // Green for single grade
return colors;
}
for (let i = 0; i < count; i++) {
const ratio = i / (count - 1); // 0 to 1, where 0 is best performance
let hue, saturation, lightness;
if (ratio <= 0.5) {
// Green to Blue transition (high to medium performance)
// 120 (green) to 220 (blue)
hue = 120 + (ratio * 2) * 100;
} else {
// Blue to Yellow transition (medium to low performance)
// Avoid the green zone (90-150 degrees) by going through purple/magenta
const adjustedRatio = (ratio - 0.5) * 2; // 0 to 1 for second half
// Go from 220 (blue) through 280 (purple) to 45 (orange-yellow)
// This avoids the green zone completely
if (adjustedRatio <= 0.6) {
// Blue to purple transition
hue = 220 + adjustedRatio * 100; // 220 to 320
} else {
// Purple to orange-yellow transition (wrapping around)
const finalRatio = (adjustedRatio - 0.6) / 0.4; // 0 to 1
hue = 320 + finalRatio * 85; // 320 to 405, then wrap to 45
if (hue > 360) hue -= 360;
}
}
// Adjust saturation and lightness for better visual distinction
if (ratio <= 0.5) {
// Green to blue: higher saturation for better performance
saturation = 70 + (1 - ratio * 2) * 15; // 70-85%
lightness = 80 + ratio * 2 * 5; // 80-85%
} else {
// Blue to yellow: maintain good contrast
saturation = 65 + ((ratio - 0.5) * 2) * 20; // 65-85%
lightness = 85 + ((ratio - 0.5) * 2) * 5; // 85-90%
}
colors.push(`hsl(${Math.round(hue)}, ${Math.round(saturation)}%, ${Math.round(lightness)}%)`);
}
return colors;
}
// Sort grades by max value (descending - highest performance first)
function sortGrades(grades) {
return [...grades].sort((a, b) => b.max - a.max);
}
// Initialize F1 colors
function initializeF1Colors() {
// Sort grades by performance (highest max value first)
sortedMacroGrades = sortGrades(macro_f1_grades);
sortedMicroGrades = sortGrades(micro_f1_grades);
const macroColors = generateColors(sortedMacroGrades.length);
const microColors = generateColors(sortedMicroGrades.length);
f1Colors.macro = {};
f1Colors.micro = {};
sortedMacroGrades.forEach((grade, index) => {
f1Colors.macro[grade.name] = macroColors[index];
});
sortedMicroGrades.forEach((grade, index) => {
f1Colors.micro[grade.name] = microColors[index];
});
}
function getModelSizeClass(params) {
if (params < 20000000) return 'model-tiny'; // < 20M
if (params < 50000000) return 'model-small'; // 20M - 50M
if (params < 100000000) return 'model-medium'; // 50M - 100M
if (params < 200000000) return 'model-large'; // 100M - 200M
if (params < 1000000000) return 'model-xlarge'; // 200M - 1B
return 'model-xxlarge'; // > 1B
}
function getF1Grade(score, grades) {
for (let grade of grades) {
if (score >= grade.min && score <= grade.max) {
return grade.name;
}
}
return grades[grades.length - 1].name; // Default to last grade
}
function formatParams(params) {
if (params >= 1000000000) {
return (params / 1000000000).toFixed(1) + 'B';
} else if (params >= 1000000) {
return (params / 1000000).toFixed(1) + 'M';
} else if (params >= 1000) {
return (params / 1000).toFixed(1) + 'K';
}
return params.toString();
}
function formatFlops(flops) {
if (flops >= 1000000000000) {
return (flops / 1000000000000).toFixed(1) + 'T';
} else if (flops >= 1000000000) {
return (flops / 1000000000).toFixed(1) + 'G';
} else if (flops >= 1000000) {
return (flops / 1000000).toFixed(1) + 'M';
} else if (flops >= 1000) {
return (flops / 1000).toFixed(1) + 'K';
}
return flops.toString();
}
function formatInputSize(size) {
return `${size}×${size}`;
}
function formatNumber(value) {
if (typeof value === 'number') {
return value.toFixed(3);
}
return value;
}
function parseNumericValue(value) {
return typeof value === 'number' ? value : parseFloat(value) || 0;
}
function renderTable(data) {
const tbody = document.getElementById('tableBody');
tbody.innerHTML = '';
data.forEach(model => {
const row = document.createElement('tr');
const sizeClass = getModelSizeClass(model.params);
row.className = sizeClass;
const macroGrade = getF1Grade(model.macro_f1, macro_f1_grades);
const microGrade = getF1Grade(model.micro_f1, micro_f1_grades);
row.innerHTML = `
<td>
<a href="https://huggingface.co/${model.hf_repo}"
target="_blank"
class="model-link">${model.hf_repo}</a>
</td>
<td>${model.architecture}</td>
<td class="number-cell">${formatInputSize(model.input_size)}</td>
<td class="number-cell">${formatParams(model.params)}</td>
<td class="number-cell">${formatFlops(model.flops)}</td>
<td class="number-cell">
<span class="f1-score" style="background-color: ${f1Colors.macro[macroGrade]}; color: #2d3748;">${formatNumber(model.macro_f1)}</span>
</td>
<td class="number-cell">
<span class="f1-score" style="background-color: ${f1Colors.micro[microGrade]}; color: #2d3748;">${formatNumber(model.micro_f1)}</span>
</td>
`;
tbody.appendChild(row);
});
updateStats(data);
}
function updateStats(data) {
const totalModels = data.length;
document.getElementById('totalModels').textContent = totalModels;
}
function renderLegend() {
const legendContainer = document.getElementById('legend');
legendContainer.innerHTML = '<h3>Legend</h3>';
// Model Size Legend
const modelSizeSection = document.createElement('div');
modelSizeSection.className = 'legend-section';
modelSizeSection.innerHTML = `
<div class="legend-title">Model Size (by Parameters)</div>
<div class="legend-items">
<div class="legend-item">
<div class="legend-color tiny"></div>
<span>Tiny (&lt; 20M)</span>
</div>
<div class="legend-item">
<div class="legend-color small"></div>
<span>Small (20M - 50M)</span>
</div>
<div class="legend-item">
<div class="legend-color medium"></div>
<span>Medium (50M - 100M)</span>
</div>
<div class="legend-item">
<div class="legend-color large"></div>
<span>Large (100M - 200M)</span>
</div>
<div class="legend-item">
<div class="legend-color xlarge"></div>
<span>X-Large (200M - 1B)</span>
</div>
<div class="legend-item">
<div class="legend-color xxlarge"></div>
<span>XX-Large (&gt; 1B)</span>
</div>
</div>
`;
legendContainer.appendChild(modelSizeSection);
// Macro F1 Legend
const macroF1Section = document.createElement('div');
macroF1Section.className = 'legend-section';
macroF1Section.innerHTML = '<div class="legend-title">Macro F1 Performance</div>';
const macroItems = document.createElement('div');
macroItems.className = 'legend-items';
sortedMacroGrades.forEach(grade => {
const item = document.createElement('div');
item.className = 'legend-item';
item.innerHTML = `
<div class="legend-color" style="background-color: ${f1Colors.macro[grade.name]};"></div>
<span>${grade.name} (${grade.min.toFixed(2)} - ${grade.max.toFixed(2)})</span>
`;
macroItems.appendChild(item);
});
macroF1Section.appendChild(macroItems);
legendContainer.appendChild(macroF1Section);
// Micro F1 Legend
const microF1Section = document.createElement('div');
microF1Section.className = 'legend-section';
microF1Section.innerHTML = '<div class="legend-title">Micro F1 Performance</div>';
const microItems = document.createElement('div');
microItems.className = 'legend-items';
sortedMicroGrades.forEach(grade => {
const item = document.createElement('div');
item.className = 'legend-item';
item.innerHTML = `
<div class="legend-color" style="background-color: ${f1Colors.micro[grade.name]};"></div>
<span>${grade.name} (${grade.min.toFixed(2)} - ${grade.max.toFixed(2)})</span>
`;
microItems.appendChild(item);
});
microF1Section.appendChild(microItems);
legendContainer.appendChild(microF1Section);
}
function sortData(column) {
const headers = document.querySelectorAll('th');
// Reset all sort indicators
headers.forEach(th => {
th.classList.remove('sort-asc', 'sort-desc');
});
// Determine sort direction
if (currentSort.column === column) {
currentSort.direction = currentSort.direction === 'asc' ? 'desc' : 'asc';
} else {
currentSort.direction = 'asc';
}
currentSort.column = column;
// Add sort indicator
const currentHeader = document.querySelector(`[data-column="${column}"]`);
if (currentHeader) {
currentHeader.classList.add(currentSort.direction === 'asc' ? 'sort-asc' : 'sort-desc');
}
// Sort data
const sortedData = [...modelData].sort((a, b) => {
let aVal = parseNumericValue(a[column]);
let bVal = parseNumericValue(b[column]);
if (currentSort.direction === 'asc') {
return aVal - bVal;
} else {
return bVal - aVal;
}
});
renderTable(sortedData);
}
// Initialize
document.addEventListener('DOMContentLoaded', function () {
// Initialize colors
initializeF1Colors();
// Set dataset information
document.getElementById('datasetLink').href = `https://huggingface.co/datasets/${dataset_repo_id}`;
document.getElementById('datasetLink').textContent = dataset_repo_id;
document.getElementById('taskTag').textContent = pretrained_tag;
// Initialize with default sort (macro_f1 descending)
if (modelData.length > 0) {
// Set initial sort indicator for macro_f1 column
const macroF1Header = document.querySelector('[data-column="macro_f1"]');
if (macroF1Header) {
macroF1Header.classList.add('sort-desc');
}
// Sort data by macro_f1 descending
const sortedData = [...modelData].sort((a, b) => {
let aVal = parseNumericValue(a.macro_f1);
let bVal = parseNumericValue(b.macro_f1);
return bVal - aVal; // Descending order
});
renderTable(sortedData);
} else {
renderTable(modelData);
}
renderLegend();
// Add sort event listeners
document.querySelectorAll('th.sortable').forEach(th => {
th.addEventListener('click', function () {
const column = this.getAttribute('data-column');
sortData(column);
});
});
});
</script>
</body>
</html>