谈到智能制造、智慧工厂,愿景是美好的,借助计算机视觉技术和 AI 算法,为自动化生产线赋予环境感知的能力,从而改善工艺流程,提高生产效率。但是,随着柔性化生产的需求增长,产线的布局调整和功能扩展在所难免,这就要求设备供应商或使用者能够对 AI 算法进行持续性的维护、优化或移植,而现实是维护成本高、团队能力缺乏。
MATLAB 就像一位全能的搭档,提供了完备的文档和友好的交互式应用程序,即使是没有数据科学背景的领域工程师,也可以在一步步引导,快速完成“数据准备-AI 算法开发-系统部署”整个工作流程。
纸上得来终觉浅,让我们来具体看看,以上工作流在一个典型的工业应用场景——零件表面缺陷检测——中是如何实现的。
◆ ◆ ◆ ◆
数据准备
摄像头采集的原始图像数据中,往往含有大量冗余信息。前处理的第一步,通常是将被检测的目标对象和背景(其他无关物体)分离开来,即提取感兴趣区域(Region Of Interest, ROI)。在这里,可以运用一个小技巧:选择一个与目标颜色对比差异足够大的背景,采用简单的图像处理方法,例如颜色空间变换、二值化处理等,就可以快速提取出目标,而不需要使用计算更复杂的 YOLO 等目标检测深度神经网络。
具体步骤如下:
1.将采集的单帧彩色 RGB 图像转换为更有利于进行图像分割的 HSV 颜色模型;
img1 = snapshot(webcam);
hsv1 = rgb2hsv(img1);
2.通过大津算法确定阈值,对图像进行二值化分割;
th = otsuthresh(imhist(hsv1(:,:,2)));
bw = hsv1(:,:,2) > th;
bw = bwareaopen(~bw,50);
3.分析区域特性,可确定边界框,再对原图进行相应的裁剪;
stats = regionprops('table',bw,'BoundingBox');
bbox = int16(stats.BoundingBox);
img2 = imcrop(img1,bbox);
4.最后进行灰度化处理。
img3 = rgb2gray(img2);
经过以上步骤,单帧图像的数据量从 207x174x3 降低至 110x100,数据维度的降低,可减轻后续分类算法的需要完成的计算量,从而提高推断速度。
如果您的实际应用场景较为复杂,可考虑加强对外部环境的控制,例如光照条件、摄像头角度等,此外,在前处理的过程中,结合更多图像处理和计算机视觉技术,例如相机校准、图像增强和降噪等方法,以获得更高质量的样本数据。
采集足够多的样本后,通过对带有真值标注的数据进行监督式机器学习,是常用的构建预测模型进行分类的方法。使用 MATLAB 中的数据存储对象 imageDatastore,可以方便快速地对硬盘中的数据进行索引,并定义数据标签来源:
categ = {'good', 'defective'};
imds =imageDatastore(fullfile(pwd, 'images', categ), ...
'IncludeSubfolders',1,'LabelSource', 'foldernames')
我们准备了一个样本大小为 784 的数据集,标签为缺陷检测结果,其中 509 个“有缺陷”(Defective)样本,273 个“无缺陷”(Good)样本,随机选取 90% 样本作为训练集,剩余 10% 作为验证集:
[trainingSet,validationSet] = splitEachLabel(imds, 0.9, 'randomize');
在数据不够多、类别不均衡的情况下,借助数据增强的方法,对图像进行不同程度的平移、旋转和缩放等,可一定程度上提高机器学习模型的泛化能力。
augmenter =imageDataAugmenter('RandXReflection',true, ...
'RandYReflection',true,'RandRotation', [-180180]);
trainingSet =augmentedImageSource([227 227],trainingSet, ...
'DataAugmentation',augmenter);
◆ ◆ ◆ ◆
AI 算法开发
AI 应用领域目前主流的方法有两大分支:一是基于统计的传统机器学习方法,例如支持向量机、随机森林等,其中需要人为定义数据的特征作为输入;二是基于人工神经网络的深度学习方法,可以直接从数据中学习特征后进行推断。接下来,我们将探讨两种方式各自的可行性和优缺点:1. 基于特征工程和支持向量机的缺陷检测;2. 基于深度神经网络的缺陷检测。
方案 1. 基于特征工程和支持向量机的缺陷检测
特征工程,是机器学习中一个非常重要的环节,对模型推断的准确度影响很大。我们尝试使用 Bag of Features 方法,从图像数据中提取特征,并转换为机器学习算法可以处理的形式——特征向量。
bag =bagOfFeatures(trainingSet);
在 Bag of Features 中,将对每张图片,先用 SURF(加速稳健特征)算法提取局部特征,再通过 K-均值聚类将相似特征合并,聚类中心构成大小为 500 的视觉词汇字典。
每张图片可以对应表示为各个视觉词汇的组合,即特征向量,用于描述各个视觉词汇出现的频率。如以下直方图所示,不同样本的特征向量有所差别。
您可以通过 encode 函数,将每张图片对应转换为对应的特征向量后,作为机器学习模型的输入进行训练:
featureVector =encode(bag, img);
也可以通过 trainImageCategoryClassifier 函数,直接接收训练集和 bag 对象,快速训练一个支持向量机(SVM)分类器:
categoryClassifier= trainImageCategoryClassifier(trainingSet,bag);
分类器对训练集的预测准确度为 82%,测试集为 75%,通常进行超参数调优,可在一定程度上提高推断准确度,然而受限于人为的特征选择,传统机器学习方法的优化空间比较有限。如何能够降低难度并进一步提高分类准确度呢?我们来看下一个方案。
方案 2. 基于深度神经网络的缺陷检测
相较于方案1,深度神经网络训练和推断对计算资源的要求更高,但是往往准确度也更高。卷积神经网络(CNN)是一种适用于视觉任务的深度神经网络架构,如下图所示,从左到右,依次是输入层、特征学习相关层(卷积层,ReLU 激活层和池化层)和分类输出层。
MATLAB 深度学习工具箱提供了基础网络层库,您可以使用交互式应用程序 Deep Network Designer 从零起步创建网络,并进行图像分类网络的训练。目前有大量优秀的预训练网络,可供开发者直接使用,您只需要按照实际的任务对网络的输出进行微调后再训练,就能以较低的数据和计算成本,得到一个功能强大的深度学习模型,这种方法称为“迁移学习”。
我们选用 SqueezeNet 进行迁移学习,保留其中特征学习的部分,加入输出大小为 2 的全连接层,并替换最后的 Softmax 和分类层,使其适用于当前的二分类缺陷检测任务。
接下来,选择数据源为之前设定的训练集 trainingSet 和验证集 validationSet,可加入数据增强方法,然后,设置学习率、优化器等训练参数:
启动训练,并查看以下图窗中的曲线了解训练进度和效果:
训练完成后,可以看到验证准确度达到 97.44%,效果相对于方案1大幅提升,您可以在此基础上,尝试继续迭代优化,或直接导出至工作空间用于推断。以上操作流程可直接导出为 MATLAB 代码,当需要扩展数据集或更换数据时,用于自动化训练过程和模型更新。
后处理与神经网络验证
深度神经网络是一个黑盒模型,使用训练好的模型对新图像进行分类,可直接输出对应的标签,但是怎样解释预测结果,神经网络的推断是否有合理依据,却难以评估,此外,简单分类也无法反映缺陷的位置和形状。为了解答这些疑问,我们可以使用类激活映射(Class Activation Mapping, CAM)的方法,提供一些用于评估网络的可视化依据。
之前提到,卷积核会对特定的特征产生不同程度的激活,下图中,每一个黑白相间的像素组代表一个卷积核对输入图像产生的激活,白色像素表示强正激活,黑色表示负激活。预测结果(类别)和最后一个卷积层的激活程度,存在一定的映射关系,全连接层的权重值 [w1 w2 … w1000]T 代表各个激活对预测结果的贡献大小,加权计算以后得到的值称为类激活映射,将其以热图(heatmap)的形式,叠加在原图像上,如下:
上图中,高亮处代表神经网络将样本判定为“有缺陷“类别的主要特征,这与实际的缺陷位置基本吻合,我们可以判断神经网络预测依据合理。
◆ ◆ ◆ ◆
系统部署
算法开发完成后,最终需要部署到生产环境才能发挥作用。MATLAB 提供了完整的工具链,支持一次开发,多平台部署,您可以将深度神经网络,连同前后处理函数和其他应用逻辑,自动生成产品级代码,运行在嵌入式设备中,或者作为应用程序,运行在桌面、网页或者云端。
在代码生成方面,MATLAB Coder 支持基于 MKL-DNN 和 ARM Compute Library 的神经网络 C/C++ 代码生成,而 GPU Coder 则支持基于 NVIDIA GPU 的 CUDA 代码生成。
接下来,让我们来看看如何在真实场景下测试以上算法。
借助硬件支持包 GPU Coder Support Package for NVIDIA GPUs,可以快速将方案 2 部署在 Jetson Nano 的开发板中,步骤如下:
1. 连接硬件:
hwobj = jetson('hostname','username','password');
2. 设置代码生成相关参数,例如生成可执行文件,使用 cuDNN 库等:
cfg =coder.gpuConfig('exe');
cfg.DeepLearningConfig= coder.DeepLearningConfig('cudnn');
cfg.DeepLearningConfig.DataType= 'fp32';
cfg.Hardware =coder.hardware('NVIDIA Jetson');
cfg.Hardware.BuildDir= '~/';
3. 自动生成代码:
codegen -config cfg targetFunction -args {ones(240, 320, 3,'uint8'), coder.Constant(Weights),coder.Constant(true)} -report
下图为在 NVIDIA Jetson Nano 开发板上,调用 Webcam,对测试样本进行缺陷检测的效果示意,在使用 cuDNN 库,采用 32 位浮点计算的情况下,同时处理两个样本帧率大约为 4.3 FPS,单样本约为 8 FPS。
在以上模型的基础上,通过生成基于 TensorRT 的 fp16 代码,或采用 Xavier 等处理能力更强的硬件,可进一步加快推断速度。此外,您也可考虑使用其他神经网络架构。在 MATLAB 附加功能资源管理器中搜索”Deep Learning for Defect Detection on Raspberry Pi”,可以获取基于树莓派的代码部署版本。
◆ ◆ ◆ ◆
总结
概括来说,在 MATLAB 中,您可以:
-
通过图像处理技术减少原始图像数据中的冗余信息
-
利用深度学习直接学习特征,实现端到端的缺陷检测
-
借助应用程序和自动代码生成工具提高 AI 算法开发和部署效率