在上一步,完成了网络的创建和数据的预处理。接下来准备对这个网络进行训练,通过训练得到一个可以用于目标检测的深度学习网络模型。这里首先要确定上一步输出的模型和数据集的存放路径是可用的,否则训练环节会因为缺少输入而报错。
Halcon的参考样例detect_pills_deep_learning_2_train.hdev详述了这一过程,这里做一些学习记录。
设置输入输出的路径
设置输入路径,主要是两个,一是上一步的预训练的以.hdl结尾的模型,另一个是数据集和样本数据字典的存放路径。
输出路径也是两个,一是存放最佳评估模型的路径,一个是最终训练完成的模型路径。
设置模型网络的基本参数
- BatchSize:每次迭代的训练样本数。
- InitialLearningRate:初始学习率
- Momentum动量,如果BatchSize比较小,这个值可以设得大一点。
- 迭代次数NumEpochs
- EvaluationIntervalEpochs指将多少个Epoch传递给评估过程,这样经评估才能得到最佳模型。
- ChangeLearningRateEpochs在某些周期内修改学习率,如果学习率不用做修改,就把它设为[]。
- ChangeLearningRateValues:在初始学习率的基础上修改其数值,这个数组的长度和ChangeLearningRateEpochs的长度一致。
设置高级参数
- WeightPrior 先验加权
- SeedRandom 设置训练中的随机数
- AugmentationParam。如果在训练中需要对样本数据进行增强,这里可以用数据字典的方式设置增强参数。使用create_dict创建字典AugmentationParam,然后使用set_dict_tuple算子设置需要增强参数属性,例如修改'augmentation_percentage‘可以设置需要增强的数据占训练数据集的比例;修改'mirror'参数表示对数据做镜像操作的方式。
- ChangeStrategy。由于在训练中有些参数需要适时进行改变,所以有个修改策略参数。例如要修改学习率,先创建一个数据字典ChangeStrategy,修改要改变的模型参数’ model_param ‘,改为'learning_rate'。修改其初始值'initial_value',改为InitialLearningRate参数的值。修改其'epochs'属性,改为ChangeLearningRateEpochs,表示学习率发生变化的Epoch区间。修改'values'值为ChangeLearningRateValues,表示学习率改变后的值。
- SerializationStrategy。为了方便存储网络,还需要序列化策略。针对最优网络模型,创建一个数据字典SerializationStrategy,修改要改变的模型参数'type',改为'best'。修改其'basename',改为BestModelBaseName参数的值。针对最终的网络模型,创建一个数据字典SerializationStrategy,修改模型参数'type',改为'final'。修改其'basename',改为FinalModelBaseName参数的值。
读取初始模型与数据集
首先用check_files_availability验证预处理模型和数据集路径是否正确。没有问题的话可以开始读取。
使用read_dl_model读取前一步初始化后的网络模型,得到模型的句柄DLModelHandle。
接着用read_dict读取预处理后的数据集,得到数据字典句柄DLDataset。
设置模型参数
设置模型参数主要通过set_dl_model_param算子,以修改属性值的方式改变关键参数的值。该算子原型如下:
set_dl_model_param( : : DLModelHandle, GenParamName, GenParamValue : )
输入三个参数:
- DLModelHandle为模型句柄。
- GenParamName为模型的参数和超参数,具体取决于网络模型的类型和任务。例如通用性的参数有'batch_size'、'batch_size'、 'learning_rate'、'momentum'等。而不同类型的网络还会有各自特有的参数,如用于目标检测的模型参数有'max_overlap','max_overlap_class_agnostic' 等。如果是用于图像分割的模型参数,有'image_dimensions'、'image_height', 'image_width'等。如果不确定哪些参数是可以修改的,可以通过get_dl_model_param算子查询一下。
- GenParamValue 为修改后的值。
注意,如果将'runtime'的值改为了’gpu’,则要确定cuDNN和cuBLAS已经成功安装了。
通过set_dl_model_param算子,可以将本文开头提到的设置的模型的基本参数传递给模型句柄DLModelHandle。如将'batch_size'设为之前的batch_size的值等等。
训练网络模型
1)创建训练参数。
这里使用create_dl_train_param算子创建一个训练参数的字典,用于存放训练参数和训练效果可视化的参数。这些参数可以做个说明:
- NumEpochs:定义了这个训练过程要用到多少个Epoch。一个Epochs表示真个训练集全部过一遍。
- EvaluationIntervalEpochs:定义了将多少个Epoch传递给评估过程,以便于评估得出最佳模型。如果这个值设为0,就表示不会进行模型评估。
- EnableDisplay:定义训练过程是否应显示出来。如果要显示的话,算子会创建一个 - DisplayParam字典用于存放图像显示的数量、随机数等显示类的参数信息。开启以后可以实时看到错误率,学习率等参数的变化。但这个显示的功能也会影响到cpu的处理速度,所以如果要训练过程的速度最大化,可以停用这个功能。
- SeedRand:该参数用于设置随机数种子,这个值应当固定下来,以便再次运行的时候,可以通过种子获得不变的随机数的值。
- GenParamName、GenParamValue:提供训练所需的其他参数。GenParamName可以看作是一系列属性名称字符串的集和,而GenParamValue就像是对应于它的属性值的集和。它们的值在之前设置网络高级参数的时候,应已经被创建并存储了高级参数的信息。如'evaluation'、 'augment' 、'change'、'epochs’等以及ChangeStrategy、SerializationStrategy的相关参数等。
- TrainParam:输出参数。这个输出参数存储了模型的参数信息,将作为训练环节的输入。
2)训练网络
接下来是最耗时的部分,即使用train_dl_model算子进行深度学习网络模型的训练。算子如下:
train_dl_model( : : DLDataset, DLModelHandle, TrainParam, StartEpoch : TrainResults, TrainInfos,EvaluationInfos)
前四个参数是输入参数,后三个是输出参数。
- DLDataset:数据集;
- DLModelHandle:模型的句柄。
- TrainParam:训练中所用的参数,即之前用 create_dl_train_param创建的结果。
- StartEpoch :起始的Epoch ,可以指从指定的Epoch开始训练。
- TrainResults:输出训练结果,一组数据字典。
- TrainInfos:输出训练信息。
- EvaluationInfos:输出验证信息。
在训练过程中,可以看到total loss 在不断的减少,直到完成了训练的过程。
接着到了第三步,即验证模型的部分。
网友评论