核心问题:怎么让一个“不会看”的模型,学会识别工业零件表面的划痕?

质检员的 0.5 秒困境

想象你是一个质检员,面前是传送带上飞速流动的钢板。每秒几十张,你要在 0.5 秒内判断:这张有没有划痕?有没有夹杂物?有没有裂纹?

人眼做不到。但神经网络可以。

目标——用深度学习,把这双"眼睛"训练出来。从 CNN 的底层原理开始,经过 YOLO 目标检测实战、LabelMe 数据标注,到用 trace-cn 辅助写训练代码,最终走完**“标注→训练→推理”**的完整闭环。


CNN 基础:卷积神经网络到底在"看"什么?

从生物视觉到数学公式

CNN 的设计灵感来自人类视觉皮层。你看到一张照片,不是逐个像素分析的——你先看到边缘,再看到形状,最后组合出"这是一张脸"。CNN 干的是同样的事:

  • 浅层卷积核提取边缘、纹理(“这里有条线”)
  • 中层把边缘组合成形状(“这是个圆形”)
  • 深层把形状组合成语义(“这是个齿轮”)

核心操作是卷积:一个小的权重矩阵(比如 3×3)在图像上滑动,每个位置做加权求和。一个 3×3 的卷积核只有 9 个参数,却能扫描整个图像——这就是参数共享的威力。全连接网络处理一张 224×224 的图片需要上亿参数,CNN 可能只需要几万。

为什么卷积核能提取特征?

假设你有一个检测水平边缘的卷积核:

[[-1, -1, -1],
 [ 0,  0,  0],
 [ 1,  1,  1]]

当它滑过图像时,遇到"上暗下亮"的区域,输出值就很大;遇到均匀区域,输出接近零。所以卷积核本质上就是一个模式匹配器——每个核负责匹配一种特定的视觉模式。

池化层:压缩但不丢失

卷积之后通常接一个池化层(最常见的是 2×2 最大池化)。它做的事情很简单:把 2×2 区域里的最大值保留下来,其余扔掉。

为什么这么"浪费"?因为池化做了两件事:

  1. 降低计算量:特征图尺寸减半,参数量降到 25%
  2. 增加鲁棒性:目标稍微平移一点,最大池化的输出不变

这就像你看一个人,不需要记住他脸上每个像素的位置,只需要知道"眼睛在鼻子上面"这种相对关系。

训练的三驾马车:损失函数、学习率、早停

损失函数衡量模型预测和真实值的差距。不同任务用不同的损失:

  • 分类用交叉熵(“你预测是猫,但其实是狗,惩罚!")
  • 目标检测用 CIoU Loss(同时考虑框的重叠面积、中心距离、宽高比)
  • 分割用 Dice Loss(对小目标特别敏感,比如医学影像里的肿瘤)

学习率控制每次更新参数的步长。太大了来回震荡,太小了原地踏步。实际训练中常用自适应学习率(如 Adam),它会根据梯度自动调整步长——梯度大就小步走,梯度小就大步跑。

早停准则是最实用的技巧之一:监控验证集损失,如果连续 N 个 epoch 都没下降,就停止训练并保存最优模型。这能有效防止过拟合——模型在训练集上表现完美,在新数据上一塌糊涂。

混淆矩阵和 ROC:模型到底学得好不好?

训练完模型,怎么评估?混淆矩阵告诉你模型犯了哪些错:

  • 精确率(Precision):预测为"有缺陷"的里面,有多少真的是?——“宁可漏报,不可误报”
  • 召回率(Recall):所有真正有缺陷的,模型抓到了多少?——“宁可误报,不可漏报”
  • F1 分数:精确率和召回率的调和平均,综合指标

工业场景里,这两个指标的取舍很关键。如果检测手机屏幕划痕,宁可多报几个"可疑"的让人复查,也不能漏掉一个真正有缺陷的——这时候召回率优先。如果是自动分拣,误报会导致良品被扔掉,那精确率更重要。


YOLO 实战:目标检测从 0 到 1

为什么是 YOLO?

目标检测的传统方法(如 R-CNN)分两步走:先生成候选区域,再逐个分类。准确但慢,跑一帧可能要几秒。

YOLO 的革命性在于:一次前向传播,同时搞定定位和分类。名字就很直白——You Only Look Once。

YOLO 的演进:从 v1 到 v8

  • YOLOv1(2016):开创性的单阶段检测。把图像分成 7×7 网格,每个格子预测边界框和类别。速度快(GPU 45 FPS),但小目标检测拉胯。
  • YOLOv2/v3:引入锚框(Anchor Box)和多尺度检测,精度提升。
  • YOLOv4/v5:融合注意力机制、数据增强策略,成为工程界的主流选择。
  • YOLOv8(2023):全面升级——无锚框设计、解耦检测头、动态标签分配。支持检测、分割、姿态估计、跟踪、分类,一套架构搞定所有任务。

YOLOv8 架构三件套

YOLOv8 的架构可以拆成三个模块:

  1. Backbone(骨干网络):基于 CSPDarknet,负责从图像中提取多层次特征。就像一个"特征工厂”,从原始像素中提炼出有用的"零件"。
  2. Neck(颈部网络):PAN-FPN 双向特征融合,把不同尺度的特征图拼接在一起。小目标看细节层(80×80),大目标看粗粒度层(20×20),中目标看中间层(40×40)。
  3. Head(检测头):解耦设计——分类和回归分开做。同时采用无锚框机制,直接预测中心点偏移和宽高,省掉了锚框设计的麻烦。

用 trace-cn 辅助写 YOLO 训练代码

这是最实用的环节。用 trace-cn(AI 编程助手)来生成 YOLO 训练代码,模式是人定思路、AI 写代码

实际操作流程:

  1. 准备数据集:NEU-DET 数据集包含 6 种钢材表面缺陷(crazing, inclusion, patches, pitted_surface, rolled-in_scale, scratches),共 1800 张图像。
  2. 划分训练集/验证集:按比例随机划分(比如 97% 训练、3% 验证)。
  3. 写 YAML 配置文件
    path: dataset
    train: images/train
    val: images/val
    names:
      0: crazing
      1: inclusion
      2: patches
      3: pitted_surface
      4: rolled-in_scale
      5: scratches
    
  4. 调用 ultralytics 训练
    from ultralytics import YOLO
    model = YOLO("yolov8n.pt")  # 加载预训练权重
    model.train(data="data.yaml", epochs=20, imgsz=640)
    

用 trace-cn 辅助写代码的妙处在于:你不需要记住 ultralytics 的 API 细节,只需要说清楚"我要做什么",它帮你补全代码。但你得能判断代码对不对——这才是工程师的核心价值。

实际训练中,用 CPU 跑 7 个 epoch 大约要 1.5 小时。如果你有 GPU,这个时间可以压缩到几分钟。训练完成后,模型就能对新的钢材图像进行缺陷检测了。


数据标注:LabelMe 工具链

为什么选 LabelMe 而不是 LabelImg?

LabelImg 是老牌标注工具,简单直接,能画矩形框,直接输出 YOLO 的 TXT 格式。但它的局限也很明显——只能画矩形框。

LabelMe 则支持矩形、多边形、圆形、线段、关键点等多种标注类型。更重要的是,它保存的是 JSON 格式,可以灵活转换为 YOLO、COCO、Pascal VOC 等多种数据格式。

功能LabelImgLabelMe
矩形框
多边形
分割
关键点
JSON 输出
扩展性★★☆★★★★★

如果今天只训练 YOLO 检测模型,LabelImg 够用。但如果未来要接触 YOLO-Seg、SAM、Mask R-CNN 这些分割模型,LabelMe 是更好的起点——标注一次,处处可用

LabelMe 使用流程

# 安装
pip install labelme

# 启动
labelme images/

操作很简单:打开图片 → Create Rectangle → 输入标签名(比如 “scratch”) → 保存。LabelMe 会自动记住你输入过的标签,后续标注越来越快。

JSON → YOLO 格式转换

LabelMe 保存的 JSON 需要转换成 YOLO 的 TXT 格式。核心转换逻辑:

# class_id x_center y_center width height(归一化坐标)
def convert(json_file, image_w, image_h):
    # 从 JSON 中提取矩形框的坐标
    # 转换为 YOLO 格式的归一化中心坐标 + 宽高
    x_center = (x1 + x2) / 2 / image_w
    y_center = (y1 + y2) / 2 / image_h
    width = (x2 - x1) / image_w
    height = (y2 - y1) / image_h
    return f"{class_id} {x_center} {y_center} {width} {height}"

这一步看起来简单,但坐标系转换是踩坑重灾区。LabelMe 用的是左上角原点的像素坐标,YOLO 要的是归一化的中心坐标。搞反了 x/y 或者忘了归一化,模型直接训废。


踩坑与排查

坑 1:CPU 训练的残酷现实

用 CPU 跑 YOLO 训练,7 个 epoch 要 1.5 小时,而且效果有限。实际工业项目中,没有 GPU 基本没法做深度学习训练。建议至少有一张 RTX 3060 以上的显卡,或者用云 GPU(Google Colab、AutoDL 等)。

坑 2:验证集太小导致评估不可靠

训练集 1770 张,验证集只有 30 张——这个比例太极端了。验证集太小,评估指标波动很大,你不知道模型是真的好还是运气好。一般建议训练集:验证集 = 8:2 或 9:1。

坑 3:类别标签大小写敏感

YOLO 的 YAML 配置文件里,类别名必须和标注时用的完全一致。Scratchscratch 是两个不同的类别。一个小写字母的差异,模型就多学了一个"幽灵类别"。

坑 4:混淆矩阵的读法

第一次看混淆矩阵容易懵。记住:行是真实标签,列是预测标签。对角线上的数字越大越好(正确分类),非对角线上的数字是错误分类。如果某一列特别"亮",说明模型容易把别的类别误判为这个类别。


演示视频


核心收获与下一步

总结

从 CNN 的卷积运算原理,到 YOLO 的端到端检测,再到 LabelMe 标注和格式转换,我们走完了深度学习在工业视觉中的完整闭环

标注(LabelMe)→ 格式转换(JSON→YOLO)→ 训练(ultralytics)→ 推理(检测结果)

这个闭环看似简单,但每一步都有坑。标注质量决定模型上限,格式转换决定数据能不能用,训练参数决定模型能不能收敛,推理部署决定能不能上产线。

四天的旅程

四天前,我们连工业相机怎么选都不清楚。现在,我们已经:

  • 搞懂了机器视觉的硬件基础和图像处理流程
  • 掌握了从数据采集到系统集成的工程方法
  • 学会了条码识别、几何检测、农产品分选等实用技术
  • 走通了深度学习从标注到部署的完整链路

从"光照→镜头→相机"的物理世界,到"卷积→池化→检测"的数字世界,我们建立了一个完整的认知框架。

下一步建议

  1. 动手练:找一个公开数据集(比如 COCO 的子集),用 LabelMe 标注 100 张图,训练一个 YOLO 模型。从标注到推理跑一遍全流程,比看十篇教程都有用。
  2. 用 GPU:CPU 训练只能用来验证流程,真正做项目必须上 GPU。建议入一张 RTX 3060 或用云 GPU。
  3. 学评估:混淆矩阵、ROC 曲线、PR 曲线这些评估工具,要能看懂、能解释。给领导汇报时,“准确率 95%“比"效果不错"有说服力得多。
  4. 关注部署:训练好的模型怎么部署到工控机上?ONNX 导出、TensorRT 加速、边缘设备推理,这些是把模型从"实验室"搬到"产线"的关键。
  5. 持续学习:YOLO 系列在快速迭代,SAM(Segment Anything)等基础模型正在改变标注方式。保持学习,但不要追新——把一个工具用到极致,比浅尝辄止十个工具有价值得多

深度学习在工业视觉中不再是"实验室里的黑科技”,而是一套可以落地的工程方法。面对实际项目,你知道该从哪里入手了。