新增基于 SHAP Partition explainer 的定位,与 Grad-CAM 形成互补对照: - engine/shap_explain.py:对目标类别求 SHAP 归因(只保留正贡献),以及方框平滑。 遮挡用数值 masker 而非教程里的 inpaint_telea——后者依赖 opencv,而我们的图已做过 逐图标准化,用 0(即该图均值)遮挡语义更干净 - scripts/shap_boxes.py:按类别抽样生成标签,并输出「原图 | Grad-CAM | SHAP」并排图 - shap 放入可选依赖组:uv sync --group explain 实测(225 张,每类 15):SHAP 在小目标类别上明显更准,框面积占比 blackdot 0.019 vs 0.269(14 倍)、mosquito 0.030 vs 0.173、whitedot 0.076 vs 0.253。 原因是 Grad-CAM 受限于 8x8 特征图(每格 16x16 像素),几像素的黑点根本不可分辨。 代价是单张 0.55 秒,全量 11k 张约 1.7 小时,而 Grad-CAM 全量只要 2 分钟。 调参时发现的坑:SHAP 第一版全部出 0 框,因为沿用了给 8x8 调的 min_area_ratio=0.02(在 128x128 上等于 328 像素)。参数不能跨分辨率照搬, SHAP 默认改为 0.002。 --max-boxes 两个脚本都默认改为 1(原为 2):一张裁片通常只对应一处缺陷。 库函数 cam_to_boxes 的默认值同步收紧,相关测试改为显式传参而不依赖默认值。 Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
54 lines
1.3 KiB
TOML
54 lines
1.3 KiB
TOML
[project]
|
|
name = "modeltraineval"
|
|
version = "0.1.0"
|
|
description = "薄膜缺陷分类定位模型的训练与评估(纯卷积,面向实时设备部署)"
|
|
readme = "README.md"
|
|
authors = [
|
|
{ name = "Shaun Zhou", email = "xiangyuzhou823@gmail.com" }
|
|
]
|
|
requires-python = ">=3.12"
|
|
dependencies = [
|
|
"torch>=2.4",
|
|
"torchvision>=0.19",
|
|
"numpy>=1.26",
|
|
"pillow>=10.3",
|
|
"pyyaml>=6.0",
|
|
"swanlab[dashboard]>=0.10.0",
|
|
"matplotlib>=3.8",
|
|
]
|
|
|
|
[dependency-groups]
|
|
dev = [
|
|
"pytest>=8.0",
|
|
"ruff>=0.6",
|
|
]
|
|
# ONNX 导出(部署用),按需安装:uv sync --group export
|
|
export = [
|
|
"onnx>=1.16",
|
|
"onnxscript>=0.2",
|
|
]
|
|
# SHAP 归因定位(scripts/shap_boxes.py),按需安装:uv sync --group explain
|
|
explain = [
|
|
"shap>=0.48",
|
|
]
|
|
|
|
[tool.uv]
|
|
# 本仓库是应用而非库:不打包安装,直接从仓库根目录运行 train.py / eval.py。
|
|
package = false
|
|
|
|
# 训练机(Linux + Nvidia GPU)请用 CUDA 版 torch,例如:
|
|
# uv pip install --index-url https://download.pytorch.org/whl/cu124 torch torchvision
|
|
# 默认 PyPI 源在 Linux 上装的是 CUDA 构建,在 macOS 上只有 CPU 构建(仅可用于评估/导出)。
|
|
|
|
[tool.pytest.ini_options]
|
|
testpaths = ["tests"]
|
|
pythonpath = ["."]
|
|
addopts = "-q"
|
|
|
|
[tool.ruff]
|
|
line-length = 110
|
|
target-version = "py312"
|
|
|
|
[tool.ruff.lint]
|
|
select = ["E", "F", "I", "UP", "B"]
|