最近新版本的halcon已经完善了深度学习方面的不足,在此我们简单实现一个分类的样本制作,数据准备、训练和预测使用。
第一步:先制作样本。
新建一个文件夹(任意命名),然后里面针对不同的类建立不同的文件夹,文件名是类名,然后将该类的图像放到对应的类下面文件夹。
接下来就是halcon代码生成数据了
*
* This example contains part 1: 'Dataset preprocessing'.
*
dev_update_off ()
*
* *********************************
* ** 设置输入输出路径 ***
* *********************************
*
* Get the path to the examples.
**get_system ('example_dir', PathExample)
* Folder with ground truth classification image data.
RawImageBaseFolder := './images/catanddog/'
*
* All example data is written to this folder.
ExampleDataDir := 'classify_animal_defects_data'
* 将所有的输出都存储在这个路径下.
DataDirectoryBaseName := ExampleDataDir + '/dldataset_animal'
*
* *************************
* ** 设置参数 ***
* *************************
*
* LabelSource for reading in the dataset.
LabelSource := 'last_folder'
*
* 数据集分为70%的训练,15%的验证
TrainingPercent := 70
ValidationPercent := 15
*
* 设置图像的宽高和维度.
ImageWidth := 300
ImageHeight := 300
ImageNumChannels := 3
*
* Further parameters for image preprocessing.
NormalizationType := 'none'
DomainHandling := 'full_domain'
*
SeedRand := 42
set_system ('seed_rand', SeedRand)
*
* *****************************************************************************
* ** Read the labeled data and split it into train, validation and test ***
* *****************************************************************************
*
*
* Read the dataset with the procedure read_dl_dataset_classification.
* Alternatively, you can read a DLDataset dictionary
* as created by e.g., the MVTec Deep Learning Tool using read_dict().
read_dl_dataset_classification (RawImageBaseFolder, LabelSource, DLDataset)
* Generate the split.
split_dl_dataset (DLDataset, TrainingPercent, ValidationPercent, [])
*
*
* *********************************
* ** Preprocess the dataset ***
* *********************************
*
* 如果不存在就创建个输出路径文件
file_exists (ExampleDataDir, FileExists)
if (not FileExists)
make_dir (ExampleDataDir)
endif
*
* Create preprocess parameters.
create_dl_preprocess_param ('classification', ImageWidth, ImageHeight, ImageNumChannels, -127, 128, NormalizationType, DomainHandling, [], [], [], [], DLPreprocessParam)
*
* Dataset directory for any outputs written by preprocess_dl_dataset.
DataDirectory := DataDirectoryBaseName + '_' + ImageWidth + 'x' + ImageHeight
*
* Preprocess the dataset. This might take a few seconds.
GenParam := dict{overwrite_files: 'auto'}
preprocess_dl_dataset (DLDataset, DataDirectory, DLPreprocessParam, GenParam, DLDatasetFileName)
*
* Store preprocess parameters separately in order to use it, e.g., during inference.
PreprocessParamFileBaseName := DataDirectory + '/dl_preprocess_param.hdict'
write_dict (DLPreprocessParam, PreprocessParamFileBaseName, [], [])
*
* *******************************************
* ** Preview the preprocessed dataset ***
* *******************************************
*
* Before moving on to training, it is recommended to check the preprocessed dataset.
*
* Display the DLSamples for 10 randomly selected train images.
find_dl_samples (DLDataset.samples, 'split', 'train', 'match', SampleIndices)
tuple_shuffle (SampleIndices, ShuffledIndices)
read_dl_samples (DLDataset, ShuffledIndices[0:9], DLSampleBatchDisplay)
*
WindowHandleDict := dict{}
for Index := 0 to |DLSampleBatchDisplay| - 1 by 1
* Loop over samples in DLSampleBatchDisplay.
dev_display_dl_data (DLSampleBatchDisplay[Index], [], DLDataset, 'classification_ground_truth', [], WindowHandleDict)
Text := 'Press Run (F5) to continue'
dev_disp_text (Text, 'window', 'bottom', 'right', 'black', [], [])
stop ()
endfor
*
* Close windows that have been used for visualization.
dev_close_window_dict (WindowHandleDict)
到此为止,基于halcon进行深度学习训练分类的数据整理部分已经完成,会生成文件夹和文件夹内的一些文件。
第二步:开始训练
dev_update_off ()
* 设置GPU
query_available_dl_devices (['runtime', 'runtime'], ['gpu', 'cpu'], DLDeviceHandles)
if (|DLDeviceHandles| == 0)
throw ('No supported device found to continue this example.')
endif
* Due to the filter used in query_available_dl_devices, the first device is a GPU, if available.
DLDevice := DLDeviceHandles[0]
get_dl_device_param (DLDevice, 'type', DLDeviceType)
if (DLDeviceType == 'cpu')
* The number of used threads may have an impact
* on the training duration.
NumThreadsTraining := 4
set_system ('thread_num', NumThreadsTraining)
endif
*
* *************************************
* ** Set input and output paths ***
* *************************************
*
* All example data is written to this folder.
ExampleDataDir := 'classify_animal_defects_data'
* 初始模块路径
ModelFileName := 'pretrained_dl_classifier_compact.hdl'
*ModelFileName :='dl_model_classification_small.hdl'
* File path of the preprocessed DLDataset.
* Note: Adapt DataDirectory after preprocessing with another image size.
DataDirectory := ExampleDataDir + '/dldataset_animal_300x300'
DLDatasetFileName := DataDirectory + '/dl_dataset.hdict'
DLPreprocessParamFileName := DataDirectory + '/dl_preprocess_param.hdict'
* Output path of the best evaluated model.
BestModelBaseName := ExampleDataDir + '/best_dl_model_classification'
* Output path for the final trained model.
FinalModelBaseName := ExampleDataDir + '/final_dl_model_classification'
*
* *******************************
* ** Set basic parameters ***
* *******************************
* The following parameters need to be adapted frequently.
*
* Model parameters.
* Batch size. In case this example is run on a GPU,
* you can set BatchSize to 'maximum' and it will be
* determined automatically using set_dl_model_param_max_gpu_batch_size.
if (DLDeviceType == 'gpu')
** BatchSize := 'maximum'
BatchSize := 8
else
BatchSize := 64
endif
* Initial learning rate.
InitialLearningRate := 0.001
* Momentum should be high if batch size is small.
Momentum := 0.9
*
* Parameters used by train_dl_model.
* Number of epochs to train the model.
NumEpochs := 100
* Evaluation interval (in epochs) to calculate evaluation measures on the validation split.
EvaluationIntervalEpochs := 1
* Change the learning rate in the following epochs, e.g., [4, 8, 12].
* Set it to [] if the learning rate should not be changed.
ChangeLearningRateEpochs := [10, 30, 60,80]
* Change the learning rate to the following values, e.g., InitialLearningRate * [0.1, 0.01, 0.001].
* The tuple has to be of the same length as ChangeLearningRateEpochs.
ChangeLearningRateValues := InitialLearningRate * [1, 0.1, 0.01,0.005]
*
* **********************************
* ** Set advanced parameters ***
* **********************************
* The following parameters might need to be changed in rare cases.
*
* Model parameter.
* Set the weight prior.
WeightPrior := 0.0005
*
* Parameters used by train_dl_model.
* Control whether training progress is displayed (true/false).
EnableDisplay := true
* Set a random seed for training.
RandomSeed := 42
set_system ('seed_rand', RandomSeed)
*
* In order to obtain nearly deterministic training results on the same GPU
* (system, driver, cuda-version) you could specify "cudnn_deterministic" as
* "true". Note, that this could slow down training a bit.
* set_system ('cudnn_deterministic', 'true')
*
* Set generic parameters of create_dl_train_param.
* Please see the documentation of create_dl_train_param for an overview on all available parameters.
GenParamName := []
GenParamValue := []
*
* Augmentation parameters.
* If samples should be augmented during training, create the dict required by augment_dl_samples.
* Here, we set the augmentation percentage and method.
AugmentationParam := dict{}
* Percentage of samples to be augmented.
AugmentationParam.augmentation_percentage := 50
* Mirror images along row and column.
AugmentationParam.mirror := 'rc'
GenParamName := [GenParamName,'augment']
GenParamValue := [GenParamValue,AugmentationParam]
*
* Change strategies.
* It is possible to change model parameters during training.
* Here, we change the learning rate if specified above.
if (|ChangeLearningRateEpochs| > 0)
ChangeStrategy := dict{}
* Specify the model parameter to be changed, here the learning rate.
ChangeStrategy.model_param := 'learning_rate'
* Start the parameter value at 'initial_value'.
ChangeStrategy.initial_value := InitialLearningRate
* Reduce the learning rate in the following epochs.
ChangeStrategy.epochs := ChangeLearningRateEpochs
* Reduce the learning rate to the following values.
ChangeStrategy.values := ChangeLearningRateValues
* Collect all change strategies as input.
GenParamName := [GenParamName,'change']
GenParamValue := [GenParamValue,ChangeStrategy]
endif
*
* Serialization strategies.
* There are several options for saving intermediate models to disk (see create_dl_train_param).
* Here, we save the best and the final model to the paths set above.
SerializationStrategy := dict{['type']: 'best', basename: BestModelBaseName}
GenParamName := [GenParamName,'serialize']
GenParamValue := [GenParamValue,SerializationStrategy]
SerializationStrategy := dict{['type']: 'final', basename: FinalModelBaseName}
GenParamName := [GenParamName,'serialize']
GenParamValue := [GenParamValue,SerializationStrategy]
*
* Display parameters.
* In this example, 20% of the training split are selected to display the
* evaluation measure for the reduced training split during the training. A lower percentage
* helps to speed up the evaluation/training. If the evaluation measure for the training split
* shall not be displayed, set this value to 0 (default).
SelectedPercentageTrainSamples := 20
* Set the x-axis argument of the training plots.
XAxisLabel := 'epochs'
DisplayParam := dict{}
DisplayParam.selected_percentage_train_samples := SelectedPercentageTrainSamples
DisplayParam.x_axis_label := XAxisLabel
GenParamName := [GenParamName,'display']
GenParamValue := [GenParamValue,DisplayParam]
*
* *****************************************
* ** Read initial model and dataset ***
* *****************************************
*
* Check if all necessary files exist.
check_data_availability (ExampleDataDir, DLDatasetFileName, DLPreprocessParamFileName)
*
* Read in the model that was initialized during preprocessing.
read_dl_model (ModelFileName, DLModelHandle)
*
* Read in the preprocessed DLDataset file.
read_dict (DLDatasetFileName, [], [], DLDataset)
*
* *******************************
* ** Set model parameters ***
* *******************************
*
* Set model hyper-parameters as specified in the settings above.
set_dl_model_param (DLModelHandle, 'learning_rate', InitialLearningRate)
set_dl_model_param (DLModelHandle, 'momentum', Momentum)
* Set the class names for the model.
ClassNames := DLDataset.class_names
set_dl_model_param (DLModelHandle, 'class_names', ClassNames)
* Get image dimensions from preprocess parameters and set them for the model.
read_dict (DLPreprocessParamFileName, [], [], DLPreprocessParam)
set_dl_model_param (DLModelHandle, 'image_dimensions', [DLPreprocessParam.image_width,DLPreprocessParam.image_height,DLPreprocessParam.image_num_channels])
if (BatchSize == 'maximum' and DLDeviceType == 'gpu')
set_dl_model_param_max_gpu_batch_size (DLModelHandle, 100)
else
if (BatchSize == 'maximum')
* Please set a suitable batch size in case of 'cpu'
* training before continuing.
stop ()
endif
set_dl_model_param (DLModelHandle, 'batch_size', BatchSize)
endif
* When the batch size is determined, set the device.
set_dl_model_param (DLModelHandle, 'device', DLDevice)
if (|WeightPrior| > 0)
set_dl_model_param (DLModelHandle, 'weight_prior', WeightPrior)
endif
* Set class weights to counteract unbalanced training data. In this example
* we choose the default values, since the classes are evenly distributed in the dataset.
tuple_gen_const (|ClassNames|, 1.0, ClassWeights)
set_dl_model_param (DLModelHandle, 'class_weights', ClassWeights)
*
* **************************
* ** Train the model ***
* **************************
*
* Create training parameters.
create_dl_train_param (DLModelHandle, NumEpochs, EvaluationIntervalEpochs, EnableDisplay, RandomSeed, GenParamName, GenParamValue, TrainParam)
*
* Start the training by calling the training operator
* train_dl_model_batch () within the following procedure.
train_dl_model (DLDataset, DLModelHandle, TrainParam, 0, TrainResults, TrainInfos, EvaluationInfos)
*
* Stop after the training has finished, before closing the windows.
dev_disp_text ('Press Run (F5) to continue', 'window', 'bottom', 'right', 'black', [], [])
stop ()