初次训练

Backbone 使用Halcon中的预训练模型
在create_dl_preprocess_param_from_model前使用create_dl_model_detection创建预训练模型

*****预处理****** 
dev_update_off ()

***预训练模型,初次训练则使用基础的几种模型
Backbone := 'pretrained_dl_classifier_resnet50.hdl'
***分类数量
NumClasses := 1
*
* 图像维度
ImageWidth := 512
ImageHeight := 320
ImageNumChannels := 1
* 
***设置容量为“中等”,足以完成此任务和提供更好的推理和训练速度。
***与“高等”相比,具有“中等”的模型的速度是其两倍多,同时显示出几乎相同的检测性能。
Capacity := 'medium'
* 
***数据集划分比例
TrainingPercent := 70
ValidationPercent := 15
* 
***随机数种子
SeedRand := 42
* 
***基础路径
ExampleDataDir := './基础路径/'
* 创建输出路径.
file_exists (ExampleDataDir, FileExists)
if (not FileExists)
    make_dir (ExampleDataDir)
endif
file_exists (ExampleDataDir+'/预处理', FileExists)
if (not FileExists)
    make_dir (ExampleDataDir+'/预处理')
endif
file_exists (ExampleDataDir+'/已训练', FileExists)
if (not FileExists)
    make_dir (ExampleDataDir+'/已训练')
endif
*输入初始地址和标签文件地址
Input_OriginalImageDir         := ExampleDataDir + '原图/images'
* 训练结果输出路径
DLModelOutputDir               := ExampleDataDir + '已训练/'
**用于测试的图像路径
TestImageDir                    :=''
*标签字典名称
HdictName                      :='dl_dataset'
*标签字典路径
Input_DatasetDictDir           :=ExampleDataDir + '预处理/' + HdictName + '.hdict'
***预训练模型输出路径
Output_PreDLModelFileName      := ExampleDataDir+'预处理/pretrained_dl_model_detection.hdl'
***预处理数据集输出路径
Output_SplitedDataSetDir       := ExampleDataDir +'预处理/'+ HdictName + '_' + ImageWidth + 'x' + ImageHeight
***模型参数(预处理参数)输出路径
Output_PreprocessParamFileName := DLModelOutputDir + 'dl_preprocess_param.hdict'
***数据集字典
Input_DLDatasetFileName        := Output_SplitedDataSetDir + '/dl_dataset.hdict'
* 最终模型文件名.
Output_FinalModelBaseName      := DLModelOutputDir + 'final_dl_model_detection'
* 最佳模型文件名.
Output_BestModelBaseName       := DLModelOutputDir + 'best_dl_model_detection'
*
*
******************************************
*****************预处理阶段****************
******************************************
set_system ('seed_rand', SeedRand) //设置随机种子
read_dict (Input_DatasetDictDir, [], [], DLDatasetDict) //读取数据集
set_dict_tuple (DLDatasetDict, 'image_dir', Input_OriginalImageDir) //设置图像路径
split_dl_dataset (DLDatasetDict, TrainingPercent, ValidationPercent, []) //分割数据集
create_dict (GenParam) //创建分割参数字典
set_dict_tuple (GenParam, 'split', 'train') //设置分割类型为训练
***
determine_dl_model_detection_param (DLDatasetDict, ImageWidth, ImageHeight, GenParam, DLDetectionModelParam) //自动选择合适的训练参数
get_dict_tuple (DLDetectionModelParam, 'min_level', MinLevel) //获取特征金字塔最小层数
get_dict_tuple (DLDetectionModelParam, 'max_level', MaxLevel) //获取特征金字塔最大层数
get_dict_tuple (DLDetectionModelParam, 'anchor_num_subscales', AnchorNumSubscales) //创建不同大小的锚点
get_dict_tuple (DLDetectionModelParam, 'anchor_aspect_ratios', AnchorAspectRatios) //创建不同形状的锚点
***
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, 'anchor_num_subscales', AnchorNumSubscales)
* set_dict_tuple (DLModelDetectionParam, 'anchor_aspect_ratios', AnchorAspectRatios)
set_dict_tuple (DLModelDetectionParam, 'capacity', Capacity) //设置模型容量
***
get_dict_tuple (DLDatasetDict, 'class_ids', ClassIDs) //从数据集中获取类别ID
set_dict_tuple (DLModelDetectionParam, 'class_ids', ClassIDs) //设置类别ID
get_dict_tuple (DLDatasetDict, 'class_names', ClassNames) //从数据集中获取类别名称
set_dict_tuple (DLModelDetectionParam, 'class_names', ClassNames) //设置类别名称
***
create_dl_model_detection (Backbone, NumClasses, DLModelDetectionParam, DLModelHandle) //创建预训练模型
write_dl_model (DLModelHandle, Output_PreDLModelFileName) //保存预训练模型
***
create_dl_preprocess_param_from_model (DLModelHandle, 'none', 'full_domain', [], [], [], DLPreprocessParam) //创建预处理参数
***
create_dict (GenParam) //创建预处理参数字典
set_dict_tuple (GenParam, 'overwrite_files', 'auto') //设置覆盖文件为自动
preprocess_dl_dataset (DLDatasetDict, Output_SplitedDataSetDir, DLPreprocessParam, GenParam, DLDatasetFilename) //开始预处理
write_dict (DLPreprocessParam, Output_PreprocessParamFileName, [], []) //保存预处理参数

******************************************
*****************训练阶段******************
******************************************
dev_update_off ()
ShowExampleScreens := true
* 
* 选择CPU或GPU
query_available_dl_devices (['runtime', 'runtime'], ['gpu', 'cpu'], DLDeviceHandles)
if (|DLDeviceHandles| == 0)
    throw ('No supported device found to continue this example.')
endif
DLDevice := DLDeviceHandles[0]
get_dl_device_param (DLDevice, 'type', DLDeviceType)
if (DLDeviceType == 'cpu')
    NumThreadsTraining := 4
    set_system ('thread_num', NumThreadsTraining)
endif
****************************
*****设置基本训练参数*********
****************************
BatchSize := 1 //训练批次大小
InitialLearningRate := 0.00005 //初始学习率
***用在权重更新的时候 v=Momentum*v-learning_rate*dw, w = w + v 
***如果上次的Momentum(v)与这次的负梯度方向是相同的,那这次下降的幅度就会加大,从而加速收敛
Momentum := 0.99 //SGD动量
NumEpochs := 400 //训练周期
EvaluationIntervalEpochs := 1 //训练中的评估周期
ChangeLearningRateEpochs := 1 //改变学习率的周期
ChangeLearningRateValues := InitialLearningRate //每次改变所使用的学习率,这里是固定学习率
* ChangeLearningRateEpochs := [50,100,200] //改变学习率的周期,第50,100,200个周期的时候改变学习率
* ChangeLearningRateValues := [0.00005,0.00001,0.000005] //每次改变所使用的学习率,分别对应50,100,200周期的时候
****************************
*****设置超参数**************
****************************
* 建议一开始将正则项系数λ设置为0,先确定一个比较好的learning rate。
* 然后固定该learning rate,给λ一个值(比如1.0),然后根据validation accuracy,
* 将λ增大或者减小10倍(增减10倍是粗调节,当你确定了λ的合适的数量级后,比如λ = 0.01,再进一步地细调节,比如调节为0.02,0.03,0.009之类。)
WeightPrior := 0.001 //正则化系数
*
EnableDisplay := true //显示训练过程
****************************
*****设置训练参数************
****************************
GenParamName := []
GenParamValue := []
create_dict (AugmentationParam) //增强参数
set_dict_tuple (AugmentationParam, 'augmentation_percentage', 50) //训练时图像增强比例
* set_dict_tuple (AugmentationParam, 'rotate', 0) //训练时图像旋转角度 [0, 90, 180]
* set_dict_tuple (AugmentationParam, 'rotate_range', 0) //训练时图像旋转角度步长
* set_dict_tuple (AugmentationParam, 'mirror', 'off') //训练时图像镜像 'r' , 'c'.
* set_dict_tuple (AugmentationParam, 'brightness_variation', 0) //训练时图像亮度变化范围 [-value, +value]. 0-255
* set_dict_tuple (AugmentationParam, 'brightness_variation_spot', 0) //训练时图像随机定位斑点的绝对亮度峰值 [-value, +value]. 0-255
* set_dict_tuple (AugmentationParam, 'crop_percentage', 1) //训练时图像剪切比例
* set_dict_tuple (AugmentationParam, 'crop_pixel', 'off') //训练时图像剪切后剩余图像宽高 [w,h]
GenParamName := [GenParamName,'augment']
GenParamValue := [GenParamValue,AugmentationParam]
****************************
*****设置训练策略************
****************************
if (|ChangeLearningRateEpochs| > 0)
    create_dict (ChangeStrategy)
    set_dict_tuple (ChangeStrategy, 'model_param', 'learning_rate')
    set_dict_tuple (ChangeStrategy, 'initial_value', InitialLearningRate)
    set_dict_tuple (ChangeStrategy, 'epochs', ChangeLearningRateEpochs)
    set_dict_tuple (ChangeStrategy, 'values', ChangeLearningRateValues)
    GenParamName := [GenParamName,'change']
    GenParamValue := [GenParamValue,ChangeStrategy]
endif
****************************
*****设置序列化策略**********
****************************
create_dict (SerializationStrategy)
set_dict_tuple (SerializationStrategy, 'type', 'best')  //训练过程中保存最佳模型
set_dict_tuple (SerializationStrategy, 'basename', Output_BestModelBaseName)
GenParamName := [GenParamName,'serialize']
GenParamValue := [GenParamValue,SerializationStrategy]
create_dict (SerializationStrategy)
set_dict_tuple (SerializationStrategy, 'type', 'final')  //训练过程中保存最终模型
set_dict_tuple (SerializationStrategy, 'basename', Output_FinalModelBaseName)
GenParamName := [GenParamName,'serialize']
GenParamValue := [GenParamValue,SerializationStrategy]
****************************
*****设置显示参数************
****************************
SelectedPercentageTrainSamples := 0 //训练过程中用于评估的样本比例
XAxisLabel := 'epochs' //X轴标签
create_dict (DisplayParam)
set_dict_tuple (DisplayParam, 'selected_percentage_train_samples', SelectedPercentageTrainSamples)
set_dict_tuple (DisplayParam, 'x_axis_label', XAxisLabel)
GenParamName := [GenParamName,'display']
GenParamValue := [GenParamValue,DisplayParam]
****************************
*****检查文件****************
****************************
check_data_availability (ExampleDataDir, Output_PreDLModelFileName, Input_DLDatasetFileName) //检查文件
read_dl_model (Output_PreDLModelFileName, DLModelHandle) //读取预训练模型
read_dict (Input_DLDatasetFileName, [], [], DLDataset) //读取数据集
****************************
*****设置训练参数************
****************************
set_dl_model_param (DLModelHandle, 'learning_rate', InitialLearningRate)
set_dl_model_param (DLModelHandle, 'momentum', Momentum)
set_dl_model_param (DLModelHandle, 'batch_size', BatchSize)
if (|WeightPrior| > 0)
    set_dl_model_param (DLModelHandle, 'weight_prior', WeightPrior)
endif
****************************
*****设置训练设备************
****************************
set_dl_model_param (DLModelHandle, 'device', DLDevice)
****************************
*****开始训练****************
****************************
create_dl_train_param (DLModelHandle, NumEpochs, EvaluationIntervalEpochs, EnableDisplay, SeedRand, GenParamName, GenParamValue, TrainParam)
train_dl_model (DLDataset, DLModelHandle, TrainParam, 0.0, TrainResults, TrainInfos, EvaluationInfos)
dev_disp_text ('Press Run (F5) to continue', 'window', 'bottom', 'right', 'black', [], [])
stop ()
dev_close_window ()
dev_close_window ()

******************************************
*****************评估结果阶段**************
******************************************
dev_update_off ()
UsePretrainedModel := false //使用预训练模型
if (UsePretrainedModel)
    RetrainedModelFileName := Output_PreDLModelFileName
else
    RetrainedModelFileName := Output_BestModelBaseName+'.hdl'
endif
EvaluationMeasures := 'all' //评估措施
IoUThresholds := [] //交并比阈值
DisplayIoUThreshold := 0.7 //显示的交并比阈值
BatchSize := 1         //批次大小
AreaNames := []        //区域名称
AreaMin := []          //区域最小值
AreaMax := []          //区域最大值
MaxNumDetections := [] //最大检测数量
****************************
*****检查文件****************
****************************
check_data_availability_for_evaluation (ExampleDataDir, Input_DLDatasetFileName, RetrainedModelFileName, UsePretrainedModel)//检查文件存在
read_dl_model (RetrainedModelFileName, DLModelHandle)
set_dl_model_param (DLModelHandle, 'batch_size', 1)
set_dl_model_param (DLModelHandle, 'device', DLDevice)
read_dict (Input_DLDatasetFileName, [], [], DLDataset)
****************************
*****设置推理参数************
****************************
set_dl_model_param (DLModelHandle, 'max_overlap_class_agnostic', 0.7)//不同类的最大重叠度
set_dl_model_param (DLModelHandle, 'max_overlap', 0.2)   //相同类的最大重叠度
set_dl_model_param (DLModelHandle, 'min_confidence', 0.6)//最小置信度
****************************
*****设置可视化参数**********
****************************
create_dict (WindowHandleDict)
create_dict (GenParam)
set_dict_tuple (GenParam, 'bbox_display_confidence', false)
get_dict_tuple (DLDataset, 'samples', DatasetSamples)
find_dl_samples (DatasetSamples, 'split', 'test', 'or', DLSampleIndices) //寻找测试集
tuple_shuffle (DLSampleIndices, DLSampleIndicesShuffled) //随机选择图像
****************************
*****可视化测试结果**********
****************************
for Index := 0 to 5 by 1
    read_dl_samples (DLDataset, DLSampleIndicesShuffled[Index], DLSampleBatch)
    apply_dl_model (DLModelHandle, DLSampleBatch, [], DLResultBatch)
    dev_display_dl_data (DLSampleBatch, DLResultBatch, DLDataset, 'bbox_both', GenParam, WindowHandleDict)
    dev_disp_text ('Press Run (F5)\nto continue', 'window', 'bottom', 'right', 'black', [], [])
    stop ()
endfor
dev_close_window_dict (WindowHandleDict)
****************************
*****设置评估参数************
****************************
create_dict (GenParamEval)
set_dict_tuple (GenParamEval, 'measures', EvaluationMeasures) //设置评估措施
if (|MaxNumDetections|)
    set_dict_tuple (GenParamEval, 'max_num_detections', MaxNumDetections) //设置最大检测数
endif
***设置子集参数
if (|AreaNames|)
    if ((|AreaNames| != |AreaMin|) or (|AreaNames| != |AreaMax|))
        throw ('AreaNames, AreaMin, and AreaMax must have the same size.')
    endif
    create_dict (AreaRanges)
    set_dict_tuple (AreaRanges, 'name', AreaNames)
    set_dict_tuple (AreaRanges, 'min', AreaMin)
    set_dict_tuple (AreaRanges, 'max', AreaMax)
    set_dict_tuple (GenParamEval, 'area_ranges', AreaRanges)
endif
if (|IoUThresholds|)
    set_dict_tuple (GenParamEval, 'iou_threshold', IoUThresholds) //设置交并比阈值
endif
**TP:正类预测为正类
**TN:负类预测为负类
**FP:负类预测为正类
**FN:负类预测为负类
set_dict_tuple (GenParamEval, 'detailed_evaluation', true) //启用TP、TN、FP评估
set_dict_tuple (GenParamEval, 'show_progress', true) //显示评估进度
****************************
*****开始评估训练结果********
****************************
evaluate_dl_model (DLDataset, DLModelHandle, 'split', 'test', GenParamEval, EvaluationResultDetection, EvalParams)
****************************
*****显示评估结果************
****************************
create_dict (DisplayParam)
***设置显示的交并比阈值
if (|DisplayIoUThreshold| == 1)
    get_dict_tuple (EvalParams, 'iou_threshold', EvalIoUThresholds)
    if (find(EvalIoUThresholds,DisplayIoUThreshold) != -1)
        set_dict_tuple (DisplayParam, 'iou_threshold', DisplayIoUThreshold)
    else
        throw ('No evaluation result for specified IoU threshold.')
    endif
endif
****************************
*****显示精确率和召回率*******
****************************
** precision_P = TP/(TP+FP)  预测正确的图片个数占总的正类预测个数的比例(从预测结果角度看,有多少预测是准确的)
**    recall_R = TP/(TP+FN)  确定了正类被预测为正类图片占所有标注图片的个数(从标注角度看,有多少被召回)
set_dict_tuple (DisplayParam, 'display_mode', ['pie_charts_precision', 'pie_charts_recall'])
create_dict (WindowHandleDict)
dev_display_detection_detailed_evaluation (EvaluationResultDetection, EvalParams, DisplayParam, WindowHandleDict)
dev_disp_text ('Press Run (F5) to continue', 'window', 'top', 'right', 'black', [], [])
stop ()
dev_close_window_dict (WindowHandleDict)
****************************
*****显示准确率数量**********
****************************
set_dict_tuple (DisplayParam, 'display_mode', 'absolute_confusion_matrix')
dev_display_detection_detailed_evaluation (EvaluationResultDetection, EvalParams, DisplayParam, WindowHandleDict)
dev_disp_text ('Press Run (F5) to continue', 'window', 'bottom', 'right', 'black', [], [])
stop ()
dev_close_window_dict (WindowHandleDict)
****************************
*****优化模型内存**********
****************************
set_dl_model_param (DLModelHandle, 'batch_size', 1)
set_dl_model_param (DLModelHandle, 'optimize_for_inference', 'true')
write_dl_model (DLModelHandle, RetrainedModelFileName)
* Close the windows.
dev_close_window_dict (WindowHandleDict)

******************************************
*****************推理测试阶段**************
******************************************
UsePretrainedModel := false //使用预训练模型
* 设置使用的模型
if (UsePretrainedModel)
    RetrainedModelFileName := Output_PreDLModelFileName
else
    RetrainedModelFileName := Output_BestModelBaseName+'.hdl'
endif
BatchSizeInference := 1 //推理使用的批次大小
* 
* 置信度和重叠度
MinConfidence := 0.6           //最小置信度
MaxOverlap := 0.2              //相同类的最大重叠度
MaxOverlapClassAgnostic := 0.7 //不同类的最大重叠度
****************************
*****检查文件****************
****************************
check_data_availability_for_inference (ExampleDataDir, Output_PreprocessParamFileName, RetrainedModelFileName, UsePretrainedModel)
read_dl_model (RetrainedModelFileName, DLModelHandle) //读取训练的模型
read_dict (Output_PreprocessParamFileName, [], [], DLPreprocessParam) //读取模型预处理参数
****************************
*****设置参数****************
****************************
set_dl_model_param (DLModelHandle, 'batch_size', BatchSizeInference) //设置批次大小
set_dl_model_param (DLModelHandle, 'device', DLDevice) //初始化设备
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)
****************************
*****设置类别字典************
****************************
create_dict (DLDataInfo)
get_dl_model_param (DLModelHandle, 'class_names', ClassNames) 
set_dict_tuple (DLDataInfo, 'class_names', ClassNames)
get_dl_model_param (DLModelHandle, 'class_ids', ClassIDs)
set_dict_tuple (DLDataInfo, 'class_ids', ClassIDs)
****************************
*****设置可视化参数**********
****************************
create_dict (WindowHandleDict)
create_dict (GenParam)
set_dict_tuple (GenParam, 'scale_windows', 1.2)
****************************
*****开始测试结果************
****************************
list_image_files (TestImageDir, 'default', 'recursive', ImageFiles)
for BatchIndex := 0 to floor(|ImageFiles| / real(BatchSizeInference)) - 1 by 1
    * 
    Batch := ImageFiles[BatchIndex * BatchSizeInference:(BatchIndex + 1) * BatchSizeInference - 1]
    read_image (ImageBatch, Batch)
    gen_dl_samples_from_images (ImageBatch, DLSampleBatch)
    preprocess_dl_samples (DLSampleBatch, DLPreprocessParam)
    apply_dl_model (DLModelHandle, DLSampleBatch, [], DLResultBatch)
    for SampleIndex := 0 to BatchSizeInference - 1 by 1
        DLSample := DLSampleBatch[SampleIndex]
        DLResult := DLResultBatch[SampleIndex]
        get_dict_tuple (DLResult, 'bbox_class_id', DetectedClassIDs)
        tuple_gen_const (|ClassIDs|, 0, NumberDetectionsPerClass)
        for Index := 0 to |ClassIDs| - 1 by 1
            NumberDetectionsPerClass[Index] := sum(DetectedClassIDs [==] ClassIDs[Index])
        endfor
        create_counting_result_text (NumberDetectionsPerClass, ClassNames, Text, TextColor, TextBoxColor)
        dev_display_dl_data (DLSample, DLResult, DLDataInfo, 'bbox_result', GenParam, WindowHandleDict)
        get_dict_tuple (WindowHandleDict, 'bbox_result', WindowHandles)
        dev_set_window (WindowHandles[0])
        set_display_font (WindowHandles[0], 16, 'mono', 'true', 'false')
        dev_disp_text (Text, 'window', 'top', 'left', TextColor, ['box_color', 'shadow'], [TextBoxColor,'false'])
        dev_disp_text ('Press Run (F5) to continue', 'window', 'bottom', 'right', 'black', [], [])
        stop ()
    endfor
endfor
dev_close_window_dict (WindowHandleDict)

追加训练

Backbone使用上一次训练的模型,一般使用最佳模型
在create_dl_preprocess_param_from_model前使用read_dl_model创建预训练模型

dev_update_off ()

******************************************
*****************准备阶段******************
******************************************
***预训练模型,在迁移训练中,使用的是上一次训练的结果
Backbone := './上一次/已训练/best_dl_model_detection.hdl'
***分类数量
NumClasses := 1
*
* 图像维度
ImageWidth := 512
ImageHeight := 320
ImageNumChannels := 1
* 
***设置容量为“中等”,足以完成此任务和提供更好的推理和训练速度。
***与“高等”相比,具有“中等”的模型的速度是其两倍多,同时显示出几乎相同的检测性能。
Capacity := 'medium'
* 
***数据集划分比例
TrainingPercent := 70
ValidationPercent := 15
* 
***随机数种子
SeedRand := 42
* 
***基础路径
ExampleDataDir := './这一次/'
* 创建输出路径.
file_exists (ExampleDataDir, FileExists)
if (not FileExists)
    make_dir (ExampleDataDir)
endif
file_exists (ExampleDataDir+'/预处理', FileExists)
if (not FileExists)
    make_dir (ExampleDataDir+'/预处理')
endif
file_exists (ExampleDataDir+'/已训练', FileExists)
if (not FileExists)
    make_dir (ExampleDataDir+'/已训练')
endif
*输入初始地址和标签文件地址
Input_OriginalImageDir         := ExampleDataDir + '原图/images'
* 训练结果输出路径
DLModelOutputDir               := ExampleDataDir + '已训练/'
**用于测试的图像路径
TestImageDir                    :=''
*标签字典名称
HdictName                      :='dl_dataset'
*标签字典路径
Input_DatasetDictDir           :=ExampleDataDir + '预处理/' + HdictName + '.hdict'
***预训练模型输出路径
Output_PreDLModelFileName      := ExampleDataDir+'预处理/pretrained_dl_model_detection.hdl'
***预处理数据集输出路径
Output_SplitedDataSetDir       := ExampleDataDir +'预处理/'+ HdictName + '_' + ImageWidth + 'x' + ImageHeight
***模型参数(预处理参数)输出路径
Output_PreprocessParamFileName := DLModelOutputDir + 'dl_preprocess_param.hdict'
***数据集字典
Input_DLDatasetFileName        := Output_SplitedDataSetDir + '/dl_dataset.hdict'
* 最终模型文件名.
Output_FinalModelBaseName      := DLModelOutputDir + 'final_dl_model_detection'
* 最佳模型文件名.
Output_BestModelBaseName       := DLModelOutputDir + 'best_dl_model_detection'
*
* 
* 选择CPU或GPU
query_available_dl_devices (['runtime', 'runtime'], ['gpu', 'cpu'], DLDeviceHandles)
if (|DLDeviceHandles| == 0)
    throw ('No supported device found to continue this example.')
endif
DLDevice := DLDeviceHandles[0]
get_dl_device_param (DLDevice, 'type', DLDeviceType)
if (DLDeviceType == 'cpu')
    NumThreadsTraining := 4
    set_system ('thread_num', NumThreadsTraining)
endif
*
******************************************
*****************预处理阶段****************
******************************************
set_system ('seed_rand', SeedRand) //设置随机种子
read_dict (Input_DatasetDictDir, [], [], DLDatasetDict) //读取数据集
set_dict_tuple (DLDatasetDict, 'image_dir', Input_OriginalImageDir) //设置图像路径
split_dl_dataset (DLDatasetDict, TrainingPercent, ValidationPercent, []) //分割数据集
create_dict (GenParam) //创建分割参数字典
set_dict_tuple (GenParam, 'split', 'train') //设置分割类型为训练
***
determine_dl_model_detection_param (DLDatasetDict, ImageWidth, ImageHeight, GenParam, DLDetectionModelParam) //自动选择合适的训练参数
get_dict_tuple (DLDetectionModelParam, 'min_level', MinLevel) //获取特征金字塔最小层数
get_dict_tuple (DLDetectionModelParam, 'max_level', MaxLevel) //获取特征金字塔最大层数
get_dict_tuple (DLDetectionModelParam, 'anchor_num_subscales', AnchorNumSubscales) //创建不同大小的锚点
get_dict_tuple (DLDetectionModelParam, 'anchor_aspect_ratios', AnchorAspectRatios) //创建不同形状的锚点
***
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, 'anchor_num_subscales', AnchorNumSubscales)
* set_dict_tuple (DLModelDetectionParam, 'anchor_aspect_ratios', AnchorAspectRatios)
set_dict_tuple (DLModelDetectionParam, 'capacity', Capacity) //设置模型容量
***
get_dict_tuple (DLDatasetDict, 'class_ids', ClassIDs) //从数据集中获取类别ID
set_dict_tuple (DLModelDetectionParam, 'class_ids', ClassIDs) //设置类别ID
get_dict_tuple (DLDatasetDict, 'class_names', ClassNames) //从数据集中获取类别名称
set_dict_tuple (DLModelDetectionParam, 'class_names', ClassNames) //设置类别名称
***创建初始模型,在迁移训练中,这里使用的是上一次训练的结果
* create_dl_model_detection (Backbone, NumClasses, DLModelDetectionParam, DLModelHandle) //创建预训练模型
read_dl_model (Backbone, DLModelHandle) //创建预训练模型
write_dl_model (DLModelHandle, Output_PreDLModelFileName) //保存预训练模型
***
create_dl_preprocess_param_from_model (DLModelHandle, 'none', 'full_domain', [], [], [], DLPreprocessParam) //创建预处理参数
***
create_dict (GenParam) //创建预处理参数字典
set_dict_tuple (GenParam, 'overwrite_files', 'auto') //设置覆盖文件为自动
preprocess_dl_dataset (DLDatasetDict, Output_SplitedDataSetDir, DLPreprocessParam, GenParam, DLDatasetFilename) //开始预处理
write_dict (DLPreprocessParam, Output_PreprocessParamFileName, [], []) //保存预处理参数

******************************************
*****************训练阶段******************
******************************************
dev_update_off ()
ShowExampleScreens := true

****************************
*****设置基本训练参数*********
****************************
BatchSize := 4 //训练批次大小
InitialLearningRate := 0.00001 //初始学习率
***用在权重更新的时候 v=Momentum*v-learning_rate*dw, weight = weight + v 
***如果上次的Momentum(v)与这次的负梯度方向是相同的,那这次下降的幅度就会加大,从而加速收敛
Momentum := 0.99 //SGD动量 
NumEpochs := 400 //训练周期
EvaluationIntervalEpochs := 1 //训练中的评估周期
ChangeLearningRateEpochs := 1 //改变学习率的周期
ChangeLearningRateValues := InitialLearningRate //每次改变所使用的学习率,这里是固定学习率
* ChangeLearningRateEpochs := [100,200,300] //改变学习率的周期,第50,100,200个周期的时候改变学习率
* ChangeLearningRateValues := [0.00005,0.00001,0.000005] //每次改变所使用的学习率,分别对应50,100,200周期的时候
****************************
*****设置超参数**************
****************************
* 建议一开始将正则项系数λ设置为0,先确定一个比较好的learning rate。
* 然后固定该learning rate,给λ一个值(比如1.0),然后根据validation accuracy,
* 将λ增大或者减小10倍(增减10倍是粗调节,当你确定了λ的合适的数量级后,比如λ = 0.01,再进一步地细调节,比如调节为0.02,0.03,0.009之类。)
WeightPrior := 0.006 //正则化系数
*
EnableDisplay := true //显示训练过程
****************************
*****设置训练参数************
****************************
GenParamName := []
GenParamValue := []
create_dict (AugmentationParam) //增强参数
set_dict_tuple (AugmentationParam, 'augmentation_percentage', 20) //训练时图像增强比例
* set_dict_tuple (AugmentationParam, 'rotate', 0) //训练时图像旋转角度 [0, 90, 180]
* set_dict_tuple (AugmentationParam, 'rotate_range', 0) //训练时图像旋转角度步长
* set_dict_tuple (AugmentationParam, 'mirror', 'off') //训练时图像镜像 'r' , 'c'.
* set_dict_tuple (AugmentationParam, 'brightness_variation', 0) //训练时图像亮度变化范围 [-value, +value]. 0-255
* set_dict_tuple (AugmentationParam, 'brightness_variation_spot', 0) //训练时图像随机定位斑点的绝对亮度峰值 [-value, +value]. 0-255
* set_dict_tuple (AugmentationParam, 'crop_percentage', 1) //训练时图像剪切比例
* set_dict_tuple (AugmentationParam, 'crop_pixel', 'off') //训练时图像剪切后剩余图像宽高 [w,h]
GenParamName := [GenParamName,'augment']
GenParamValue := [GenParamValue,AugmentationParam]
****************************
*****设置训练策略************
****************************
if (|ChangeLearningRateEpochs| > 0)
    create_dict (ChangeStrategy)
    set_dict_tuple (ChangeStrategy, 'model_param', 'learning_rate')
    set_dict_tuple (ChangeStrategy, 'initial_value', InitialLearningRate)
    set_dict_tuple (ChangeStrategy, 'epochs', ChangeLearningRateEpochs)
    set_dict_tuple (ChangeStrategy, 'values', ChangeLearningRateValues)
    GenParamName := [GenParamName,'change']
    GenParamValue := [GenParamValue,ChangeStrategy]
endif
****************************
*****设置序列化策略**********
****************************
create_dict (SerializationStrategy)
set_dict_tuple (SerializationStrategy, 'type', 'best')  //训练过程中保存最佳模型
set_dict_tuple (SerializationStrategy, 'basename', Output_BestModelBaseName)
GenParamName := [GenParamName,'serialize']
GenParamValue := [GenParamValue,SerializationStrategy]
create_dict (SerializationStrategy)
set_dict_tuple (SerializationStrategy, 'type', 'final')  //训练过程中保存最终模型
set_dict_tuple (SerializationStrategy, 'basename', Output_FinalModelBaseName)
GenParamName := [GenParamName,'serialize']
GenParamValue := [GenParamValue,SerializationStrategy]
****************************
*****设置显示参数************
****************************
SelectedPercentageTrainSamples := 0 //训练过程中用于评估的样本比例
XAxisLabel := 'epochs' //X轴标签
create_dict (DisplayParam)
set_dict_tuple (DisplayParam, 'selected_percentage_train_samples', SelectedPercentageTrainSamples)
set_dict_tuple (DisplayParam, 'x_axis_label', XAxisLabel)
GenParamName := [GenParamName,'display']
GenParamValue := [GenParamValue,DisplayParam]
****************************
*****检查文件****************
****************************
check_data_availability (ExampleDataDir, Output_PreDLModelFileName, Input_DLDatasetFileName) //检查文件
read_dl_model (Output_PreDLModelFileName, DLModelHandle) //读取预训练模型
read_dict (Input_DLDatasetFileName, [], [], DLDataset) //读取数据集
****************************
*****设置训练参数************
****************************
set_dl_model_param (DLModelHandle, 'learning_rate', InitialLearningRate)
set_dl_model_param (DLModelHandle, 'momentum', Momentum)
set_dl_model_param (DLModelHandle, 'batch_size', BatchSize)
set_dl_model_param (DLModelHandle, 'freeze_backbone_level', 2)//冻结层数
if (|WeightPrior| > 0)
    set_dl_model_param (DLModelHandle, 'weight_prior', WeightPrior)
endif
****************************
*****设置训练设备************
****************************
set_dl_model_param (DLModelHandle, 'device', DLDevice)
****************************
*****开始训练****************
****************************
create_dl_train_param (DLModelHandle, NumEpochs, EvaluationIntervalEpochs, EnableDisplay, SeedRand, GenParamName, GenParamValue, TrainParam)
train_dl_model (DLDataset, DLModelHandle, TrainParam, 0.0, TrainResults, TrainInfos, EvaluationInfos)
dev_disp_text ('Press Run (F5) to continue', 'window', 'bottom', 'right', 'black', [], [])
stop ()
dev_close_window ()
dev_close_window ()

******************************************
*****************评估结果阶段**************
******************************************
dev_update_off ()
UsePretrainedModel := false //使用预训练模型
if (UsePretrainedModel)
    RetrainedModelFileName := Output_PreDLModelFileName
else
    RetrainedModelFileName := Output_BestModelBaseName+'.hdl'
endif
EvaluationMeasures := 'all' //评估措施
IoUThresholds := [] //交并比阈值
DisplayIoUThreshold := 0.7 //显示的交并比阈值
BatchSize := 1         //批次大小
AreaNames := []        //区域名称
AreaMin := []          //区域最小值
AreaMax := []          //区域最大值
MaxNumDetections := [] //最大检测数量
****************************
*****检查文件****************
****************************
check_data_availability_for_evaluation (ExampleDataDir, Input_DLDatasetFileName, RetrainedModelFileName, UsePretrainedModel)//检查文件存在
read_dl_model (RetrainedModelFileName, DLModelHandle)
set_dl_model_param (DLModelHandle, 'batch_size', 1)
set_dl_model_param (DLModelHandle, 'device', DLDevice)
read_dict (Input_DLDatasetFileName, [], [], DLDataset)
****************************
*****设置推理参数************
****************************
set_dl_model_param (DLModelHandle, 'max_overlap_class_agnostic', 0.7)//不同类的最大重叠度
set_dl_model_param (DLModelHandle, 'max_overlap', 0.2)   //相同类的最大重叠度
set_dl_model_param (DLModelHandle, 'min_confidence', 0.6)//最小置信度
****************************
*****设置可视化参数**********
****************************
create_dict (WindowHandleDict)
create_dict (GenParam)
set_dict_tuple (GenParam, 'bbox_display_confidence', false)
get_dict_tuple (DLDataset, 'samples', DatasetSamples)
find_dl_samples (DatasetSamples, 'split', 'test', 'or', DLSampleIndices) //寻找测试集
tuple_shuffle (DLSampleIndices, DLSampleIndicesShuffled) //随机选择图像
****************************
*****可视化测试结果**********
****************************
for Index := 0 to 5 by 1
    read_dl_samples (DLDataset, DLSampleIndicesShuffled[Index], DLSampleBatch)
    apply_dl_model (DLModelHandle, DLSampleBatch, [], DLResultBatch)
    dev_display_dl_data (DLSampleBatch, DLResultBatch, DLDataset, 'bbox_both', GenParam, WindowHandleDict)
    dev_disp_text ('Press Run (F5)\nto continue', 'window', 'bottom', 'right', 'black', [], [])
    stop ()
endfor
dev_close_window_dict (WindowHandleDict)
****************************
*****设置评估参数************
****************************
create_dict (GenParamEval)
set_dict_tuple (GenParamEval, 'measures', EvaluationMeasures) //设置评估措施
if (|MaxNumDetections|)
    set_dict_tuple (GenParamEval, 'max_num_detections', MaxNumDetections) //设置最大检测数
endif
***设置子集参数
if (|AreaNames|)
    if ((|AreaNames| != |AreaMin|) or (|AreaNames| != |AreaMax|))
        throw ('AreaNames, AreaMin, and AreaMax must have the same size.')
    endif
    create_dict (AreaRanges)
    set_dict_tuple (AreaRanges, 'name', AreaNames)
    set_dict_tuple (AreaRanges, 'min', AreaMin)
    set_dict_tuple (AreaRanges, 'max', AreaMax)
    set_dict_tuple (GenParamEval, 'area_ranges', AreaRanges)
endif
if (|IoUThresholds|)
    set_dict_tuple (GenParamEval, 'iou_threshold', IoUThresholds) //设置交并比阈值
endif
**TP:正类预测为正类
**TN:负类预测为负类
**FP:负类预测为正类
**FN:负类预测为负类
set_dict_tuple (GenParamEval, 'detailed_evaluation', true) //启用TP、TN、FP评估
set_dict_tuple (GenParamEval, 'show_progress', true) //显示评估进度
****************************
*****开始评估训练结果********
****************************
evaluate_dl_model (DLDataset, DLModelHandle, 'split', 'test', GenParamEval, EvaluationResultDetection, EvalParams)
****************************
*****显示评估结果************
****************************
create_dict (DisplayParam)
***设置显示的交并比阈值
if (|DisplayIoUThreshold| == 1)
    get_dict_tuple (EvalParams, 'iou_threshold', EvalIoUThresholds)
    if (find(EvalIoUThresholds,DisplayIoUThreshold) != -1)
        set_dict_tuple (DisplayParam, 'iou_threshold', DisplayIoUThreshold)
    else
        throw ('No evaluation result for specified IoU threshold.')
    endif
endif
****************************
*****显示精确率和召回率*******
****************************
** precision_P = TP/(TP+FP)  预测正确的图片个数占总的正类预测个数的比例(从预测结果角度看,有多少预测是准确的)
**    recall_R = TP/(TP+FN)  确定了正类被预测为正类图片占所有标注图片的个数(从标注角度看,有多少被召回)
set_dict_tuple (DisplayParam, 'display_mode', ['pie_charts_precision', 'pie_charts_recall'])
create_dict (WindowHandleDict)
dev_display_detection_detailed_evaluation (EvaluationResultDetection, EvalParams, DisplayParam, WindowHandleDict)
dev_disp_text ('Press Run (F5) to continue', 'window', 'top', 'right', 'black', [], [])
stop ()
dev_close_window_dict (WindowHandleDict)
****************************
*****显示准确率数据**********
****************************
set_dict_tuple (DisplayParam, 'display_mode', 'absolute_confusion_matrix')
dev_display_detection_detailed_evaluation (EvaluationResultDetection, EvalParams, DisplayParam, WindowHandleDict)
dev_disp_text ('Press Run (F5) to continue', 'window', 'bottom', 'right', 'black', [], [])
stop ()
dev_close_window_dict (WindowHandleDict)
****************************
*****优化模型内存**********
****************************
set_dl_model_param (DLModelHandle, 'batch_size', 1)
set_dl_model_param (DLModelHandle, 'optimize_for_inference', 'true')
write_dl_model (DLModelHandle, RetrainedModelFileName)
* Close the windows.
dev_close_window_dict (WindowHandleDict)

******************************************
*****************推理测试阶段**************
******************************************
UsePretrainedModel := false //使用预训练模型
* 设置使用的模型
if (UsePretrainedModel)
    RetrainedModelFileName := Output_PreDLModelFileName
else
    RetrainedModelFileName := Output_BestModelBaseName+'.hdl'
endif
BatchSizeInference := 1 //推理使用的批次大小
* 
* 置信度和重叠度
MinConfidence := 0.6           //最小置信度
MaxOverlap := 0.2              //相同类的最大重叠度
MaxOverlapClassAgnostic := 0.7 //不同类的最大重叠度
****************************
*****检查文件****************
****************************
check_data_availability_for_inference (ExampleDataDir, Output_PreprocessParamFileName, RetrainedModelFileName, UsePretrainedModel)
read_dl_model (RetrainedModelFileName, DLModelHandle) //读取训练的模型
read_dict (Output_PreprocessParamFileName, [], [], DLPreprocessParam) //读取模型预处理参数
****************************
*****设置参数****************
****************************
set_dl_model_param (DLModelHandle, 'batch_size', BatchSizeInference) //设置批次大小
set_dl_model_param (DLModelHandle, 'device', DLDevice) //初始化设备
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)
****************************
*****设置类别字典************
****************************
create_dict (DLDataInfo)
get_dl_model_param (DLModelHandle, 'class_names', ClassNames) 
set_dict_tuple (DLDataInfo, 'class_names', ClassNames)
get_dl_model_param (DLModelHandle, 'class_ids', ClassIDs)
set_dict_tuple (DLDataInfo, 'class_ids', ClassIDs)
****************************
*****设置可视化参数**********
****************************
create_dict (WindowHandleDict)
create_dict (GenParam)
set_dict_tuple (GenParam, 'scale_windows', 1.2)
****************************
*****开始测试结果************
****************************
list_image_files (TestImageDir, 'default', 'recursive', ImageFiles)
for BatchIndex := 0 to floor(|ImageFiles| / real(BatchSizeInference)) - 1 by 1
    * 
    Batch := ImageFiles[BatchIndex * BatchSizeInference:(BatchIndex + 1) * BatchSizeInference - 1]
    read_image (ImageBatch, Batch)
    gen_dl_samples_from_images (ImageBatch, DLSampleBatch)
    preprocess_dl_samples (DLSampleBatch, DLPreprocessParam)
    apply_dl_model (DLModelHandle, DLSampleBatch, [], DLResultBatch)
    for SampleIndex := 0 to BatchSizeInference - 1 by 1
        DLSample := DLSampleBatch[SampleIndex]
        DLResult := DLResultBatch[SampleIndex]
        get_dict_tuple (DLResult, 'bbox_class_id', DetectedClassIDs)
        if (DetectedClassIDs==[])
            dev_display (ImageBatch)
            dev_disp_text ('Prediction failed', 'window', 'top', 'left', 'red', [], [])
            dev_disp_text ('Press Run (F5) to continue', 'window', 'bottom', 'right', 'black', [], [])            
            stop ()
            continue
        endif
        tuple_gen_const (|ClassIDs|, 0, NumberDetectionsPerClass)
        for Index := 0 to |ClassIDs| - 1 by 1
            NumberDetectionsPerClass[Index] := sum(DetectedClassIDs [==] ClassIDs[Index])
        endfor
        dev_display_dl_data (DLSample, DLResult, DLDataInfo, 'bbox_result', GenParam, WindowHandleDict)
        get_dict_tuple (WindowHandleDict, 'bbox_result', WindowHandles)
        dev_set_window (WindowHandles[0])
        set_display_font (WindowHandles[0], 16, 'mono', 'true', 'false')
        dev_disp_text ('Press Run (F5) to continue', 'window', 'bottom', 'right', 'black', [], [])
        stop ()
    endfor
endfor
dev_close_window_dict (WindowHandleDict)
Logo

腾讯云面向开发者汇聚海量精品云计算使用和开发经验,营造开放的云计算技术生态圈。

更多推荐