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>
This commit is contained in:
Shaun Zhou
2026-09-07 11:19:42 +08:00
co-authored by Claude Opus 5
parent 5f31ed0a92
commit 5d395b7c25
15 changed files with 56 additions and 46 deletions
+4 -4
View File
@@ -1,7 +1,7 @@
# 未分类样本的无监督聚类:算法与数学说明
本文档说明 `scripts/cluster_unlabeled.py` 背后的完整算法:每一步在做什么数学变换、
为什么这样选、以及在 `data/film` 上的实测依据。
为什么这样选、以及在 `data/raw/film` 上的实测依据。
代码入口:[`scripts/cluster_unlabeled.py`](../scripts/cluster_unlabeled.py)、
[`engine/cluster.py`](../engine/cluster.py)、[`engine/simclr.py`](../engine/simclr.py)、
@@ -28,7 +28,7 @@
## 1. 问题设定与记号
给定一组**无标注**图像 $\mathcal{I} = \{I_1, \dots, I_N\}$(`data/film` 下递归扫描到
给定一组**无标注**图像 $\mathcal{I} = \{I_1, \dots, I_N\}$(`data/raw/film` 下递归扫描到
$N = 14{,}579$ 张 PNG),在没有任何类别标签的前提下,把它们划分成 $k$ 个互不相交的簇
$$
@@ -76,7 +76,7 @@ flowchart TB
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
scan["data/raw/film 递归扫描<br/>N = 14,579 张 PNG<br/>尺寸各异 84×83 ~ 4464×1139"]:::input
subgraph PRE["① 预处理 — 抹掉采集因子"]
direction LR
@@ -487,7 +487,7 @@ $$
**为什么这个指标关键**:数据里真有 $k$ 团结构时,不同初始化会收敛到同一套划分,NMI ≈ 1;若是在硬切一团连续的数据,边界位置随初值乱跳,NMI 会很低。它比轮廓系数更能识破"强行分 $k$ 类"的情形。实测中它一眼揪出了白化的问题(稳定性 0.01)。
> **不使用外部标签。** `data/film` 下的目录名(`grease`、`wrinkle`、`反面纵黑点`……)
> **不使用外部标签。** `data/raw/film` 下的目录名(`grease`、`wrinkle`、`反面纵黑点`……)
> 是人工整理的历史产物,既不完整也未必正确,因此既不参与聚类、也不用于评估。
---