halcon 例程deep learning水果分类器。
* This example shows how to train a deep learning fruit classifier, along with
* a short overview of the necessary steps.训练分类器
* Initialization.
dev_update_off ()
dev_close_window ()
WindowWidth := 800
WindowHeight := 600
dev_open_window_fit_size (0, 0, WindowWidth, WindowHeight, -1, -1, WindowHandle)
set_display_font (WindowHandle, 16, 'mono', 'true', 'false')
*设置显示字体格式
* Some procedures use a random number generator. Set the seed for reproducibility.
set_system ('seed_rand', 42)
* Introduction text.
dev_disp_introduction_text ()
stop ()
dev_close_window ()
dev_resize_window_fit_size (0, 0, WindowWidth, WindowHeight, -1, -1)
dev_clear_window ()
*
* ** TRAINING **
* Read one of the pretrained networks.读取已训练过的的网络
read_dl_classifier ('pretrained_dl_classifier_compact.hdl', DLClassifierHandle)
* Path to directory with images.
RawDataFolder := 'food/' + ['apple_braeburn','apple_golden_delicious','apple_topaz','peach','pear']
* Get the raw data set with labels.
read_dl_classifier_data_set (RawDataFolder, 'last_folder', RawImageFiles, Labels, LabelIndices, Classes)
* Path of output directory for preprocessed data set.
PreprocessedFolder := 'fruit_preprocessed'
* Set to true to overwrite existing images.
OverwritePreprocessingFolder := false
* By default, we will remove the folder with the preprocessed data.
* In a real application you might want to keep this data (if the
* preprocessing does not change to save time).程序结束删除处理后的图像文件
RemovePreprocessingAfterExample := true
*
* If the preprocessed has been generated already,
* we skip this part.
file_exists (PreprocessedFolder, FileExists)
if (not FileExists or OverwritePreprocessingFolder)
* Preprocessing of the raw data.
if (FileExists)
remove_dir_recursively (PreprocessedFolder)
endif
* Create output directories.
make_dir (PreprocessedFolder)
for I := 0 to |Classes| - 1 by 1
make_dir (PreprocessedFolder + '/' + Classes[I])
endfor
* Define output file names.
parse_filename (RawImageFiles, BaseNames, Extensions, Directories)
ObjectFilesOut := PreprocessedFolder + '/' + Labels + '/' + BaseNames + '.hobj'
* Check if output file names
* overlap in the preprocessed folder.
* This is just a sanity check.
check_output_file_names_for_duplicates (RawImageFiles, ObjectFilesOut)
* Preprocess images and save them as hobj files.处理原始图像并存储
for I := 0 to |RawImageFiles| - 1 by 1
read_image (Image, RawImageFiles[I])
* Preprocess the image with a custom procedure
* in order to remove the background.
preprocess_dl_fruit_example (Image, ImagePreprocessed, DLClassifierHandle)
* Write preprocessed image to hobj file.
write_object (ImagePreprocessed, ObjectFilesOut[I])
dev_disp_preprocessing_progress (I, RawImageFiles, PreprocessedFolder, WindowHandle)
endfor
dev_clear_window ()
dev_disp_text ('Preprocessing done.', 'window', 'top', 'left', 'black', [], [])
endif
*
* 2) Split data into training, validation, and test set.数据分类
*
* Read the data, i.e., the paths of the images and their respective ground truth labels.
read_dl_classifier_data_set (PreprocessedFolder, 'last_folder', ImageFiles, Labels, LabelsIndices, Classes)
*
* Split the data into three subsets,
* for training 70%, validation 15%, and testing 15%.
TrainingPercent := 70
ValidationPercent := 15
split_dl_classifier_data_set (ImageFiles, Labels, TrainingPercent, ValidationPercent, TrainingImages, TrainingLabels, ValidationImages, ValidationLabels, TestImages, TestLabels)
*
* Set training hyper-parameters.
* In order to retrain the neural network, we have to specify
* the class names of our classification problem.
set_dl_classifier_param (DLClassifierHandle, 'classes', Classes)
* Set the batch size.
BatchSize := 64
set_dl_classifier_param (DLClassifierHandle, 'batch_size', BatchSize)
* Try to initialize the runtime environment.
try
set_dl_classifier_param (DLClassifierHandle, 'runtime_init', 'immediately')
catch (Exception)
dev_disp_error_text (Exception)
if (RemovePreprocessingAfterExample and Exception[0] != 4104)
remove_dir_recursively (PreprocessedFolder)
dev_disp_text ('Preprocessed data in folder "' + PreprocessedFolder + '" have been deleted.', 'window', 'bottom', 'left', 'black', [], [])
endif
stop ()
endtry
* For this data set, an initial learning rate of 0.001
* has proven to yield good results.
InitialLearningRate := 0.001
set_dl_classifier_param (DLClassifierHandle, 'learning_rate', InitialLearningRate)
* In this example, we reduce the learning rate
* by a factor of 1/10 every 4th epoch.
LearningRateStepEveryNthEpoch := 30
LearningRateStepRatio := 0.1
* We iterate 100 times over the full training set.
NumEpochs := 100
*
* Train the classifier.
*
dev_clear_window ()
dev_disp_text ('Training has started...', 'window', 'top', 'left', 'black', [], [])
*
PlotEveryNthEpoch := 4
FileName := 'classifier_fruit.hdl'
train_fruit_classifier (DLClassifierHandle, FileName, NumEpochs, TrainingImages, TrainingLabels, ValidationImages, ValidationLabels, LearningRateStepEveryNthEpoch, LearningRateStepRatio, PlotEveryNthEpoch, WindowHandle)
dev_disp_text ('Press Run (F5) to continue', 'window', 'bottom', 'right', 'black', [], [])
stop ()
read_dl_classifier (FileName, DLClassifierHandle)
*
* Compute the confusion matrix for the validation data set.
get_predicted_classes (ValidationImages, DLClassifierHandle, PredictedClassesValidation)
gen_confusion_matrix (ValidationLabels, PredictedClassesValidation, [], [], WindowHandle, ConfusionMatrix)
dev_disp_text ('Validation data', 'window', 'top', 'left', 'gray', 'box', 'false')
dev_disp_text ('Press Run (F5) to continue', 'window', 'bottom', 'right', 'black', [], [])
stop ()
dev_clear_window ()
*
* ** INFERENCE **
*
* This part shows a typical inference scenario.
* Read the classifier.
read_dl_classifier (FileName, DLClassifierHandle)
* If it is not possible to accumulate more than one image
* at a time the batch size should be set to 1.
set_dl_classifier_param (DLClassifierHandle, 'batch_size', 1)
* Set the runtime to 'cpu' to perform the inference on the
* CPU, if this is possible on the current hardware.
* (CPU inference is only supported on Intel compatible x86
* processors)
try
set_dl_classifier_param (DLClassifierHandle, 'runtime', 'cpu')
Runtime := 'cpu'
catch (Exception)
* Keep the 'gpu' runtime if switching to 'cpu' failed.
Runtime := 'gpu'
endtry
* This initializes the runtime environment immediately.
set_dl_classifier_param (DLClassifierHandle, 'runtime_init', 'immediately')
*
dev_resize_window_fit_size (0, 0, WindowWidth, WindowHeight, -1, -1)
dev_disp_inference_text (Runtime)
stop ()
* Read / acquire images in a loop and classify them.
for Index := 0 to 20 by 1
ImageFile := RawImageFiles[floor(rand(1) * |RawImageFiles|)]
read_image (Image, ImageFile)
dev_resize_window_fit_image (Image, 0, 0, -1, -1)
preprocess_dl_fruit_example (Image, ImagePreprocessed, DLClassifierHandle)
apply_dl_classifier (ImagePreprocessed, DLClassifierHandle, DLClassifierResultHandle)
get_dl_classifier_result (DLClassifierResultHandle, 'all', 'predicted_classes', PredictedClass)
*
dev_display (Image)
Text := 'Predicted class: ' + PredictedClass
dev_disp_text (Text, 'window', 'top', 'left', 'white', 'box', 'false')
dev_disp_text ('Press Run (F5) to continue', 'window', 'bottom', 'right', 'black', [], [])
stop ()
endfor
stop ()
if (RemovePreprocessingAfterExample)
remove_dir_recursively (PreprocessedFolder)
dev_disp_text ('End of program.\nPreprocessed data have been deleted.', 'window', 'bottom', 'right', 'black', [], [])
else
dev_disp_text (' End of program ', 'window', 'bottom', 'right', 'black', [], [])
endif