一、Halcon17之后就已经推出了深度学习模块,之前一直没太关注过,最近一个项目需要用到目标检测,于是研究了Halcon深度学习三大模块,图像分类,目标检测,语义分割。并总结出来,供有缘人参考。
二、我使用的halcon版本是Halcon18.11,别的版本类似,在此不做阐述。欲使用Halcon深度学习,需要提前安装Halcon18.11.0.1-windows以及halcon-18.11.0.1-windows-deep-learning。深度学习安装包安装成功之后可以右键Halcon图标,打开文件位置查看以下关键文件有无。在路径D:\Program Files\MVTec\HALCON-18.11-Progress\dl下,有五个预训练深度模型,分别为pretrained_dl_classifier_compact.hdl,pretrained_dl_classifier_enhanced.hdl,pretrained_dl_classifier_resnet50.hdl,pretrained_dl_segmentation_compact.hdl,pretrained_dl_segmentation_enhanced.hdl。在路径D:\Program Files\MVTec\HALCON-18.11-Progress\bin\x64-win64\thirdparty下有两个第三方库,cublas64_100.dll,cudnn64_7.dll。这两个库是CUDA库和GPU加速必备的库。在路径D:\Program Files\MVTec\HALCON-18.11-Progress\bin\x64-win64下,还有个比较关键的库hcpudnn.dll,这个库是部署到VS里面时,设置CPU运行推断必须的库。还有cuda_10.0.130_411.31_win10 可以在英伟达官网下载,然后安装。这个是正好匹配Halcon18.11.0.1的cuda版本。
三、软件安装完毕后,还有一个重要的东西,就是标注工具。目标检测和语义分割的标注工具不同,图像分类不需要标注工具。dlt-0.6-ea-offline,mvtec_hdev_labeltool_v1.2。都可以自己在网上下载到。
四、代码实现,在Halcon官方例程里,有详细的代码案例供大家学习。其中图像分类和语义分割可以完全按官方例程,自己仿写,比较简单。我主要介绍下目标检测。代码如下。
dev_update_off ()
*** 创建检测模型 ***
**设置参数
*必须的参数
Backbone := ‘pretrained_dl_classifier_resnet50.hdl’
*class_ids的数量,标签的总类别数量
NumClasses := 4
*模型所需图片的规格参数
ImageWidth := 512
ImageHeight := 320
ImageNumChannels := 3
*金字塔参数
MinLevel := 2
MaxLevel := 4
NumSubscales := 3
AspectRatios := [1.0,0.5,2.0]
*容量参数
Capacity := ‘medium’
*创建模型参数字典
create_dict (DLModelDetectionParam)
set_dict_tuple (DLModelDetectionParam, ‘image_width’, ImageWidth)
set_dict_tuple (DLModelDetectionParam, ‘image_height’, ImageHeight)
set_dict_tuple (DLModelDetectionParam, ‘image_num_channels’, ImageNumChannels)
set_dict_tuple (DLModelDetectionParam, ‘min_level’, MinLevel)
set_dict_tuple (DLModelDetectionParam, ‘max_level’, MaxLevel)
set_dict_tuple (DLModelDetectionParam, ‘num_subscales’, NumSubscales)
set_dict_tuple (DLModelDetectionParam, ‘aspect_ratios’, AspectRatios)
set_dict_tuple (DLModelDetectionParam, ‘capacity’, Capacity)
*** 预处理数据 ***
**设置路径
*总路径
DataDir := ‘D:/A20_DeepLearning’
*图片路径
HalconImageDir:= DataDir + ‘/testImages/’
*数据集路径
PillBagHdictFile := DataDir + ‘/images.hdict’
*输出的模型路径
DLModelFileName := DataDir + ‘/pretrained_dl_model_detection.hdl’
**设置参数,训练集70%,验证集15%,测试集15%
TrainingPercent := 70
ValidationPercent := 15
*随机种子
SeedRand := 42
*判断总路径是否存在
file_exists (DataDir, FileExists)
if (not FileExists)
make_dir (DataDir)
endif
*读取数据集
read_dict (PillBagHdictFile, [], [], DLDataset)
*获取数据集ID给到模型参数
get_dict_tuple (DLDataset, ‘class_ids’, ClassIDs)
set_dl_model_param (DLModelHandle, ‘class_ids’, ClassIDs)
*生成新的模型
write_dl_model (DLModelHandle, DLModelFileName)
set_system (‘seed_rand’, SeedRand)
*分割数据集
split_dl_dataset (DLDataset, TrainingPercent, ValidationPercent, [])
*从模型中获取预处理参数
create_dict (GenParam)
set_dict_tuple (GenParam, ‘overwrite_files’, true)
create_dl_preprocess_param_from_model (DLModelHandle, ‘false’, ‘full_domain’, [], [], [], DLPreprocessParam)
*预处理
preprocess_dl_dataset (DLDataset, DataDirectory, DLPreprocessParam, GenParam, DLDatasetFilename)
*编写预处理参数以在后面的部分中使用它们
write_dict (DLPreprocessParam, PreprocessParamFileName, [], [])
*** 训练 ***
设置训练相关模型参数.
set_dl_model_param (DLModelHandle, ‘batch_size’, 2)
set_dl_model_param (DLModelHandle, ‘learning_rate’, 0.001)
set_dl_model_param (DLModelHandle, ‘runtime_init’, ‘immediately’)
创建在模型中使用的训练参数字典
*参数:模型、将训练模型的时期数(越大训练效果越好)、定义将多少时间传递给下一个模型评估
是否显示训练进度、设置随机种子、输出参数的名称、输出参数的字典、输出句柄
create_dl_train_param (DLModelHandle, 150, 1, ‘true’, 42, [], [], TrainParam)
*在数据集上训练一个基于深度学习的模型
train_dl_model (DLDataset, DLModelHandle, TrainParam, 0, TrainResults, TrainInfos, EvaluationInfos)
*
dev_close_window ()
dev_close_window ()
*** 评估 ***
create_dict (WindowDict)
create_dict (GenParamEval)
set_dict_tuple (GenParamEval, ‘detailed_evaluation’, true)
set_dict_tuple (GenParamEval, ‘show_progress’, true)
*对选定的DLDataset样本评估DLModelHandle给出的模型。
evaluate_dl_model (DLDataset, DLModelHandle, ‘split’, ‘test’, GenParamEval, EvaluationResult, EvalParams)
*
create_dict (DisplayMode)
set_dict_tuple (DisplayMode, ‘display_mode’, [‘pie_charts_precision’,‘pie_charts_recall’])
*可视化类型检测模型的详细评估结果
dev_display_detection_detailed_evaluation (EvaluationResult, EvalParams, DisplayMode, WindowDict)
stop ()
*关闭字典中包含句柄的所有窗口。
dev_display_dl_data_close_windows (WindowDict)
*** 测试 ***
*获取该路径下的所有图片
list_image_files (HalconImageDir, ‘default’, ‘recursive’, ImageFiles)
*对图片文件进行随机排序
tuple_shuffle (ImageFiles, ImageFilesShuffled)
*每次读取一张
set_dl_model_param (DLModelHandle, ‘batch_size’, 1)
*设置模型最小分数,最大重叠
set_dl_model_param (DLModelHandle, ‘min_confidence’, MinConfidence)
set_dl_model_param (DLModelHandle, ‘max_overlap’, MaxOverlap)
set_dl_model_param (DLModelHandle, ‘max_overlap_class_agnostic’, MaxOverlapClassAgnostic)
for i := 0 to |ImageFiles|-1 by 1
read_image (Image, ImageFilesShuffled[i])
compose3 (Image, Image, Image, MultiChannelImage)
gen_dl_samples_from_images (MultiChannelImage, DLSampleInference)
preprocess_dl_samples (DLSampleInference, DLPreprocessParam)
apply_dl_model (DLModelHandle, DLSampleInference, [], DLResult)
*获取结果
get_dict_tuple (DLResult, ‘bbox_row1’, bbox_row1)
get_dict_tuple (DLResult, ‘bbox_col1’, bbox_col1)
get_dict_tuple (DLResult, ‘bbox_row2’, bbox_row2)
get_dict_tuple (DLResult, ‘bbox_col2’, bbox_col2)
get_dict_tuple (DLResult, ‘bbox_class_id’, bbox_class_id)
get_dict_tuple (DLResult, ‘bbox_confidence’, bbox_confidence)
*为一个示例可视化不同的图像、注释和推理结果。
dev_display_dl_data (DLSampleInference, DLResult, DLDataset, ‘bbox_result’, [], WindowDict)
dev_disp_text (‘Press Run (F5) to continue’, ‘window’, ‘bottom’, ‘right’, ‘black’, [], [])
stop ()
endfor
*关闭可视化窗体
dev_display_dl_data_close_windows (WindowDict)
五、训练测试完毕后,可以在VS里面调用训练好的模型,需要把前面介绍过的关键库文件,dll放在项目执行目录下。
六、Halcon预训练模型区别如下:
6.1.pretrained_dl_classifier_compact.hdl模型
网络的优点是节省内存以及运行效率高,模型支持‘real’图像类型。如果想知道网络模型各参数值,可以使用算子get_dl_classifier_param获取,网络没有全连接层。网络架构支持改变训练图像尺寸,但最小尺寸不能低于15 x 15。
6.2.pretrained_dl_classifier_enhanced.hdl模型
对比compact网络,此网络拥有更多的隐含层,因此可以胜任更复杂的分类任务。但是代价是更大内存以及更长的训练时间,另外由于隐含层的增多,计算相较于上面的网络更复杂,所以batch_size不能设置太大。同样此网络架构也支持改变训练图像尺寸,但是最小尺寸不能低于47 x 47。虽然网络架构没有对图像尺寸设置上限,但是如果图像尺寸越大,那么需要占用的内存资源就越多,对内存的要求就更高,同时耗时更多。更改图像大小将重新初始化全连接层的权重,因此需要重新训练网络。
6.3.retrained_dl_classifier_resnet50.hdl模型
对比pretrained_dl_classifier_enhanced.hdl网络模型,此模型对更复杂的分类任务表现效果更好。它的网络结构不同于以上两个模型,训练时稳定性以及鲁棒性更好。同样此网络架构也支持改变训练图像尺寸,但是最小尺寸不能低于32 x 32。尽管同样是全连接层,图像大小的改变不会导致权重的重新初始化。