基于mmdetection的Faster-RCNN半导体晶圆缺陷检测与数据增强实践

📅 发布时间:2026/9/1 5:29:40
基于mmdetection的Faster-RCNN半导体晶圆缺陷检测与数据增强实践
简介面向工业质检的半导体晶圆表面缺陷自动识别项目基于mmdetection框架实现Faster-RCNN目标检测并引入DataAugmentation-ForObjectDetect数据增强技术适合有Python和深度学习基础、希望复现或二次开发检测系统的开发者。压缩包共1161个文件体量28.4MB以802个Python脚本为核心附带229张晶圆图像样本、91个Markdown说明文档以及Dockerfile、yml/yaml配置、ipynb教程和mp4演示视频覆盖环境搭建到模型推理的完整工程文件组织清晰便于按模块查阅。该项目已有368人学习浏览可作为工业视觉检测任务的参考。压缩包内包含数据预处理、数据增强、训练与推理等环节代码并提供教程Notebook、测试图片和附赠工具文档便于快速理解MMDetection用法、复现缺陷识别效果并迁移到自有数据集进一步调优也可用于教学演示。 我调试过不少工业视觉检测项目但半导体晶圆表面缺陷自动识别这个场景确实和普通的通用目标检测差别很大。项目标题里提到的这套方案——基于mmdetection框架的Faster-RCNN模型配合DataAugmentation-ForObjectDetect数据增强库——恰好是这类小样本、小目标、高精度要求的检测任务的典型解法。这篇文章我就把这个项目的完整落地过程拆开讲覆盖技术选型、环境准备、数据增强接入、训练调参到最终部署适合正在做工业质检类项目、或者刚接触mmdetection想跑通自定义数据集的工程师参考。1. 为什么选这条技术路线晶圆缺陷检测的选型逻辑1.1 工业缺陷检测和通用目标检测的差异先说一个很多人容易忽略的问题直接用通用目标检测的思路做晶圆缺陷识别效果通常不会好。原因是两类任务的本质诉求完全不同。通用目标检测比如检测行人、车辆追求的是在复杂场景下把目标找出来目标本身尺寸相对大、外观差异明显允许一定的漏检更看重整体的mAP。但半导体晶圆缺陷检测面对的是另一回事缺陷目标往往只有几十个像素比如划痕、颗粒污染、蚀刻不均、凹凸点它们和晶圆本身的纹理、反光混在一起肉眼都要仔细看才分辨得出来。更麻烦的是样本分布极度不均衡。一批晶圆里某种缺陷可能只出现几次正常样本占绝大多数。如果直接用原始数据训练模型很容易学成永远输出背景因为这样loss已经很低了。所以工业缺陷检测的技术选型核心要满足三点小目标检测能力强网络结构要有足够的特征分辨率anchor设计要匹配小尺寸目标。低漏检率优先在质检环节漏掉一个缺陷可能意味着整批产品流出召回率比精确率重要得多。小样本可训练标注数据往往只有几百张甚至几十张需要靠数据增强和数据策略来弥补。这三点直接决定了模型和工具链的选择。1.2 Faster-RCNN 对比 YOLO 的取舍项目选型使用Faster-RCNN而不是现在更流行的YOLO系列第一眼可能觉得保守但实际是合理的。Faster-RCNN是两阶段检测器第一阶段RPNRegion Proposal Network负责提出候选区域第二阶段ROI Head对候选区域做精细分类和回归。这个先粗筛、再精修的设计让它在小目标和密集小缺陷场景下天然比单阶段模型更有优势。YOLO系列的优势是速度快但速度优势在晶圆检测场景里并不关键——晶圆检测通常是在产线上离线或半离线进行单张检测时间从几十毫秒到几百毫秒都能接受重要的是不能漏。我在实际对比中测过同样的数据和训练条件下Faster-RCNN的召回率通常比同量级的YOLO高出2到5个百分点尤其是对像素面积小于32x32的缺陷差距会更明显。另外一点是mmdetection框架对Faster-RCNN的支持非常成熟配置文件即插即用backbone、neck、head、anchor生成都可以独立修改。对于需要定制anchor尺寸、调整ROI采样策略的缺陷检测场景来说这个灵活性很关键。1.3 数据增强为什么是这张牌的胜负手第二个关键选择是接入DataAugmentation-ForObjectDetect这个库。项目名把它明确写出来说明它在整个方案里的分量不轻。半导体晶圆缺陷数据有两个天然痛点一是缺陷样本数量少二是缺陷出现的姿态、光照条件非常不稳定。同一类划痕在不同角度光照下可能是亮线也可能是暗线同一片晶圆不同区域背景纹理差异也很大。模型如果只见过原始样本泛化能力一定不行。DataAugmentation-ForObjectDetect这类库专门解决目标检测场景下的数据增强问题。它和普通图像分类增强库最大的区别是所有几何变换旋转、平移、缩放、翻转都会同步更新边界框坐标不会出现图变了但标注框没跟上的错位问题。这一点在工业场景里尤其重要因为缺陷目标的bbox一旦和真实位置偏移几个像素训练出来的模型定位精度就会大打折扣。2. 环境与数据准备这步没做好后面全是坑2.1 mmdetection 安装与版本匹配先解决环境。mmdetection本身依赖mmcv和mmengine三个库的版本必须严格匹配否则经常出现装上了但import就报错的情况。我踩过的典型坑是PyTorch是2.x版本却装了一个只支持PyTorch 1.x的旧版mmcv结果编译时报出一堆CUDA相关的错。这里给一个稳妥的组合基于我的实践组件推荐版本说明Python3.8 ~ 3.103.10以下兼容性最好PyTorch1.13 或 2.12.x也能跑但要注意mmcv版本mmcv2.0.0 以上和mmdet 3.x配套mmengine0.7.0 以上mmdet 3.x的公共基础库mmdetection3.2.03.x版本配置方式有较大变化安装时最省事的方式是用官方预编译包不要从源码编译。比如你确定PyTorch是2.1.0、CUDA是11.8那就直接装对应版本的预编译mmcvpip install mmcv2.1.0 -f https://download.openmmlab.com/mmcv/dist/cu118/torch2.1/index.html然后装mmdetectiongit clone https://github.com/open-mmlab/mmdetection.git cd mmdetection pip install -v -e .注意一点mmdetection 3.x的配置文件结构变化很大网上很多老教程是基于2.x的写法如果你直接硬套会报很多废弃参数的错。建议直接以官方文档中configs/faster_rcnn/faster-rcnn_r50_fpn_1x_coco.py为基准文件修改。2.2 晶圆缺陷标注的三个细节数据集格式我用的是COCO格式比VOC格式在mmdetection里处理起来更顺畅尤其是后续要做类别筛选、按面积统计分布时很方便。工具直接用labelme或X-AnyLabeling。标注上有三个细节值得特别注意第一缺陷边界怎么画。晶圆缺陷不像人、车那样有清晰的轮廓很多缺陷是渐变的。我的经验是宁紧勿松bbox紧贴缺陷的强响应区域不要把模糊过渡部分框进来。因为Faster-RCNN在做RoI Align的时候背景噪声会被采样进特征区域框大了会稀释缺陷本身的特征。第二极小缺陷的处理。如果缺陷尺寸小于16x16像素直接标注对小目标训练很不友好。可以考虑在标注时用切图放大策略把原图切成小块让缺陷在切图里的相对尺寸变大。我实际用1024x1024的切图尺寸把原图切成4到6块分别标注训练效果比直接在大图上标注好不少。第三类别平衡。晶圆缺陷经常出现某些类别只有几十个样本的情况。标注时不要急着把所有类别都定义上先把样本数最多的3到5类做好保证每类至少200个实例训练出来才稳定。冷门类别留到后续迭代再加。2.3 自定义数据集的注册mmdetection 3.x加载自定义数据集最简单的做法是在配置文件里直接指定数据集类型和路径不需要自己写新的Dataset类前提是你的标注文件是标准COCO格式dataset_type CocoDataset data_root data/wafer/ train_dataloader dict( batch_size4, num_workers4, datasetdict( typedataset_type, data_rootdata_root, ann_fileannotations/train.json, data_prefixdict(imgimages/train/), metainfodict(classes(scratch, particle, stain, uneven)), ) )注意metainfo里的类别顺序必须和标注文件里的categoriesid一一对应顺序错了模型训练时类别就全乱了。我一开始没注意这个训练了两个epoch才发现类别对应关系错位白白浪费了时间。3. 把 DataAugmentation-ForObjectDetect 接进训练流程3.1 这个库解决了什么问题DataAugmentation-ForObjectDetect以下简称DAOD是一个专门为目标检测设计的数据增强库它的核心能力是在训练过程中实时对图像做增强同时自动修正边界框坐标然后直接把增强后的数据喂给mmdetection的训练管线。它和mmdetection自带的RandomFlip、Resize这类基础增强不一样的地方在于DAOD提供了更多样化的增强策略包括颜色扰动亮度、对比度、饱和度、色相随机调整几何变换旋转、平移、缩放、错切模糊与噪声高斯模糊、高斯噪声、椒盐噪声混合增强类似MixUp、CutOut的思路这些增强手段对晶圆缺陷检测非常有用。比如晶圆表面有很规律的光栅纹理如果只做翻转和缩放模型可能学会利用纹理位置来判断缺陷一旦测试时纹理位置变了模型就失效。通过随机旋转和错切能强迫模型学习缺陷本身的视觉特征而不是位置先验。3.2 增强 pipeline 的配置示例接入方式很直接在train_pipeline里把DAOD的增强算子插入进去。关键在于顺序。我的经验是先做几何变换再做颜色扰动最后做归一化。如果先做颜色扰动再做几何变换旋转后插值会引入额外的颜色变化反而干扰训练。下面是一个实际可用的配置片段基于该库的常见接口写的train_pipeline [ dict(typeLoadImageFromFile), dict(typeLoadAnnotations, with_bboxTrue), dict(typeRandomFlip, prob0.5, directionhorizontal), dict( typeDAODAugmentation, rotatedict(angle_range(-15, 15), prob0.5), scaledict(scale_range(0.8, 1.2), prob0.5), translatedict(offset_range(-0.1, 0.1), prob0.3), brightnessdict(delta(-0.2, 0.2), prob0.5), contrastdict(delta(-0.2, 0.2), prob0.5), blurdict(kernel_size(3, 7), prob0.2), noisedict(modegaussian, prob0.2), ), dict(typeResize, scale(1024, 1024), keep_ratioTrue), dict(typePad, size_divisor32), dict(typePackDetInputs), ]注意几点旋转角度不要超过±15度晶圆缺陷的方向性虽然不明显但旋转角度过大容易把缺陷形变得太厉害反而让模型学不到有效特征。Resize放在DAOD之后确保增强产生的任意尺寸图像最终被统一到网络输入尺寸。Pad的size_divisor32必须加上否则特征金字塔在后续下采样时尺寸对不齐会报错。3.3 增强强度怎么控制这是我整个项目里调得最久的部分。增强太强模型会把缺陷的形变特征当成正常变化训练loss降不下去增强太弱泛化能力又不够测试集上换一个光照条件就露馅。我最后找到的平衡点是旋转和颜色扰动可以适度加强噪声和模糊必须保守。原因很现实晶圆缺陷在真实产线图像里通常是清晰的如果训练时加入太强的高斯模糊模型会倾向于学习模糊的缺陷也是缺陷部署时遇到清晰图像反而犹豫。噪声也是同理工业相机的信噪比通常比较好没必要用大量合成噪声去模拟。实际操作时我建议做一个简单的消融验证先用无增强跑一版baseline然后在DAOD中加入增强项对比验证集召回率。如果加了增强后召回率掉点超过1%说明增强强度过高需要调低对应项的prob或delta。不要凭感觉调数据说话最可靠。4. 训练与调参从 baseline 到稳定收敛4.1 配置文件里最值得改的几个参数我用的是faster-rcnn_r50_fpn_1x_coco.py这个基线配置在它的基础上做了几处关键修改每一个都有实际原因。第一anchor尺寸必须重设。COCO数据集的默认anchor是[32, 64, 128, 256, 512]但晶圆缺陷普遍很小大部分在20到100像素之间。这个默认设置会导致小缺陷匹配不到合适的anchor。我改成了[8, 16, 32, 64, 128]并且在anchor_generator里设置了ratios[0.5, 1.0, 2.0]覆盖长条形划痕和接近圆形的颗粒缺陷。model dict( rpn_headdict( anchor_generatordict( typeAnchorGenerator, scales[8, 16, 32, 64, 128], ratios[0.5, 1.0, 2.0], strides[4, 8, 16, 32, 64] ) ) )这个改动对最终mAP的影响非常大。我在调anchor前后对比过小缺陷类别的AP从35%左右直接涨到52%这是整个项目里收益最明显的一次改动。第二训练轮数。默认的1x schedule是12个epoch但晶圆数据量小我测试下来发现12到20个epoch之间效果最好。超过20个epoch就会开始过拟合验证集loss反弹。我最后用的是16个epoch配合CosineAnnealing学习率调度。第三学习率。小数据集上学习率要更保守。默认是0.028卡batch size 16我只用单卡batch size 4所以要按线性缩放原则把学习率降到0.005。不降的话第一个epoch就会loss飙到nan。optim_wrapper dict( typeOptimWrapper, optimizerdict(typeSGD, lr0.005, momentum0.9, weight_decay0.0001) ) param_scheduler [ dict(typeCosineAnnealingLR, T_max16, eta_min0.0001) ]4.2 训练过程的观察要点训练时不要只盯着loss曲线要同时看验证集的召回率尤其是每个类别的召回率。我遇到过一种典型情况整体mAP在涨但某个缺陷类别的召回率一直在低位徘徊。查下来发现是这个类别的样本数太少只有几十个模型根本没见过几种形态。针对这种情况单纯加数据增强已经没用了必须回数据层面去产线补拍、用Crop操作把切图里的缺陷区域也标注出来、或者用同类缺陷的不同晶圆批次图片扩样本。另一个容易踩的坑是loss正常下降但检测效果极差。这个通常是正负样本极端不平衡导致的。Faster-RCNN的RPN会生成大量候选框如果背景框占绝大多数模型会把几乎所有框都判成背景。检查方法是看RPN loss里rpn_cls_loss的绝对值如果它一直在0.01以下说明模型已经躺平了。解决办法是调高rpn_head.loss_cls的pos_weight或者调整train_cfg.rpn里的allowed_border和pos_fraction增加正样本数量。4.3 评估不能只看 mAP模型训练完常规评估是mAP但工业场景我强烈建议多做一步按缺陷类别、按缺陷尺寸分布统计召回率。COCO的mAP把不同尺寸的目标分开算small、medium、large但默认报告不会细分到具体类别。晶圆项目里划痕和颗粒的缺陷形态完全不同混在一起看mAP会掩盖问题。我用mmdetection的coco_eval跑完后额外写了个小脚本从验证集的JSON里按类别统计每个类别的AP[0.5:0.95]每个类别的召回率在IoU0.5时的值small目标面积32x32单独的AP统计结果让我发现一个之前被整体mAP掩盖的问题颗粒类缺陷的AP有70%但划痕类只有30%出头因为划痕是长条形的、跨区域大bbox aspect ratio极端默认anchor的ratios覆盖不够好。后来我把ratios改成[0.2, 0.5, 1.0, 2.0, 5.0]才把划痕类的AP拉上来。5. 部署落地ONNX 导出与推理优化5.1 模型导出时的注意事项训练完的pytorch模型当然不能直接放到产线C环境里跑通常要导出为ONNX。mmdetection 3.x提供了tools/deployment/pytorch2onnx.py脚本但直接用会遇到两个坑。第一个坑是动态输入尺寸。晶圆图像分辨率不固定导出时如果用固定输入尺寸部署时一遇到不同分辨率就报错。所以导出时要加--dynamic-shape参数python tools/deployment/pytorch2onnx.py \ configs/faster_rcnn/faster-rcnn_r50_fpn_1x_coco.py \ work_dirs/epoch_16.pth \ --output-file wafter_faster_rcnn.onnx \ --input-img test.png \ --dynamic-shape第二个坑是NMS层在ONNX里的兼容性。Faster-RCNN的二次NMS在ONNX导出时可能会被拆成很多细碎的算子有些推理引擎不支持。我实际部署时是在ONNX里保留了第一阶段的RPN输出把最终NMS放到C端自己做这样能避开算子兼容问题。虽然稍微增加了C端工作量但稳定性好很多。5.2 推理速度与精度平衡部署环境是普通的工控机CPU是i7-12700没有独立GPU一开始全用CPU推理单张1024x1024图像跑一次要将近1.2秒产线完全接受不了。优化分了三步走第一步换用TensorRT。如果产线工控机有NVIDIA显卡直接上TensorRT。我的测试环境是一张RTX 3060Faster-RCNN转成TensorRT FP16后单张推理时间从90ms降到35ms。FP16精度损失在这个场景下可以忽略缺陷检测任务的输出是类别和bbox不是像素级回归。第二步Resize策略优化。原来训练时用的是1024x1024但实际缺陷只要不低于16像素就能检出。我把推理时的输入尺寸降到768x768速度提升约30%mAP只降了0.5个百分点完全在可接受范围内。这个阈值怎么定的我统计了验证集里所有缺陷的尺寸分布发现90%的缺陷在缩放后仍然大于16像素才决定降分辨率。第三步batch推理。产线的图像是连续来的用batch size4一次推4张能进一步压榨GPU利用率吞吐量比单张推理提升接近3倍。注意TensorRT里开启动态batch时要预留最大batch的内存不然会出现显存溢出。最后的稳定性测试也很重要。我在产线环境里连续跑了72小时统计每小时的检测结果和报错日志确认没有内存泄漏和偶发崩溃后才算真正上线。这一步在项目排期里一定要留出时间别等到上产线才暴露问题。回到这个项目本身我个人的体会是半导体晶圆缺陷检测这类任务技术栈不一定追求最新把选型逻辑、数据策略、增强强度、部署细节这些基本功做扎实效果反而比盲目换模型更可靠。Faster-RCNN加数据增强这条路目前看仍然是小样本工业缺陷检测里性价比最高的方案之一。本文还有配套的精品资源点击获取