Files
ModelTrainEval/figures/clustering-pipeline.mmd
T
Shaun ZhouandClaude Opus 5 5d395b7c25 chore: 数据迁到 data/raw/ 后同步所有路径引用
原始数据从 data/<数据集> 移到了 data/raw/<数据集>。

- 聚类配置的 dataset.root:film / pearlescent 均改为 data/raw/ 下
- 检测配置的 img_dir 与 label_dir 注释同步
- README、data/README、算法文档、流程图(含重新渲染的 PNG)与各脚本
  docstring 里的路径示例一并更新
- data/README 补充目录约定:原始数据只读放 data/raw/,
  export_clusters.py 的派生数据集放在 data/ 下与 raw/ 平级
- 顺手把 unlabeled 数据集加进 datasets/__init__.py:此前它没在包初始化时注册,
  build_dataset({"name": "unlabeled"}) 只有在别处先 import 过该模块时才可用

迁移后重跑全量聚类,结果与迁移前逐项一致(轮廓 0.3255、稳定性 0.9641、
簇大小 [4507, 3795, 4849, 1428])。

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-09-07 11:19:42 +08:00

74 lines
3.2 KiB
Plaintext
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
flowchart TB
classDef input fill:#D1FAE5,stroke:#10B981,stroke-width:2px,color:#064E3B
classDef prep fill:#DBEAFE,stroke:#2563EB,stroke-width:2px,color:#1E3A8A
classDef feat fill:#DBEAFE,stroke:#2563EB,stroke-width:2px,color:#1E3A8A
classDef reduce fill:#EDE9FE,stroke:#7C3AED,stroke-width:2px,color:#4C1D95
classDef cluster fill:#EDE9FE,stroke:#7C3AED,stroke-width:2px,color:#4C1D95
classDef out fill:#FFEDD5,stroke:#EA580C,stroke-width:2px,color:#7C2D12
classDef metric fill:#FEF3C7,stroke:#D97706,stroke-width:2px,color:#78350F
scan["data/raw/film 递归扫描<br/>N = 14,579 张 PNG<br/>尺寸各异 84×83 ~ 4464×1139"]:::input
subgraph PRE["① 预处理 — 抹掉采集因子"]
direction LR
resize["双线性拉伸<br/>H×W → 128×128<br/>不保长宽比"]:::prep
tensor["转张量 + RGBA/L → RGB<br/>x ∈ ℝ³ˣ¹²⁸ˣ¹²⁸"]:::prep
zscore["逐图标准化<br/>x̃ = (x − μₓ) / σₓ<br/>抹掉亮度 μ 与对比度 σ"]:::prep
resize --> tensor --> zscore
end
subgraph FEAT["② 特征提取 — 纹理优先"]
direction LR
stem["resnet18 stem<br/>conv1 → bn → relu → maxpool"]:::feat
l1["layer1<br/>64ch, stride 4"]:::feat
l2["layer2<br/>128ch, stride 8"]:::feat
l3["layer3<br/>256ch, stride 16"]:::feat
gap2["GAP → ℓ₂ 归一化<br/>u⁽²⁾ ∈ S¹²⁷"]:::feat
gap3["GAP → ℓ₂ 归一化<br/>u⁽³⁾ ∈ S²⁵⁵"]:::feat
concat["拼接<br/>z = [u⁽²⁾; u⁽³⁾] ∈ ℝ³⁸⁴"]:::feat
stem --> l1 --> l2 --> l3
l2 --> gap2 --> concat
l3 --> gap3 --> concat
end
subgraph RED["③ 降维"]
direction LR
norm["ℓ₂ 归一化<br/>ẑ = z / ‖z‖₂"]:::reduce
pca["PCA 投影 384 → 32<br/>y = Uᵀ(ẑ − z̄)<br/>不白化:保留 λ 谱"]:::reduce
norm --> pca
end
subgraph CLU["④ 聚类 K-Means"]
direction LR
init["k-means++ 初始化<br/>p(xᵢ) ∝ D(xᵢ)²"]:::cluster
lloyd["Lloyd 迭代<br/>指派 ↔ 更新质心"]:::cluster
best["n_init = 10<br/>取 inertia 最小的一次"]:::cluster
assign["全量指派<br/>cᵢ = argminⱼ ‖yᵢ − μⱼ‖₂"]:::cluster
init --> lloyd --> best --> assign
end
subgraph EVAL["⑤ 无标签评估"]
direction LR
sil["轮廓系数 s̄<br/>簇是否紧致"]:::metric
stab["换种子稳定性<br/>NMI(C_seed0, C_seed7)"]:::metric
end
subgraph OUT["⑥ 产出"]
direction LR
csv["assignments.csv<br/>路径 / 簇号 / 距质心"]:::out
links["clusters/cluster_XX/<br/>软链目录,按距质心排序"]:::out
prev["cluster_XX_preview.png<br/>代表样本拼图"]:::out
summ["summary.json<br/>簇大小 / 轮廓 / 稳定性"]:::out
end
simclr["可选:SimCLR 自监督<br/>method = simclr<br/>cuda / mps 均可"]:::feat
scan --> PRE
PRE -->|"x̃ᵢ"| FEAT
scan -.->|"双视图增强"| simclr
simclr -.->|"域内骨架权重"| FEAT
FEAT -->|"z ∈ ℝᴺˣ³⁸⁴"| RED
RED -->|"y ∈ ℝᴺˣ³²"| CLU
CLU -->|"标签 c"| EVAL
CLU -->|"标签 c + 距离 d"| OUT