File size: 7,598 Bytes
b8f8211 41ff7b3 0e9808f 128b81a 41ff7b3 128b81a 41ff7b3 128b81a 41ff7b3 128b81a | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 | ---
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**
|