回收场的传送带上,紫铜、黄铜、铝合金、不锈钢混在一起顺流而下,工人手里拿着磁铁和砂纸,一眼扫过去就把大类分开——这套流程在中小型再生资源企业里实在太常见了。可真正麻烦的地方在于,人工分拣只能回答“这是什么金属”,回答不了“这块料够不够一级品”这种问题。而回收报价里,纯度和等级偏偏就是最关键的变量。
所以当时我决定做一套试验性系统:基于SVM和ANN的废弃金属分类、分等级方案,用机器视觉加机器学习,在传送带上完成金属的类别识别和品级判断。这里说的分类是把金属分出大类,分等级是在同一个大类里继续判出质量等级,比如紫铜一级、紫铜二级。这套系统不需要顶级服务器,普通工控机就能跑,整个思路也适合中小型回收企业自己复制。下面把我从需求到落地踩过的坑、调过的参数、以及最终能跑通的结构完整记录下来。
1. 项目背景与需求拆解
1.1 回收行业真正卡在哪
很多没进过回收车间的人,以为废旧金属分拣就是“看看颜色、吸吸磁铁”。实际上去到现场之后就明白,这活儿远比想象中复杂。
先说效率。熟练分拣工一天处理两吨左右确实能做,但前提是料型相对规整,而且不能长时间保持高准确率。连续干四五个小时之后,眼睛疲劳、注意力下降,铜和铁当然不会看错,但铝合金里不同系列的牌号、黄铜和青铜这类相似料型就很容易混。普通回收厂往往没有太多质检岗位,一个工人要同时负责几个环节,漏检率就上去了。
再说等级。绝大多数回收厂对废料的等级判断靠的是老师傅经验,比如“光亮铜一级”“铜米二级”“紫铜三级”。这些经验有体系,但不稳定,一个师傅一个判断标准。卖料的时候,如果等级定低了,高值料被当成低值料卖掉,一年下来损失不小;定高了,买方检测不通过又会产生纠纷。
用机器来做分类和分级,本质上是把老师傅的经验固化成一套可重复、可校准的判断流程。这也是我最初做这个项目的核心动机:不是要取代人工,而是让分拣结果更有稳定性和说服力。
1.2 需求定义:从单模型分类到两阶段分级
一开始我把问题想简单了,以为训练一个分类模型,能识别出“铜、铝、铁、不锈钢、锌”就完工了。后来跟做回收贸易的朋友聊过之后才意识到,工业现场的完整需求其实包含两层:
第一层是类别判定:这块料到底是什么金属,属于哪个大类。
第二层是等级判定:在同类金属里,这块料能定几级。
这两个问题性质不一样。大类之间特征差异大,颜色、密度、纹理都很明显;等级之间的差异却细微得多,往往只是氧化程度、杂质多少、表面油污覆盖比例的区别。如果用同一个模型硬扛两个任务,模型会被“大类特征”主导,等级上的细节特征反而学不到。
所以最终系统被设计成两阶段:先用SVM跑大类分类,再对属于同一大类的样本,用ANN做等级判断。
1.3 优先落地的应用场景
我梳理过三个潜在场景。
第一个是破碎线前端的预分拣。料还没破碎,块头大,速度快,主要需求是快速分大类,对等级判断不必太精细。
第二个是质检台上的精细检测。料已经被挑出来,放到固定工位,相机和光源条件可控,这时候可以做高精度的等级判定。
第三个是拆解流水线上的部件级识别,比如识别电机里的漆包线、铜绕组、铝壳,这需要细颗粒度的模型和更复杂的训练集。
我最终选择第二个场景作为切入点,原因是它最能体现“分类+分级”的完整价值,而且环境可控、数据好采集、模型好部署。先把这套流程跑通,再往传送带上搬,难度阶梯合理。
2. 技术选型:SVM和ANN各自的定位
2.1 两种算法的直觉理解
SVM全称支持向量机,核心思路是找一个超平面把不同类别的样本分开,并且让分隔边界离两边样本的距离最大化。它很擅长处理中小规模的样本数据,尤其是特征维度几十维以内的情况。只要特征有区分度,SVM给出的结果非常稳。
ANN全称人工神经网络,本质是一个多层非线性函数拟合器。给它足够多带标签的样本,它能自己找到输入特征和输出类别之间的复杂映射关系。ANN的优势是上限高,表达能力远超传统机器学习模型,缺点是需要数据多、调参也费些功夫。
如果做个通俗类比,SVM像那种要求极其严格的质检员,他的原则很明确,就是要让不同类别之间的“安全距离”尽可能大,逻辑简单可解释。ANN更像一个见多识广的老师傅,看了成千上万个料之后建立起一种直觉,你说不清具体规则,但他判得就是准。
2.2 为什么组合而不是二选一
有人会问:既然ANN这么强,为什么不全部用ANN?或者既然SVM省事,为什么不全部用SVM?
我当时的判断依据是任务性质。
大类分类的特征是离散性明显的:紫铜和黄铜的颜色分布差异很大,铝合金和碳钢的纹理、反光差异也很大。这种情况SVM非常擅长,且样本量不用太大,几百张也能训练出不错的效果。SVM还有一个优点,分类决策边界相对简单,模型不容易在小数据集上过拟合。
等级判断就不同了。同一种金属的二级和三级,可能在颜色直方图上只有几个百分点的差异,可能同时涉及颜色、纹理、几何形状、表面覆盖率多个维度的连续特征。这些特征的联合作用用ANN来拟合更自然,网络可以学到“颜色上偏暗一点点但同时表面氧化斑占比较多,倾向于降级”这类复杂逻辑。
所以我采用了组合流程:
第一阶段:SVM做粗分类,输出7个大类。
第二阶段:对每个大类单独训练一个ANN等级模型,输出一级、二级、三级以及置信度。
2.3 为什么没直接上深度学习卷积网络
这是我在实际交流中回答最多的问题。现在提到图像分类,很多人第一反应就是上CNN或者更重的网络。但在这个项目里,我刻意避开了。
原因有三点。
第一是数据规模。回收现场的废料样本不像公开数据集一样容易获取。每种金属几百张图已经很不容易了,还要覆盖不同污染程度、不同照明条件、不同磨损状态。这点样本量塞给CNN,很容易过拟合,训出来的精度反而没有手工特征加SVM稳定。
第二是标注成本。深度学习端到端方案意味着要框出金属区域、标注类别、标注等级,数据清洗和标注工作量非常大。而手工特征方案只需要保证图像质量稳定,提取出来的特征有明确物理含义,标注压力小得多。
第三是硬件约束。很多回收车间没有专门的GPU工作站,现场能放一台普通i5工控机就不错了。SVM和轻量级ANN对这类设备非常友好,推理时间稳定在几十毫秒级,而深度学习模型即便能跑,散热、功耗和延迟都会增加部署复杂度。
做工程有时候不是选最前沿的方案,而是选资源约束下最稳的方案。
2.4 整体数据处理流程
这套系统的完整链路是:光电传感器触发相机拍照,采集到的图像先做ROI裁剪和预处理,然后提取颜色、纹理、几何特征,特征向量进入SVM做类别粗分;如果置信度够高,再送入该类别对应的ANN等级模型;最后根据阈值规则输出最终结论。
这个流程从我第一次试验到现在基本没变,变的只是特征维度和模型超参数。
3. 数据采集与特征工程
3.1 数据源选择:视觉为主、光谱辅助
废弃金属分类和分等级,可选的数据源其实不少。
视觉数据最容易获取,工业相机加固定光源就能搭建,信息也直观,适合判断大类。
光谱数据非常可靠,不同金属材质在近红外波段有各自的反射特征,但硬件成本高,一台手持式光谱仪的价格能顶好几个相机。光谱采样速度也慢一些,不太适合连续传送带场景。
我最终的方案是视觉为主,光谱辅助。也就是说,日常运行全靠视觉特征驱动,遇到关键仲裁料时,操作员用手持光谱仪抽检复核。这样既控制了成本,又能给模型结果加一道保险。
3.2 图像采集细节
采集设备这方面,我踩过不少坑。最开始用普通监控摄像头,分辨率倒是够了,但动态范围和色彩还原跟不上,金属表面反光一严重,拍出来的颜色和实际差异非常大。后来换成工业相机,加上两个固定条形光源,效果才稳定下来。
采集时要特别注意几点:
相机曝光时间要固定,不要开自动曝光。金属表面高光区很容易过曝,一旦过曝,颜色特征全废。
光源角度要统一。我测试过正面光和侧光,最终选的是45度角照射,既能减少正面反光,又能保留表面纹理细节。
加遮光罩。现场环境光不稳定,窗帘拉不严、灯泡色温不一致都会影响图像色彩分布。一个简易遮光罩就能解决一大半问题。
每块废料最好采集多个角度图像。废料形状不规则,只拍一面会漏掉重要表面特征。我后来采用“触发后连续拍三帧,取特征最稳定的作为代表”。
3.3 特征工程的几个关键点
特征工程是这个项目真正的灵魂。
我用了三类特征组合:
颜色特征:将图像转到HSV颜色空间,统计色调H、饱和度S、亮度V的均值和方差。金属表面的氧化程度、杂色覆盖比例,在色调和饱和度上反映非常明显。
纹理特征:用局部二值模式(LBP)和灰度共生矩阵(GLCM)提取表面纹理差异。比如锈蚀铁皮和光亮不锈钢的纹理粗糙度差异就很大。
几何特征:提取金属块轮廓的面积、周长、长宽比、凸度、最小外接矩形等。虽然废料形状随机,但当某类金属常见形态是片状而另一类是块状时,几何特征仍有区分价值。
这组特征最终压缩到12到20维左右,SVM训练非常舒服。别小看这些传统特征,在样本量有限、场景受控的项目里,它们的稳定性和可解释性比盲目堆深度学习网络要好得多。
3.4 特征预处理的必要操作
对SVM来说,特征必须先标准化。不同特征的量纲差距很大,比如面积动辄几千,色调均值却只有几十到一百多,如果不做标准化,SVM的距离计算会被大尺度特征主导。
我采用StandardScaler做z-score标准化,把所有特征拉到均值0、方差1的分布上。做标准化时有个细节,必须只用训练集的均值和方差去转换验证集和测试集,不能把验证集数据混进来一起算,否则会有信息泄漏,评估结果虚高。
标准化之后我又做了PCA降维。12到20维特征已经不算高,但PCA仍然有意义:它可以把相关的颜色特征、纹理特征压缩成几个正交主成分,减小冗余,加快SVM训练速度。我试过降到8到10维,分类精度几乎没有下降,训练时间明显减少。
3.5 标签体系与标注流程
标签是监督学习的根基,尤其等级标注更要设计得严谨。
我的标签体系是两个字段:
类别字段:紫铜、黄铜、铝合金、碳钢、不锈钢、锌、混合料。
等级字段:一级、二级、三级。一级对应表面干净、无明显氧化、杂质少;二级对应轻度氧化、少量杂质或油污;三级对应明显氧化、大面积油污、夹杂较多杂质。
为了让标注尽量客观,我制定了一份标注规范,附了每种等级的参考图片。两位标注员独立标注同一批数据,标签不一致的图片直接剔除,不参与训练。这看起来麻烦,但有效避免了模型学到不一致的边界。
4. 模型训练与调参实战
4.1 数据划分与交叉验证
数据准备好之后,第一步是划分训练集、验证集和测试集。我按6比2比2分配,并且使用分层采样,保证每一类金属在三个集合中的比例大致一致。如果随机乱切,某类样本全落在测试集里,训练时就没见过这个类,准确率自然崩。
训练过程中我用5折交叉验证来评估模型稳定性,最终以测试集上的结果为准。交叉验证的主要目的是防止“某一折切片运气好导致评估结果失真”的情况,尤其是样本量不大的项目里,单次切分的偶然性非常大。
4.2 SVM模型调参重点
SVM部分我直接用RBF径向基核函数,这也是小样本非线性分类最常用、最稳妥的选择。RBF核有两个关键超参数:
C表示对误差的容忍程度。C越大,模型越倾向于正确分类所有训练样本,容易过拟合;C越小,边界越平滑,可能欠拟合。
gamma控制单个样本影响范围。gamma越大,决策边界越复杂,容易过拟合;gamma越小,边界越平滑。
我用网格搜索在C=[0.1, 1, 10, 100]和gamma=[scale, 0.01, 0.1]范围内做5折交叉验证,最终选到C=10、gamma=scale,测试集大类分类准确率91.7%。
代码层面非常简洁:
from sklearn.svm import SVC from sklearn.preprocessing import StandardScaler from sklearn.pipeline import Pipeline pipe = Pipeline([ ('scaler', StandardScaler()), ('svc', SVC(kernel='rbf', C=10, gamma='scale', probability=True)) ]) pipe.fit(X_train, y_train) print(pipe.score(X_test, y_test))调参的一个技巧:不需要一上来就把网格范围铺得很大。先用C=1、gamma=scale跑一版,看混淆矩阵里哪几类容易混,再针对性地调。紫铜和黄铜如果混,说明更可能是特征问题而不是参数问题,这时候应该回头补充特征而不是罚参数。
4.3 ANN等级模型的结构与训练
等级模型我按每个大类单独训练。以紫铜为例,输入特征12维,输出是3个等级。
网络结构非常简单,两层全连接,神经元数量分别是16和8,激活函数用ReLU,输出层Softmax,中间加了Dropout防止过拟合。
from tensorflow.keras.models import Sequential from tensorflow.keras.layers import Dense, Dropout model = Sequential([ Dense(16, activation='relu', input_dim=12), Dropout(0.2), Dense(8, activation='relu'), Dense(3, activation='softmax') ]) model.compile(optimizer='adam', loss='categorical_crossentropy', metrics=['accuracy'])训练的时候设置早停,monitor验证集损失,patience=10,避免模型在训练集上反复滚导致过拟合。batch size用32,初始学习率用Adam默认的0.001。
最终紫铜等级判定的测试集准确率87.2%,macro F1得分0.86。我把这个结果跟只用颜色特征跑的模型对比了一下,准确率掉了5个多点,说明几何和纹理特征对等级判断确实有增量贡献。
4.4 评估指标不能只看准确率
分类和分级都容易出现类别不均衡。比如锌的样本少,它在总样本里占比只有不到10%,即使模型把所有锌都判成铝合金,准确率也只下降几个百分点,但业务上这种错误很致命。
所以要同时查精确率、召回率和F1,对每个类分别看。我用混淆矩阵辅助分析,紫铜和不锈钢很容易区分,但铝合金和锌之间偶尔会混,判断依据主要是光泽度和密度相关特征。这时候除了调模型参数,还要考虑在物理层增加传感器辅助,比如电涡流传感信号,作为额外特征输入。
5. 分类与分级体系设计
5.1 分类和分级是两个逻辑层次
回到最初的需求,系统输出的不是单一标签,而是一个结构化结果:
金属大类 + 等级 + 置信度。
大类由SVM决定,等级由对应大类的ANN模型决定。这个设计有一个好处:等级模型不需要知道全局有多少个类别,只需要关注自己那一个类内部的规律,学习负担大大减轻。
如果某块料被SVM判成铝合金,置信度却只有0.55,我宁可让它进人工复检通道,而不是强行交给铝合金等级模型去处理。因为一旦大类错了,后续分级结果没有任何意义。
5.2 规则与模型融合的分级策略
纯模型输出在等级边界上往往不稳定。同一块紫铜,拍两次可能得出一次一级一次二级,虽然差距不大,但现场操作员会觉得很困惑。
我在模型输出之后加了几条业务规则:
如果一级概率大于0.7且其他等级概率都低于0.2,判一级。
如果一级概率介于0.5到0.7,同时二级概率大于0.3,判二级。
如果任意两个等级概率都低于0.3,判定为“待复检”。
这个策略相当于给模型结果加了一个置信度缓冲区间,宁可放弃一部分自动判断,也不乱下结论。实际运行下来,自动判定率约75%,其中绝大多数正确率都很稳定。剩下的25%进入人工抽检,成本也可接受。
5.3 拒识机制可以救命
回收现场最怕的不是已知类别判错,而是遇到训练时完全没有见过的料型。比如某天收到一批镀金边角料,表面特征和铜类似,但跟训练集的任何一类都不完全匹配。模型硬分类的话,会把它强行塞进某个最近类里,结果可能给出一级的高置信度结论,实际卖出时才发现误差巨大。
解决办法是在特征空间里做距离判断。我保存了训练集各类别的特征质心,当新样本的特征向量距离所有质心都超过阈值时,系统输出“未知料”,直接送到人工处理。这个拒识机制看起来简单,但它避免了系统在未知样本上“胡说八道”,是工业现场部署必不可少的模块。
6. 系统落地与工程化实践
6.1 硬件拓扑与软件流程
实验室里能跑通模型只是第一步,真正上现场还有一堆事。
硬件配置方面,我用的是普通工控机加工业相机。相机固定在金属支架上,下方是传送带或检测台,两侧布置了LED条形光源,光电传感器在相机前方不远处,当金属块经过时产生硬触发信号,相机立刻拍照,避免软件轮询丢帧。
软件处理流程是这样的:
光电触发 → 相机拍照 → ROI裁剪 → 图像预处理 → 特征提取 → SVM大类分类 → ANN等级判定 → 规则检查 → 输出结果到PLC
结果输出给PLC之后,由PLC控制气动阀或者机械臂把不同等级的料推到对应料仓。现场显示屏幕上同时展示图像、类别、等级和置信度,方便工人确认。
6.2 实时性与性能优化
在普通i5工控机、没有GPU的条件下,单张图像从采集到输出结果控制在80到120毫秒。这个速度完全满足传送带每秒一两个物件的节拍要求。
处理耗时分布大致是:图像预处理占大头,特征提取次之,两个模型推理反而不到20毫秒。这说明瓶颈在视觉前处理,不在模型本身。
几个优化手段:
ROI裁剪只处理金属块所在区域,不做整幅图像全局处理。图像缩放到200乘200像素以内,对特征提取精度影响很小,但处理速度提升明显。颜色直方图和LBP特征提取用向量化实现,不用逐像素循环。
6.3 部署现场遇到的现实问题
实验室里模型准确率91.7%,真正搬到现场首周平均准确率只有86%左右。这个差距在预期之内,但还是要逐个解决。
最大干扰是光照。现场灯光会闪、会衰减,不同班次环境光差异也大。应对办法是定期校准白平衡,并且在训练时有意识地做色彩抖动增强,把亮度、饱和度随机调高调低,让模型对光照变化更钝感。
第二是遮挡和堆叠。传送带上金属件难免互相挤压,拍到的图像可能只露半边。我的处理是加逻辑规则:如果ROI面积占图像比例过小,或者轮廓紧贴图像边缘,判定为“不稳定样本”,不进入分类流程,等下一轮再测。
第三是灰尘。相机镜头和光源罩几天不擦就会发蒙,图像整体偏灰,特征分布整体漂移。定个规矩:每班开机前擦镜头,每周检查光源照度。
7. 常见问题与排查技巧实录
7.1 高频问题速查表
做这个项目前前后后遇到的坑不少,我把最典型的问题整理成表格,便于后来者对照自查。
| 问题现象 | 可能原因 | 解决思路 |
|---|---|---|
| 少数类别召回率低 | 样本量不均衡,模型倾向多数类 | 设置class_weight=balanced,或对少数类过采样 |
| 现场误检率明显高于实验室 | 光照漂移、表面状态变化 | 重做白平衡校准,利用现场数据增量训练 |
| 金属表面高光反光导致判错 | 特征过度依赖亮度信息 | 加偏振光滤光片,重点使用色调和纹理特征 |
| 等级判定在同一块料上波动大 | 等级边界定义太细、光照变化 | 检查标注一致性,放宽规则阈值,多次采样取均值 |
| 推理速度突然变慢 | 图像队列堆积、预处理耗时 | 限制ROI大小,增加缓存队列上限 |
| 新料型被强行分到已知类别 | 特征空间距离未检查 | 添加已知类别质心距离阈值,超出则拒识 |
7.2 排查思路与长期维护
如果系统输出开始异常,我的排查顺序很固定:先检查图像本身,再查特征分布,最后查模型输出。
很多问题根源都在图像质量上。镜头脏了、光源暗了、曝光参数被意外改动了,都会导致后续所有环节失效。先把原始图像打印出来看一遍,往往就能定位问题。
特征分布检查需要对比历史统计。我会维护一张特征分布表,记录正常状态下色调均值、饱和度均值、轮廓面积均值的区间。如果某天这些值出现大范围偏移,说明现场条件变了,模型输入分布也跟着变了,此时需要补充新数据重新训练。
还有一个重要经验:不要训练完模型就撒手不管。回收现场的料型变化很快,上周还是以铜线和铝块为主,这周可能来了一批镀锌板。模型的静态性能会在数月内自然衰减。我采取的维护策略是每周收集一批误判案例,每个月做一次增量训练,把badcase逐步掺入训练集,让模型跟上现场变化。
8. 从模型到产线,一些想复盘的事
这个项目做到最后,我最大的感触是:模型本身只是整条链路里风险最低的一环。真正决定系统成败的,是数据采集的标准、等级标注的定义,以及现场规则与模型输出的磨合。
如果让我重新做一遍,我会把更多时间花在设计等级标准和标注规范上。因为模型训练可以靠调试,参数不对可以重跑,但标注边界模糊的数据,无论用什么模型都学不到一个清晰的决策线,这是人工磨合的代价,换不回模型的稳定性能。
还有一点值得提醒:别指望部署完成就一劳永逸,模型在回收场景里一定是持续迭代的。定期复盘误判样本、维护数据分布、调整个别类别阈值,这些琐碎工作才是让整个系统从“能跑”走向“稳跑”的关键。个人体会而言,这套基于SVM和ANN的组合方案虽然谈不上新潮,但在数据量有限、计算资源受限的工业场景里,它确实是一条既可控、落地又快的路径。