Claude Code skill for publication-quality scientific visualisations: chart, architecture, flowchart, comparison, pipeline. Bundles matplotlib publication defaults (300 DPI, serif font, colorblind palette), NADEZHDA project palette, Mermaid conventions, and ready-to-use templates. Contents: - SKILL.md — behaviour spec (5 types, generation pipeline) - README.md — human-facing entry: when, install, examples - reference/chart_patterns.md — Pareto/bar/radar/heatmap snippets - templates/architecture_nadezhda.md — Mermaid templates for Teacher-Student / LUPI / fusion Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
172 lines
5.6 KiB
Markdown
172 lines
5.6 KiB
Markdown
# Шаблоны визуализаций для CVGL
|
|
|
|
## 1. Pareto Front: Params vs R@1
|
|
|
|
```python
|
|
import matplotlib.pyplot as plt
|
|
import numpy as np
|
|
|
|
methods = {
|
|
'Sample4Geo': (88.5, 92.65),
|
|
'VimGeo': (50.87, 96.19),
|
|
'QDFL': (5.0, 95.00),
|
|
'MobileGeo': (28.57, 97.15),
|
|
'(MGS)²': (100.0, 97.50),
|
|
'NADEZHDA': (8.5, None), # target
|
|
}
|
|
|
|
fig, ax = plt.subplots(figsize=(8, 5))
|
|
for name, (params, r1) in methods.items():
|
|
if r1 is None:
|
|
ax.scatter(params, 90, marker='*', s=200, c='#ff7f0e', zorder=5)
|
|
ax.annotate(f'{name}\n(target)', (params, 90), fontsize=9, ha='center', va='bottom')
|
|
else:
|
|
ax.scatter(params, r1, s=100, zorder=4)
|
|
ax.annotate(name, (params, r1), fontsize=9, textcoords='offset points', xytext=(5, 5))
|
|
|
|
ax.set_xlabel('Parameters (M)')
|
|
ax.set_ylabel('R@1 (%) on University-1652')
|
|
ax.set_title('Accuracy vs Model Size: CVGL Methods')
|
|
ax.axvspan(0, 10, alpha=0.1, color='green', label='Edge budget (≤10M)')
|
|
ax.legend()
|
|
plt.savefig('pareto_params_r1.png', dpi=300, bbox_inches='tight')
|
|
plt.savefig('pareto_params_r1.pdf', bbox_inches='tight')
|
|
```
|
|
|
|
## 2. Grouped Bar: R@1 Across Datasets
|
|
|
|
```python
|
|
import matplotlib.pyplot as plt
|
|
import numpy as np
|
|
|
|
methods = ['Sample4Geo', 'VimGeo', 'GeoDTR+', 'CAMP', 'CGSI']
|
|
datasets = ['Univ-1652', 'CVUSA', 'CVACT-test']
|
|
data = np.array([
|
|
[92.65, 98.68, 75.0], # Sample4Geo
|
|
[0, 96.19, 81.69], # VimGeo
|
|
[94.67, 95.43, 0], # GeoDTR+
|
|
[94.46, 98.97, 0], # CAMP
|
|
[95.45, 0, 0], # CGSI
|
|
])
|
|
|
|
x = np.arange(len(methods))
|
|
width = 0.25
|
|
fig, ax = plt.subplots(figsize=(10, 5))
|
|
for i, ds in enumerate(datasets):
|
|
mask = data[:, i] > 0
|
|
bars = ax.bar(x[mask] + i * width, data[mask, i], width, label=ds)
|
|
|
|
ax.set_ylabel('R@1 (%)')
|
|
ax.set_xticks(x + width)
|
|
ax.set_xticklabels(methods, rotation=15, ha='right')
|
|
ax.legend()
|
|
ax.set_ylim(70, 102)
|
|
plt.savefig('r1_comparison.png', dpi=300, bbox_inches='tight')
|
|
```
|
|
|
|
## 3. Training Curve with Loss Components
|
|
|
|
```python
|
|
import matplotlib.pyplot as plt
|
|
import numpy as np
|
|
|
|
epochs = np.arange(60)
|
|
# Simulated progressive staging
|
|
l_task = 1.5 * np.exp(-0.03 * epochs) + 0.2
|
|
l_lupi = np.where(epochs < 10, 0, np.where(epochs < 20,
|
|
0.5 * (epochs - 10) / 10, 0.5)) * np.exp(-0.02 * (epochs - 10).clip(0))
|
|
l_feat = np.where(epochs < 10, 0, 0.3 * np.exp(-0.02 * (epochs - 10)))
|
|
l_total = l_task + l_lupi + l_feat
|
|
|
|
fig, ax = plt.subplots(figsize=(8, 4))
|
|
ax.plot(epochs, l_task, label='$L_{task}$ (InfoNCE)', linewidth=2)
|
|
ax.plot(epochs, l_lupi, label='$L_{LUPI}$ (MSE)', linewidth=2, linestyle='--')
|
|
ax.plot(epochs, l_feat, label='$L_{feat}$ (alignment)', linewidth=2, linestyle=':')
|
|
ax.plot(epochs, l_total, label='$L_{total}$', linewidth=2.5, color='black', alpha=0.7)
|
|
|
|
ax.axvspan(0, 10, alpha=0.08, color='blue', label='Warmup')
|
|
ax.axvspan(10, 20, alpha=0.08, color='orange', label='Ramp-up')
|
|
ax.axvspan(20, 60, alpha=0.05, color='green', label='Full')
|
|
|
|
ax.set_xlabel('Epoch')
|
|
ax.set_ylabel('Loss')
|
|
ax.set_title('Progressive Loss Staging (NADEZHDA)')
|
|
ax.legend(ncol=2, fontsize=9)
|
|
plt.savefig('training_curve.png', dpi=300, bbox_inches='tight')
|
|
```
|
|
|
|
## 4. Architecture Block Diagram (matplotlib patches)
|
|
|
|
```python
|
|
import matplotlib.pyplot as plt
|
|
import matplotlib.patches as mpatches
|
|
|
|
fig, ax = plt.subplots(figsize=(14, 6))
|
|
ax.set_xlim(0, 14)
|
|
ax.set_ylim(0, 6)
|
|
ax.axis('off')
|
|
|
|
def add_block(ax, xy, w, h, label, color, sublabel=''):
|
|
box = mpatches.FancyBboxPatch(xy, w, h, boxstyle='round,pad=0.1',
|
|
facecolor=color, edgecolor='black', linewidth=1.5, alpha=0.85)
|
|
ax.add_patch(box)
|
|
ax.text(xy[0] + w/2, xy[1] + h/2, label, ha='center', va='center',
|
|
fontsize=10, fontweight='bold')
|
|
if sublabel:
|
|
ax.text(xy[0] + w/2, xy[1] + 0.15, sublabel, ha='center', va='bottom',
|
|
fontsize=7, color='gray')
|
|
|
|
def add_arrow(ax, start, end, label=''):
|
|
ax.annotate('', xy=end, xytext=start,
|
|
arrowprops=dict(arrowstyle='->', lw=1.5, color='#333'))
|
|
if label:
|
|
mid = ((start[0]+end[0])/2, (start[1]+end[1])/2 + 0.15)
|
|
ax.text(*mid, label, fontsize=7, ha='center', color='#555')
|
|
|
|
# Teacher side
|
|
add_block(ax, (0.5, 4), 2, 1.2, 'DINOv2-L\n(frozen+LoRA)', '#1f77b4', '304M params')
|
|
add_block(ax, (0.5, 2), 2, 1.2, 'Multi-FiLM\nFusion', '#9467bd', 'text→visual modulation')
|
|
add_block(ax, (0.5, 0.3), 2, 1.2, 'Teacher\nDescriptor', '#1f77b4', '512-dim')
|
|
|
|
# Student side
|
|
add_block(ax, (5, 4), 2, 1.2, 'FastViT-T12\n(shared)', '#ff7f0e', '8.5M params')
|
|
add_block(ax, (5, 0.3), 2, 1.2, 'Student\nDescriptor', '#ff7f0e', '512-dim')
|
|
|
|
# Distillation arrows
|
|
add_arrow(ax, (2.5, 0.9), (5, 0.9), '$L_{LUPI}$')
|
|
add_arrow(ax, (2.5, 4.6), (5, 4.6), '$L_{feat}$')
|
|
|
|
ax.set_title('NADEZHDA: Teacher-Student Architecture', fontsize=14, fontweight='bold')
|
|
plt.savefig('nadezhda_architecture.png', dpi=300, bbox_inches='tight')
|
|
```
|
|
|
|
## 5. Mermaid: LUPI Distillation Pipeline
|
|
|
|
````markdown
|
|
```mermaid
|
|
graph LR
|
|
subgraph Teacher ["Teacher (356M, cloud)"]
|
|
S1[Satellite RGB] --> TE[DINOv2-L + LoRA]
|
|
D1[Drone RGB] --> TE
|
|
SV[Street-View] --> TE
|
|
DP[Depth Map] --> TE
|
|
TX[Text Desc.] --> FM[Multi-FiLM]
|
|
FM --> TE
|
|
TE --> TD[Teacher Descriptor 512-dim]
|
|
end
|
|
|
|
subgraph Student ["Student (8.5M, edge)"]
|
|
S2[Satellite RGB] --> SE[FastViT-T12]
|
|
D2[Drone RGB] --> SE
|
|
SE --> SD[Student Descriptor 512-dim]
|
|
end
|
|
|
|
TD -->|L_LUPI: MSE| SD
|
|
TE -->|L_feat: Conv1x1 proj| SE
|
|
TD -->|L_RKD: relational| SD
|
|
|
|
style Teacher fill:#e3f2fd,stroke:#1565c0
|
|
style Student fill:#fff3e0,stroke:#e65100
|
|
```
|
|
````
|