| --- |
| license: other |
| library_name: onnx |
| pipeline_tag: image-classification |
| tags: |
| - industrial |
| - defect-detection |
| - optical-filter |
| - quality-inspection |
| - onnx |
| --- |
| |
| # 滤光片外观质检 · 开箱即用推理包 |
|
|
| 暗场成像的 IR-CUT 滤光片裁片,判**良品 / 不良**,可选输出缺陷类型(划痕 / 麻点 / 崩边)。 |
|
|
| 推理端**不需要 PyTorch、不需要 timm、不需要 GPU**,只要 4 个 pip 包。 |
|
|
| --- |
|
|
| ## 📚 完整文档 |
|
|
| | 文件 | 内容 | |
| |---|---| |
| | [`docs/INDEX.md`](docs/INDEX.md) | **项目总索引**:四个仓库怎么选、三个核心结论、数据一览 | |
| | [`docs/REPRODUCE.md`](docs/REPRODUCE.md) | **完整复现指南**:环境、数据准备、逐个实验的命令与预期数字 | |
| | [`docs/FILES.md`](docs/FILES.md) | **逐文件使用说明**:41 个脚本、结果表字段、51 个训练产物目录 | |
| | [`docs/RESULTS.md`](docs/RESULTS.md) | **全部实验结果**:42 个模型完整榜单、分割 vs 分类同口径对决 | |
| | [`docs/AUDIT.md`](docs/AUDIT.md) | **诚实性审计**:四道审计的原理与结果,为什么这次的高分是真的 | |
| | [`docs/CAVEATS.md`](docs/CAVEATS.md) | ⚠ **已知问题与边界**,上线前必读(含我犯过的评估口径错误) | |
| | [`docs/REPOS.md`](docs/REPOS.md) | 四个仓库逐一说明与下载方式 | |
|
|
| --- |
|
|
| --- |
|
|
| ## 三种用法,任选 |
|
|
| ### A. 零安装 —— 单个可执行文件(推荐) |
|
|
| 目标机上**不需要 Python、不需要装任何东西**,下载一个文件就能跑。模型已打进二进制。 |
|
|
| ```bash |
| # CPU 版(145 MB,任何 x86_64 Linux 都能跑) |
| chmod +x binaries/filter-predict-cpu |
| ./binaries/filter-predict-cpu -i 图片目录/ -o result.xlsx |
| |
| # GPU 版(1.3 GB,自动用 CUDA;需要 NVIDIA 驱动 ≥ CUDA 12.x) |
| chmod +x binaries/filter-predict-gpu |
| ./binaries/filter-predict-gpu -i 图片目录/ -o result.xlsx |
| ``` |
|
|
| 实测速度:CPU **22 张/秒**,GPU(RTX 4090)**3608 张/秒**。 |
|
|
| ### B. Python 脚本(想改代码时用) |
|
|
| ```bash |
| pip install -r requirements.txt # onnxruntime numpy pillow openpyxl |
| python predict.py -i sample_images/ -o result.xlsx |
| ``` |
|
|
| ### C. 只要 ONNX,自己接 |
|
|
| `filter_binary.onnx` 输入 `float32[N,3,320,320]`,输出 `logits[N,2]`。 |
| 预处理必须与 `predict.py:preprocess()` 一致(等比缩放补零 → 灰世界白平衡 → 逐图 z-score),否则结果不可信。 |
|
|
| ### 单张图 |
| ```bash |
| python predict.py -i /path/to/filter_0001.png |
| ``` |
| ``` |
| 文件 : filter_0001.png |
| 判定 : 良品 |
| 不良概率: 0.0060 |
| ``` |
|
|
| ### 整个目录 → xlsx(递归扫描子目录) |
| ```bash |
| python predict.py -i /path/to/images/ -o result.xlsx |
| ``` |
| 输出表格:`图片名 | 判定 | 不良概率 | 相对路径` |
|
|
| ### 附带缺陷类型 |
| ```bash |
| python predict.py -i images/ -o result.xlsx --with-type |
| ``` |
| 多两列:`缺陷类型 | 类型置信度`(只对判为不良的填) |
|
|
| ### 不想装 openpyxl |
| 输出写 `.csv` 即可(UTF-8 BOM,Excel 直接双击能开): |
| ```bash |
| python predict.py -i images/ -o result.csv |
| ``` |
|
|
| --- |
|
|
| ## 调判废松紧 |
|
|
| **只有一个参数可调:`--threshold`(不良概率的判废线)。** |
| 调高 → 判不良的更少,不良桶更纯,但漏检多。调低 → 抓得全,但误杀更多良品。 |
|
|
| 标定表(阈值在 val 集上定,test 锁箱只评一次;「产线 10%」是按产线不良率 10% 换算的): |
|
|
| | 档位 | 阈值 | test 误报 | test 检出 | 不良桶混入良品 | 产线10%口径 | 每万片冤杀 | 每万片漏检 | |
| |---|---|---|---|---|---|---|---| |
| | 最严 | `0.787` | 4/185 | 95.5% | **1.83%** | 16.9% | 195 | 45 | |
| | 保守 | `0.509` | 8/185 | 98.7% | 3.49% | 28.3% | 389 | 13 | |
| | **平衡(默认)** | `0.459` | 8/185 | **99.1%** | 3.48% | 28.2% | 389 | 9 | |
| | 宽松 | `0.411` | 9/185 | 99.1% | 3.90% | 30.6% | 438 | 9 | |
| | 高召回 | `0.242` | 11/185 | 99.6% | 4.70% | 35.0% | 535 | 4 | |
|
|
| ```bash |
| python predict.py -i images/ -o r.xlsx --threshold 0.787 # 最严 |
| ``` |
|
|
| > **注意**:分数分布是双峰的,0.51~0.79 之间几乎是空的,所以中间档位区分度很低。 |
| > 真正有意义的选择是「最严 0.787」和「平衡 0.459」两档。 |
|
|
| --- |
|
|
| ## 模型与性能 |
|
|
| | | 判废模型 | 类型模型 | |
| |---|---|---| |
| | 文件 | `filter_binary.onnx` (16.8 MB) | `filter_4class.onnx` (85.1 MB) | |
| | 骨干 | mobilenetv3_large_100 (4.2M) | resnet34 (21.3M) | |
| | 输入 | 320×320 | 320×320 | |
| | 输出 | 良品 / 不良 | 良品 / 划痕 / 麻点 / 崩边 | |
| | test AUROC | **0.9913 ± 0.0049** | 0.9867 | |
| | test 平衡准确率 | 0.9746 | **0.9213** | |
|
|
| **速度**(实测,纯 CPU,无 GPU):约 **20 张/秒**。有 GPU 会自动用(装 `onnxruntime-gpu` 即可),约 1500 张/秒。 |
|
|
| 四分类逐类召回(test):划痕 88.0% / 崩边 94.1% / 良品 95.1% / 麻点 91.3% |
|
|
| --- |
|
|
| ## 这个模型可信吗 |
|
|
| **做过 4 道诚实性审计,全部通过:** |
|
|
| | 审计 | 结果 | |
| |---|---| |
| | 批次指纹强度 | 92% —— 图像里**确实**带着可区分批次的信息(有作弊空间) | |
| | **未见类「碎」检出** | **100%** —— 这一类整类从没进过训练,模型照样抓到 | |
| | 跨批次泛化 | 留整个批次当考卷,AUROC 0.9862 vs 同批次 0.9911,**只掉 0.005** | |
| | 冻结特征对照 | 只见良品的 kNN (0.9634) **打败** 用了标签的线性探针 (0.9461) —— 拿到标签没优势,说明没有可解锁的捷径 | |
|
|
| 这套审计不是形式:本项目上一代的图级分类模型曾拿到 AUROC=1.0,一测就发现它认的是"这张图来自哪个压缩包",30 张目检干净的图全被打 0.999+。这一代是真的。 |
|
|
| --- |
|
|
| ## 已知边界(务必阅读) |
|
|
| - **验证样本量有限**:test 只有 185 张良品。0 误报的 95% 置信上界是 1.61%, |
| **无法证明产线级的低误杀率**。要证明误报率 <1%,需要约 300 张干净良品;<0.1% 需要约 3000 张。 |
| - **「不良桶混入良品」随产线不良率剧烈变化**。表里 test 口径 1.83%, |
| 换算到产线不良率 10% 就是 16.9%。**这个指标不是模型属性,必须绑定你的实际不良率才有意义。** |
| - **色调漂移未做压力测试**。原始数据存在采集配置的色调漂移(B 通道逐日 15→8→5)。 |
| 预处理里的逐图灰世界白平衡是为此设计的,但**没有在真实漂移上验证过**。 |
| 上线建议固定白平衡,并监控良品分数分布。 |
| - **不可擦拭脏污检出仅约 53%**。这一类"擦不擦得掉"是物理属性, |
| 单张图像原理上判不了,训练时已整类排除。 |
| - **训练数据的良品标签本身约 3.3% 存疑**(漏标的真缺陷)。误报数字受此影响。 |
| - 输入图假定是**已裁到单片边界的暗场图**,原始尺寸 300~360px 量级。整版图或明场图不适用。 |
|
|
| --- |
|
|
| ## 文件清单 |
|
|
| ``` |
| binaries/ |
| filter-predict-cpu 零安装可执行文件,145 MB,CPU,22 张/秒 |
| filter-predict-gpu 零安装可执行文件,1.3 GB,CUDA,3608 张/秒 |
| predict.py 推理脚本(需自备 4 个 pip 包) |
| filter_binary.onnx 判废模型 + filter_binary.json(含阈值标定表) |
| filter_4class.onnx 类型模型 + filter_4class.json |
| requirements.txt 4 个 pip 包 |
| sample_images/ 22 张样例图(来自锁箱 test,从未参与训练) |
| weights/ PyTorch 原始权重(.pt,需 timm + torch 才能加载) |
| results/ 全部实验结果表、训练曲线、逐图打分 |
| README.md 本文件 |
| ``` |
|
|
| 配套数据集:**https://huggingface.co/datasets/daipath/filter-inspection-data** |
|
|