- 新增 §10.5:SimCLR vs ImageNet 预训练在 14,579 张上的同设置对比。 只训 1 个 epoch 的域内特征在 k=4 上即追平(轮廓 0.334 vs 0.325), 在 k=2 上大幅胜出(轮廓 0.469、稳定性 0.991)——目视确认该二分正是 "有明显缺陷 / 弱纹理近空白",可直接作为流水线的第一级过滤 - 复杂度表补 MPS 实测:特征提取 84s(CPU) -> 51s(MPS),SimCLR 约 65s/epoch - README 增加"计算后端"小节(三后端的 AMP 默认值、显存统计与限制) - 流程图与对照表同步去掉已移除的 GPU 守卫 Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
81 lines
3.5 KiB
Markdown
81 lines
3.5 KiB
Markdown
# 无监督聚类流水线
|
||
|
||
从 `data/film` 的原始图片到可人工核对的分组结果:六个阶段的数据流、张量形状与每步的数学操作。
|
||
虚线是可选的 SimCLR 自监督分支(`method: simclr`,CUDA 与 Apple MPS 均可)。
|
||
|
||
```mermaid
|
||
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/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
|
||
```
|