 Shaun ZhouandClaude Opus 5
|
af0897f8c7
|
refactor(detect): 数据集改为扁平结构、不划分 train/val,Label Studio 文件放到根目录
prepare_yolo_dataset.py 的产出先导入 Label Studio 复核,划分留到复核之后,于是:
- 去掉按类别分层的 train/val 切分以及 --val-ratio / --seed,images/ 与 labels/
下直接是文件;name_map.csv 去掉 split 列,summary.json 的逐类数量改为单列。
- label_studio/ 子目录的内容上移一层:扁平的数据集本身就是 label-studio-converter
要求的 <input>/{images,labels,classes.txt},tasks.json 与 labeling config 直接
生成在根目录,不再需要额外的硬链接视图,DOCUMENT_ROOT 即数据集根目录。
- data.yaml 的 train 与 val 只能指向同一个 images/。ultralytics 能读,但验证指标
算的是训练集本身,mAP 虚高、早停与 best.pt 的选择失真。脚本结束时告警,
detect.py 检测到 train == val 时也告警。
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
|
2026-09-15 17:19:53 +08:00 |
|
 Shaun ZhouandClaude Opus 5
|
1a43267b55
|
feat(detect): --label-studio 一步生成可导入 Label Studio 的复核视图
label-studio-converter import yolo 只认 <input>/{images,labels,classes.txt},且
os.listdir 不递归,看不见 train/val 子目录,直接喂数据集会 "No labels converted"。
按类别重命名后文件名全局唯一,于是在 <out>/label_studio/ 下把两个 split 拍平
(硬链接:Label Studio 本地存储会校验路径在 DOCUMENT_ROOT 之下,软链接可能越界),
再调用 converter 生成 tasks.json 与 labeling config。
- 框以 predictions 导入:它们是 SHAP/Grad-CAM 生成的,审核员提交后才成为
annotation,导出时没审过的框不会混进去。
- 不传 image_dims:真实数据有 3223 种尺寸,传了会写错每条标注的宽高。
- 任务数与图片数不符时报错,而不是静默少导。
- converter 自带的导入提示漏掉了 LABEL_STUDIO_LOCAL_FILES_* 环境变量(它在循环里
改写了 image_root_url,之后与默认值比较失败),静音后由脚本打印带实际路径的步骤。
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
|
2026-09-15 17:06:40 +08:00 |
|
 Shaun ZhouandClaude Opus 5
|
7adc5b6332
|
feat(detect): YOLO 数据集统一为 PNG、按类别重命名并附 classes.txt
- 图片统一成 PNG。pearlescent / blue / uv 的原始数据是 BMP,generate_boxes.py
按原后缀链接,于是 runs/boxes_shap 里 3685 张 BMP 与 7526 张 PNG 混在一起,
ripple 与 uneven 两类全是 BMP。按文件头(而非后缀)判断:真 PNG 照旧硬链接,
其余无损转换,不缩放像素,归一化框坐标原样有效;CMYK 等 PNG 存不下的模式转 RGB。
在真实数据上核对过 3685 张转换结果逐像素一致。
- 文件按 <类别>_<序号> 重新编号。类别取标签第一列,文件名不会与标签矛盾;
序号在类内按源路径排序、与划分无关,换种子重跑名字不变。新旧名对照写入
name_map.csv,源文件名里的正反面、位置、时间戳不丢。--keep-names 保留原名。
- 输出 classes.txt(行号即 class_id),供 LabelImg / X-AnyLabeling 复核框时使用。
- 撞名检查改为按输出文件名的小写比较:统一后缀后 a.png 与 a.bmp 会撞,
macOS 默认文件系统也不区分大小写。
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
|
2026-09-15 16:45:58 +08:00 |
|
 Shaun ZhouandClaude Opus 5
|
012b3efc73
|
feat(detect): 按来源类别处置无框图片(--empty-policy)
空标签在 YOLO 里的语义是"这张图什么都没有",是一个明确的负样本断言,而不是
"有缺陷但没能定位出来"。原先一律保留,于是 runs/boxes_gradcam 的 339 张空标签
里有 270 张是人工标成缺陷、Grad-CAM 却失手的图(blackdot 占该类 11%、black 占
24%),它们正以"此图无缺陷"的身份进入训练,等于在教模型抑制真实缺陷。
--empty-policy 接一个全局默认加若干 `类别=策略`:
keep 当负样本保留(默认)/ drop 丢弃 / full 退化成整图框
整图框需要重写标签而不是链接源文件(内容不同),且有了确定类别之后要跟着本类
一起参与分层划分。类别名或策略拼错直接报错——静默忽略会让策略看着生效其实没有。
没显式指定、又落到 keep 的类别会打一条告警。
替换掉原来的 --drop-empty:它是一刀切,会把 normal 那 69 张有价值的负样本一起扔掉。
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
|
2026-09-11 16:34:16 +08:00 |
|
 Shaun ZhouandClaude Opus 5
|
8dc2fe6a2e
|
feat(detect): 把弱监督框数据集链接到 data/ 并接上 YOLO 训练
第五步产出的框标签按类别分目录,便于人工核对;检测训练要的是 train/val
划分——类别写在标签第一列,不靠目录名。补上两个入口:
- scripts/prepare_yolo_dataset.py:拍平类别目录、按类别分层切分、硬链接到
data/。分层是必需的,black 只有 53 张,随机切容易让小类在验证集里挂零。
无框的图默认保留(检测训练里是压低误检的负样本);拍平后的同名冲突直接
报错而不是静默覆盖。
- detect.py + configs/detect/film.yaml:包一层 ultralytics,沿用本仓库的
配置继承、设备解析与 SwanLab 可视化。
选 YOLOv8 而不是 v11/v12:CLAUDE.md 限定只用 convolution 模型,YOLO11 骨架
里有 C2PSA、YOLO12 以注意力为主,只有 v8 的 C2f + SPPF 是纯卷积。
mosaic/mixup 关掉——每张图只有一个弱监督框,拼接后小目标被缩得更小,对
blackdot/whitedot 这类只占千分之几面积的类别是净伤害。
ultralytics 的 project 必须传绝对路径,相对路径会被它再拼到全局 settings
的 runs_dir 上,产出会跑到 runs/detect/runs/detect/<name> 去。
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
|
2026-09-11 12:05:50 +08:00 |
|