Skip to content

Commit cbb3090

Browse files
committed
add exhaustive human review gate
1 parent 41c0655 commit cbb3090

25 files changed

Lines changed: 1901 additions & 8 deletions

.github/workflows/ci.yml

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -50,6 +50,11 @@ jobs:
5050
python examples/create_prioritization_fixture.py --output-dir /tmp/ylr-priority-fixture
5151
yolo-label-recovery prioritize /tmp/ylr-priority-fixture/candidates_review.csv /tmp/ylr-priority-fixture/dataset --output-dir /tmp/ylr-priority-output --budget 12 --redact-paths
5252
python -c "import json; d=json.load(open('/tmp/ylr-priority-output/prioritization_summary.json')); assert d['totals']['candidate_rows']==36 and d['totals']['selected_images']==12 and d['totals']['selected_classes']==6 and len({r['candidate_classes'] for r in d['queue'][:6]})==6"
53+
- name: Run exhaustive GT/AUTO review demo
54+
run: |
55+
python examples/create_review_fixture.py --output-dir /tmp/ylr-review-fixture
56+
yolo-label-recovery review-build /tmp/ylr-review-fixture/dataset /tmp/ylr-review-fixture/candidates.csv --output-dir /tmp/ylr-review-output --render --redact-paths
57+
python -c "import json; d=json.load(open('/tmp/ylr-review-output/summary.json')); assert d['review_rows']==4 and d['render_failures']==0 and set(d['image_class_cases'])=={'GT0_AUTO0','GT0_AUTO1','GT1_AUTO0','GT1_AUTO1'}"
5358
- name: Build wheel
5459
run: python -m pip wheel --no-deps --wheel-dir dist .
5560
- name: Reject private artifacts

CHANGELOG.md

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,14 @@
11
# Changelog
22

3+
## 0.9.0
4+
5+
- Added exhaustive `GT0_AUTO0`, `GT1_AUTO0`, `GT0_AUTO1` and `GT1_AUTO1` image/class accounting.
6+
- Added pure-Python IoU, IoS, normalized center-distance and area-ratio decision rules for same-target and cross-class conflicts.
7+
- Added `review-build` for portable visual review bundles, full audit CSVs, decision templates and HTML summaries.
8+
- Added `review-ui`, an offline autosaving Tk reviewer with explicit add, replace, evaluation, reject and uncertain actions.
9+
- Added `review-apply` with unresolved-decision blocking, source-GT drift detection, duplicate rechecks and immutable derived datasets.
10+
- Added a packaged default six-class policy, public no-GPU fixture, static preview, bilingual documentation, ADR and CI coverage.
11+
312
## 0.8.0
413

514
- Added the CPU-only, read-only `prioritize` command for image-level active human-review queues.

README.md

Lines changed: 32 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -59,6 +59,12 @@ The public fixture groups resize, JPEG recompression and brightness variants wit
5959

6060
The public fixture contains `36` imbalanced REVIEW images. A budget of `12` covers all `6` classes, with one class represented in each of the first six positions. Dynamic rarity prevents small classes from being ignored while perceptual diversity suppresses repeated frames.
6161

62+
### Exhaustive GT/AUTO human-review gate
63+
64+
![Pre-generated same-target ambiguity review](docs/assets/review-gate-preview.jpg)
65+
66+
The no-GPU fixture enumerates all four image/class states (`GT0_AUTO0`, `GT1_AUTO0`, `GT0_AUTO1`, `GT1_AUTO1`). It combines IoU, intersection-over-smaller-area, normalized center distance and area ratio to distinguish already-labelled objects, same-target extent disagreement, distinct missing objects and cross-class conflicts. High confidence remains evidence, not permission to write a label.
67+
6268
## Why this project exists
6369

6470
Multi-class datasets often contain combined scenes such as `person + helmet + smoking` or `person + slipper`. If the original annotation process focused on one target at a time, valid objects from other classes can be missing. Training a new multi-class model on incomplete labels can make the model learn the wrong supervision signal.
@@ -78,11 +84,14 @@ flowchart TD
7884
G --> I["REVIEW + audit CSV"]
7985
G --> J["AUTO candidate"]
8086
J --> M{"Optional verifier agreement"}
81-
M -->|"supported"| K["Derived label tree"]
87+
M -->|"supported evidence"| R["Exhaustive GT/AUTO review gate"]
8288
M -->|"unsupported"| I
89+
I --> R
90+
R -->|"explicit human decision"| K["Immutable derived label tree"]
8391
K --> N["Trainable YOLO dataset"]
8492
I --> L["HTML report and class-wise samples"]
8593
J --> L
94+
R --> L
8695
```
8796

8897
## Main properties
@@ -100,6 +109,9 @@ flowchart TD
100109
- Independent Teacher candidate streams can gate AUTO decisions with one-to-one spatial agreement without loading two models together.
101110
- Perceptual hashes, a BK-tree and conservative visual guards group repeated review work and expose near-duplicate split leakage.
102111
- Image-level active review combines confidence entropy, dynamically decayed class rarity and greedy perceptual diversity.
112+
- Exhaustive GT/AUTO accounting prevents candidate-only reports from hiding absence cases.
113+
- Offline review requires explicit add, replace, evaluation or reject decisions and autosaves progress.
114+
- Safe apply blocks unresolved decisions, detects source-GT drift, rechecks duplicates and creates an immutable derived dataset.
103115
- Every scan records a local manifest with parameters, image inventory, package versions, CUDA and GPU metadata.
104116

105117
## One-minute public demo
@@ -175,6 +187,23 @@ yolo-label-recovery prioritize D:\runs\candidates_review.csv D:\data\mining-safe
175187
--redact-paths
176188
```
177189

190+
Build an exhaustive offline review bundle from Teacher candidate evidence:
191+
192+
```powershell
193+
python examples\create_review_fixture.py --output-dir .demo-review-fixture
194+
yolo-label-recovery review-build .demo-review-fixture\dataset .demo-review-fixture\candidates.csv `
195+
--output-dir .demo-review-result `
196+
--render `
197+
--redact-paths
198+
```
199+
200+
After every row has an explicit human decision, create a separate reviewed dataset:
201+
202+
```powershell
203+
yolo-label-recovery review-apply D:\data\mining-safety D:\runs\company-review\company_decisions.csv `
204+
--output-root D:\data\mining-safety-reviewed
205+
```
206+
178207
For GPU-assisted label recovery, first install the CUDA-compatible PyTorch build required by the target GPU, then install the inference extra:
179208

180209
```powershell
@@ -295,6 +324,8 @@ See:
295324
- [Perceptual near-duplicate grouping (Simplified Chinese)](docs/NEAR_DUPLICATES.zh-CN.md)
296325
- [Active review prioritization](docs/ACTIVE_REVIEW.md)
297326
- [Active review prioritization (Simplified Chinese)](docs/ACTIVE_REVIEW.zh-CN.md)
327+
- [Exhaustive GT/AUTO human review](docs/HUMAN_REVIEW.md)
328+
- [Exhaustive GT/AUTO human review (Simplified Chinese)](docs/HUMAN_REVIEW.zh-CN.md)
298329
- [Interview presentation](docs/INTERVIEW_STORY.md)
299330
- [Portfolio and interview guide](docs/PORTFOLIO_GUIDE.md)
300331
- [Portfolio and interview guide (Simplified Chinese)](docs/PORTFOLIO_GUIDE.zh-CN.md)

README.zh-CN.md

Lines changed: 32 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -59,6 +59,12 @@
5959

6060
公开样例包含 `36` 张类别不均衡的 REVIEW 图片。预算为 `12` 时覆盖全部 `6` 类,前六个位置每类各占一个。动态稀缺度避免小类被忽略,感知多样性则抑制重复连续帧。
6161

62+
### GT/AUTO 全情况人工审核门控
63+
64+
![预生成同目标框尺度冲突审核图](docs/assets/review-gate-preview.jpg)
65+
66+
无 GPU 合成样例枚举 `GT0_AUTO0``GT1_AUTO0``GT0_AUTO1``GT1_AUTO1` 四种图片/类别状态,并联合 IoU、IoS、归一化中心距离和面积倍率,区分已标注目标、同目标框尺度不一致、不同漏标目标和跨类别冲突。高置信度仍然只是证据,不代表拥有写标签的权限。
67+
6268
## 为什么需要这个项目
6369

6470
多类别数据集经常包含 `person + helmet + smoking``person + slipper` 等联合场景。如果原始标注工作每次只关注一个目标,图中其他类别的有效目标就可能漏标。使用不完整标签训练多类别模型时,这些目标会被当作背景,从而向模型传递错误监督信号。
@@ -78,11 +84,14 @@ flowchart TD
7884
G --> I["REVIEW + 审计 CSV"]
7985
G --> J["AUTO 候选"]
8086
J --> M{"可选验证 Teacher 一致性"}
81-
M -->|"获得支持"| K["派生标签目录"]
87+
M -->|"形成支持证据"| R["GT/AUTO 全情况人工门控"]
8288
M -->|"未获支持"| I
89+
I --> R
90+
R -->|"明确人工决策"| K["不可变派生标签目录"]
8391
K --> N["可训练 YOLO 数据集"]
8492
I --> L["HTML 报告与分类抽样图"]
8593
J --> L
94+
R --> L
8695
```
8796

8897
## 核心特性
@@ -100,6 +109,9 @@ flowchart TD
100109
- 使用独立 Teacher 候选流进行一对一空间一致性门控,无需同时加载两个模型。
101110
- 使用感知哈希、BK-tree 和保守视觉约束压缩重复审核工作,并发现跨划分近重复泄漏。
102111
- 图片级主动审核联合置信度熵、动态衰减类别稀缺度和贪心感知多样性。
112+
- 完整 GT/AUTO 枚举避免只看候选框的报告遗漏无预测状态。
113+
- 离线审核要求明确选择新增、替换、评测标签或拒绝,并自动保存审核进度。
114+
- 安全写回会阻止未完成决策、检测源 GT 漂移、再次查重,并创建不可变的派生数据集。
103115
- 每次扫描生成 manifest,记录参数、图片清单、依赖版本、CUDA 和 GPU 信息。
104116

105117
## 一分钟公开演示
@@ -175,6 +187,23 @@ yolo-label-recovery prioritize D:\runs\candidates_review.csv D:\data\mining-safe
175187
--redact-paths
176188
```
177189

190+
根据 Teacher 候选证据生成完整离线审核包:
191+
192+
```powershell
193+
python examples\create_review_fixture.py --output-dir .demo-review-fixture
194+
yolo-label-recovery review-build .demo-review-fixture\dataset .demo-review-fixture\candidates.csv `
195+
--output-dir .demo-review-result `
196+
--render `
197+
--redact-paths
198+
```
199+
200+
全部候选完成人工决策后,创建一个独立的审核后数据集:
201+
202+
```powershell
203+
yolo-label-recovery review-apply D:\data\mining-safety D:\runs\company-review\company_decisions.csv `
204+
--output-root D:\data\mining-safety-reviewed
205+
```
206+
178207
如需使用 GPU 自动补标,请先安装与目标 GPU/CUDA 兼容的 PyTorch,再安装推理依赖:
179208

180209
```powershell
@@ -295,6 +324,8 @@ out-root/
295324
- [感知近重复聚类(英文)](docs/NEAR_DUPLICATES.md)
296325
- [主动审核优先级(中文)](docs/ACTIVE_REVIEW.zh-CN.md)
297326
- [主动审核优先级(英文)](docs/ACTIVE_REVIEW.md)
327+
- [GT/AUTO 全情况人工审核(中文)](docs/HUMAN_REVIEW.zh-CN.md)
328+
- [GT/AUTO 全情况人工审核(英文)](docs/HUMAN_REVIEW.md)
298329
- [面试项目讲解](docs/INTERVIEW_STORY.md)
299330
- [作品集与面试指南(中文)](docs/PORTFOLIO_GUIDE.zh-CN.md)
300331
- [作品集与面试指南(英文)](docs/PORTFOLIO_GUIDE.md)

configs/review_policy.example.yaml

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
version: 2
2+
classes:
3+
person: {high_conf: 0.85, review_conf: 0.60}
4+
helmet: {high_conf: 0.80, review_conf: 0.55}
5+
vest: {high_conf: 0.80, review_conf: 0.55}
6+
tractor: {high_conf: 0.85, review_conf: 0.60}
7+
slipper: {high_conf: 0.75, review_conf: 0.45}
8+
smoking: {high_conf: 0.80, review_conf: 0.40}
9+
10+
geometry:
11+
existing_high_iou: 0.60
12+
existing_high_ios: 0.90
13+
existing_high_center_distance: 0.35
14+
existing_ambiguous_iou: 0.20
15+
existing_ambiguous_ios: 0.55
16+
existing_ambiguous_center_distance: 0.80
17+
candidate_duplicate_iou: 0.90
18+
cross_class_conflict_iou: 0.65
19+
cross_class_conflict_area_ratio: 2.00
20+
21+
split_policy:
22+
train: review_and_apply
23+
val: review_gold_only
24+
test: review_gold_only

docs/ARCHITECTURE.md

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,8 @@ The tool addresses incomplete labels in multi-class YOLO datasets. A single mult
1919
10. Flush audit files and atomically advance `state.json` after the batch commit.
2020
11. Release results, model, label cache and CUDA cache before the next class.
2121
12. Generate `report.html` from the summary, CSV audit trail and bounded sample images.
22+
13. Optionally build an exhaustive GT/AUTO review bundle from the candidate evidence.
23+
14. Apply only explicit human decisions to a new dataset after duplicate and source-GT drift checks.
2224

2325
Each recovery run also writes `manifest.json` at startup. It captures the immutable run signature, arguments, image/model inventory, package versions, CUDA details and GPU properties. A completed run adds result totals and per-class statistics. If the process crashes, the manifest remains in `running` state and `state.json` identifies the last committed batch.
2426

@@ -63,6 +65,12 @@ flowchart LR
6365

6466
The calibration sample is evidence for the routing policy, not a replacement for an independent model test set. A policy should be recalibrated when the Teacher model, target camera domain, operating conditions or annotation rules change.
6567

68+
## Human authority boundary
69+
70+
The 0.9 review workflow separates evidence generation from label-writing authority. `review-build` is read-only and classifies every candidate using same-class and cross-class geometry. `review-ui` records explicit human decisions. `review-apply` is the only stage allowed to create a reviewed dataset, and it never targets the source tree.
71+
72+
Same-target ambiguity cannot be accepted as a second box: it requires an explicit replacement decision tied to the reviewed GT line and coordinates. If that GT changes between review and apply, the replacement is rejected. Val/test decisions remain held by default so dataset remediation cannot silently move the evaluation goalposts.
73+
6674
## Active review acquisition
6775

6876
The optional `prioritize` stage consumes candidate CSV evidence after scanning. It groups boxes by image, resolves each image inside the dataset boundary and ranks a fixed review budget using confidence entropy, dynamically decayed class rarity and minimum perceptual distance to the already selected set.

docs/HUMAN_REVIEW.md

Lines changed: 119 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,119 @@
1+
# Exhaustive GT/AUTO human-review gate
2+
3+
[English](HUMAN_REVIEW.md) | [简体中文](HUMAN_REVIEW.zh-CN.md)
4+
5+
## Motivation
6+
7+
A Teacher prediction is evidence, not ground truth. Confidence alone cannot safely decide whether a box is a missing object, a duplicate of an existing annotation, a differently sized box for the same target, or a conflict with another class. The review gate makes those cases explicit before any derived label dataset is created.
8+
9+
## Complete image/class state space
10+
11+
Every image and class belongs to exactly one state:
12+
13+
| State | Existing GT | Teacher evidence | Default handling |
14+
|---|---:|---:|---|
15+
| `GT0_AUTO0` | No | No | No action; retained for coverage accounting |
16+
| `GT1_AUTO0` | Yes | No | Keep the existing GT |
17+
| `GT0_AUTO1` | No | Yes | Evaluate confidence, geometry and split policy |
18+
| `GT1_AUTO1` | Yes | Yes | Resolve already-labelled, same-target ambiguity or distinct targets |
19+
20+
The matrix is generated for every image/class pair, not only for images containing candidates. This prevents a report from silently ignoring absence cases.
21+
22+
## Complementary geometry
23+
24+
For candidate box $A$ and target box $B$, intersection-over-union is:
25+
26+
$$
27+
\operatorname{IoU}(A,B)=\frac{|A\cap B|}{|A\cup B|}
28+
$$
29+
30+
IoU becomes small when one valid box is contained in a much larger box. Intersection-over-smaller-area therefore provides a second signal:
31+
32+
$$
33+
\operatorname{IoS}(A,B)=\frac{|A\cap B|}{\min(|A|,|B|)}
34+
$$
35+
36+
The normalized center distance is:
37+
38+
$$
39+
d_c(A,B)=\frac{\sqrt{(c_x^A-c_x^B)^2+(c_y^A-c_y^B)^2}}{\sqrt{\min(|A|,|B|)}}
40+
$$
41+
42+
The area ratio is:
43+
44+
$$
45+
r_a(A,B)=\frac{\max(|A|,|B|)}{\min(|A|,|B|)}
46+
$$
47+
48+
The default policy uses these signals as follows:
49+
50+
- Already labelled: `IoU >= 0.60`, or `IoS >= 0.90` with normalized center distance `<= 0.35`.
51+
- Same target, ambiguous extent: `IoU >= 0.20`, or `IoS >= 0.55` with normalized center distance `<= 0.80`.
52+
- Near-duplicate Teacher candidates: same-class candidate IoU `>= 0.90`; only the higher-confidence candidate survives.
53+
- Cross-class conflict: cross-class IoU `>= 0.65` and area ratio `<= 2.0`; route to a human instead of deleting a potentially valid nested small object.
54+
55+
## Candidate terminal states
56+
57+
Each Teacher candidate receives one terminal state:
58+
59+
| Terminal state | Human review | Allowed result |
60+
|---|---:|---|
61+
| `INVALID` | No | Reject |
62+
| `MODEL_DUPLICATE` | No | Reject lower-confidence duplicate |
63+
| `GT_ALREADY_LABELED` | No | Keep GT, do not add another box |
64+
| `GT_SAME_AMBIGUOUS` | Yes | Explicitly replace the matched GT or reject |
65+
| `GT_CROSS_CLASS_CONFLICT` | Yes | Add as a distinct class or reject |
66+
| `TRAIN_MISSING_HIGH/MEDIUM` | Yes | Add or reject |
67+
| `EVAL_MISSING_HIGH/MEDIUM` | Yes | Accept as gold-evaluation evidence or reject |
68+
| `BELOW_REVIEW_THRESHOLD` | No by default | Preserve in the audit table; optionally include in review |
69+
| `SPLIT_DISABLED` | No | Reject |
70+
71+
High confidence does not bypass the human gate. The policy separates evidence strength from permission to change labels.
72+
73+
## Offline review bundle
74+
75+
```powershell
76+
yolo-label-recovery review-build D:\data\dataset D:\runs\candidates_all.csv `
77+
--policy configs\review_policy.example.yaml `
78+
--output-dir D:\runs\company-review `
79+
--render `
80+
--redact-paths
81+
```
82+
83+
The output contains the complete audit table, review queue, decision template, rendered candidates, matrix coverage, an HTML summary and an offline Tk reviewer. The reviewer autosaves `company_decisions.csv` and resumes from the first unfinished row.
84+
85+
Review keys:
86+
87+
- `A`: accept a distinct missing box.
88+
- `P`: replace the highlighted same-class GT.
89+
- `E`: accept a val/test gold-label candidate.
90+
- `D`: reject.
91+
- `U`: temporarily uncertain; must be resolved before apply.
92+
93+
## Safe apply
94+
95+
```powershell
96+
yolo-label-recovery review-apply D:\data\dataset D:\runs\company-review\company_decisions.csv `
97+
--policy configs\review_policy.example.yaml `
98+
--output-root D:\data\dataset-reviewed
99+
```
100+
101+
The apply stage enforces the following invariants:
102+
103+
- Blank and uncertain decisions block the entire operation.
104+
- The output cannot equal, contain or be a parent of the source dataset.
105+
- Source images and labels are never modified.
106+
- Replace is valid only for `GT_SAME_AMBIGUOUS` and only if the referenced GT has not changed since review.
107+
- Accepted additions are checked again against the latest derived labels before writing.
108+
- Val/test decisions are held by default to avoid silently changing the evaluation contract.
109+
- Every applied, replaced, held and rejected row remains auditable.
110+
111+
## Public demo
112+
113+
```powershell
114+
python examples\create_review_fixture.py --output-dir .demo-review-fixture
115+
yolo-label-recovery review-build .demo-review-fixture\dataset .demo-review-fixture\candidates.csv `
116+
--output-dir .demo-review-result --render --redact-paths
117+
```
118+
119+
The fixture intentionally covers all four image/class states and the main candidate terminal decisions without requiring a GPU, private image or model weight.

0 commit comments

Comments
 (0)