summaryrefslogtreecommitdiffstats
path: root/ml/dlib/examples
diff options
context:
space:
mode:
Diffstat (limited to 'ml/dlib/examples')
-rw-r--r--ml/dlib/examples/3d_point_cloud_ex.cpp50
-rw-r--r--ml/dlib/examples/CMakeLists.txt250
-rw-r--r--ml/dlib/examples/LICENSE_FOR_EXAMPLE_PROGRAMS.txt22
-rw-r--r--ml/dlib/examples/assignment_learning_ex.cpp325
-rw-r--r--ml/dlib/examples/bayes_net_ex.cpp307
-rw-r--r--ml/dlib/examples/bayes_net_from_disk_ex.cpp83
-rw-r--r--ml/dlib/examples/bayes_net_gui_ex.cpp989
-rw-r--r--ml/dlib/examples/bridge_ex.cpp365
-rw-r--r--ml/dlib/examples/bsp_ex.cpp282
-rw-r--r--ml/dlib/examples/compress_stream_ex.cpp245
-rw-r--r--ml/dlib/examples/config.txt30
-rw-r--r--ml/dlib/examples/config_reader_ex.cpp146
-rw-r--r--ml/dlib/examples/custom_trainer_ex.cpp277
-rw-r--r--ml/dlib/examples/dir_nav_ex.cpp75
-rw-r--r--ml/dlib/examples/dnn_face_recognition_ex.cpp220
-rw-r--r--ml/dlib/examples/dnn_imagenet_ex.cpp171
-rw-r--r--ml/dlib/examples/dnn_imagenet_train_ex.cpp368
-rw-r--r--ml/dlib/examples/dnn_inception_ex.cpp154
-rw-r--r--ml/dlib/examples/dnn_introduction2_ex.cpp388
-rw-r--r--ml/dlib/examples/dnn_introduction_ex.cpp170
-rw-r--r--ml/dlib/examples/dnn_metric_learning_ex.cpp128
-rw-r--r--ml/dlib/examples/dnn_metric_learning_on_images_ex.cpp340
-rw-r--r--ml/dlib/examples/dnn_mmod_dog_hipsterizer.cpp180
-rw-r--r--ml/dlib/examples/dnn_mmod_ex.cpp230
-rw-r--r--ml/dlib/examples/dnn_mmod_face_detection_ex.cpp114
-rw-r--r--ml/dlib/examples/dnn_mmod_find_cars2_ex.cpp96
-rw-r--r--ml/dlib/examples/dnn_mmod_find_cars_ex.cpp236
-rw-r--r--ml/dlib/examples/dnn_mmod_train_find_cars_ex.cpp425
-rw-r--r--ml/dlib/examples/dnn_semantic_segmentation_ex.cpp172
-rw-r--r--ml/dlib/examples/dnn_semantic_segmentation_ex.h200
-rw-r--r--ml/dlib/examples/dnn_semantic_segmentation_train_ex.cpp390
-rw-r--r--ml/dlib/examples/empirical_kernel_map_ex.cpp355
-rw-r--r--ml/dlib/examples/face_detection_ex.cpp103
-rw-r--r--ml/dlib/examples/face_landmark_detection_ex.cpp144
-rwxr-xr-xml/dlib/examples/faces/2007_007763.jpgbin89619 -> 0 bytes
-rwxr-xr-xml/dlib/examples/faces/2008_001009.jpgbin41770 -> 0 bytes
-rwxr-xr-xml/dlib/examples/faces/2008_001322.jpgbin65344 -> 0 bytes
-rwxr-xr-xml/dlib/examples/faces/2008_002079.jpgbin92641 -> 0 bytes
-rwxr-xr-xml/dlib/examples/faces/2008_002470.jpgbin91349 -> 0 bytes
-rwxr-xr-xml/dlib/examples/faces/2008_002506.jpgbin79316 -> 0 bytes
-rwxr-xr-xml/dlib/examples/faces/2008_004176.jpgbin93821 -> 0 bytes
-rwxr-xr-xml/dlib/examples/faces/2008_007676.jpgbin110034 -> 0 bytes
-rwxr-xr-xml/dlib/examples/faces/2009_004587.jpgbin79462 -> 0 bytes
-rw-r--r--ml/dlib/examples/faces/Tom_Cruise_avp_2014_4.jpgbin66360 -> 0 bytes
-rw-r--r--ml/dlib/examples/faces/bald_guys.jpgbin648373 -> 0 bytes
-rw-r--r--ml/dlib/examples/faces/dogs.jpgbin175216 -> 0 bytes
-rw-r--r--ml/dlib/examples/faces/image_metadata_stylesheet.xsl109
-rw-r--r--ml/dlib/examples/faces/testing.xml43
-rw-r--r--ml/dlib/examples/faces/testing_with_face_landmarks.xml1772
-rw-r--r--ml/dlib/examples/faces/training.xml34
-rw-r--r--ml/dlib/examples/faces/training_with_face_landmarks.xml1280
-rw-r--r--ml/dlib/examples/fhog_ex.cpp88
-rw-r--r--ml/dlib/examples/fhog_object_detector_ex.cpp269
-rw-r--r--ml/dlib/examples/file_to_code_ex.cpp111
-rw-r--r--ml/dlib/examples/graph_labeling_ex.cpp259
-rw-r--r--ml/dlib/examples/gui_api_ex.cpp231
-rw-r--r--ml/dlib/examples/hough_transform_ex.cpp84
-rw-r--r--ml/dlib/examples/image_ex.cpp104
-rw-r--r--ml/dlib/examples/integrate_function_adapt_simp_ex.cpp89
-rw-r--r--ml/dlib/examples/iosockstream_ex.cpp47
-rw-r--r--ml/dlib/examples/johns/John_Salley/000179_02159509.jpgbin9192 -> 0 bytes
-rw-r--r--ml/dlib/examples/johns/John_Salley/000183_02159543.jpgbin9811 -> 0 bytes
-rw-r--r--ml/dlib/examples/johns/John_Salley/000186_02159346.jpgbin8161 -> 0 bytes
-rw-r--r--ml/dlib/examples/johns/John_Salley/000189_02159361.jpgbin9000 -> 0 bytes
-rw-r--r--ml/dlib/examples/johns/John_Salley/000190_02159501.jpgbin8133 -> 0 bytes
-rw-r--r--ml/dlib/examples/johns/John_Salley/000192_02159531.jpgbin9465 -> 0 bytes
-rw-r--r--ml/dlib/examples/johns/John_Salley/000194_02159572.jpgbin7450 -> 0 bytes
-rw-r--r--ml/dlib/examples/johns/John_Salley/000197_02159322.jpgbin9227 -> 0 bytes
-rw-r--r--ml/dlib/examples/johns/John_Salley/000197_02159525.jpgbin7935 -> 0 bytes
-rw-r--r--ml/dlib/examples/johns/John_Salley/000198_02159470.jpgbin10581 -> 0 bytes
-rw-r--r--ml/dlib/examples/johns/John_Salley/000200_02159354.jpgbin8485 -> 0 bytes
-rw-r--r--ml/dlib/examples/johns/John_Savage/000264_01099001.jpgbin6494 -> 0 bytes
-rw-r--r--ml/dlib/examples/johns/John_Savage/000274_01099061.jpgbin6031 -> 0 bytes
-rw-r--r--ml/dlib/examples/johns/John_Savage/000277_01099000.jpgbin6636 -> 0 bytes
-rw-r--r--ml/dlib/examples/johns/John_Savage/000289_01099139.jpgbin5746 -> 0 bytes
-rw-r--r--ml/dlib/examples/johns/John_Savage/000290_01099067.jpgbin6812 -> 0 bytes
-rw-r--r--ml/dlib/examples/johns/John_Savage/000290_01099090.jpgbin5937 -> 0 bytes
-rw-r--r--ml/dlib/examples/johns/John_Savage/000291_01099023.jpgbin6374 -> 0 bytes
-rw-r--r--ml/dlib/examples/johns/John_Savage/000291_01099214.jpgbin5640 -> 0 bytes
-rw-r--r--ml/dlib/examples/johns/John_Savage/000293_01099081.jpgbin6849 -> 0 bytes
-rw-r--r--ml/dlib/examples/johns/John_Savage/000296_01099007.jpgbin6576 -> 0 bytes
-rw-r--r--ml/dlib/examples/johns/John_Savage/000299_01099008.jpgbin5924 -> 0 bytes
-rw-r--r--ml/dlib/examples/johns/John_Schneider/000288_00925786.jpgbin7542 -> 0 bytes
-rw-r--r--ml/dlib/examples/johns/John_Schneider/000302_00925785.jpgbin6806 -> 0 bytes
-rw-r--r--ml/dlib/examples/johns/John_Schneider/000307_00925823.jpgbin7004 -> 0 bytes
-rw-r--r--ml/dlib/examples/johns/John_Schneider/000325_00925954.jpgbin7627 -> 0 bytes
-rw-r--r--ml/dlib/examples/johns/John_Schneider/000326_00925765.jpgbin7325 -> 0 bytes
-rw-r--r--ml/dlib/examples/johns/John_Schneider/000326_00926089.jpgbin7167 -> 0 bytes
-rw-r--r--ml/dlib/examples/johns/John_Schneider/000326_00926128.jpgbin6057 -> 0 bytes
-rw-r--r--ml/dlib/examples/johns/John_Schneider/000326_00926139.jpgbin6233 -> 0 bytes
-rw-r--r--ml/dlib/examples/johns/John_Schneider/000329_00925859.jpgbin6870 -> 0 bytes
-rw-r--r--ml/dlib/examples/johns/John_Schneider/000329_00925963.jpgbin7393 -> 0 bytes
-rw-r--r--ml/dlib/examples/johns/John_Schneider/000331_00926012.jpgbin6852 -> 0 bytes
-rw-r--r--ml/dlib/examples/johns/John_Shimkus/000373_03228153.jpgbin6910 -> 0 bytes
-rw-r--r--ml/dlib/examples/johns/John_Shimkus/000375_03227651.jpgbin6952 -> 0 bytes
-rw-r--r--ml/dlib/examples/johns/John_Shimkus/000376_02340068.jpgbin6810 -> 0 bytes
-rw-r--r--ml/dlib/examples/johns/John_Shimkus/000378_02340151.jpgbin7215 -> 0 bytes
-rw-r--r--ml/dlib/examples/johns/John_Shimkus/000378_03227610.jpgbin7215 -> 0 bytes
-rw-r--r--ml/dlib/examples/johns/John_Shimkus/000383_03227939.jpgbin5846 -> 0 bytes
-rw-r--r--ml/dlib/examples/johns/John_Shimkus/000385_03227766.jpgbin6084 -> 0 bytes
-rw-r--r--ml/dlib/examples/johns/John_Shimkus/000388_03227773.jpgbin6510 -> 0 bytes
-rw-r--r--ml/dlib/examples/johns/John_Shimkus/000390_03227666.jpgbin7838 -> 0 bytes
-rw-r--r--ml/dlib/examples/johns/John_Shimkus/000394_02340150.jpgbin10182 -> 0 bytes
-rw-r--r--ml/dlib/examples/johns/John_Shimkus/000396_03227722.jpgbin5802 -> 0 bytes
-rw-r--r--ml/dlib/examples/johns/John_Simm/000288_00470387.jpgbin6513 -> 0 bytes
-rw-r--r--ml/dlib/examples/johns/John_Simm/000297_00470170.jpgbin7194 -> 0 bytes
-rw-r--r--ml/dlib/examples/johns/John_Simm/000300_00470148.jpgbin7289 -> 0 bytes
-rw-r--r--ml/dlib/examples/johns/John_Simm/000304_00470122.jpgbin6582 -> 0 bytes
-rw-r--r--ml/dlib/examples/johns/John_Simm/000305_00470162.jpgbin7965 -> 0 bytes
-rw-r--r--ml/dlib/examples/johns/John_Simm/000305_00470717.jpgbin8694 -> 0 bytes
-rw-r--r--ml/dlib/examples/johns/John_Simm/000306_00470222.jpgbin6306 -> 0 bytes
-rw-r--r--ml/dlib/examples/johns/John_Simm/000306_00470223.jpgbin6274 -> 0 bytes
-rw-r--r--ml/dlib/examples/johns/John_Simm/000309_00470287.jpgbin6195 -> 0 bytes
-rw-r--r--ml/dlib/examples/johns/John_Simm/000310_00470421.jpgbin5563 -> 0 bytes
-rw-r--r--ml/dlib/examples/johns/John_Simm/000310_00470511.jpgbin7574 -> 0 bytes
-rw-r--r--ml/dlib/examples/kcentroid_ex.cpp129
-rw-r--r--ml/dlib/examples/kkmeans_ex.cpp154
-rw-r--r--ml/dlib/examples/krls_ex.cpp94
-rw-r--r--ml/dlib/examples/krls_filter_ex.cpp109
-rw-r--r--ml/dlib/examples/krr_classification_ex.cpp205
-rw-r--r--ml/dlib/examples/krr_regression_ex.cpp104
-rw-r--r--ml/dlib/examples/learning_to_track_ex.cpp354
-rw-r--r--ml/dlib/examples/least_squares_ex.cpp228
-rw-r--r--ml/dlib/examples/linear_manifold_regularizer_ex.cpp284
-rw-r--r--ml/dlib/examples/logger_custom_output_ex.cpp73
-rw-r--r--ml/dlib/examples/logger_ex.cpp70
-rw-r--r--ml/dlib/examples/logger_ex_2.cpp153
-rw-r--r--ml/dlib/examples/matrix_ex.cpp276
-rw-r--r--ml/dlib/examples/matrix_expressions_ex.cpp406
-rwxr-xr-xml/dlib/examples/max_cost_assignment_ex.cpp47
-rw-r--r--ml/dlib/examples/member_function_pointer_ex.cpp78
-rw-r--r--ml/dlib/examples/mlp_ex.cpp86
-rw-r--r--ml/dlib/examples/mmod_cars_test_image.jpgbin100135 -> 0 bytes
-rw-r--r--ml/dlib/examples/mmod_cars_test_image2.jpgbin259439 -> 0 bytes
-rw-r--r--ml/dlib/examples/model_selection_ex.cpp148
-rw-r--r--ml/dlib/examples/mpc_ex.cpp156
-rw-r--r--ml/dlib/examples/multiclass_classification_ex.cpp248
-rw-r--r--ml/dlib/examples/multithreaded_object_ex.cpp138
-rw-r--r--ml/dlib/examples/object_detector_advanced_ex.cpp302
-rw-r--r--ml/dlib/examples/object_detector_ex.cpp263
-rw-r--r--ml/dlib/examples/one_class_classifiers_ex.cpp245
-rw-r--r--ml/dlib/examples/optimization_ex.cpp319
-rw-r--r--ml/dlib/examples/parallel_for_ex.cpp158
-rw-r--r--ml/dlib/examples/pipe_ex.cpp172
-rw-r--r--ml/dlib/examples/pipe_ex_2.cpp160
-rw-r--r--ml/dlib/examples/quantum_computing_ex.cpp337
-rw-r--r--ml/dlib/examples/queue_ex.cpp78
-rw-r--r--ml/dlib/examples/random_cropper_ex.cpp99
-rw-r--r--ml/dlib/examples/rank_features_ex.cpp152
-rw-r--r--ml/dlib/examples/running_stats_ex.cpp58
-rw-r--r--ml/dlib/examples/rvm_ex.cpp217
-rw-r--r--ml/dlib/examples/rvm_regression_ex.cpp101
-rw-r--r--ml/dlib/examples/sequence_labeler_ex.cpp392
-rw-r--r--ml/dlib/examples/sequence_segmenter_ex.cpp238
-rw-r--r--ml/dlib/examples/server_http_ex.cpp108
-rw-r--r--ml/dlib/examples/server_iostream_ex.cpp84
-rw-r--r--ml/dlib/examples/sockets_ex.cpp63
-rw-r--r--ml/dlib/examples/sockstreambuf_ex.cpp92
-rw-r--r--ml/dlib/examples/sqlite_ex.cpp137
-rw-r--r--ml/dlib/examples/std_allocator_ex.cpp57
-rw-r--r--ml/dlib/examples/surf_ex.cpp82
-rw-r--r--ml/dlib/examples/svm_c_ex.cpp266
-rw-r--r--ml/dlib/examples/svm_ex.cpp255
-rw-r--r--ml/dlib/examples/svm_pegasos_ex.cpp160
-rw-r--r--ml/dlib/examples/svm_rank_ex.cpp151
-rw-r--r--ml/dlib/examples/svm_sparse_ex.cpp120
-rw-r--r--ml/dlib/examples/svm_struct_ex.cpp414
-rw-r--r--ml/dlib/examples/svr_ex.cpp96
-rw-r--r--ml/dlib/examples/thread_function_ex.cpp71
-rw-r--r--ml/dlib/examples/thread_pool_ex.cpp183
-rw-r--r--ml/dlib/examples/threaded_object_ex.cpp79
-rw-r--r--ml/dlib/examples/threads_ex.cpp93
-rw-r--r--ml/dlib/examples/timer_ex.cpp56
-rw-r--r--ml/dlib/examples/train_object_detector.cpp422
-rw-r--r--ml/dlib/examples/train_shape_predictor_ex.cpp198
-rw-r--r--ml/dlib/examples/using_custom_kernels_ex.cpp208
-rw-r--r--ml/dlib/examples/video_frames/frame_000100.jpgbin4674 -> 0 bytes
-rw-r--r--ml/dlib/examples/video_frames/frame_000101.jpgbin4756 -> 0 bytes
-rw-r--r--ml/dlib/examples/video_frames/frame_000102.jpgbin4683 -> 0 bytes
-rw-r--r--ml/dlib/examples/video_frames/frame_000103.jpgbin4653 -> 0 bytes
-rw-r--r--ml/dlib/examples/video_frames/frame_000104.jpgbin4807 -> 0 bytes
-rw-r--r--ml/dlib/examples/video_frames/frame_000105.jpgbin4760 -> 0 bytes
-rw-r--r--ml/dlib/examples/video_frames/frame_000106.jpgbin4640 -> 0 bytes
-rw-r--r--ml/dlib/examples/video_frames/frame_000107.jpgbin4713 -> 0 bytes
-rw-r--r--ml/dlib/examples/video_frames/frame_000108.jpgbin4908 -> 0 bytes
-rw-r--r--ml/dlib/examples/video_frames/frame_000109.jpgbin4854 -> 0 bytes
-rw-r--r--ml/dlib/examples/video_frames/frame_000110.jpgbin4775 -> 0 bytes
-rw-r--r--ml/dlib/examples/video_frames/frame_000111.jpgbin4587 -> 0 bytes
-rw-r--r--ml/dlib/examples/video_frames/frame_000112.jpgbin4759 -> 0 bytes
-rw-r--r--ml/dlib/examples/video_frames/frame_000113.jpgbin4686 -> 0 bytes
-rw-r--r--ml/dlib/examples/video_frames/frame_000114.jpgbin4740 -> 0 bytes
-rw-r--r--ml/dlib/examples/video_frames/frame_000115.jpgbin4667 -> 0 bytes
-rw-r--r--ml/dlib/examples/video_frames/frame_000116.jpgbin5027 -> 0 bytes
-rw-r--r--ml/dlib/examples/video_frames/frame_000117.jpgbin5160 -> 0 bytes
-rw-r--r--ml/dlib/examples/video_frames/frame_000118.jpgbin5033 -> 0 bytes
-rw-r--r--ml/dlib/examples/video_frames/frame_000119.jpgbin5262 -> 0 bytes
-rw-r--r--ml/dlib/examples/video_frames/frame_000120.jpgbin5213 -> 0 bytes
-rw-r--r--ml/dlib/examples/video_frames/frame_000121.jpgbin5229 -> 0 bytes
-rw-r--r--ml/dlib/examples/video_frames/frame_000122.jpgbin5076 -> 0 bytes
-rw-r--r--ml/dlib/examples/video_frames/frame_000123.jpgbin5162 -> 0 bytes
-rw-r--r--ml/dlib/examples/video_frames/frame_000124.jpgbin5068 -> 0 bytes
-rw-r--r--ml/dlib/examples/video_frames/frame_000125.jpgbin5108 -> 0 bytes
-rw-r--r--ml/dlib/examples/video_frames/frame_000126.jpgbin4987 -> 0 bytes
-rw-r--r--ml/dlib/examples/video_frames/frame_000127.jpgbin5068 -> 0 bytes
-rw-r--r--ml/dlib/examples/video_frames/frame_000128.jpgbin4973 -> 0 bytes
-rw-r--r--ml/dlib/examples/video_frames/frame_000129.jpgbin4931 -> 0 bytes
-rw-r--r--ml/dlib/examples/video_frames/frame_000130.jpgbin5087 -> 0 bytes
-rw-r--r--ml/dlib/examples/video_frames/frame_000131.jpgbin4982 -> 0 bytes
-rw-r--r--ml/dlib/examples/video_frames/frame_000132.jpgbin4965 -> 0 bytes
-rw-r--r--ml/dlib/examples/video_frames/frame_000133.jpgbin4944 -> 0 bytes
-rw-r--r--ml/dlib/examples/video_frames/frame_000134.jpgbin4854 -> 0 bytes
-rw-r--r--ml/dlib/examples/video_frames/frame_000135.jpgbin4803 -> 0 bytes
-rw-r--r--ml/dlib/examples/video_frames/frame_000136.jpgbin4793 -> 0 bytes
-rw-r--r--ml/dlib/examples/video_frames/frame_000137.jpgbin4863 -> 0 bytes
-rw-r--r--ml/dlib/examples/video_frames/frame_000138.jpgbin4969 -> 0 bytes
-rw-r--r--ml/dlib/examples/video_frames/frame_000139.jpgbin4960 -> 0 bytes
-rw-r--r--ml/dlib/examples/video_frames/frame_000140.jpgbin5064 -> 0 bytes
-rw-r--r--ml/dlib/examples/video_frames/frame_000141.jpgbin5115 -> 0 bytes
-rw-r--r--ml/dlib/examples/video_frames/frame_000142.jpgbin5112 -> 0 bytes
-rw-r--r--ml/dlib/examples/video_frames/frame_000143.jpgbin5095 -> 0 bytes
-rw-r--r--ml/dlib/examples/video_frames/frame_000144.jpgbin5082 -> 0 bytes
-rw-r--r--ml/dlib/examples/video_frames/frame_000145.jpgbin4971 -> 0 bytes
-rw-r--r--ml/dlib/examples/video_frames/frame_000146.jpgbin4828 -> 0 bytes
-rw-r--r--ml/dlib/examples/video_frames/frame_000147.jpgbin4813 -> 0 bytes
-rw-r--r--ml/dlib/examples/video_frames/frame_000148.jpgbin4804 -> 0 bytes
-rw-r--r--ml/dlib/examples/video_frames/frame_000149.jpgbin4686 -> 0 bytes
-rw-r--r--ml/dlib/examples/video_frames/frame_000150.jpgbin4859 -> 0 bytes
-rw-r--r--ml/dlib/examples/video_frames/frame_000151.jpgbin4780 -> 0 bytes
-rw-r--r--ml/dlib/examples/video_frames/frame_000152.jpgbin4733 -> 0 bytes
-rw-r--r--ml/dlib/examples/video_frames/frame_000153.jpgbin4619 -> 0 bytes
-rw-r--r--ml/dlib/examples/video_frames/frame_000154.jpgbin4661 -> 0 bytes
-rw-r--r--ml/dlib/examples/video_frames/frame_000155.jpgbin4584 -> 0 bytes
-rw-r--r--ml/dlib/examples/video_frames/frame_000156.jpgbin4577 -> 0 bytes
-rw-r--r--ml/dlib/examples/video_frames/frame_000157.jpgbin4680 -> 0 bytes
-rw-r--r--ml/dlib/examples/video_frames/frame_000158.jpgbin4759 -> 0 bytes
-rw-r--r--ml/dlib/examples/video_frames/frame_000159.jpgbin4671 -> 0 bytes
-rw-r--r--ml/dlib/examples/video_frames/frame_000160.jpgbin4776 -> 0 bytes
-rw-r--r--ml/dlib/examples/video_frames/frame_000161.jpgbin4767 -> 0 bytes
-rw-r--r--ml/dlib/examples/video_frames/frame_000162.jpgbin4763 -> 0 bytes
-rw-r--r--ml/dlib/examples/video_frames/frame_000163.jpgbin4793 -> 0 bytes
-rw-r--r--ml/dlib/examples/video_frames/frame_000164.jpgbin4809 -> 0 bytes
-rw-r--r--ml/dlib/examples/video_frames/frame_000165.jpgbin4774 -> 0 bytes
-rw-r--r--ml/dlib/examples/video_frames/frame_000166.jpgbin4801 -> 0 bytes
-rw-r--r--ml/dlib/examples/video_frames/frame_000167.jpgbin4724 -> 0 bytes
-rw-r--r--ml/dlib/examples/video_frames/frame_000168.jpgbin4656 -> 0 bytes
-rw-r--r--ml/dlib/examples/video_frames/frame_000169.jpgbin4544 -> 0 bytes
-rw-r--r--ml/dlib/examples/video_frames/frame_000170.jpgbin4554 -> 0 bytes
-rw-r--r--ml/dlib/examples/video_frames/frame_000171.jpgbin4574 -> 0 bytes
-rw-r--r--ml/dlib/examples/video_frames/frame_000172.jpgbin4379 -> 0 bytes
-rw-r--r--ml/dlib/examples/video_frames/frame_000173.jpgbin4185 -> 0 bytes
-rw-r--r--ml/dlib/examples/video_frames/frame_000174.jpgbin4457 -> 0 bytes
-rw-r--r--ml/dlib/examples/video_frames/frame_000175.jpgbin4596 -> 0 bytes
-rw-r--r--ml/dlib/examples/video_frames/frame_000176.jpgbin4630 -> 0 bytes
-rw-r--r--ml/dlib/examples/video_frames/frame_000177.jpgbin4539 -> 0 bytes
-rw-r--r--ml/dlib/examples/video_frames/frame_000178.jpgbin4582 -> 0 bytes
-rw-r--r--ml/dlib/examples/video_frames/frame_000179.jpgbin4522 -> 0 bytes
-rw-r--r--ml/dlib/examples/video_frames/frame_000180.jpgbin4599 -> 0 bytes
-rw-r--r--ml/dlib/examples/video_frames/frame_000181.jpgbin4523 -> 0 bytes
-rw-r--r--ml/dlib/examples/video_frames/frame_000182.jpgbin4694 -> 0 bytes
-rw-r--r--ml/dlib/examples/video_frames/frame_000183.jpgbin4729 -> 0 bytes
-rw-r--r--ml/dlib/examples/video_frames/frame_000184.jpgbin4916 -> 0 bytes
-rw-r--r--ml/dlib/examples/video_frames/frame_000185.jpgbin4759 -> 0 bytes
-rw-r--r--ml/dlib/examples/video_frames/frame_000186.jpgbin4963 -> 0 bytes
-rw-r--r--ml/dlib/examples/video_frames/frame_000187.jpgbin5026 -> 0 bytes
-rw-r--r--ml/dlib/examples/video_frames/frame_000188.jpgbin5150 -> 0 bytes
-rw-r--r--ml/dlib/examples/video_frames/frame_000189.jpgbin5233 -> 0 bytes
-rw-r--r--ml/dlib/examples/video_frames/frame_000190.jpgbin4999 -> 0 bytes
-rw-r--r--ml/dlib/examples/video_frames/frame_000191.jpgbin5043 -> 0 bytes
-rw-r--r--ml/dlib/examples/video_frames/frame_000192.jpgbin4730 -> 0 bytes
-rw-r--r--ml/dlib/examples/video_frames/frame_000193.jpgbin4773 -> 0 bytes
-rw-r--r--ml/dlib/examples/video_frames/frame_000194.jpgbin4959 -> 0 bytes
-rw-r--r--ml/dlib/examples/video_frames/frame_000195.jpgbin4775 -> 0 bytes
-rw-r--r--ml/dlib/examples/video_frames/frame_000196.jpgbin5078 -> 0 bytes
-rw-r--r--ml/dlib/examples/video_frames/frame_000197.jpgbin5424 -> 0 bytes
-rw-r--r--ml/dlib/examples/video_frames/frame_000198.jpgbin5373 -> 0 bytes
-rw-r--r--ml/dlib/examples/video_frames/frame_000199.jpgbin5797 -> 0 bytes
-rw-r--r--ml/dlib/examples/video_frames/frame_000200.jpgbin6121 -> 0 bytes
-rw-r--r--ml/dlib/examples/video_frames/frame_000201.jpgbin6208 -> 0 bytes
-rw-r--r--ml/dlib/examples/video_frames/frame_000202.jpgbin6116 -> 0 bytes
-rw-r--r--ml/dlib/examples/video_frames/frame_000203.jpgbin6070 -> 0 bytes
-rw-r--r--ml/dlib/examples/video_frames/frame_000204.jpgbin6069 -> 0 bytes
-rw-r--r--ml/dlib/examples/video_frames/frame_000205.jpgbin5959 -> 0 bytes
-rw-r--r--ml/dlib/examples/video_frames/frame_000206.jpgbin5717 -> 0 bytes
-rw-r--r--ml/dlib/examples/video_frames/frame_000207.jpgbin5751 -> 0 bytes
-rw-r--r--ml/dlib/examples/video_frames/frame_000208.jpgbin5529 -> 0 bytes
-rw-r--r--ml/dlib/examples/video_frames/frame_000209.jpgbin5404 -> 0 bytes
-rw-r--r--ml/dlib/examples/video_frames/frame_000210.jpgbin5458 -> 0 bytes
-rw-r--r--ml/dlib/examples/video_frames/frame_000211.jpgbin5320 -> 0 bytes
-rw-r--r--ml/dlib/examples/video_frames/frame_000212.jpgbin5257 -> 0 bytes
-rw-r--r--ml/dlib/examples/video_frames/frame_000213.jpgbin5462 -> 0 bytes
-rw-r--r--ml/dlib/examples/video_frames/frame_000214.jpgbin5434 -> 0 bytes
-rw-r--r--ml/dlib/examples/video_frames/frame_000215.jpgbin5822 -> 0 bytes
-rw-r--r--ml/dlib/examples/video_frames/frame_000216.jpgbin6131 -> 0 bytes
-rw-r--r--ml/dlib/examples/video_frames/frame_000217.jpgbin6031 -> 0 bytes
-rw-r--r--ml/dlib/examples/video_frames/frame_000218.jpgbin6105 -> 0 bytes
-rw-r--r--ml/dlib/examples/video_frames/frame_000219.jpgbin6136 -> 0 bytes
-rw-r--r--ml/dlib/examples/video_frames/frame_000220.jpgbin5870 -> 0 bytes
-rw-r--r--ml/dlib/examples/video_frames/frame_000221.jpgbin5694 -> 0 bytes
-rw-r--r--ml/dlib/examples/video_frames/frame_000222.jpgbin5430 -> 0 bytes
-rw-r--r--ml/dlib/examples/video_frames/frame_000223.jpgbin5222 -> 0 bytes
-rw-r--r--ml/dlib/examples/video_frames/frame_000224.jpgbin4880 -> 0 bytes
-rw-r--r--ml/dlib/examples/video_frames/frame_000225.jpgbin5090 -> 0 bytes
-rw-r--r--ml/dlib/examples/video_frames/frame_000226.jpgbin4821 -> 0 bytes
-rw-r--r--ml/dlib/examples/video_frames/frame_000227.jpgbin4738 -> 0 bytes
-rw-r--r--ml/dlib/examples/video_frames/frame_000228.jpgbin4500 -> 0 bytes
-rw-r--r--ml/dlib/examples/video_frames/frame_000229.jpgbin4360 -> 0 bytes
-rw-r--r--ml/dlib/examples/video_frames/frame_000230.jpgbin4236 -> 0 bytes
-rw-r--r--ml/dlib/examples/video_frames/frame_000231.jpgbin4243 -> 0 bytes
-rw-r--r--ml/dlib/examples/video_frames/frame_000232.jpgbin4191 -> 0 bytes
-rw-r--r--ml/dlib/examples/video_frames/frame_000233.jpgbin4232 -> 0 bytes
-rw-r--r--ml/dlib/examples/video_frames/frame_000234.jpgbin4250 -> 0 bytes
-rw-r--r--ml/dlib/examples/video_frames/frame_000235.jpgbin4119 -> 0 bytes
-rw-r--r--ml/dlib/examples/video_frames/frame_000236.jpgbin4004 -> 0 bytes
-rw-r--r--ml/dlib/examples/video_frames/frame_000237.jpgbin4248 -> 0 bytes
-rw-r--r--ml/dlib/examples/video_frames/frame_000238.jpgbin4283 -> 0 bytes
-rw-r--r--ml/dlib/examples/video_frames/frame_000239.jpgbin4325 -> 0 bytes
-rw-r--r--ml/dlib/examples/video_frames/frame_000240.jpgbin4458 -> 0 bytes
-rw-r--r--ml/dlib/examples/video_frames/frame_000241.jpgbin4577 -> 0 bytes
-rw-r--r--ml/dlib/examples/video_frames/frame_000242.jpgbin4699 -> 0 bytes
-rw-r--r--ml/dlib/examples/video_frames/frame_000243.jpgbin4773 -> 0 bytes
-rw-r--r--ml/dlib/examples/video_frames/frame_000244.jpgbin4956 -> 0 bytes
-rw-r--r--ml/dlib/examples/video_frames/frame_000245.jpgbin5054 -> 0 bytes
-rw-r--r--ml/dlib/examples/video_frames/frame_000246.jpgbin5200 -> 0 bytes
-rw-r--r--ml/dlib/examples/video_frames/frame_000247.jpgbin5210 -> 0 bytes
-rw-r--r--ml/dlib/examples/video_frames/frame_000248.jpgbin5252 -> 0 bytes
-rw-r--r--ml/dlib/examples/video_frames/frame_000249.jpgbin5249 -> 0 bytes
-rw-r--r--ml/dlib/examples/video_frames/frame_000250.jpgbin5148 -> 0 bytes
-rw-r--r--ml/dlib/examples/video_frames/license.txt6
-rw-r--r--ml/dlib/examples/video_tracking_ex.cpp72
-rw-r--r--ml/dlib/examples/webcam_face_pose_ex.cpp100
-rw-r--r--ml/dlib/examples/xml_parser_ex.cpp115
331 files changed, 0 insertions, 23069 deletions
diff --git a/ml/dlib/examples/3d_point_cloud_ex.cpp b/ml/dlib/examples/3d_point_cloud_ex.cpp
deleted file mode 100644
index f64a68976..000000000
--- a/ml/dlib/examples/3d_point_cloud_ex.cpp
+++ /dev/null
@@ -1,50 +0,0 @@
-// The contents of this file are in the public domain. See LICENSE_FOR_EXAMPLE_PROGRAMS.txt
-/*
-
- This is an example illustrating the use of the perspective_window tool
- in the dlib C++ Library. It is a simple tool for displaying 3D point
- clouds on the screen.
-
-*/
-
-#include <dlib/gui_widgets.h>
-#include <dlib/image_transforms.h>
-#include <cmath>
-
-using namespace dlib;
-using namespace std;
-
-// ----------------------------------------------------------------------------------------
-
-int main()
-{
- // Let's make a point cloud that looks like a 3D spiral.
- std::vector<perspective_window::overlay_dot> points;
- dlib::rand rnd;
- for (double i = 0; i < 20; i+=0.001)
- {
- // Get a point on a spiral
- dlib::vector<double> val(sin(i),cos(i),i/4);
-
- // Now add some random noise to it
- dlib::vector<double> temp(rnd.get_random_gaussian(),
- rnd.get_random_gaussian(),
- rnd.get_random_gaussian());
- val += temp/20;
-
- // Pick a color based on how far we are along the spiral
- rgb_pixel color = colormap_jet(i,0,20);
-
- // And add the point to the list of points we will display
- points.push_back(perspective_window::overlay_dot(val, color));
- }
-
- // Now finally display the point cloud.
- perspective_window win;
- win.set_title("perspective_window 3D point cloud");
- win.add_overlay(points);
- win.wait_until_closed();
-}
-
-// ----------------------------------------------------------------------------
-
diff --git a/ml/dlib/examples/CMakeLists.txt b/ml/dlib/examples/CMakeLists.txt
deleted file mode 100644
index 5c408d74f..000000000
--- a/ml/dlib/examples/CMakeLists.txt
+++ /dev/null
@@ -1,250 +0,0 @@
-#
-# _______ _ _ _____ _____ _____ _____
-# |__ __| | | |_ _|/ ____| |_ _|/ ____| /\
-# | | | |__| | | | | (___ | | | (___ / \
-# | | | __ | | | \___ \ | | \___ \ / /\ \
-# | | | | | |_| |_ ____) | _| |_ ____) | / ____ \
-# |_|__|_|_ |_|_____|_____/__ |_____|_____/ /_/ _ \_\
-# |__ __| | | |__ __/ __ \| __ \|_ _| /\ | |
-# | | | | | | | | | | | | |__) | | | / \ | |
-# | | | | | | | | | | | | _ / | | / /\ \ | |
-# | | | |__| | | | | |__| | | \ \ _| |_ / ____ \| |____
-# |_| \____/ |_| \____/|_| \_\_____/_/ \_\______|
-#
-#
-# _____ ______ _____ _______ _ _ ______
-# | __ \| ____| /\ | __ \ |__ __| | | | ____|
-# | |__) | |__ / \ | | | | | | | |__| | |__
-# | _ /| __| / /\ \ | | | | | | | __ | __|
-# | | \ \| |____ / ____ \| |__| | | | | | | | |____
-# |_|__\_\______/_/_ __\_\_____/__ _ |_|__|_|_ |_|______|_ _ _
-# / ____/ __ \| \/ | \/ | ____| \ | |__ __/ ____| | | | | |
-# | | | | | | \ / | \ / | |__ | \| | | | | (___ | | | | |
-# | | | | | | |\/| | |\/| | __| | . ` | | | \___ \ | | | | |
-# | |___| |__| | | | | | | | |____| |\ | | | ____) | |_|_|_|_|
-# \_____\____/|_| |_|_| |_|______|_| \_| |_| |_____/ (_|_|_|_)
-#
-#
-#
-# This is a CMake makefile. CMake is a tool that helps you build C++ programs.
-# You can download CMake from http://www.cmake.org. This CMakeLists.txt file
-# you are reading builds dlib's example programs.
-#
-
-
-cmake_minimum_required(VERSION 2.8.12)
-# Every project needs a name. We call this the "examples" project.
-project(examples)
-
-
-# Tell cmake we will need dlib. This command will pull in dlib and compile it
-# into your project. Note that you don't need to compile or install dlib. All
-# cmake needs is the dlib source code folder and it will take care of everything.
-add_subdirectory(../dlib dlib_build)
-
-
-# The next thing we need to do is tell CMake about the code you want to
-# compile. We do this with the add_executable() statement which takes the name
-# of the output executable and then a list of .cpp files to compile. Here we
-# are going to compile one of the dlib example programs which has only one .cpp
-# file, assignment_learning_ex.cpp. If your program consisted of multiple .cpp
-# files you would simply list them here in the add_executable() statement.
-add_executable(assignment_learning_ex assignment_learning_ex.cpp)
-# Finally, you need to tell CMake that this program, assignment_learning_ex,
-# depends on dlib. You do that with this statement:
-target_link_libraries(assignment_learning_ex dlib::dlib)
-
-
-
-# To compile this program all you need to do is ask cmake. You would type
-# these commands from within the directory containing this CMakeLists.txt
-# file:
-# mkdir build
-# cd build
-# cmake ..
-# cmake --build . --config Release
-#
-# The cmake .. command looks in the parent folder for a file named
-# CMakeLists.txt, reads it, and sets up everything needed to build program.
-# Also, note that CMake can generate Visual Studio or XCode project files. So
-# if instead you had written:
-# cd build
-# cmake .. -G Xcode
-#
-# You would be able to open the resulting Xcode project and compile and edit
-# the example programs within the Xcode IDE. CMake can generate a lot of
-# different types of IDE projects. Run the cmake -h command to see a list of
-# arguments to -G to see what kinds of projects cmake can generate for you. It
-# probably includes your favorite IDE in the list.
-
-
-
-
-#################################################################################
-#################################################################################
-# A CMakeLists.txt file can compile more than just one program. So below we
-# tell it to compile the other dlib example programs using pretty much the
-# same CMake commands we used above.
-#################################################################################
-#################################################################################
-
-
-# Since there are a lot of examples I'm going to use a macro to simplify this
-# CMakeLists.txt file. However, usually you will create only one executable in
-# your cmake projects and use the syntax shown above.
-macro(add_example name)
- add_executable(${name} ${name}.cpp)
- target_link_libraries(${name} dlib::dlib )
-endmacro()
-
-# if an example requires GUI, call this macro to check DLIB_NO_GUI_SUPPORT to include or exclude
-macro(add_gui_example name)
- if (DLIB_NO_GUI_SUPPORT)
- message("No GUI support, so we won't build the ${name} example.")
- else()
- add_example(${name})
- endif()
-endmacro()
-
-# The deep learning toolkit requires a compiler with essentially complete C++11
-# support. However, versions of Visual Studio prior to October 2016 didn't
-# provide enough C++11 support to compile the DNN tooling, but were good enough
-# to compile the rest of dlib. So new versions of Visual Studio 2015 will
-# work. However, Visual Studio 2017 had some C++11 support regressions, so it
-# wasn't until December 2017 that Visual Studio 2017 had good enough C++11
-# support to compile the DNN examples. So if you are using Visual Studio, make
-# sure you have an updated version if you want to compile the DNN code.
-#
-# Also note that Visual Studio users should give the -T host=x64 option so that
-# CMake will instruct Visual Studio to use its 64bit toolchain. If you don't
-# do this then by default Visual Studio uses a 32bit toolchain, WHICH RESTRICTS
-# THE COMPILER TO ONLY 2GB OF RAM, causing it to run out of RAM and crash when
-# compiling some of the DNN examples. So generate your project with a statement
-# like this:
-# cmake .. -G "Visual Studio 14 2015 Win64" -T host=x64
-if (NOT USING_OLD_VISUAL_STUDIO_COMPILER)
- add_example(dnn_metric_learning_ex)
- add_gui_example(dnn_face_recognition_ex)
- add_example(dnn_introduction_ex)
- add_example(dnn_introduction2_ex)
- add_example(dnn_inception_ex)
- add_gui_example(dnn_mmod_ex)
- add_gui_example(dnn_mmod_face_detection_ex)
- add_gui_example(random_cropper_ex)
- add_gui_example(dnn_mmod_dog_hipsterizer)
- add_gui_example(dnn_imagenet_ex)
- add_gui_example(dnn_mmod_find_cars_ex)
- add_gui_example(dnn_mmod_find_cars2_ex)
- add_example(dnn_mmod_train_find_cars_ex)
- add_gui_example(dnn_semantic_segmentation_ex)
- add_example(dnn_imagenet_train_ex)
- add_example(dnn_semantic_segmentation_train_ex)
- add_example(dnn_metric_learning_on_images_ex)
-endif()
-
-
-if (DLIB_NO_GUI_SUPPORT)
- message("No GUI support, so we won't build the webcam_face_pose_ex example.")
-else()
- find_package(OpenCV QUIET)
- if (OpenCV_FOUND)
- include_directories(${OpenCV_INCLUDE_DIRS})
-
- add_executable(webcam_face_pose_ex webcam_face_pose_ex.cpp)
- target_link_libraries(webcam_face_pose_ex dlib::dlib ${OpenCV_LIBS} )
- else()
- message("OpenCV not found, so we won't build the webcam_face_pose_ex example.")
- endif()
-endif()
-
-
-
-#here we apply our macros
-add_gui_example(3d_point_cloud_ex)
-add_example(bayes_net_ex)
-add_example(bayes_net_from_disk_ex)
-add_gui_example(bayes_net_gui_ex)
-add_example(bridge_ex)
-add_example(bsp_ex)
-add_example(compress_stream_ex)
-add_example(config_reader_ex)
-add_example(custom_trainer_ex)
-add_example(dir_nav_ex)
-add_example(empirical_kernel_map_ex)
-add_gui_example(face_detection_ex)
-add_gui_example(face_landmark_detection_ex)
-add_gui_example(fhog_ex)
-add_gui_example(fhog_object_detector_ex)
-add_example(file_to_code_ex)
-add_example(graph_labeling_ex)
-add_gui_example(gui_api_ex)
-add_gui_example(hough_transform_ex)
-add_gui_example(image_ex)
-add_example(integrate_function_adapt_simp_ex)
-add_example(iosockstream_ex)
-add_example(kcentroid_ex)
-add_example(kkmeans_ex)
-add_example(krls_ex)
-add_example(krls_filter_ex)
-add_example(krr_classification_ex)
-add_example(krr_regression_ex)
-add_example(learning_to_track_ex)
-add_example(least_squares_ex)
-add_example(linear_manifold_regularizer_ex)
-add_example(logger_custom_output_ex)
-add_example(logger_ex)
-add_example(logger_ex_2)
-add_example(matrix_ex)
-add_example(matrix_expressions_ex)
-add_example(max_cost_assignment_ex)
-add_example(member_function_pointer_ex)
-add_example(mlp_ex)
-add_example(model_selection_ex)
-add_gui_example(mpc_ex)
-add_example(multiclass_classification_ex)
-add_example(multithreaded_object_ex)
-add_gui_example(object_detector_advanced_ex)
-add_gui_example(object_detector_ex)
-add_gui_example(one_class_classifiers_ex)
-add_example(optimization_ex)
-add_example(parallel_for_ex)
-add_example(pipe_ex)
-add_example(pipe_ex_2)
-add_example(quantum_computing_ex)
-add_example(queue_ex)
-add_example(rank_features_ex)
-add_example(running_stats_ex)
-add_example(rvm_ex)
-add_example(rvm_regression_ex)
-add_example(sequence_labeler_ex)
-add_example(sequence_segmenter_ex)
-add_example(server_http_ex)
-add_example(server_iostream_ex)
-add_example(sockets_ex)
-add_example(sockstreambuf_ex)
-add_example(std_allocator_ex)
-add_gui_example(surf_ex)
-add_example(svm_c_ex)
-add_example(svm_ex)
-add_example(svm_pegasos_ex)
-add_example(svm_rank_ex)
-add_example(svm_sparse_ex)
-add_example(svm_struct_ex)
-add_example(svr_ex)
-add_example(thread_function_ex)
-add_example(thread_pool_ex)
-add_example(threaded_object_ex)
-add_example(threads_ex)
-add_example(timer_ex)
-add_gui_example(train_object_detector)
-add_example(train_shape_predictor_ex)
-add_example(using_custom_kernels_ex)
-add_gui_example(video_tracking_ex)
-add_example(xml_parser_ex)
-
-
-if (DLIB_LINK_WITH_SQLITE3)
- add_example(sqlite_ex)
-endif()
-
-
diff --git a/ml/dlib/examples/LICENSE_FOR_EXAMPLE_PROGRAMS.txt b/ml/dlib/examples/LICENSE_FOR_EXAMPLE_PROGRAMS.txt
deleted file mode 100644
index c69b87af3..000000000
--- a/ml/dlib/examples/LICENSE_FOR_EXAMPLE_PROGRAMS.txt
+++ /dev/null
@@ -1,22 +0,0 @@
-The intent of the example programs supplied with the dlib C++ library is
-to both instruct users and to also provide a simple body of code they
-may copy and paste from. To make this as painless as possible all the
-example programs have been placed into the public domain.
-
-
-This work is hereby released into the Public Domain.
-To view a copy of the public domain dedication, visit
-http://creativecommons.org/licenses/publicdomain/ or send a
-letter to
- Creative Commons
- 171 Second Street
- Suite 300,
- San Francisco, California, 94105, USA.
-
-
-
-Public domain dedications are not recognized by some countries. So
-if you live in an area where the above dedication isn't valid then
-you can consider the example programs to be licensed under the Boost
-Software License.
-
diff --git a/ml/dlib/examples/assignment_learning_ex.cpp b/ml/dlib/examples/assignment_learning_ex.cpp
deleted file mode 100644
index 7a3acd013..000000000
--- a/ml/dlib/examples/assignment_learning_ex.cpp
+++ /dev/null
@@ -1,325 +0,0 @@
-// The contents of this file are in the public domain. See LICENSE_FOR_EXAMPLE_PROGRAMS.txt
-/*
-
- This is an example illustrating the use of the dlib machine learning tools for
- learning to solve the assignment problem.
-
- Many tasks in computer vision or natural language processing can be thought of
- as assignment problems. For example, in a computer vision application where
- you are trying to track objects moving around in video, you likely need to solve
- an association problem every time you get a new video frame. That is, each new
- frame will contain objects (e.g. people, cars, etc.) and you will want to
- determine which of these objects are actually things you have seen in previous
- frames.
-
- The assignment problem can be optimally solved using the well known Hungarian
- algorithm. However, this algorithm requires the user to supply some function
- which measures the "goodness" of an individual association. In many cases the
- best way to measure this goodness isn't obvious and therefore machine learning
- methods are used.
-
- The remainder of this example will show you how to learn a goodness function
- which is optimal, in a certain sense, for use with the Hungarian algorithm. To
- do this, we will make a simple dataset of example associations and use them to
- train a supervised machine learning method.
-
- Finally, note that there is a whole example program dedicated to assignment
- learning problems where you are trying to make an object tracker. So if that is
- what you are interested in then take a look at the learning_to_track_ex.cpp
- example program.
-*/
-
-
-#include <iostream>
-#include <dlib/svm_threaded.h>
-
-using namespace std;
-using namespace dlib;
-
-
-// ----------------------------------------------------------------------------------------
-
-/*
- In an association problem, we will talk about the "Left Hand Set" (LHS) and the
- "Right Hand Set" (RHS). The task will be to learn to map all elements of LHS to
- unique elements of RHS. If an element of LHS can't be mapped to a unique element of
- RHS for some reason (e.g. LHS is bigger than RHS) then it can also be mapped to the
- special -1 output, indicating no mapping to RHS.
-
- So the first step is to define the type of elements in each of these sets. In the
- code below we will use column vectors in both LHS and RHS. However, in general,
- they can each contain any type you like. LHS can even contain a different type
- than RHS.
-*/
-
-typedef dlib::matrix<double,0,1> column_vector;
-
-// This type represents a pair of LHS and RHS. That is, sample_type::first
-// contains a left hand set and sample_type::second contains a right hand set.
-typedef std::pair<std::vector<column_vector>, std::vector<column_vector> > sample_type;
-
-// This type will contain the association information between LHS and RHS. That is,
-// it will determine which elements of LHS map to which elements of RHS.
-typedef std::vector<long> label_type;
-
-// In this example, all our LHS and RHS elements will be 3-dimensional vectors.
-const unsigned long num_dims = 3;
-
-void make_data (
- std::vector<sample_type>& samples,
- std::vector<label_type>& labels
-);
-/*!
- ensures
- - This function creates a training dataset of 5 example associations.
- - #samples.size() == 5
- - #labels.size() == 5
- - for all valid i:
- - #samples[i].first == a left hand set
- - #samples[i].second == a right hand set
- - #labels[i] == a set of integers indicating how to map LHS to RHS. To be
- precise:
- - #samples[i].first.size() == #labels[i].size()
- - for all valid j:
- -1 <= #labels[i][j] < #samples[i].second.size()
- (A value of -1 indicates that #samples[i].first[j] isn't associated with anything.
- All other values indicate the associating element of #samples[i].second)
- - All elements of #labels[i] which are not equal to -1 are unique. That is,
- multiple elements of #samples[i].first can't associate to the same element
- in #samples[i].second.
-!*/
-
-// ----------------------------------------------------------------------------------------
-
-struct feature_extractor
-{
- /*!
- Recall that our task is to learn the "goodness of assignment" function for
- use with the Hungarian algorithm. The dlib tools assume this function
- can be written as:
- match_score(l,r) == dot(w, PSI(l,r)) + bias
- where l is an element of LHS, r is an element of RHS, w is a parameter vector,
- bias is a scalar value, and PSI() is a user supplied feature extractor.
-
- This feature_extractor is where we implement PSI(). How you implement this
- is highly problem dependent.
- !*/
-
- // The type of feature vector returned from get_features(). This must be either
- // a dlib::matrix or a sparse vector.
- typedef column_vector feature_vector_type;
-
- // The types of elements in the LHS and RHS sets
- typedef column_vector lhs_element;
- typedef column_vector rhs_element;
-
-
- unsigned long num_features() const
- {
- // Return the dimensionality of feature vectors produced by get_features()
- return num_dims;
- }
-
- void get_features (
- const lhs_element& left,
- const rhs_element& right,
- feature_vector_type& feats
- ) const
- /*!
- ensures
- - #feats == PSI(left,right)
- (i.e. This function computes a feature vector which, in some sense,
- captures information useful for deciding if matching left to right
- is "good").
- !*/
- {
- // Let's just use the squared difference between each vector as our features.
- // However, it should be emphasized that how to compute the features here is very
- // problem dependent.
- feats = squared(left - right);
- }
-
-};
-
-// We need to define serialize() and deserialize() for our feature extractor if we want
-// to be able to serialize and deserialize our learned models. In this case the
-// implementation is empty since our feature_extractor doesn't have any state. But you
-// might define more complex feature extractors which have state that needs to be saved.
-void serialize (const feature_extractor& , std::ostream& ) {}
-void deserialize (feature_extractor& , std::istream& ) {}
-
-// ----------------------------------------------------------------------------------------
-
-int main()
-{
- try
- {
- // Get a small bit of training data.
- std::vector<sample_type> samples;
- std::vector<label_type> labels;
- make_data(samples, labels);
-
-
- structural_assignment_trainer<feature_extractor> trainer;
- // This is the common SVM C parameter. Larger values encourage the
- // trainer to attempt to fit the data exactly but might overfit.
- // In general, you determine this parameter by cross-validation.
- trainer.set_c(10);
- // This trainer can use multiple CPU cores to speed up the training.
- // So set this to the number of available CPU cores.
- trainer.set_num_threads(4);
-
- // Do the training and save the results in assigner.
- assignment_function<feature_extractor> assigner = trainer.train(samples, labels);
-
-
- // Test the assigner on our data. The output will indicate that it makes the
- // correct associations on all samples.
- cout << "Test the learned assignment function: " << endl;
- for (unsigned long i = 0; i < samples.size(); ++i)
- {
- // Predict the assignments for the LHS and RHS in samples[i].
- std::vector<long> predicted_assignments = assigner(samples[i]);
- cout << "true labels: " << trans(mat(labels[i]));
- cout << "predicted labels: " << trans(mat(predicted_assignments)) << endl;
- }
-
- // We can also use this tool to compute the percentage of assignments predicted correctly.
- cout << "training accuracy: " << test_assignment_function(assigner, samples, labels) << endl;
-
-
- // Since testing on your training data is a really bad idea, we can also do 5-fold cross validation.
- // Happily, this also indicates that all associations were made correctly.
- randomize_samples(samples, labels);
- cout << "cv accuracy: " << cross_validate_assignment_trainer(trainer, samples, labels, 5) << endl;
-
-
-
- // Finally, the assigner can be serialized to disk just like most dlib objects.
- serialize("assigner.dat") << assigner;
-
- // recall from disk
- deserialize("assigner.dat") >> assigner;
- }
- catch (std::exception& e)
- {
- cout << "EXCEPTION THROWN" << endl;
- cout << e.what() << endl;
- }
-}
-
-// ----------------------------------------------------------------------------------------
-
-void make_data (
- std::vector<sample_type>& samples,
- std::vector<label_type>& labels
-)
-{
- // Make four different vectors. We will use them to make example assignments.
- column_vector A(num_dims), B(num_dims), C(num_dims), D(num_dims);
- A = 1,0,0;
- B = 0,1,0;
- C = 0,0,1;
- D = 0,1,1;
-
- std::vector<column_vector> lhs;
- std::vector<column_vector> rhs;
- label_type mapping;
-
- // In all the assignments to follow, we will only say an element of the LHS
- // matches an element of the RHS if the two are equal. So A matches with A,
- // B with B, etc. But never A with C, for example.
- // ------------------------
-
- lhs.resize(3);
- lhs[0] = A;
- lhs[1] = B;
- lhs[2] = C;
-
- rhs.resize(3);
- rhs[0] = B;
- rhs[1] = A;
- rhs[2] = C;
-
- mapping.resize(3);
- mapping[0] = 1; // lhs[0] matches rhs[1]
- mapping[1] = 0; // lhs[1] matches rhs[0]
- mapping[2] = 2; // lhs[2] matches rhs[2]
-
- samples.push_back(make_pair(lhs,rhs));
- labels.push_back(mapping);
-
- // ------------------------
-
- lhs[0] = C;
- lhs[1] = A;
- lhs[2] = B;
-
- rhs[0] = A;
- rhs[1] = B;
- rhs[2] = D;
-
- mapping[0] = -1; // The -1 indicates that lhs[0] doesn't match anything in rhs.
- mapping[1] = 0; // lhs[1] matches rhs[0]
- mapping[2] = 1; // lhs[2] matches rhs[1]
-
- samples.push_back(make_pair(lhs,rhs));
- labels.push_back(mapping);
-
- // ------------------------
-
- lhs[0] = A;
- lhs[1] = B;
- lhs[2] = C;
-
- rhs.resize(4);
- rhs[0] = C;
- rhs[1] = B;
- rhs[2] = A;
- rhs[3] = D;
-
- mapping[0] = 2;
- mapping[1] = 1;
- mapping[2] = 0;
-
- samples.push_back(make_pair(lhs,rhs));
- labels.push_back(mapping);
-
- // ------------------------
-
- lhs.resize(2);
- lhs[0] = B;
- lhs[1] = C;
-
- rhs.resize(3);
- rhs[0] = C;
- rhs[1] = A;
- rhs[2] = D;
-
- mapping.resize(2);
- mapping[0] = -1;
- mapping[1] = 0;
-
- samples.push_back(make_pair(lhs,rhs));
- labels.push_back(mapping);
-
- // ------------------------
-
- lhs.resize(3);
- lhs[0] = D;
- lhs[1] = B;
- lhs[2] = C;
-
- // rhs will be empty. So none of the items in lhs can match anything.
- rhs.resize(0);
-
- mapping.resize(3);
- mapping[0] = -1;
- mapping[1] = -1;
- mapping[2] = -1;
-
- samples.push_back(make_pair(lhs,rhs));
- labels.push_back(mapping);
-
-}
-
diff --git a/ml/dlib/examples/bayes_net_ex.cpp b/ml/dlib/examples/bayes_net_ex.cpp
deleted file mode 100644
index 64f2ad957..000000000
--- a/ml/dlib/examples/bayes_net_ex.cpp
+++ /dev/null
@@ -1,307 +0,0 @@
-// The contents of this file are in the public domain. See LICENSE_FOR_EXAMPLE_PROGRAMS.txt
-/*
- This is an example illustrating the use of the Bayesian Network
- inference utilities found in the dlib C++ library.
-
-
- In this example all the nodes in the Bayesian network are
- boolean variables. That is, they take on either the value
- 0 or the value 1.
-
- The network contains 4 nodes and looks as follows:
-
- B C
- \\ //
- \/ \/
- A
- ||
- \/
- D
-
-
- The probabilities of each node are summarized below. (The probability
- of each node being 0 is not listed since it is just P(X=0) = 1-p(X=1) )
-
- p(B=1) = 0.01
-
- p(C=1) = 0.001
-
- p(A=1 | B=0, C=0) = 0.01
- p(A=1 | B=0, C=1) = 0.5
- p(A=1 | B=1, C=0) = 0.9
- p(A=1 | B=1, C=1) = 0.99
-
- p(D=1 | A=0) = 0.2
- p(D=1 | A=1) = 0.5
-
-*/
-
-
-#include <dlib/bayes_utils.h>
-#include <dlib/graph_utils.h>
-#include <dlib/graph.h>
-#include <dlib/directed_graph.h>
-#include <iostream>
-
-
-using namespace dlib;
-using namespace std;
-
-// ----------------------------------------------------------------------------------------
-
-int main()
-{
- try
- {
- // There are many useful convenience functions in this namespace. They all
- // perform simple access or modify operations on the nodes of a bayesian network.
- // You don't have to use them but they are convenient and they also will check for
- // various errors in your bayesian network when your application is built with
- // the DEBUG or ENABLE_ASSERTS preprocessor definitions defined. So their use
- // is recommended. In fact, most of the global functions used in this example
- // program are from this namespace.
- using namespace bayes_node_utils;
-
- // This statement declares a bayesian network called bn. Note that a bayesian network
- // in the dlib world is just a directed_graph object that contains a special kind
- // of node called a bayes_node.
- directed_graph<bayes_node>::kernel_1a_c bn;
-
- // Use an enum to make some more readable names for our nodes.
- enum nodes
- {
- A = 0,
- B = 1,
- C = 2,
- D = 3
- };
-
- // The next few blocks of code setup our bayesian network.
-
- // The first thing we do is tell the bn object how many nodes it has
- // and also add the three edges. Again, we are using the network
- // shown in ASCII art at the top of this file.
- bn.set_number_of_nodes(4);
- bn.add_edge(A, D);
- bn.add_edge(B, A);
- bn.add_edge(C, A);
-
-
- // Now we inform all the nodes in the network that they are binary
- // nodes. That is, they only have two possible values.
- set_node_num_values(bn, A, 2);
- set_node_num_values(bn, B, 2);
- set_node_num_values(bn, C, 2);
- set_node_num_values(bn, D, 2);
-
- assignment parent_state;
- // Now we will enter all the conditional probability information for each node.
- // Each node's conditional probability is dependent on the state of its parents.
- // To specify this state we need to use the assignment object. This assignment
- // object allows us to specify the state of each nodes parents.
-
-
- // Here we specify that p(B=1) = 0.01
- // parent_state is empty in this case since B is a root node.
- set_node_probability(bn, B, 1, parent_state, 0.01);
- // Here we specify that p(B=0) = 1-0.01
- set_node_probability(bn, B, 0, parent_state, 1-0.01);
-
-
- // Here we specify that p(C=1) = 0.001
- // parent_state is empty in this case since B is a root node.
- set_node_probability(bn, C, 1, parent_state, 0.001);
- // Here we specify that p(C=0) = 1-0.001
- set_node_probability(bn, C, 0, parent_state, 1-0.001);
-
-
- // This is our first node that has parents. So we set the parent_state
- // object to reflect that A has both B and C as parents.
- parent_state.add(B, 1);
- parent_state.add(C, 1);
- // Here we specify that p(A=1 | B=1, C=1) = 0.99
- set_node_probability(bn, A, 1, parent_state, 0.99);
- // Here we specify that p(A=0 | B=1, C=1) = 1-0.99
- set_node_probability(bn, A, 0, parent_state, 1-0.99);
-
- // Here we use the [] notation because B and C have already
- // been added into parent state.
- parent_state[B] = 1;
- parent_state[C] = 0;
- // Here we specify that p(A=1 | B=1, C=0) = 0.9
- set_node_probability(bn, A, 1, parent_state, 0.9);
- set_node_probability(bn, A, 0, parent_state, 1-0.9);
-
- parent_state[B] = 0;
- parent_state[C] = 1;
- // Here we specify that p(A=1 | B=0, C=1) = 0.5
- set_node_probability(bn, A, 1, parent_state, 0.5);
- set_node_probability(bn, A, 0, parent_state, 1-0.5);
-
- parent_state[B] = 0;
- parent_state[C] = 0;
- // Here we specify that p(A=1 | B=0, C=0) = 0.01
- set_node_probability(bn, A, 1, parent_state, 0.01);
- set_node_probability(bn, A, 0, parent_state, 1-0.01);
-
-
- // Here we set probabilities for node D.
- // First we clear out parent state so that it doesn't have any of
- // the assignments for the B and C nodes used above.
- parent_state.clear();
- parent_state.add(A,1);
- // Here we specify that p(D=1 | A=1) = 0.5
- set_node_probability(bn, D, 1, parent_state, 0.5);
- set_node_probability(bn, D, 0, parent_state, 1-0.5);
-
- parent_state[A] = 0;
- // Here we specify that p(D=1 | A=0) = 0.2
- set_node_probability(bn, D, 1, parent_state, 0.2);
- set_node_probability(bn, D, 0, parent_state, 1-0.2);
-
-
-
- // We have now finished setting up our bayesian network. So let's compute some
- // probability values. The first thing we will do is compute the prior probability
- // of each node in the network. To do this we will use the join tree algorithm which
- // is an algorithm for performing exact inference in a bayesian network.
-
- // First we need to create an undirected graph which contains set objects at each node and
- // edge. This long declaration does the trick.
- typedef dlib::set<unsigned long>::compare_1b_c set_type;
- typedef graph<set_type, set_type>::kernel_1a_c join_tree_type;
- join_tree_type join_tree;
-
- // Now we need to populate the join_tree with data from our bayesian network. The next
- // function calls do this. Explaining exactly what they do is outside the scope of this
- // example. Just think of them as filling join_tree with information that is useful
- // later on for dealing with our bayesian network.
- create_moral_graph(bn, join_tree);
- create_join_tree(join_tree, join_tree);
-
- // Now that we have a proper join_tree we can use it to obtain a solution to our
- // bayesian network. Doing this is as simple as declaring an instance of
- // the bayesian_network_join_tree object as follows:
- bayesian_network_join_tree solution(bn, join_tree);
-
-
- // now print out the probabilities for each node
- cout << "Using the join tree algorithm:\n";
- cout << "p(A=1) = " << solution.probability(A)(1) << endl;
- cout << "p(A=0) = " << solution.probability(A)(0) << endl;
- cout << "p(B=1) = " << solution.probability(B)(1) << endl;
- cout << "p(B=0) = " << solution.probability(B)(0) << endl;
- cout << "p(C=1) = " << solution.probability(C)(1) << endl;
- cout << "p(C=0) = " << solution.probability(C)(0) << endl;
- cout << "p(D=1) = " << solution.probability(D)(1) << endl;
- cout << "p(D=0) = " << solution.probability(D)(0) << endl;
- cout << "\n\n\n";
-
-
- // Now to make things more interesting let's say that we have discovered that the C
- // node really has a value of 1. That is to say, we now have evidence that
- // C is 1. We can represent this in the network using the following two function
- // calls.
- set_node_value(bn, C, 1);
- set_node_as_evidence(bn, C);
-
- // Now we want to compute the probabilities of all the nodes in the network again
- // given that we now know that C is 1. We can do this as follows:
- bayesian_network_join_tree solution_with_evidence(bn, join_tree);
-
- // now print out the probabilities for each node
- cout << "Using the join tree algorithm:\n";
- cout << "p(A=1 | C=1) = " << solution_with_evidence.probability(A)(1) << endl;
- cout << "p(A=0 | C=1) = " << solution_with_evidence.probability(A)(0) << endl;
- cout << "p(B=1 | C=1) = " << solution_with_evidence.probability(B)(1) << endl;
- cout << "p(B=0 | C=1) = " << solution_with_evidence.probability(B)(0) << endl;
- cout << "p(C=1 | C=1) = " << solution_with_evidence.probability(C)(1) << endl;
- cout << "p(C=0 | C=1) = " << solution_with_evidence.probability(C)(0) << endl;
- cout << "p(D=1 | C=1) = " << solution_with_evidence.probability(D)(1) << endl;
- cout << "p(D=0 | C=1) = " << solution_with_evidence.probability(D)(0) << endl;
- cout << "\n\n\n";
-
- // Note that when we made our solution_with_evidence object we reused our join_tree object.
- // This saves us the time it takes to calculate the join_tree object from scratch. But
- // it is important to note that we can only reuse the join_tree object if we haven't changed
- // the structure of our bayesian network. That is, if we have added or removed nodes or
- // edges from our bayesian network then we must recompute our join_tree. But in this example
- // all we did was change the value of a bayes_node object (we made node C be evidence)
- // so we are ok.
-
-
-
-
-
- // Next this example will show you how to use the bayesian_network_gibbs_sampler object
- // to perform approximate inference in a bayesian network. This is an algorithm
- // that doesn't give you an exact solution but it may be necessary to use in some
- // instances. For example, the join tree algorithm used above, while fast in many
- // instances, has exponential runtime in some cases. Moreover, inference in bayesian
- // networks is NP-Hard for general networks so sometimes the best you can do is
- // find an approximation.
- // However, it should be noted that the gibbs sampler does not compute the correct
- // probabilities if the network contains a deterministic node. That is, if any
- // of the conditional probability tables in the bayesian network have a probability
- // of 1.0 for something the gibbs sampler should not be used.
-
-
- // This Gibbs sampler algorithm works by randomly sampling possibles values of the
- // network. So to use it we should set the network to some initial state.
-
- set_node_value(bn, A, 0);
- set_node_value(bn, B, 0);
- set_node_value(bn, D, 0);
-
- // We will leave the C node with a value of 1 and keep it as an evidence node.
-
-
- // First create an instance of the gibbs sampler object
- bayesian_network_gibbs_sampler sampler;
-
-
- // To use this algorithm all we do is go into a loop for a certain number of times
- // and each time through we sample the bayesian network. Then we count how
- // many times a node has a certain state. Then the probability of that node
- // having that state is just its count/total times through the loop.
-
- // The following code illustrates the general procedure.
- unsigned long A_count = 0;
- unsigned long B_count = 0;
- unsigned long C_count = 0;
- unsigned long D_count = 0;
-
- // The more times you let the loop run the more accurate the result will be. Here we loop
- // 2000 times.
- const long rounds = 2000;
- for (long i = 0; i < rounds; ++i)
- {
- sampler.sample_graph(bn);
-
- if (node_value(bn, A) == 1)
- ++A_count;
- if (node_value(bn, B) == 1)
- ++B_count;
- if (node_value(bn, C) == 1)
- ++C_count;
- if (node_value(bn, D) == 1)
- ++D_count;
- }
-
- cout << "Using the approximate Gibbs Sampler algorithm:\n";
- cout << "p(A=1 | C=1) = " << (double)A_count/(double)rounds << endl;
- cout << "p(B=1 | C=1) = " << (double)B_count/(double)rounds << endl;
- cout << "p(C=1 | C=1) = " << (double)C_count/(double)rounds << endl;
- cout << "p(D=1 | C=1) = " << (double)D_count/(double)rounds << endl;
- }
- catch (std::exception& e)
- {
- cout << "exception thrown: " << endl;
- cout << e.what() << endl;
- cout << "hit enter to terminate" << endl;
- cin.get();
- }
-}
-
-
-
diff --git a/ml/dlib/examples/bayes_net_from_disk_ex.cpp b/ml/dlib/examples/bayes_net_from_disk_ex.cpp
deleted file mode 100644
index eaab5881a..000000000
--- a/ml/dlib/examples/bayes_net_from_disk_ex.cpp
+++ /dev/null
@@ -1,83 +0,0 @@
-// The contents of this file are in the public domain. See LICENSE_FOR_EXAMPLE_PROGRAMS.txt
-/*
- This is an example illustrating the use of the Bayesian Network
- inference utilities found in the dlib C++ library. In this example
- we load a saved Bayesian Network from disk.
-*/
-
-
-#include <dlib/bayes_utils.h>
-#include <dlib/graph_utils.h>
-#include <dlib/graph.h>
-#include <dlib/directed_graph.h>
-#include <iostream>
-#include <fstream>
-
-
-using namespace dlib;
-using namespace std;
-
-// ----------------------------------------------------------------------------------------
-
-int main(int argc, char** argv)
-{
- try
- {
- // This statement declares a bayesian network called bn. Note that a bayesian network
- // in the dlib world is just a directed_graph object that contains a special kind
- // of node called a bayes_node.
- directed_graph<bayes_node>::kernel_1a_c bn;
-
- if (argc != 2)
- {
- cout << "You must supply a file name on the command line. The file should "
- << "contain a serialized Bayesian Network" << endl;
- return 1;
- }
-
- ifstream fin(argv[1],ios::binary);
-
- // Note that the saved networks produced by the bayes_net_gui_ex.cpp example can be deserialized
- // into a network. So you can make your networks using that GUI if you like.
- cout << "Loading the network from disk..." << endl;
- deserialize(bn, fin);
-
- cout << "Number of nodes in the network: " << bn.number_of_nodes() << endl;
-
- // Let's compute some probability values using the loaded network using the join tree (aka. Junction
- // Tree) algorithm.
-
- // First we need to create an undirected graph which contains set objects at each node and
- // edge. This long declaration does the trick.
- typedef graph<dlib::set<unsigned long>::compare_1b_c, dlib::set<unsigned long>::compare_1b_c>::kernel_1a_c join_tree_type;
- join_tree_type join_tree;
-
- // Now we need to populate the join_tree with data from our bayesian network. The next two
- // function calls do this. Explaining exactly what they do is outside the scope of this
- // example. Just think of them as filling join_tree with information that is useful
- // later on for dealing with our bayesian network.
- create_moral_graph(bn, join_tree);
- create_join_tree(join_tree, join_tree);
-
- // Now we have a proper join_tree we can use it to obtain a solution to our
- // bayesian network. Doing this is as simple as declaring an instance of
- // the bayesian_network_join_tree object as follows:
- bayesian_network_join_tree solution(bn, join_tree);
-
-
- // now print out the probabilities for each node
- cout << "Using the join tree algorithm:\n";
- for (unsigned long i = 0; i < bn.number_of_nodes(); ++i)
- {
- // print out the probability distribution for node i.
- cout << "p(node " << i <<") = " << solution.probability(i);
- }
- }
- catch (exception& e)
- {
- cout << "exception thrown: " << e.what() << endl;
- return 1;
- }
-}
-
-
diff --git a/ml/dlib/examples/bayes_net_gui_ex.cpp b/ml/dlib/examples/bayes_net_gui_ex.cpp
deleted file mode 100644
index 81101912c..000000000
--- a/ml/dlib/examples/bayes_net_gui_ex.cpp
+++ /dev/null
@@ -1,989 +0,0 @@
-// The contents of this file are in the public domain. See LICENSE_FOR_EXAMPLE_PROGRAMS.txt
-/*
- This is a rather involved example illustrating the use of the GUI api from
- the dlib C++ Library. This program is a fully functional utility for
- creating Bayesian Networks. It allows the user to graphically draw the network,
- save/load the network to/from disk, and also to calculate the posterior
- probability of any node in the network given a set of evidence.
-
- This is not the first dlib example program you should be looking at. If you
- want to see a simpler GUI example please look at the gui_api_ex.cpp or
- image_ex.cpp example.
-
- If you want to understand how to use the Bayesian Network utilities in the library
- you should definitely look at the bayes_net_ex.cpp example program. It gives a
- comprehensive introduction to creating and manipulating Bayesian Networks. If you
- want to see how to load a saved network from disk and use it in a non-GUI application
- then look at the bayes_net_from_disk_ex.cpp example.
-
-
- Now all of that being said, if you have already looked at the other relevant
- examples and want to see a more in-depth example then by all means, continue reading. :)
-*/
-
-#include <memory>
-#include <sstream>
-#include <string>
-
-#include <dlib/gui_widgets.h>
-#include <dlib/directed_graph.h>
-#include <dlib/string.h>
-#include <dlib/bayes_utils.h>
-#include <dlib/set.h>
-#include <dlib/graph_utils.h>
-#include <dlib/stl_checked.h>
-
-
-using namespace std;
-using namespace dlib;
-using namespace dlib::bayes_node_utils;
-
-// ----------------------------------------------------------------------------
-
-typedef directed_graph<bayes_node>::kernel_1a_c directed_graph_type;
-typedef directed_graph<bayes_node>::kernel_1a_c::node_type node_type;
-typedef graph<dlib::set<unsigned long>::compare_1b_c, dlib::set<unsigned long>::compare_1b_c>::kernel_1a_c join_tree_type;
-
-// ----------------------------------------------------------------------------
-
-class main_window : public drawable_window
-{
- /*!
- INITIAL VALUE
- This window starts out hidden and with an empty Bayesian Network
-
- WHAT THIS OBJECT REPRESENTS
- This object is the main window of a utility for drawing Bayesian Networks.
- It allows you to draw a directed graph and to set the conditional probability
- tables up for each node in the network. It also allows you to compute the
- posterior probability of each node. And finally, it lets you save and load
- networks from file
- !*/
-public:
- main_window();
- ~main_window();
-
-private:
-
- // Private helper methods
-
- void initialize_node_cpt_if_necessary ( unsigned long index );
- void load_selected_node_tables_into_cpt_grid ();
- void load_selected_node_tables_into_ppt_grid ();
- void no_node_selected ();
-
-
- // Event handlers
-
- void on_cpt_grid_modified(unsigned long row, unsigned long col);
- void on_evidence_toggled ();
- void on_graph_modified ();
- void on_menu_file_open ();
- void on_menu_file_quit ();
- void on_menu_file_save ();
- void on_menu_file_save_as ();
- void on_menu_help_about ();
- void on_menu_help_help ();
- void on_node_deleted ();
- void on_node_deselected ( unsigned long n );
- void on_node_selected (unsigned long n);
- void on_open_file_selected ( const std::string& file_name);
- void on_save_file_selected ( const std::string& file_name);
- void on_sel_node_evidence_modified ();
- void on_sel_node_num_values_modified ();
- void on_sel_node_text_modified ();
- void on_window_resized ();
- void recalculate_probabilities ();
-
- // Member data
-
- const rgb_pixel color_non_evidence;
- const rgb_pixel color_default_bg;
- const rgb_pixel color_evidence;
- const rgb_pixel color_error;
- const rgb_pixel color_gray;
- bool graph_modified_since_last_recalc;
-
- button btn_calculate;
- check_box sel_node_is_evidence;
- directed_graph_drawer<directed_graph_type> graph_drawer;
- label sel_node_index;
- label sel_node_num_values_label;
- label sel_node_text_label;
- label sel_node_evidence_label;
- menu_bar mbar;
- named_rectangle selected_node_rect;
- tabbed_display tables;
- text_field sel_node_num_values;
- text_field sel_node_text;
- text_field sel_node_evidence;
- text_grid cpt_grid;
- text_grid ppt_grid;
- unsigned long selected_node_index;
- bool node_is_selected;
- widget_group cpt_group;
- widget_group ppt_group;
-
- std::unique_ptr<bayesian_network_join_tree> solution;
- join_tree_type join_tree;
- // The std_vector_c is an object identical to the std::vector except that it checks
- // all its preconditions and throws a dlib::fatal_error if they are violated.
- std_vector_c<assignment> cpt_grid_assignments;
- std::string graph_file_name;
-};
-
-// ----------------------------------------------------------------------------------------
-
-int main()
-{
- // create our window
- main_window my_window;
-
- // tell our window to put itself on the screen
- my_window.show();
-
- // wait until the user closes this window before we let the program
- // terminate.
- my_window.wait_until_closed();
-}
-
-// ----------------------------------------------------------------------------------------
-
-#ifdef WIN32
-// If you use main() as your entry point when building a program on MS Windows then
-// there will be a black console window associated with your application. If you
-// want your application to not have this console window then you need to build
-// using the WinMain() entry point as shown below and also set your compiler to
-// produce a "Windows" project instead of a "Console" project. In visual studio
-// this can be accomplished by going to project->properties->general configuration->
-// Linker->System->SubSystem and selecting Windows instead of Console.
-//
-int WINAPI WinMain (HINSTANCE, HINSTANCE, PSTR cmds, int)
-{
- main();
- return 0;
-}
-#endif
-
-// ----------------------------------------------------------------------------------------
-// ----------------------------------------------------------------------------------------
-// Methods from the main_window object
-// ----------------------------------------------------------------------------------------
-// ----------------------------------------------------------------------------------------
-
-main_window::
-main_window(
-) :
- color_non_evidence(0,0,0),
- color_default_bg(255,255,255),
- color_evidence(100,200,100),
- color_error(255,0,0),
- color_gray(210,210,210),
- graph_modified_since_last_recalc(true),
- btn_calculate(*this),
- sel_node_is_evidence(*this),
- graph_drawer(*this),
- sel_node_index(*this),
- sel_node_num_values_label (*this),
- sel_node_text_label(*this),
- sel_node_evidence_label(*this),
- mbar(*this),
- selected_node_rect(*this),
- tables(*this),
- sel_node_num_values(*this),
- sel_node_text(*this),
- sel_node_evidence(*this),
- cpt_grid(*this),
- ppt_grid(*this),
- selected_node_index(0),
- node_is_selected(false),
- cpt_group(*this),
- ppt_group(*this)
-{
- // Note that all the GUI widgets take a reference to the window that contains them
- // as their constructor argument. This is a universal feature of GUI widgets in the
- // dlib library.
-
- set_title("Bayesian Network Utility");
-
- // position the widget that is responsible for drawing the directed graph, the graph_drawer,
- // just below the mbar (menu bar) widget.
- graph_drawer.set_pos(5,mbar.bottom()+5);
- set_size(750,400);
-
- // register the event handlers with their respective widgets
- btn_calculate.set_click_handler (*this, &main_window::recalculate_probabilities);
- cpt_grid.set_text_modified_handler (*this, &main_window::on_cpt_grid_modified);
- graph_drawer.set_graph_modified_handler (*this, &main_window::on_graph_modified);
- graph_drawer.set_node_deleted_handler (*this, &main_window::on_node_deleted);
- graph_drawer.set_node_deselected_handler (*this, &main_window::on_node_deselected);
- graph_drawer.set_node_selected_handler (*this, &main_window::on_node_selected);
- sel_node_evidence.set_text_modified_handler (*this, &main_window::on_sel_node_evidence_modified);
- sel_node_is_evidence.set_click_handler (*this, &main_window::on_evidence_toggled);
- sel_node_num_values.set_text_modified_handler(*this, &main_window::on_sel_node_num_values_modified);
- sel_node_text.set_text_modified_handler (*this, &main_window::on_sel_node_text_modified);
-
- // now set the text of some of our buttons and labels
- btn_calculate.set_name("Recalculate posterior probability table");
- selected_node_rect.set_name("Selected node");
- sel_node_evidence_label.set_text("evidence value:");
- sel_node_is_evidence.set_name("is evidence");
- sel_node_num_values_label.set_text("Number of values: ");
- sel_node_text_label.set_text("Node label:");
-
- // Now setup the tabbed display. It will have two tabs, one for the conditional
- // probability table and one for the posterior probability table.
- tables.set_number_of_tabs(2);
- tables.set_tab_name(0,"Conditional probability table");
- tables.set_tab_name(1,"Posterior probability table");
- cpt_group.add(cpt_grid,0,0);
- ppt_group.add(ppt_grid,0,0);
- tables.set_tab_group(0,cpt_group);
- tables.set_tab_group(1,ppt_group);
-
- // Now setup the menu bar. We will have two menus. A File and Help menu.
- mbar.set_number_of_menus(2);
- mbar.set_menu_name(0,"File",'F');
- mbar.set_menu_name(1,"Help",'H');
-
- // add the entries to the File menu.
- mbar.menu(0).add_menu_item(menu_item_text("Open", *this, &main_window::on_menu_file_open, 'O'));
- mbar.menu(0).add_menu_item(menu_item_separator());
- mbar.menu(0).add_menu_item(menu_item_text("Save", *this, &main_window::on_menu_file_save, 'S'));
- mbar.menu(0).add_menu_item(menu_item_text("Save As",*this, &main_window::on_menu_file_save_as, 'a'));
- mbar.menu(0).add_menu_item(menu_item_separator());
- mbar.menu(0).add_menu_item(menu_item_text("Quit", *this, &main_window::on_menu_file_quit, 'Q'));
-
- // Add the entries to the Help menu.
- mbar.menu(1).add_menu_item(menu_item_text("Help", *this, &main_window::on_menu_help_help, 'e'));
- mbar.menu(1).add_menu_item(menu_item_text("About", *this, &main_window::on_menu_help_about, 'A'));
-
-
- // call our helper functions and window resize event to get the widgets
- // to all arrange themselves correctly in our window.
- no_node_selected();
- on_window_resized();
-}
-
-// ----------------------------------------------------------------------------------------
-
-main_window::
-~main_window(
-)
-{
- // You should always call close_window() in the destructor of window
- // objects to ensure that no events will be sent to this window while
- // it is being destructed.
- close_window();
-}
-
-// ----------------------------------------------------------------------------------------
-// ----------------------------------------------------------------------------------------
-// Private methods from the main_window object
-// ----------------------------------------------------------------------------------------
-// ----------------------------------------------------------------------------------------
-
-void main_window::
-load_selected_node_tables_into_ppt_grid (
-)
-{
- // This function just takes the currently selected graph node and loads
- // its posterior probabilities into the ppt_graph widget.
- node_type& node = graph_drawer.graph_node(selected_node_index);
- ppt_grid.set_grid_size(2,node.data.table().num_values());
-
- // load the top row of the table into the grid. This row is the "title bar" row
- // that tells you what each column contains.
- for (unsigned long col = 0; col < node.data.table().num_values(); ++col)
- {
- ppt_grid.set_text(0,col,"P(node=" + cast_to_string(col) + ")");
- ppt_grid.set_background_color(0,col,rgb_pixel(150,150,250));
- ppt_grid.set_editable(0,col,false);
- }
-
- // If we have a solution to the network on hand then load the probabilities
- // from that into the table
- if (solution)
- {
- // get the probability distribution for the currently selected node out
- // of the solution.
- const matrix<double,1> prob = solution->probability(selected_node_index);
-
- // now load the probabilities into the ppt_grid so the user can see them.
- for (unsigned long col = 0; col < node.data.table().num_values(); ++col)
- {
- ppt_grid.set_text(1,col,cast_to_string(prob(col)));
- }
- }
-
- // make the second row of the table non-editable have a color that indicates
- // that to the user
- for (unsigned long col = 0; col < node.data.table().num_values(); ++col)
- {
- ppt_grid.set_background_color(1,col,color_gray);
- ppt_grid.set_editable(1,col,false);
- }
-}
-
-// ----------------------------------------------------------------------------------------
-
-void main_window::
-load_selected_node_tables_into_cpt_grid (
-)
-{
- // This function just takes the conditional probability table in the
- // currently selected graph node and puts it into the cpt_grid widget.
-
- node_type& node = graph_drawer.graph_node(selected_node_index);
-
- initialize_node_cpt_if_necessary(selected_node_index);
- cpt_grid_assignments.clear();
-
- // figure out how many rows there should be in the cpt
- unsigned long cpt_rows = 1;
- for (unsigned long i = 0; i < node.number_of_parents(); ++i)
- {
- cpt_rows *= node.parent(i).data.table().num_values();
- }
-
- unsigned long cpt_cols = node.data.table().num_values();
-
- cpt_grid.set_grid_size(cpt_rows+1, cpt_cols+ node.number_of_parents());
- const unsigned long num_cols = cpt_grid.number_of_columns();
-
- // fill in the top row of the grid that shows which parent node the left hand columns go with
- assignment a(node_first_parent_assignment(graph_drawer.graph(),selected_node_index));
- unsigned long col = 0;
- a.reset();
- while (a.move_next())
- {
- cpt_grid.set_text(0,col,cast_to_string(a.element().key()) + ": " + graph_drawer.node_label(a.element().key()) );
- cpt_grid.set_background_color(0,col,rgb_pixel(120,210,210));
- cpt_grid.set_editable(0,col,false);
- ++col;
- }
-
- // fill in the top row of the grid that shows which probability the right hand columns go with
- for (col = node.number_of_parents(); col < num_cols; ++col)
- {
- cpt_grid.set_text(0,col,"P(node=" + cast_to_string(col-node.number_of_parents()) + ")");
- cpt_grid.set_background_color(0,col,rgb_pixel(150,150,250));
- cpt_grid.set_editable(0,col,false);
- }
-
- // now loop over all the possible parent assignments for this node
- const unsigned long num_values = node.data.table().num_values();
- unsigned long row = 1;
- do
- {
- col = 0;
-
- // fill in the left side of the grid row that shows what the parent assignment is
- a.reset();
- while (a.move_next())
- {
- cpt_grid.set_text(row,col,cast_to_string(a.element().value()));
- cpt_grid.set_background_color(row,col,rgb_pixel(180,255,255));
- cpt_grid.set_editable(row,col,false);
-
- ++col;
- }
-
- // fill in the right side of the grid row that shows what the conditional probabilities are
- for (unsigned long value = 0; value < num_values; ++value)
- {
- const double prob = node.data.table().probability(value,a);
- cpt_grid.set_text(row,col,cast_to_string(prob));
- ++col;
- }
-
- // save this assignment so we can use it later to modify the node's
- // conditional probability table if the user modifies the cpt_grid
- cpt_grid_assignments.push_back(a);
- ++row;
- } while (node_next_parent_assignment(graph_drawer.graph(),selected_node_index,a));
-
-}
-
-// ----------------------------------------------------------------------------------------
-
-void main_window::
-initialize_node_cpt_if_necessary (
- unsigned long index
-)
-{
- node_type& node = graph_drawer.graph_node(index);
-
- // if the cpt for this node isn't properly filled out then let's clear it out
- // and populate it with some reasonable default values
- if (node_cpt_filled_out(graph_drawer.graph(), index) == false)
- {
- node.data.table().empty_table();
-
- const unsigned long num_values = node.data.table().num_values();
-
- // loop over all the possible parent assignments for this node and fill them out
- // with reasonable default values
- assignment a(node_first_parent_assignment(graph_drawer.graph(), index));
- do
- {
- // set the first value to have probability 1
- node.data.table().set_probability(0, a, 1.0);
-
- // set all the other values to have probability 0
- for (unsigned long value = 1; value < num_values; ++value)
- node.data.table().set_probability(value, a, 0);
-
- } while (node_next_parent_assignment(graph_drawer.graph(), index,a));
- }
-}
-
-// ----------------------------------------------------------------------------------------
-
-void main_window::
-no_node_selected (
-)
-{
- // Make it so that no node is selected on the gui. Do this by disabling things
- // and clearing out text fields and so forth.
-
-
- node_is_selected = false;
- tables.disable();
- sel_node_evidence.disable();
- sel_node_is_evidence.disable();
- sel_node_index.disable();
- sel_node_evidence_label.disable();
- sel_node_text_label.disable();
- sel_node_text.disable();
- sel_node_index.set_text("index:");
- sel_node_num_values_label.disable();
- sel_node_num_values.disable();
- cpt_grid.set_grid_size(0,0);
- ppt_grid.set_grid_size(0,0);
-
- sel_node_is_evidence.set_unchecked();
- sel_node_text.set_text("");
- sel_node_num_values.set_text("");
- sel_node_evidence.set_text("");
- sel_node_num_values.set_background_color(color_default_bg);
- sel_node_evidence.set_background_color(color_default_bg);
-}
-
-// ----------------------------------------------------------------------------------------
-
-void main_window::
-recalculate_probabilities (
-)
-{
- // clear out the current solution
- solution.reset();
- if (graph_is_connected(graph_drawer.graph()) == false)
- {
- message_box("Error","Your graph has nodes that are completely disconnected from the other nodes.\n"
- "You must connect them somehow");
- }
- else if (graph_drawer.graph().number_of_nodes() > 0)
- {
- if (graph_modified_since_last_recalc)
- {
- // make sure all the cpts are filled out
- const unsigned long num_nodes = graph_drawer.graph().number_of_nodes();
- for (unsigned long i = 0; i < num_nodes; ++i)
- {
- initialize_node_cpt_if_necessary(i);
- }
-
- // remake the join tree for this graph
- create_moral_graph(graph_drawer.graph(), join_tree);
- create_join_tree(join_tree, join_tree);
- graph_modified_since_last_recalc = false;
- }
-
- // create a solution to this bayesian network using the join tree algorithm
- solution.reset(new bayesian_network_join_tree(graph_drawer.graph(), join_tree));
-
- if (node_is_selected)
- {
- load_selected_node_tables_into_ppt_grid();
- }
- }
-}
-
-// ----------------------------------------------------------------------------------------
-// ----------------------------------------------------------------------------------------
-// Event handling methods from the main_window object
-// ----------------------------------------------------------------------------------------
-// ----------------------------------------------------------------------------------------
-
-// This event is called when the user selects a file with a saved
-// bayesian network in it.
-void main_window::
-on_open_file_selected (
- const std::string& file_name
-)
-{
- try
- {
- no_node_selected();
- ifstream fin(file_name.c_str(), ios::binary);
- graph_drawer.load_graph(fin);
- graph_file_name = file_name;
- set_title("Bayesian Network Utility - " + right_substr(file_name,"\\/"));
- }
- catch (...)
- {
- message_box("Error", "Unable to load graph file " + file_name);
- }
-}
-
-// ----------------------------------------------------------------------------------------
-
-// This event is called when the user selects from the menu bar File->Open
-void main_window::
-on_menu_file_open (
-)
-{
- // display a file chooser window and when the user choses a file
- // call the on_open_file_selected() function
- open_existing_file_box(*this, &main_window::on_open_file_selected);
-}
-
-// ----------------------------------------------------------------------------------------
-
-// This event is called when the user selects from the menu bar File->Save
-void main_window::
-on_menu_file_save (
-)
-{
- // if we don't currently have any file name associated with our graph
- if (graph_file_name.size() == 0)
- {
- // display a file chooser window and when the user choses a file
- // call the on_save_file_selected() function
- save_file_box(*this, &main_window::on_save_file_selected);
- }
- else
- {
- // we know what file to open so just do that and save the graph to it
- ofstream fout(graph_file_name.c_str(), ios::binary);
- graph_drawer.save_graph(fout);
- }
-}
-
-// ----------------------------------------------------------------------------------------
-
-// This event is called when the user choses which file to save the graph to
-void main_window::
-on_save_file_selected (
- const std::string& file_name
-)
-{
- ofstream fout(file_name.c_str(), ios::binary);
- graph_drawer.save_graph(fout);
- graph_file_name = file_name;
- set_title("Bayesian Network Utility - " + right_substr(file_name,"\\/"));
-}
-
-// ----------------------------------------------------------------------------------------
-
-// This event is called when the user selects from the menu bar File->Save As
-void main_window::
-on_menu_file_save_as (
-)
-{
- // display a file chooser window and when the user choses a file
- // call the on_save_file_selected() function
- save_file_box(*this, &main_window::on_save_file_selected);
-}
-
-// ----------------------------------------------------------------------------------------
-
-// This event is called when the user selects from the menu bar File->Quit
-void main_window::
-on_menu_file_quit (
-)
-{
- close_window();
-}
-
-// ----------------------------------------------------------------------------------------
-
-// This event is called when the user selects from the menu bar Help->Help
-void main_window::
-on_menu_help_help (
-)
-{
- message_box("Help",
- "To create new nodes right click on the drawing area.\n"
- "To create edges select the parent node and then shift+left click on the child node.\n"
- "To remove nodes or edges select them by left clicking and then press the delete key.");
-}
-
-// ----------------------------------------------------------------------------------------
-
-// This event is called when the user selects from the menu bar Help->About
-void main_window::
-on_menu_help_about (
-)
-{
- message_box("About","This application is the GUI front end to the dlib C++ Library's\n"
- "Bayesian Network inference utilities\n\n"
- "Version 1.2\n\n"
- "See http://dlib.net for updates");
-}
-
-// ----------------------------------------------------------------------------------------
-
-// This event is called when the user modifies the graph_drawer widget. That is,
-// when the user adds or removes an edge or node in the graph.
-void main_window::
-on_graph_modified (
-)
-{
- // make note of the modification
- graph_modified_since_last_recalc = true;
- // clear out the solution object since we will need to recalculate it
- // since the graph changed
- solution.reset();
-}
-
-// ----------------------------------------------------------------------------------------
-
-// This event is called when the user modifies the evidence value for a node
-void main_window::
-on_sel_node_evidence_modified (
-)
-{
- // make a reference to the node in the graph that is currently selected
- node_type& node = graph_drawer.graph_node(selected_node_index);
- unsigned long value;
- try
- {
- // get the numerical value of the new evidence value. Here we are taking
- // the string from the text field and casting it to an unsigned long.
- value = sa = trim(sel_node_evidence.text());
- }
- catch (string_cast_error&)
- {
- // if the user put something that isn't an integer into the
- // text field then make it have a different background color
- // so that they can easily see this.
- sel_node_evidence.set_background_color(color_error);
- return;
- }
-
- // validate the input from the user and store it in the selected node
- // if it is ok
- if (value >= node.data.table().num_values())
- {
- sel_node_evidence.set_background_color(color_error);
- }
- else
- {
- node.data.set_value(value);
- sel_node_evidence.set_background_color(color_default_bg);
- }
-
- // clear out the solution to the graph since we now need
- // to recalculate it.
- solution.reset();
-}
-
-// ----------------------------------------------------------------------------------------
-
-// This event is called when the user modifies the number of evidence values for
-// a node.
-void main_window::
-on_sel_node_num_values_modified (
-)
-{
- // make a reference to the node in the graph that is currently selected
- node_type& node = graph_drawer.graph_node(selected_node_index);
-
- unsigned long num_values;
- try
- {
- // get the number of values out of the text field.
- num_values = sa = trim(sel_node_num_values.text());
- }
- catch (string_cast_error&)
- {
- sel_node_num_values.set_background_color(color_error);
- return;
- }
-
- // validate the input from the user to make sure it is something reasonable
- if (num_values < 2 || num_values > 100)
- {
- sel_node_num_values.set_background_color(color_error);
- }
- else
- {
- // update the graph
- node.data.table().set_num_values(num_values);
- graph_modified_since_last_recalc = true;
- sel_node_num_values.set_background_color(color_default_bg);
-
- on_sel_node_evidence_modified();
- // also make sure the evidence value of this node makes sense still
- if (node.data.is_evidence() && node.data.value() >= num_values)
- {
- // just set it to zero
- node.data.set_value(0);
- }
-
- }
-
- solution.reset();
-
- // call these functions so that the conditional and posterior probability
- // tables get updated
- load_selected_node_tables_into_cpt_grid();
- load_selected_node_tables_into_ppt_grid();
-}
-
-// ----------------------------------------------------------------------------------------
-
-// This event is called when the user modifies the cpt_grid (i.e. the conditional
-// probability table widget)
-void main_window::
-on_cpt_grid_modified(unsigned long row, unsigned long col)
-{
- node_type& node = graph_drawer.graph_node(selected_node_index);
- solution.reset();
-
- double prob;
- try
- {
- // get the new value out of the table
- prob = sa = cpt_grid.text(row,col);
- }
- catch (string_cast_error&)
- {
- cpt_grid.set_background_color(row,col,color_error);
- return;
- }
-
- // validate the value
- if (prob < 0 || prob > 1)
- {
- cpt_grid.set_background_color(row,col,color_error);
- return;
- }
-
- // the value of this node that is having its conditional probability
- // updated
- const unsigned long cur_val = col-node.number_of_parents();
-
- node.data.table().set_probability(cur_val, cpt_grid_assignments[row-1], prob);
-
- // sum the probabilities in the cpt and modify the last one such that they all
- // sum to 1. We are excluding either the first or last element from the sum
- // because we are going to set it equal to 1-sum below.
- double sum = 0;
- if (cur_val != node.data.table().num_values()-1)
- {
- for (unsigned long i = 0; i < node.data.table().num_values()-1; ++i)
- sum += node.data.table().probability(i, cpt_grid_assignments[row-1]);
- }
- else
- {
- for (unsigned long i = 1; i < node.data.table().num_values(); ++i)
- sum += node.data.table().probability(i, cpt_grid_assignments[row-1]);
- }
-
- // make sure all the probabilities sum to 1
- if (sum > 1.0)
- {
- cpt_grid.set_background_color(row,cpt_grid.number_of_columns()-1,color_error);
- }
- else
- {
- // edit one of the other elements in the table to ensure that the probabilities still sum to 1
- if (cur_val == node.data.table().num_values()-1)
- {
- node.data.table().set_probability(0, cpt_grid_assignments[row-1], 1-sum);
- cpt_grid.set_text(row,node.number_of_parents(),cast_to_string(1-sum));
- }
- else
- {
- node.data.table().set_probability(node.data.table().num_values()-1, cpt_grid_assignments[row-1], 1-sum);
- cpt_grid.set_text(row,cpt_grid.number_of_columns()-1,cast_to_string(1-sum));
- }
-
- cpt_grid.set_background_color(row,cpt_grid.number_of_columns()-1,color_default_bg);
- cpt_grid.set_background_color(row,col,color_default_bg);
- }
-
-}
-
-// ----------------------------------------------------------------------------------------
-
-// This event is called when the user resizes the main_window. Note that unlike the other
-// events, this event is part of the drawable_window base class that main_window inherits from.
-// So you won't see any statements in the constructor that say "register the main_window::on_window_resized function"
-void main_window::
-on_window_resized ()
-{
- // when you override any of the drawable_window events you have to make sure you
- // call the drawable_window's version of them because it needs to process
- // the events as well. So we do that here.
- drawable_window::on_window_resized();
-
- // The rest of this function positions the widgets on the window
- unsigned long width,height;
- get_size(width,height);
-
- // Don't do anything if the user just made the window too small. That is, leave
- // the widgets where they are.
- if (width < 500 || height < 350)
- return;
-
- // Set the size of the probability tables and the drawing area for the graph
- graph_drawer.set_size(width-370,height-10-mbar.height());
- cpt_grid.set_size((width-graph_drawer.width())-35,height-237);
- ppt_grid.set_size((width-graph_drawer.width())-35,height-237);
- // tell the tabbed display to make itself just the right size to contain
- // the two probability tables.
- tables.fit_to_contents();
-
-
- // Now position all the widgets in the window. Note that much of the positioning
- // is relative to other widgets. This part of the code I just figured out by
- // trying stuff and rerunning the program to see if it looked nice.
- sel_node_index.set_pos(graph_drawer.right()+14,graph_drawer.top()+18);
- sel_node_text_label.set_pos(sel_node_index.left(),sel_node_index.bottom()+5);
- sel_node_text.set_pos(sel_node_text_label.right()+5,sel_node_index.bottom());
- sel_node_num_values_label.set_pos(sel_node_index.left(), sel_node_text.bottom()+5);
- sel_node_num_values.set_pos(sel_node_num_values_label.right(), sel_node_text.bottom()+5);
- sel_node_is_evidence.set_pos(sel_node_index.left(),sel_node_num_values.bottom()+5);
- sel_node_evidence_label.set_pos(sel_node_index.left(),sel_node_is_evidence.bottom()+5);
- sel_node_evidence.set_pos(sel_node_evidence_label.right()+5,sel_node_is_evidence.bottom());
- tables.set_pos(sel_node_index.left(),sel_node_evidence.bottom()+5);
- sel_node_evidence.set_width(tables.right()-sel_node_evidence.left()+1);
- sel_node_text.set_width(tables.right()-sel_node_text.left()+1);
- sel_node_num_values.set_width(tables.right()-sel_node_num_values.left()+1);
-
-
-
- // Tell the named rectangle to position itself such that it fits around the
- // tabbed display that contains the probability tables and the label at the top of the
- // screen.
- selected_node_rect.wrap_around(sel_node_index.get_rect()+
- tables.get_rect());
-
- // finally set the button to be at the bottom of the named rectangle
- btn_calculate.set_pos(selected_node_rect.left(), selected_node_rect.bottom()+5);
-}
-
-// ----------------------------------------------------------------------------------------
-
-// This event is called by the graph_drawer widget when the user selects a node
-void main_window::
-on_node_selected (unsigned long n)
-{
- // make a reference to the selected node
- node_type& node = graph_drawer.graph_node(n);
-
-
- // enable all the widgets related to the selected node
- selected_node_index = n;
- node_is_selected = true;
- tables.enable();
- sel_node_is_evidence.enable();
- sel_node_index.enable();
- sel_node_evidence_label.enable();
- sel_node_text_label.enable();
- sel_node_text.enable();
- sel_node_num_values_label.enable();
- sel_node_num_values.enable();
-
- // make sure the num_values field of the node's cpt is set to something valid.
- // So default it to 2 if it isn't set already.
- if (node.data.table().num_values() < 2)
- {
- node.data.table().set_num_values(2);
- graph_modified_since_last_recalc = true;
- }
-
- // setup the evidence check box and input field
- sel_node_index.set_text("index: " + cast_to_string(n));
- if (graph_drawer.graph_node(n).data.is_evidence())
- {
- sel_node_is_evidence.set_checked();
- sel_node_evidence.enable();
- sel_node_evidence.set_text(cast_to_string(graph_drawer.graph_node(n).data.value()));
- }
- else
- {
- sel_node_is_evidence.set_unchecked();
- sel_node_evidence.disable();
- sel_node_evidence.set_text("");
- }
-
- sel_node_num_values.set_text(cast_to_string(node_num_values(graph_drawer.graph(),n)));
-
- sel_node_text.set_text(graph_drawer.node_label(n));
-
- load_selected_node_tables_into_cpt_grid();
- load_selected_node_tables_into_ppt_grid();
-}
-
-// ----------------------------------------------------------------------------------------
-
-// This event is called when the user toggles the "is evidence" check box
-void main_window::
-on_evidence_toggled (
-)
-{
- if (sel_node_is_evidence.is_checked())
- {
- graph_drawer.graph_node(selected_node_index).data.set_as_evidence();
- sel_node_evidence.enable();
- sel_node_evidence.set_text(cast_to_string(graph_drawer.graph_node(selected_node_index).data.value()));
-
- graph_drawer.set_node_color(selected_node_index, color_evidence);
- }
- else
- {
- graph_drawer.graph_node(selected_node_index).data.set_as_nonevidence();
- sel_node_evidence.disable();
- sel_node_evidence.set_text("");
- sel_node_evidence.set_background_color(color_default_bg);
- graph_drawer.set_node_color(selected_node_index, color_non_evidence);
- }
- solution.reset();
-}
-
-// ----------------------------------------------------------------------------------------
-
-// This event is called when the user causes no node to be selected
-void main_window::
-on_node_deselected ( unsigned long )
-{
- no_node_selected();
-}
-
-// ----------------------------------------------------------------------------------------
-
-// This event is called when the user causes a node to be deleted
-void main_window::
-on_node_deleted ( )
-{
- no_node_selected();
-}
-
-// ----------------------------------------------------------------------------------------
-
-// This event is called when the user changes the text in the "node label" text field
-void main_window::
-on_sel_node_text_modified (
-)
-{
- // set the selected node's text to match whatever the user just typed in
- graph_drawer.set_node_label(selected_node_index,sel_node_text.text());
-}
-
-// ----------------------------------------------------------------------------------------
-
diff --git a/ml/dlib/examples/bridge_ex.cpp b/ml/dlib/examples/bridge_ex.cpp
deleted file mode 100644
index bc772ccbb..000000000
--- a/ml/dlib/examples/bridge_ex.cpp
+++ /dev/null
@@ -1,365 +0,0 @@
-// The contents of this file are in the public domain. See LICENSE_FOR_EXAMPLE_PROGRAMS.txt
-
-
-/*
- This is an example showing how to use the bridge object from from the
- dlib C++ Library to send messages via TCP/IP.
-
- In particular, this example will walk you through four progressively
- more complex use cases of the bridge object. Note that this example
- program assumes you are already familiar with the pipe object and at
- least the contents of the pipe_ex_2.cpp example program.
-*/
-
-
-// =========== Example program output ===========
-/*
- ---- Running example 1 ----
- dequeued value: 1
- dequeued value: 2
- dequeued value: 3
-
- ---- Running example 2 ----
- dequeued value: 1
- dequeued value: 2
- dequeued value: 3
-
- ---- Running example 3 ----
- dequeued int: 1
- dequeued int: 2
- dequeued struct: 3 some string
-
- ---- Running example 4 ----
- bridge 1 status: is_connected: true
- bridge 1 status: foreign_ip: 127.0.0.1
- bridge 1 status: foreign_port: 43156
- bridge 2 status: is_connected: true
- bridge 2 status: foreign_ip: 127.0.0.1
- bridge 2 status: foreign_port: 12345
- dequeued int: 1
- dequeued int: 2
- dequeued struct: 3 some string
- bridge 1 status: is_connected: false
- bridge 1 status: foreign_ip: 127.0.0.1
- bridge 1 status: foreign_port: 12345
-*/
-
-
-#include <dlib/bridge.h>
-#include <dlib/type_safe_union.h>
-#include <iostream>
-
-using namespace dlib;
-using namespace std;
-
-// ----------------------------------------------------------------------------------------
-
-void run_example_1();
-void run_example_2();
-void run_example_3();
-void run_example_4();
-
-// ----------------------------------------------------------------------------------------
-
-int main()
-{
- run_example_1();
- run_example_2();
- run_example_3();
- run_example_4();
-}
-
-// ----------------------------------------------------------------------------------------
-// ----------------------------------------------------------------------------------------
-// ----------------------------------------------------------------------------------------
-
-void run_example_1(
-)
-{
- cout << "\n ---- Running example 1 ---- " << endl;
-
- /*
- The idea of the bridge is basically to allow two different dlib::pipe objects
- to be connected together via a TCP connection. This is best illustrated by
- the following short example. In it we create two pipes, in and out. When
- an object is enqueued into the out pipe it will be automatically sent
- through a TCP connection and once received at the other end it will be
- inserted into the in pipe.
- */
- dlib::pipe<int> in(4), out(4);
-
-
- // This bridge will listen on port 12345 for an incoming TCP connection. Then
- // it will read data from that connection and put it into the in pipe.
- bridge b2(listen_on_port(12345), receive(in));
-
- // This bridge will initiate a TCP connection and then start dequeuing
- // objects from out and transmitting them over the connection.
- bridge b1(connect_to_ip_and_port("127.0.0.1", 12345), transmit(out));
-
- // As an aside, in a real program, each of these bridges and pipes would be in a
- // separate application. But to make this example self contained they are both
- // right here.
-
-
-
- // Now let's put some things into the out pipe
- int value = 1;
- out.enqueue(value);
-
- value = 2;
- out.enqueue(value);
-
- value = 3;
- out.enqueue(value);
-
-
- // Now those 3 ints can be dequeued from the in pipe. They will show up
- // in the same order they were inserted into the out pipe.
- in.dequeue(value);
- cout << "dequeued value: "<< value << endl;
- in.dequeue(value);
- cout << "dequeued value: "<< value << endl;
- in.dequeue(value);
- cout << "dequeued value: "<< value << endl;
-}
-
-// ----------------------------------------------------------------------------------------
-// ----------------------------------------------------------------------------------------
-// ----------------------------------------------------------------------------------------
-
-void run_example_2(
-)
-{
- cout << "\n ---- Running example 2 ---- " << endl;
-
- /*
- This example makes a simple echo server on port 12345. When an object
- is inserted into the out pipe it will be sent over a TCP connection, get
- put into the echo pipe and then immediately read out of the echo pipe and
- sent back over the TCP connection where it will finally be placed into the in
- pipe.
- */
-
- dlib::pipe<int> in(4), out(4), echo(4);
-
- // Just like TCP connections, a bridge can send data both directions. The directionality
- // of a pipe is indicated by the receive() and transmit() type decorations. Also, the order
- // they are listed doesn't matter.
- bridge echo_bridge(listen_on_port(12345), receive(echo), transmit(echo));
-
- // Note that you can also specify the ip and port as a string by using connect_to().
- bridge b1(connect_to("127.0.0.1:12345"), transmit(out), receive(in));
-
-
- int value = 1;
- out.enqueue(value);
-
- value = 2;
- out.enqueue(value);
-
- value = 3;
- out.enqueue(value);
-
-
- in.dequeue(value);
- cout << "dequeued value: "<< value << endl;
- in.dequeue(value);
- cout << "dequeued value: "<< value << endl;
- in.dequeue(value);
- cout << "dequeued value: "<< value << endl;
-}
-
-// ----------------------------------------------------------------------------------------
-// ----------------------------------------------------------------------------------------
-// ----------------------------------------------------------------------------------------
-
-struct my_example_object
-{
- /*
- All objects passing through a dlib::bridge must be serializable. This
- means there must exist global functions called serialize() and deserialize()
- which can convert an object into a bit stream and then reverse the process.
-
- This example object illustrates how this is done.
- */
-
- int value;
- std::string str;
-};
-
-void serialize (const my_example_object& item, std::ostream& out)
-{
- /*
- serialize() just needs to write the state of item to the output stream.
- You can do this however you like. Below, I'm using the serialize functions
- for int and std::string which come with dlib. But again, you can do whatever
- you want here.
- */
- dlib::serialize(item.value, out);
- dlib::serialize(item.str, out);
-}
-
-void deserialize (my_example_object& item, std::istream& in)
-{
- /*
- deserialize() is just the inverse of serialize(). Again, you can do
- whatever you want here so long as it correctly reconstructs item. This
- also means that deserialize() must always consume as many bytes as serialize()
- generates.
- */
- dlib::deserialize(item.value, in);
- dlib::deserialize(item.str, in);
-}
-
-// ----------------------------------------------------------------------------------------
-
-void run_example_3(
-)
-{
- cout << "\n ---- Running example 3 ---- " << endl;
-
- /*
- In this example we will just send ints and my_example_object objects
- over a TCP connection. Since we are sending more than one type of
- object through a pipe we will need to use the type_safe_union.
- */
-
- typedef type_safe_union<int, my_example_object> tsu_type;
-
- dlib::pipe<tsu_type> in(4), out(4);
-
- // Note that we don't have to start the listening bridge first. If b2
- // fails to make a connection it will just keep trying until successful.
- bridge b2(connect_to("127.0.0.1:12345"), receive(in));
- // We don't have to configure a bridge in it's constructor. If it's
- // more convenient we can do so by calling reconfigure() instead.
- bridge b1;
- b1.reconfigure(listen_on_port(12345), transmit(out));
-
- tsu_type msg;
-
- msg = 1;
- out.enqueue(msg);
-
- msg = 2;
- out.enqueue(msg);
-
- msg.get<my_example_object>().value = 3;
- msg.get<my_example_object>().str = "some string";
- out.enqueue(msg);
-
-
- // dequeue the three objects we sent and print them on the screen.
- for (int i = 0; i < 3; ++i)
- {
- in.dequeue(msg);
- if (msg.contains<int>())
- {
- cout << "dequeued int: "<< msg.get<int>() << endl;
- }
- else if (msg.contains<my_example_object>())
- {
- cout << "dequeued struct: "<< msg.get<my_example_object>().value << " "
- << msg.get<my_example_object>().str << endl;
- }
- }
-}
-
-// ----------------------------------------------------------------------------------------
-// ----------------------------------------------------------------------------------------
-// ----------------------------------------------------------------------------------------
-
-void run_example_4(
-)
-{
- cout << "\n ---- Running example 4 ---- " << endl;
-
- /*
- This final example is the same as example 3 except we will also now be getting
- status messages from the bridges. These bridge_status messages tell us the
- state of the TCP connection associated with a bridge. Is it connected or not?
- Who it is connected to?
-
- The way you get these status messages is by ensuring that your receive pipe is
- capable of storing bridge_status objects. If it is then the bridge will
- automatically insert bridge_status messages into your receive pipe whenever
- there is a status change.
-
- There are only two kinds of status changes. The establishment of a connection
- or the closing of a connection. Also, a connection which closes due to you
- calling clear(), reconfigure(), or destructing a bridge does not generate a
- status message since, in this case, you already know about it and just want
- the bridge to destroy itself as quickly as possible.
- */
-
-
- typedef type_safe_union<int, my_example_object, bridge_status> tsu_type;
-
- dlib::pipe<tsu_type> in(4), out(4);
- dlib::pipe<bridge_status> b1_status(4);
-
- // setup both bridges to have receive pipes capable of holding bridge_status messages.
- bridge b1(listen_on_port(12345), transmit(out), receive(b1_status));
- // Note that we can also use a hostname with connect_to() instead of supplying an IP address.
- bridge b2(connect_to("localhost:12345"), receive(in));
-
- tsu_type msg;
- bridge_status bs;
-
- // Once a connection is established it will generate a status message from each bridge.
- // Let's get those and print them.
- b1_status.dequeue(bs);
- cout << "bridge 1 status: is_connected: " << boolalpha << bs.is_connected << endl;
- cout << "bridge 1 status: foreign_ip: " << bs.foreign_ip << endl;
- cout << "bridge 1 status: foreign_port: " << bs.foreign_port << endl;
-
- in.dequeue(msg);
- bs = msg.get<bridge_status>();
- cout << "bridge 2 status: is_connected: " << bs.is_connected << endl;
- cout << "bridge 2 status: foreign_ip: " << bs.foreign_ip << endl;
- cout << "bridge 2 status: foreign_port: " << bs.foreign_port << endl;
-
-
-
- msg = 1;
- out.enqueue(msg);
-
- msg = 2;
- out.enqueue(msg);
-
- msg.get<my_example_object>().value = 3;
- msg.get<my_example_object>().str = "some string";
- out.enqueue(msg);
-
-
- // Read the 3 things we sent over the connection.
- for (int i = 0; i < 3; ++i)
- {
- in.dequeue(msg);
- if (msg.contains<int>())
- {
- cout << "dequeued int: "<< msg.get<int>() << endl;
- }
- else if (msg.contains<my_example_object>())
- {
- cout << "dequeued struct: "<< msg.get<my_example_object>().value << " "
- << msg.get<my_example_object>().str << endl;
- }
- }
-
- // cause bridge 1 to shutdown completely. This will close the connection and
- // therefore bridge 2 will generate a status message indicating the connection
- // just closed.
- b1.clear();
- in.dequeue(msg);
- bs = msg.get<bridge_status>();
- cout << "bridge 1 status: is_connected: " << bs.is_connected << endl;
- cout << "bridge 1 status: foreign_ip: " << bs.foreign_ip << endl;
- cout << "bridge 1 status: foreign_port: " << bs.foreign_port << endl;
-}
-
-// ----------------------------------------------------------------------------------------
-// ----------------------------------------------------------------------------------------
-// ----------------------------------------------------------------------------------------
-
diff --git a/ml/dlib/examples/bsp_ex.cpp b/ml/dlib/examples/bsp_ex.cpp
deleted file mode 100644
index 7dffa68d6..000000000
--- a/ml/dlib/examples/bsp_ex.cpp
+++ /dev/null
@@ -1,282 +0,0 @@
-// The contents of this file are in the public domain. See LICENSE_FOR_EXAMPLE_PROGRAMS.txt
-/*
-
- This is an example illustrating the use of the Bulk Synchronous Parallel (BSP)
- processing tools from the dlib C++ Library. These tools allow you to easily setup a
- number of processes running on different computers which cooperate to compute some
- result.
-
- In this example, we will use the BSP tools to find the minimizer of a simple function.
- In particular, we will setup a nested grid search where different parts of the grid are
- searched in parallel by different processes.
-
-
- To run this program you should do the following (supposing you want to use three BSP
- nodes to do the grid search and, to make things easy, you will run them all on your
- current computer):
-
- 1. Open three command windows and navigate each to the folder containing the
- compiled bsp_ex.cpp program. Let's call these window 1, window 2, and window 3.
-
- 2. In window 1 execute this command:
- ./bsp_ex -l12345
- This will start a listening BSP node that listens on port 12345. The BSP node
- won't do anything until we tell all the nodes to start running in step 4 below.
-
- 3. In window 2 execute this command:
- ./bsp_ex -l12346
- This starts another listening BSP node. Note that since we are running this
- example all on one computer you need to use different listening port numbers
- for each listening node.
-
- 4. In window 3 execute this command:
- ./bsp_ex localhost:12345 localhost:12346
- This will start a BSP node that connects to the others and gets them all running.
- Additionally, as you will see when we go over the code below, it will also print
- the final output of the BSP process, which is the minimizer of our test function.
- Once it terminates, all the other BSP nodes will also automatically terminate.
-*/
-
-
-
-
-
-#include <dlib/cmd_line_parser.h>
-#include <dlib/bsp.h>
-#include <dlib/matrix.h>
-
-#include <iostream>
-
-using namespace std;
-using namespace dlib;
-
-// ----------------------------------------------------------------------------------------
-
-// These are the functions executed by the BSP nodes. They are defined below.
-void bsp_job_node_0 (bsp_context& bsp, double& min_value, double& optimal_x);
-void bsp_job_other_nodes (bsp_context& bsp, long grid_resolution);
-
-// ----------------------------------------------------------------------------------------
-
-int main(int argc, char** argv)
-{
- try
- {
- // Use the dlib command_line_parser to parse the command line. See the
- // compress_stream_ex.cpp example program for an introduction to the command line
- // parser.
- command_line_parser parser;
- parser.add_option("h","Display this help message.");
- parser.add_option("l","Run as a listening BSP node.",1);
- parser.parse(argc, argv);
- parser.check_option_arg_range("l", 1, 65535);
-
-
- // Print a help message if the user gives -h on the command line.
- if (parser.option("h"))
- {
- // display all the command line options
- cout << "Usage: bsp_ex (-l port | <list of hosts>)\n";
- parser.print_options();
- return 0;
- }
-
-
- // If the command line contained -l
- if (parser.option("l"))
- {
- // Get the argument to -l
- const unsigned short listening_port = get_option(parser, "l", 0);
- cout << "Listening on port " << listening_port << endl;
-
- const long grid_resolution = 100;
-
- // bsp_listen() starts a listening BSP job. This means that it will wait until
- // someone calls bsp_connect() and connects to it before it starts running.
- // However, once it starts it will call bsp_job_other_nodes() which will then
- // do all the real work.
- //
- // The first argument is the port to listen on. The second argument is the
- // function which it should run to do all the work. The other arguments are
- // optional and allow you to pass values into the bsp_job_other_nodes()
- // routine. In this case, we are passing the grid_resolution to
- // bsp_job_other_nodes().
- bsp_listen(listening_port, bsp_job_other_nodes, grid_resolution);
- }
- else
- {
- if (parser.number_of_arguments() == 0)
- {
- cout << "You must give some listening BSP nodes as arguments to this program!" << endl;
- return 0;
- }
-
- // Take the hostname:port strings from the command line and put them into the
- // vector of hosts.
- std::vector<network_address> hosts;
- for (unsigned long i = 0; i < parser.number_of_arguments(); ++i)
- hosts.push_back(parser[i]);
-
- double min_value, optimal_x;
-
- // Calling bsp_connect() does two things. First, it tells all the BSP jobs
- // listed in the hosts vector to start running. Second, it starts a locally
- // running BSP job that executes bsp_job_node_0() and passes it any arguments
- // listed after bsp_job_node_0. So in this case it passes it the 3rd and 4th
- // arguments.
- //
- // Note also that we use dlib::ref() which causes these arguments to be passed
- // by reference. This means that bsp_job_node_0() will be able to modify them
- // and we will see the results here in main() after bsp_connect() terminates.
- bsp_connect(hosts, bsp_job_node_0, dlib::ref(min_value), dlib::ref(optimal_x));
-
- // bsp_connect() and bsp_listen() block until all the BSP nodes have terminated.
- // Therefore, we won't get to this part of the code until the BSP processing
- // has finished. But once we do we can print the results like so:
- cout << "optimal_x: "<< optimal_x << endl;
- cout << "min_value: "<< min_value << endl;
- }
-
- }
- catch (std::exception& e)
- {
- cout << "error in main(): " << e.what() << endl;
- }
-}
-
-// ----------------------------------------------------------------------------------------
-
-/*
- We are going to use the BSP tools to find the minimum of f(x). Note that
- it's minimizer is at x == 2.0.
-*/
-double f (double x)
-{
- return std::pow(x-2.0, 2.0);
-}
-
-// ----------------------------------------------------------------------------------------
-
-void bsp_job_node_0 (bsp_context& bsp, double& min_value, double& optimal_x)
-{
- // This function is called by bsp_connect(). In general, any BSP node can do anything
- // you want. However, in this example we use this node as a kind of controller for the
- // other nodes. In particular, since we are doing a nested grid search, this node's
- // job will be to collect results from other nodes and then decide which part of the
- // number line subsequent iterations should focus on.
- //
- // Also, each BSP node has a node ID number. You can determine it by calling
- // bsp.node_id(). However, the node spawned by a call to bsp_connect() always has a
- // node ID of 0 (hence the name of this function). Additionally, all functions
- // executing a BSP task always take a bsp_context as their first argument. This object
- // is the interface that allows BSP jobs to communicate with each other.
-
-
- // Now let's get down to work. Recall that we are trying to find the x value that
- // minimizes the f(x) defined above. The grid search will start out by considering the
- // range [-1e100, 1e100] on the number line. It will progressively narrow this window
- // until it has located the minimizer of f(x) to within 1e-15 of its true value.
- double left = -1e100;
- double right = 1e100;
-
- min_value = std::numeric_limits<double>::infinity();
- double interval_width = std::abs(right-left);
-
- // keep going until the window is smaller than 1e-15.
- while (right-left > 1e-15)
- {
- // At the start of each loop, we broadcast the current window to all the other BSP
- // nodes. They will each search a separate part of the window and then report back
- // the smallest values they found in their respective sub-windows.
- //
- // Also, you can send/broadcast/receive anything that has global serialize() and
- // deserialize() routines defined for it. Dlib comes with serialization functions
- // for a lot of types by default, so we don't have to define anything for this
- // example program. However, if you want to send an object you defined then you
- // will need to write your own serialization functions. See the documentation for
- // dlib's serialize() routine or the bridge_ex.cpp example program for an example.
- bsp.broadcast(left);
- bsp.broadcast(right);
-
- // Receive the smallest values found from the other BSP nodes.
- for (unsigned int k = 1; k < bsp.number_of_nodes(); ++k)
- {
- // The other nodes will send std::pairs of x/f(x) values. So that is what we
- // receive.
- std::pair<double,double> val;
- bsp.receive(val);
- // save the smallest result.
- if (val.second < min_value)
- {
- min_value = val.second;
- optimal_x = val.first;
- }
- }
-
- // Now narrow the search window by half.
- interval_width *= 0.5;
- left = optimal_x - interval_width/2;
- right = optimal_x + interval_width/2;
- }
-}
-
-// ----------------------------------------------------------------------------------------
-
-void bsp_job_other_nodes (bsp_context& bsp, long grid_resolution)
-{
- // This is the BSP job called by bsp_listen(). In these jobs we will receive window
- // ranges from the controller node, search our sub-window, and then report back the
- // location of the best x value we found.
-
- double left, right;
-
- // The try_receive() function will either return true with the next message or return
- // false if there aren't any more messages in flight between nodes and all other BSP
- // nodes are blocked on calls to receive or have terminated. That is, try_receive()
- // only returns false if waiting for a message would result in all the BSP nodes
- // waiting forever.
- //
- // Therefore, try_receive() serves both as a message receiving tool as well as an
- // implicit form of barrier synchronization. In this case, we use it to know when to
- // terminate. That is, we know it is time to terminate if all the messages between
- // nodes have been received and all nodes are inactive due to either termination or
- // being blocked on a receive call. This will happen once the controller node above
- // terminates since it will result in all the other nodes inevitably becoming blocked
- // on this try_receive() line with no messages to process.
- while (bsp.try_receive(left))
- {
- bsp.receive(right);
-
- // Compute a sub-window range for us to search. We use our node's ID value and the
- // total number of nodes to select a subset of the [left, right] window. We will
- // store the grid points from our sub-window in values_to_check.
- const double l = (bsp.node_id()-1)/(bsp.number_of_nodes()-1.0);
- const double r = bsp.node_id() /(bsp.number_of_nodes()-1.0);
- const double width = right-left;
- // Select grid_resolution number of points which are linearly spaced throughout our
- // sub-window.
- const matrix<double> values_to_check = linspace(left+l*width, left+r*width, grid_resolution);
-
- // Search all the points in values_to_check and figure out which one gives the
- // minimum value of f().
- double best_x = 0;
- double best_val = std::numeric_limits<double>::infinity();
- for (long j = 0; j < values_to_check.size(); ++j)
- {
- double temp = f(values_to_check(j));
- if (temp < best_val)
- {
- best_val = temp;
- best_x = values_to_check(j);
- }
- }
-
- // Report back the identity of the best point we found in our sub-window. Note
- // that the second argument to send(), the 0, is the node ID to send to. In this
- // case we send our results back to the controller node.
- bsp.send(make_pair(best_x, best_val), 0);
- }
-}
-
-// ----------------------------------------------------------------------------------------
-
diff --git a/ml/dlib/examples/compress_stream_ex.cpp b/ml/dlib/examples/compress_stream_ex.cpp
deleted file mode 100644
index 502400e5e..000000000
--- a/ml/dlib/examples/compress_stream_ex.cpp
+++ /dev/null
@@ -1,245 +0,0 @@
-// The contents of this file are in the public domain. See LICENSE_FOR_EXAMPLE_PROGRAMS.txt
-/*
-
- This is an example illustrating the use of the compress_stream and
- cmd_line_parser components from the dlib C++ Library.
-
- This example implements a simple command line compression utility.
-
-
- The output from the program when the -h option is given is:
-
- Usage: compress_stream_ex (-c|-d|-l) --in input_file --out output_file
- Options:
- -c Indicates that we want to compress a file.
- -d Indicates that we want to decompress a file.
- --in <arg> This option takes one argument which specifies the name of the
- file we want to compress/decompress.
- --out <arg> This option takes one argument which specifies the name of the
- output file.
-
- Miscellaneous Options:
- -h Display this help message.
- -l <arg> Set the compression level [1-3], 3 is max compression, default
- is 2.
-
-*/
-
-
-
-
-#include <dlib/compress_stream.h>
-#include <dlib/cmd_line_parser.h>
-#include <iostream>
-#include <fstream>
-#include <string>
-
-// I am making a typedefs for the versions of compress_stream I want to use.
-typedef dlib::compress_stream::kernel_1da cs1;
-typedef dlib::compress_stream::kernel_1ea cs2;
-typedef dlib::compress_stream::kernel_1ec cs3;
-
-
-using namespace std;
-using namespace dlib;
-
-
-int main(int argc, char** argv)
-{
- try
- {
- command_line_parser parser;
-
- // first I will define the command line options I want.
- // Add a -c option and tell the parser what the option is for.
- parser.add_option("c","Indicates that we want to compress a file.");
- parser.add_option("d","Indicates that we want to decompress a file.");
- // add a --in option that takes 1 argument
- parser.add_option("in","This option takes one argument which specifies the name of the file we want to compress/decompress.",1);
- // add a --out option that takes 1 argument
- parser.add_option("out","This option takes one argument which specifies the name of the output file.",1);
- // In the code below, we use the parser.print_options() method to print all our
- // options to the screen. We can tell it that we would like some options to be
- // grouped together by calling set_group_name() before adding those options. In
- // general, you can make as many groups as you like by calling set_group_name().
- // However, here we make only one named group.
- parser.set_group_name("Miscellaneous Options");
- parser.add_option("h","Display this help message.");
- parser.add_option("l","Set the compression level [1-3], 3 is max compression, default is 2.",1);
-
-
- // now I will parse the command line
- parser.parse(argc,argv);
-
-
- // Now I will use the parser to validate some things about the command line.
- // If any of the following checks fail then an exception will be thrown and it will
- // contain a message that tells the user what the problem was.
-
- // First I want to check that none of the options were given on the command line
- // more than once. To do this I define an array that contains the options
- // that shouldn't appear more than once and then I just call check_one_time_options()
- const char* one_time_opts[] = {"c", "d", "in", "out", "h", "l"};
- parser.check_one_time_options(one_time_opts);
- // Here I'm checking that the user didn't pick both the c and d options at the
- // same time.
- parser.check_incompatible_options("c", "d");
-
- // Here I'm checking that the argument to the l option is an integer in the range 1 to 3.
- // That is, it should be convertible to an int by dlib::string_assign and be either
- // 1, 2, or 3. Note that if you wanted to allow floating point values in the range 1 to
- // 3 then you could give a range 1.0 to 3.0 or explicitly supply a type of float or double
- // to the template argument of the check_option_arg_range() function.
- parser.check_option_arg_range("l", 1, 3);
-
- // The 'l' option is a sub-option of the 'c' option. That is, you can only select the
- // compression level when compressing. This command below checks that the listed
- // sub options are always given in the presence of their parent options.
- const char* c_sub_opts[] = {"l"};
- parser.check_sub_options("c", c_sub_opts);
-
- // check if the -h option was given on the command line
- if (parser.option("h"))
- {
- // display all the command line options
- cout << "Usage: compress_stream_ex (-c|-d|-l) --in input_file --out output_file\n";
- // This function prints out a nicely formatted list of
- // all the options the parser has
- parser.print_options();
- return 0;
- }
-
- // Figure out what the compression level should be. If the user didn't supply
- // this command line option then a value of 2 will be used.
- int compression_level = get_option(parser,"l",2);
-
-
- // make sure one of the c or d options was given
- if (!parser.option("c") && !parser.option("d"))
- {
- cout << "Error in command line:\n You must specify either the c option or the d option.\n";
- cout << "\nTry the -h option for more information." << endl;
- return 0;
- }
-
-
- string in_file;
- string out_file;
-
- // check if the user told us the input file and if they did then
- // get the file name
- if (parser.option("in"))
- {
- in_file = parser.option("in").argument();
- }
- else
- {
- cout << "Error in command line:\n You must specify an input file.\n";
- cout << "\nTry the -h option for more information." << endl;
- return 0;
- }
-
-
- // check if the user told us the output file and if they did then
- // get the file name
- if (parser.option("out"))
- {
- out_file = parser.option("out").argument();
- }
- else
- {
- cout << "Error in command line:\n You must specify an output file.\n";
- cout << "\nTry the -h option for more information." << endl;
- return 0;
- }
-
-
- // open the files we will be reading from and writing to
- ifstream fin(in_file.c_str(),ios::binary);
- ofstream fout(out_file.c_str(),ios::binary);
-
- // make sure the files opened correctly
- if (!fin)
- {
- cout << "Error opening file " << in_file << ".\n";
- return 0;
- }
-
- if (!fout)
- {
- cout << "Error creating file " << out_file << ".\n";
- return 0;
- }
-
-
-
- // now perform the actual compression or decompression.
- if (parser.option("c"))
- {
- // save the compression level to the output file
- serialize(compression_level, fout);
-
- switch (compression_level)
- {
- case 1:
- {
- cs1 compressor;
- compressor.compress(fin,fout);
- }break;
- case 2:
- {
- cs2 compressor;
- compressor.compress(fin,fout);
- }break;
- case 3:
- {
- cs3 compressor;
- compressor.compress(fin,fout);
- }break;
- }
- }
- else
- {
- // obtain the compression level from the input file
- deserialize(compression_level, fin);
-
- switch (compression_level)
- {
- case 1:
- {
- cs1 compressor;
- compressor.decompress(fin,fout);
- }break;
- case 2:
- {
- cs2 compressor;
- compressor.decompress(fin,fout);
- }break;
- case 3:
- {
- cs3 compressor;
- compressor.decompress(fin,fout);
- }break;
- default:
- {
- cout << "Error in compressed file, invalid compression level" << endl;
- }break;
- }
- }
-
-
-
-
- }
- catch (exception& e)
- {
- // Note that this will catch any cmd_line_parse_error exceptions and print
- // the default message.
- cout << e.what() << endl;
- }
-}
-
-
-
-
-
diff --git a/ml/dlib/examples/config.txt b/ml/dlib/examples/config.txt
deleted file mode 100644
index da21d170c..000000000
--- a/ml/dlib/examples/config.txt
+++ /dev/null
@@ -1,30 +0,0 @@
-# This is an example config file. Note that # is used to create a comment.
-
-# At its most basic level a config file is just a bunch of key/value pairs.
-# So for example:
-key1 = value2
-dlib = a C++ library
-
-# You can also define "sub blocks" in your config files like so
-user1
-{
- # Inside a sub block you can list more key/value pairs.
- id = 42
- name = davis
-
- # you can also nest sub-blocks as deep as you want
- details
- {
- editor = vim
- home_dir = /home/davis
- }
-}
-user2 {
- id = 1234
- name = joe
- details {
- editor = emacs
- home_dir = /home/joe
- }
-}
-
diff --git a/ml/dlib/examples/config_reader_ex.cpp b/ml/dlib/examples/config_reader_ex.cpp
deleted file mode 100644
index 02ad1cc68..000000000
--- a/ml/dlib/examples/config_reader_ex.cpp
+++ /dev/null
@@ -1,146 +0,0 @@
-// The contents of this file are in the public domain. See LICENSE_FOR_EXAMPLE_PROGRAMS.txt
-/*
-
- This is an example illustrating the use of the config_reader component
- from the dlib C++ Library.
-
- This example uses the config_reader to load a config file and then
- prints out the values of various fields in the file.
-*/
-
-
-#include <dlib/config_reader.h>
-#include <iostream>
-#include <fstream>
-#include <vector>
-
-
-using namespace std;
-using namespace dlib;
-
-// ----------------------------------------------------------------------------------------
-// For reference, the contents of the config file used in this example is reproduced below:
-/*
-
-# This is an example config file. Note that # is used to create a comment.
-
-# At its most basic level a config file is just a bunch of key/value pairs.
-# So for example:
-key1 = value2
-dlib = a C++ library
-
-# You can also define "sub blocks" in your config files like so
-user1
-{
- # Inside a sub block you can list more key/value pairs.
- id = 42
- name = davis
-
- # you can also nest sub-blocks as deep as you want
- details
- {
- editor = vim
- home_dir = /home/davis
- }
-}
-user2 {
- id = 1234
- name = joe
- details {
- editor = emacs
- home_dir = /home/joe
- }
-}
-
-*/
-// ----------------------------------------------------------------------------------------
-
-void print_config_reader_contents (
- const config_reader& cr,
- int depth = 0
-);
-/*
- This is a simple function that recursively walks through everything in
- a config reader and prints it to the screen.
-*/
-
-// ----------------------------------------------------------------------------------------
-
-int main()
-{
- try
- {
- config_reader cr("config.txt");
-
- // Use our recursive function to print everything in the config file.
- print_config_reader_contents(cr);
-
- // Now let's access some of the fields of the config file directly. You
- // use [] for accessing key values and .block() for accessing sub-blocks.
-
- // Print out the string value assigned to key1 in the config file
- cout << cr["key1"] << endl;
-
- // Print out the name field inside the user1 sub-block
- cout << cr.block("user1")["name"] << endl;
- // Now print out the editor field in the details block
- cout << cr.block("user1").block("details")["editor"] << endl;
-
-
- // Note that you can use get_option() to easily convert fields into
- // non-string types. For example, the config file has an integer id
- // field that can be converted into an int like so:
- int id1 = get_option(cr,"user1.id",0);
- int id2 = get_option(cr,"user2.id",0);
- cout << "user1's id is " << id1 << endl;
- cout << "user2's id is " << id2 << endl;
- // The third argument to get_option() is the default value returned if
- // the config reader doesn't contain a corresponding entry. So for
- // example, the following prints 321 since there is no user3.
- int id3 = get_option(cr,"user3.id",321);
- cout << "user3's id is " << id3 << endl;
-
- }
- catch (exception& e)
- {
- // Finally, note that the config_reader throws exceptions if the config
- // file is corrupted or if you ask it for a key or block that doesn't exist.
- // Here we print out any such error messages.
- cout << e.what() << endl;
- }
-}
-
-// ----------------------------------------------------------------------------------------
-
-void print_config_reader_contents (
- const config_reader& cr,
- int depth
-)
-{
- // Make a string with depth*4 spaces in it.
- const string padding(depth*4, ' ');
-
- // We can obtain a list of all the keys and sub-blocks defined
- // at the current level in the config reader like so:
- vector<string> keys, blocks;
- cr.get_keys(keys);
- cr.get_blocks(blocks);
-
- // Now print all the key/value pairs
- for (unsigned long i = 0; i < keys.size(); ++i)
- cout << padding << keys[i] << " = " << cr[keys[i]] << endl;
-
- // Now print all the sub-blocks.
- for (unsigned long i = 0; i < blocks.size(); ++i)
- {
- // First print the block name
- cout << padding << blocks[i] << " { " << endl;
- // Now recursively print the contents of the sub block. Note that the cr.block()
- // function returns another config_reader that represents the sub-block.
- print_config_reader_contents(cr.block(blocks[i]), depth+1);
- cout << padding << "}" << endl;
- }
-}
-
-// ----------------------------------------------------------------------------------------
-
diff --git a/ml/dlib/examples/custom_trainer_ex.cpp b/ml/dlib/examples/custom_trainer_ex.cpp
deleted file mode 100644
index 39af53f39..000000000
--- a/ml/dlib/examples/custom_trainer_ex.cpp
+++ /dev/null
@@ -1,277 +0,0 @@
-// The contents of this file are in the public domain. See LICENSE_FOR_EXAMPLE_PROGRAMS.txt
-/*
- This example program shows you how to create your own custom binary classification
- trainer object and use it with the multiclass classification tools in the dlib C++
- library. This example assumes you have already become familiar with the concepts
- introduced in the multiclass_classification_ex.cpp example program.
-
-
- In this example we will create a very simple trainer object that takes a binary
- classification problem and produces a decision rule which says a test point has the
- same class as whichever centroid it is closest to.
-
- The multiclass training dataset will consist of four classes. Each class will be a blob
- of points in one of the quadrants of the cartesian plane. For fun, we will use
- std::string labels and therefore the labels of these classes will be the following:
- "upper_left",
- "upper_right",
- "lower_left",
- "lower_right"
-*/
-
-#include <dlib/svm_threaded.h>
-
-#include <iostream>
-#include <vector>
-
-#include <dlib/rand.h>
-
-using namespace std;
-using namespace dlib;
-
-// Our data will be 2-dimensional data. So declare an appropriate type to contain these points.
-typedef matrix<double,2,1> sample_type;
-
-// ----------------------------------------------------------------------------------------
-
-struct custom_decision_function
-{
- /*!
- WHAT THIS OBJECT REPRESENTS
- This object is the representation of our binary decision rule.
- !*/
-
- // centers of the two classes
- sample_type positive_center, negative_center;
-
- double operator() (
- const sample_type& x
- ) const
- {
- // if x is closer to the positive class then return +1
- if (length(positive_center - x) < length(negative_center - x))
- return +1;
- else
- return -1;
- }
-};
-
-// Later on in this example we will save our decision functions to disk. This
-// pair of routines is needed for this functionality.
-void serialize (const custom_decision_function& item, std::ostream& out)
-{
- // write the state of item to the output stream
- serialize(item.positive_center, out);
- serialize(item.negative_center, out);
-}
-
-void deserialize (custom_decision_function& item, std::istream& in)
-{
- // read the data from the input stream and store it in item
- deserialize(item.positive_center, in);
- deserialize(item.negative_center, in);
-}
-
-// ----------------------------------------------------------------------------------------
-
-class simple_custom_trainer
-{
- /*!
- WHAT THIS OBJECT REPRESENTS
- This is our example custom binary classifier trainer object. It simply
- computes the means of the +1 and -1 classes, puts them into our
- custom_decision_function, and returns the results.
-
- Below we define the train() function. I have also included the
- requires/ensures definition for a generic binary classifier's train()
- !*/
-public:
-
-
- custom_decision_function train (
- const std::vector<sample_type>& samples,
- const std::vector<double>& labels
- ) const
- /*!
- requires
- - is_binary_classification_problem(samples, labels) == true
- (e.g. labels consists of only +1 and -1 values, samples.size() == labels.size())
- ensures
- - returns a decision function F with the following properties:
- - if (new_x is a sample predicted have +1 label) then
- - F(new_x) >= 0
- - else
- - F(new_x) < 0
- !*/
- {
- sample_type positive_center, negative_center;
-
- // compute sums of each class
- positive_center = 0;
- negative_center = 0;
- for (unsigned long i = 0; i < samples.size(); ++i)
- {
- if (labels[i] == +1)
- positive_center += samples[i];
- else // this is a -1 sample
- negative_center += samples[i];
- }
-
- // divide by number of +1 samples
- positive_center /= sum(mat(labels) == +1);
- // divide by number of -1 samples
- negative_center /= sum(mat(labels) == -1);
-
- custom_decision_function df;
- df.positive_center = positive_center;
- df.negative_center = negative_center;
-
- return df;
- }
-};
-
-// ----------------------------------------------------------------------------------------
-
-void generate_data (
- std::vector<sample_type>& samples,
- std::vector<string>& labels
-);
-/*!
- ensures
- - make some four class data as described above.
- - each class will have 50 samples in it
-!*/
-
-// ----------------------------------------------------------------------------------------
-
-int main()
-{
- std::vector<sample_type> samples;
- std::vector<string> labels;
-
- // First, get our labeled set of training data
- generate_data(samples, labels);
-
- cout << "samples.size(): "<< samples.size() << endl;
-
- // Define the trainer we will use. The second template argument specifies the type
- // of label used, which is string in this case.
- typedef one_vs_one_trainer<any_trainer<sample_type>, string> ovo_trainer;
-
-
- ovo_trainer trainer;
-
- // Now tell the one_vs_one_trainer that, by default, it should use the simple_custom_trainer
- // to solve the individual binary classification subproblems.
- trainer.set_trainer(simple_custom_trainer());
-
- // Next, to make things a little more interesting, we will setup the one_vs_one_trainer
- // to use kernel ridge regression to solve the upper_left vs lower_right binary classification
- // subproblem.
- typedef radial_basis_kernel<sample_type> rbf_kernel;
- krr_trainer<rbf_kernel> rbf_trainer;
- rbf_trainer.set_kernel(rbf_kernel(0.1));
- trainer.set_trainer(rbf_trainer, "upper_left", "lower_right");
-
-
- // Now let's do 5-fold cross-validation using the one_vs_one_trainer we just setup.
- // As an aside, always shuffle the order of the samples before doing cross validation.
- // For a discussion of why this is a good idea see the svm_ex.cpp example.
- randomize_samples(samples, labels);
- cout << "cross validation: \n" << cross_validate_multiclass_trainer(trainer, samples, labels, 5) << endl;
- // This dataset is very easy and everything is correctly classified. Therefore, the output of
- // cross validation is the following confusion matrix.
- /*
- 50 0 0 0
- 0 50 0 0
- 0 0 50 0
- 0 0 0 50
- */
-
-
- // We can also obtain the decision rule as always.
- one_vs_one_decision_function<ovo_trainer> df = trainer.train(samples, labels);
-
- cout << "predicted label: "<< df(samples[0]) << ", true label: "<< labels[0] << endl;
- cout << "predicted label: "<< df(samples[90]) << ", true label: "<< labels[90] << endl;
- // The output is:
- /*
- predicted label: upper_right, true label: upper_right
- predicted label: lower_left, true label: lower_left
- */
-
-
- // Finally, let's save our multiclass decision rule to disk. Remember that we have
- // to specify the types of binary decision function used inside the one_vs_one_decision_function.
- one_vs_one_decision_function<ovo_trainer,
- custom_decision_function, // This is the output of the simple_custom_trainer
- decision_function<radial_basis_kernel<sample_type> > // This is the output of the rbf_trainer
- > df2, df3;
-
- df2 = df;
- // save to a file called df.dat
- serialize("df.dat") << df2;
-
- // load the function back in from disk and store it in df3.
- deserialize("df.dat") >> df3;
-
-
- // Test df3 to see that this worked.
- cout << endl;
- cout << "predicted label: "<< df3(samples[0]) << ", true label: "<< labels[0] << endl;
- cout << "predicted label: "<< df3(samples[90]) << ", true label: "<< labels[90] << endl;
- // Test df3 on the samples and labels and print the confusion matrix.
- cout << "test deserialized function: \n" << test_multiclass_decision_function(df3, samples, labels) << endl;
-
-}
-
-// ----------------------------------------------------------------------------------------
-
-void generate_data (
- std::vector<sample_type>& samples,
- std::vector<string>& labels
-)
-{
- const long num = 50;
-
- sample_type m;
-
- dlib::rand rnd;
-
-
- // add some points in the upper right quadrant
- m = 10, 10;
- for (long i = 0; i < num; ++i)
- {
- samples.push_back(m + randm(2,1,rnd));
- labels.push_back("upper_right");
- }
-
- // add some points in the upper left quadrant
- m = -10, 10;
- for (long i = 0; i < num; ++i)
- {
- samples.push_back(m + randm(2,1,rnd));
- labels.push_back("upper_left");
- }
-
- // add some points in the lower right quadrant
- m = 10, -10;
- for (long i = 0; i < num; ++i)
- {
- samples.push_back(m + randm(2,1,rnd));
- labels.push_back("lower_right");
- }
-
- // add some points in the lower left quadrant
- m = -10, -10;
- for (long i = 0; i < num; ++i)
- {
- samples.push_back(m + randm(2,1,rnd));
- labels.push_back("lower_left");
- }
-
-}
-
-// ----------------------------------------------------------------------------------------
-
diff --git a/ml/dlib/examples/dir_nav_ex.cpp b/ml/dlib/examples/dir_nav_ex.cpp
deleted file mode 100644
index 2f51f2d1b..000000000
--- a/ml/dlib/examples/dir_nav_ex.cpp
+++ /dev/null
@@ -1,75 +0,0 @@
-// The contents of this file are in the public domain. See LICENSE_FOR_EXAMPLE_PROGRAMS.txt
-/*
-
- This is an example illustrating the use of the dir_nav component from the dlib C++ Library.
- It prints a listing of all directories and files in the users
- current working directory or the directory specified on the command line.
-
-*/
-
-
-#include <iostream>
-#include <iomanip>
-#include <dlib/dir_nav.h>
-#include <vector>
-#include <algorithm>
-
-using namespace std;
-using namespace dlib;
-
-
-int main(int argc, char** argv)
-{
- try
- {
- string loc;
- if (argc == 2)
- loc = argv[1];
- else
- loc = "."; // if no argument is given then use the current working dir.
-
- directory test(loc);
-
-
- cout << "directory: " << test.name() << endl;
- cout << "full path: " << test.full_name() << endl;
- cout << "is root: " << ((test.is_root())?"yes":"no") << endl;
-
- // get all directories and files in test
- std::vector<directory> dirs = test.get_dirs();
- std::vector<file> files = test.get_files();
-
- // sort the files and directories
- sort(files.begin(), files.end());
- sort(dirs.begin(), dirs.end());
-
- cout << "\n\n\n";
-
- // print all the subdirectories
- for (unsigned long i = 0; i < dirs.size(); ++i)
- cout << " <DIR> " << dirs[i].name() << "\n";
-
- // print all the subfiles
- for (unsigned long i = 0; i < files.size(); ++i)
- cout << setw(13) << files[i].size() << " " << files[i].name() << "\n";
-
-
- cout << "\n\nnumber of dirs: " << dirs.size() << endl;
- cout << "number of files: " << files.size() << endl;
-
- }
- catch (file::file_not_found& e)
- {
- cout << "file not found or accessible: " << e.info << endl;
- }
- catch (directory::dir_not_found& e)
- {
- cout << "dir not found or accessible: " << e.info << endl;
- }
- catch (directory::listing_error& e)
- {
- cout << "listing error: " << e.info << endl;
- }
-}
-
-
diff --git a/ml/dlib/examples/dnn_face_recognition_ex.cpp b/ml/dlib/examples/dnn_face_recognition_ex.cpp
deleted file mode 100644
index 4c0a2a02b..000000000
--- a/ml/dlib/examples/dnn_face_recognition_ex.cpp
+++ /dev/null
@@ -1,220 +0,0 @@
-// The contents of this file are in the public domain. See LICENSE_FOR_EXAMPLE_PROGRAMS.txt
-/*
- This is an example illustrating the use of the deep learning tools from the dlib C++
- Library. In it, we will show how to do face recognition. This example uses the
- pretrained dlib_face_recognition_resnet_model_v1 model which is freely available from
- the dlib web site. This model has a 99.38% accuracy on the standard LFW face
- recognition benchmark, which is comparable to other state-of-the-art methods for face
- recognition as of February 2017.
-
- In this example, we will use dlib to do face clustering. Included in the examples
- folder is an image, bald_guys.jpg, which contains a bunch of photos of action movie
- stars Vin Diesel, The Rock, Jason Statham, and Bruce Willis. We will use dlib to
- automatically find their faces in the image and then to automatically determine how
- many people there are (4 in this case) as well as which faces belong to each person.
-
- Finally, this example uses a network with the loss_metric loss. Therefore, if you want
- to learn how to train your own models, or to get a general introduction to this loss
- layer, you should read the dnn_metric_learning_ex.cpp and
- dnn_metric_learning_on_images_ex.cpp examples.
-*/
-
-#include <dlib/dnn.h>
-#include <dlib/gui_widgets.h>
-#include <dlib/clustering.h>
-#include <dlib/string.h>
-#include <dlib/image_io.h>
-#include <dlib/image_processing/frontal_face_detector.h>
-
-using namespace dlib;
-using namespace std;
-
-// ----------------------------------------------------------------------------------------
-
-// The next bit of code defines a ResNet network. It's basically copied
-// and pasted from the dnn_imagenet_ex.cpp example, except we replaced the loss
-// layer with loss_metric and made the network somewhat smaller. Go read the introductory
-// dlib DNN examples to learn what all this stuff means.
-//
-// Also, the dnn_metric_learning_on_images_ex.cpp example shows how to train this network.
-// The dlib_face_recognition_resnet_model_v1 model used by this example was trained using
-// essentially the code shown in dnn_metric_learning_on_images_ex.cpp except the
-// mini-batches were made larger (35x15 instead of 5x5), the iterations without progress
-// was set to 10000, and the training dataset consisted of about 3 million images instead of
-// 55. Also, the input layer was locked to images of size 150.
-template <template <int,template<typename>class,int,typename> class block, int N, template<typename>class BN, typename SUBNET>
-using residual = add_prev1<block<N,BN,1,tag1<SUBNET>>>;
-
-template <template <int,template<typename>class,int,typename> class block, int N, template<typename>class BN, typename SUBNET>
-using residual_down = add_prev2<avg_pool<2,2,2,2,skip1<tag2<block<N,BN,2,tag1<SUBNET>>>>>>;
-
-template <int N, template <typename> class BN, int stride, typename SUBNET>
-using block = BN<con<N,3,3,1,1,relu<BN<con<N,3,3,stride,stride,SUBNET>>>>>;
-
-template <int N, typename SUBNET> using ares = relu<residual<block,N,affine,SUBNET>>;
-template <int N, typename SUBNET> using ares_down = relu<residual_down<block,N,affine,SUBNET>>;
-
-template <typename SUBNET> using alevel0 = ares_down<256,SUBNET>;
-template <typename SUBNET> using alevel1 = ares<256,ares<256,ares_down<256,SUBNET>>>;
-template <typename SUBNET> using alevel2 = ares<128,ares<128,ares_down<128,SUBNET>>>;
-template <typename SUBNET> using alevel3 = ares<64,ares<64,ares<64,ares_down<64,SUBNET>>>>;
-template <typename SUBNET> using alevel4 = ares<32,ares<32,ares<32,SUBNET>>>;
-
-using anet_type = loss_metric<fc_no_bias<128,avg_pool_everything<
- alevel0<
- alevel1<
- alevel2<
- alevel3<
- alevel4<
- max_pool<3,3,2,2,relu<affine<con<32,7,7,2,2,
- input_rgb_image_sized<150>
- >>>>>>>>>>>>;
-
-// ----------------------------------------------------------------------------------------
-
-std::vector<matrix<rgb_pixel>> jitter_image(
- const matrix<rgb_pixel>& img
-);
-
-// ----------------------------------------------------------------------------------------
-
-int main(int argc, char** argv) try
-{
- if (argc != 2)
- {
- cout << "Run this example by invoking it like this: " << endl;
- cout << " ./dnn_face_recognition_ex faces/bald_guys.jpg" << endl;
- cout << endl;
- cout << "You will also need to get the face landmarking model file as well as " << endl;
- cout << "the face recognition model file. Download and then decompress these files from: " << endl;
- cout << "http://dlib.net/files/shape_predictor_5_face_landmarks.dat.bz2" << endl;
- cout << "http://dlib.net/files/dlib_face_recognition_resnet_model_v1.dat.bz2" << endl;
- cout << endl;
- return 1;
- }
-
- // The first thing we are going to do is load all our models. First, since we need to
- // find faces in the image we will need a face detector:
- frontal_face_detector detector = get_frontal_face_detector();
- // We will also use a face landmarking model to align faces to a standard pose: (see face_landmark_detection_ex.cpp for an introduction)
- shape_predictor sp;
- deserialize("shape_predictor_5_face_landmarks.dat") >> sp;
- // And finally we load the DNN responsible for face recognition.
- anet_type net;
- deserialize("dlib_face_recognition_resnet_model_v1.dat") >> net;
-
- matrix<rgb_pixel> img;
- load_image(img, argv[1]);
- // Display the raw image on the screen
- image_window win(img);
-
- // Run the face detector on the image of our action heroes, and for each face extract a
- // copy that has been normalized to 150x150 pixels in size and appropriately rotated
- // and centered.
- std::vector<matrix<rgb_pixel>> faces;
- for (auto face : detector(img))
- {
- auto shape = sp(img, face);
- matrix<rgb_pixel> face_chip;
- extract_image_chip(img, get_face_chip_details(shape,150,0.25), face_chip);
- faces.push_back(move(face_chip));
- // Also put some boxes on the faces so we can see that the detector is finding
- // them.
- win.add_overlay(face);
- }
-
- if (faces.size() == 0)
- {
- cout << "No faces found in image!" << endl;
- return 1;
- }
-
- // This call asks the DNN to convert each face image in faces into a 128D vector.
- // In this 128D vector space, images from the same person will be close to each other
- // but vectors from different people will be far apart. So we can use these vectors to
- // identify if a pair of images are from the same person or from different people.
- std::vector<matrix<float,0,1>> face_descriptors = net(faces);
-
-
- // In particular, one simple thing we can do is face clustering. This next bit of code
- // creates a graph of connected faces and then uses the Chinese whispers graph clustering
- // algorithm to identify how many people there are and which faces belong to whom.
- std::vector<sample_pair> edges;
- for (size_t i = 0; i < face_descriptors.size(); ++i)
- {
- for (size_t j = i; j < face_descriptors.size(); ++j)
- {
- // Faces are connected in the graph if they are close enough. Here we check if
- // the distance between two face descriptors is less than 0.6, which is the
- // decision threshold the network was trained to use. Although you can
- // certainly use any other threshold you find useful.
- if (length(face_descriptors[i]-face_descriptors[j]) < 0.6)
- edges.push_back(sample_pair(i,j));
- }
- }
- std::vector<unsigned long> labels;
- const auto num_clusters = chinese_whispers(edges, labels);
- // This will correctly indicate that there are 4 people in the image.
- cout << "number of people found in the image: "<< num_clusters << endl;
-
-
- // Now let's display the face clustering results on the screen. You will see that it
- // correctly grouped all the faces.
- std::vector<image_window> win_clusters(num_clusters);
- for (size_t cluster_id = 0; cluster_id < num_clusters; ++cluster_id)
- {
- std::vector<matrix<rgb_pixel>> temp;
- for (size_t j = 0; j < labels.size(); ++j)
- {
- if (cluster_id == labels[j])
- temp.push_back(faces[j]);
- }
- win_clusters[cluster_id].set_title("face cluster " + cast_to_string(cluster_id));
- win_clusters[cluster_id].set_image(tile_images(temp));
- }
-
-
-
-
- // Finally, let's print one of the face descriptors to the screen.
- cout << "face descriptor for one face: " << trans(face_descriptors[0]) << endl;
-
- // It should also be noted that face recognition accuracy can be improved if jittering
- // is used when creating face descriptors. In particular, to get 99.38% on the LFW
- // benchmark you need to use the jitter_image() routine to compute the descriptors,
- // like so:
- matrix<float,0,1> face_descriptor = mean(mat(net(jitter_image(faces[0]))));
- cout << "jittered face descriptor for one face: " << trans(face_descriptor) << endl;
- // If you use the model without jittering, as we did when clustering the bald guys, it
- // gets an accuracy of 99.13% on the LFW benchmark. So jittering makes the whole
- // procedure a little more accurate but makes face descriptor calculation slower.
-
-
- cout << "hit enter to terminate" << endl;
- cin.get();
-}
-catch (std::exception& e)
-{
- cout << e.what() << endl;
-}
-
-// ----------------------------------------------------------------------------------------
-
-std::vector<matrix<rgb_pixel>> jitter_image(
- const matrix<rgb_pixel>& img
-)
-{
- // All this function does is make 100 copies of img, all slightly jittered by being
- // zoomed, rotated, and translated a little bit differently. They are also randomly
- // mirrored left to right.
- thread_local dlib::rand rnd;
-
- std::vector<matrix<rgb_pixel>> crops;
- for (int i = 0; i < 100; ++i)
- crops.push_back(jitter_image(img,rnd));
-
- return crops;
-}
-
-// ----------------------------------------------------------------------------------------
-
diff --git a/ml/dlib/examples/dnn_imagenet_ex.cpp b/ml/dlib/examples/dnn_imagenet_ex.cpp
deleted file mode 100644
index d1fa82823..000000000
--- a/ml/dlib/examples/dnn_imagenet_ex.cpp
+++ /dev/null
@@ -1,171 +0,0 @@
-// The contents of this file are in the public domain. See LICENSE_FOR_EXAMPLE_PROGRAMS.txt
-/*
- This example shows how to classify an image into one of the 1000 imagenet
- categories using the deep learning tools from the dlib C++ Library. We will
- use the pretrained ResNet34 model available on the dlib website.
-
- The ResNet34 architecture is from the paper Deep Residual Learning for Image
- Recognition by He, Zhang, Ren, and Sun. The model file that comes with dlib
- was trained using the dnn_imagenet_train_ex.cpp program on a Titan X for
- about 2 weeks. This pretrained model has a top5 error of 7.572% on the 2012
- imagenet validation dataset.
-
- For an introduction to dlib's DNN module read the dnn_introduction_ex.cpp and
- dnn_introduction2_ex.cpp example programs.
-
-
- Finally, these tools will use CUDA and cuDNN to drastically accelerate
- network training and testing. CMake should automatically find them if they
- are installed and configure things appropriately. If not, the program will
- still run but will be much slower to execute.
-*/
-
-
-
-#include <dlib/dnn.h>
-#include <iostream>
-#include <dlib/data_io.h>
-#include <dlib/gui_widgets.h>
-#include <dlib/image_transforms.h>
-
-using namespace std;
-using namespace dlib;
-
-// ----------------------------------------------------------------------------------------
-
-// This block of statements defines the resnet-34 network
-
-template <template <int,template<typename>class,int,typename> class block, int N, template<typename>class BN, typename SUBNET>
-using residual = add_prev1<block<N,BN,1,tag1<SUBNET>>>;
-
-template <template <int,template<typename>class,int,typename> class block, int N, template<typename>class BN, typename SUBNET>
-using residual_down = add_prev2<avg_pool<2,2,2,2,skip1<tag2<block<N,BN,2,tag1<SUBNET>>>>>>;
-
-template <int N, template <typename> class BN, int stride, typename SUBNET>
-using block = BN<con<N,3,3,1,1,relu<BN<con<N,3,3,stride,stride,SUBNET>>>>>;
-
-template <int N, typename SUBNET> using ares = relu<residual<block,N,affine,SUBNET>>;
-template <int N, typename SUBNET> using ares_down = relu<residual_down<block,N,affine,SUBNET>>;
-
-template <typename SUBNET> using level1 = ares<512,ares<512,ares_down<512,SUBNET>>>;
-template <typename SUBNET> using level2 = ares<256,ares<256,ares<256,ares<256,ares<256,ares_down<256,SUBNET>>>>>>;
-template <typename SUBNET> using level3 = ares<128,ares<128,ares<128,ares_down<128,SUBNET>>>>;
-template <typename SUBNET> using level4 = ares<64,ares<64,ares<64,SUBNET>>>;
-
-using anet_type = loss_multiclass_log<fc<1000,avg_pool_everything<
- level1<
- level2<
- level3<
- level4<
- max_pool<3,3,2,2,relu<affine<con<64,7,7,2,2,
- input_rgb_image_sized<227>
- >>>>>>>>>>>;
-
-// ----------------------------------------------------------------------------------------
-
-rectangle make_random_cropping_rect_resnet(
- const matrix<rgb_pixel>& img,
- dlib::rand& rnd
-)
-{
- // figure out what rectangle we want to crop from the image
- double mins = 0.466666666, maxs = 0.875;
- auto scale = mins + rnd.get_random_double()*(maxs-mins);
- auto size = scale*std::min(img.nr(), img.nc());
- rectangle rect(size, size);
- // randomly shift the box around
- point offset(rnd.get_random_32bit_number()%(img.nc()-rect.width()),
- rnd.get_random_32bit_number()%(img.nr()-rect.height()));
- return move_rect(rect, offset);
-}
-
-// ----------------------------------------------------------------------------------------
-
-void randomly_crop_images (
- const matrix<rgb_pixel>& img,
- dlib::array<matrix<rgb_pixel>>& crops,
- dlib::rand& rnd,
- long num_crops
-)
-{
- std::vector<chip_details> dets;
- for (long i = 0; i < num_crops; ++i)
- {
- auto rect = make_random_cropping_rect_resnet(img, rnd);
- dets.push_back(chip_details(rect, chip_dims(227,227)));
- }
-
- extract_image_chips(img, dets, crops);
-
- for (auto&& img : crops)
- {
- // Also randomly flip the image
- if (rnd.get_random_double() > 0.5)
- img = fliplr(img);
-
- // And then randomly adjust the colors.
- apply_random_color_offset(img, rnd);
- }
-}
-
-// ----------------------------------------------------------------------------------------
-
-int main(int argc, char** argv) try
-{
- if (argc == 1)
- {
- cout << "Give this program image files as command line arguments.\n" << endl;
- cout << "You will also need a copy of the file resnet34_1000_imagenet_classifier.dnn " << endl;
- cout << "available at http://dlib.net/files/resnet34_1000_imagenet_classifier.dnn.bz2" << endl;
- cout << endl;
- return 1;
- }
-
- std::vector<string> labels;
- anet_type net;
- deserialize("resnet34_1000_imagenet_classifier.dnn") >> net >> labels;
-
- // Make a network with softmax as the final layer. We don't have to do this
- // if we just want to output the single best prediction, since the anet_type
- // already does this. But if we instead want to get the probability of each
- // class as output we need to replace the last layer of the network with a
- // softmax layer, which we do as follows:
- softmax<anet_type::subnet_type> snet;
- snet.subnet() = net.subnet();
-
- dlib::array<matrix<rgb_pixel>> images;
- matrix<rgb_pixel> img, crop;
-
- dlib::rand rnd;
- image_window win;
-
- // Read images from the command prompt and print the top 5 best labels for each.
- for (int i = 1; i < argc; ++i)
- {
- load_image(img, argv[i]);
- const int num_crops = 16;
- // Grab 16 random crops from the image. We will run all of them through the
- // network and average the results.
- randomly_crop_images(img, images, rnd, num_crops);
- // p(i) == the probability the image contains object of class i.
- matrix<float,1,1000> p = sum_rows(mat(snet(images.begin(), images.end())))/num_crops;
-
- win.set_image(img);
- // Print the 5 most probable labels
- for (int k = 0; k < 5; ++k)
- {
- unsigned long predicted_label = index_of_max(p);
- cout << p(predicted_label) << ": " << labels[predicted_label] << endl;
- p(predicted_label) = 0;
- }
-
- cout << "Hit enter to process the next image";
- cin.get();
- }
-
-}
-catch(std::exception& e)
-{
- cout << e.what() << endl;
-}
-
diff --git a/ml/dlib/examples/dnn_imagenet_train_ex.cpp b/ml/dlib/examples/dnn_imagenet_train_ex.cpp
deleted file mode 100644
index e672018d3..000000000
--- a/ml/dlib/examples/dnn_imagenet_train_ex.cpp
+++ /dev/null
@@ -1,368 +0,0 @@
-// The contents of this file are in the public domain. See LICENSE_FOR_EXAMPLE_PROGRAMS.txt
-/*
- This program was used to train the resnet34_1000_imagenet_classifier.dnn
- network used by the dnn_imagenet_ex.cpp example program.
-
- You should be familiar with dlib's DNN module before reading this example
- program. So read dnn_introduction_ex.cpp and dnn_introduction2_ex.cpp first.
-*/
-
-
-
-#include <dlib/dnn.h>
-#include <iostream>
-#include <dlib/data_io.h>
-#include <dlib/image_transforms.h>
-#include <dlib/dir_nav.h>
-#include <iterator>
-#include <thread>
-
-using namespace std;
-using namespace dlib;
-
-// ----------------------------------------------------------------------------------------
-
-template <template <int,template<typename>class,int,typename> class block, int N, template<typename>class BN, typename SUBNET>
-using residual = add_prev1<block<N,BN,1,tag1<SUBNET>>>;
-
-template <template <int,template<typename>class,int,typename> class block, int N, template<typename>class BN, typename SUBNET>
-using residual_down = add_prev2<avg_pool<2,2,2,2,skip1<tag2<block<N,BN,2,tag1<SUBNET>>>>>>;
-
-template <int N, template <typename> class BN, int stride, typename SUBNET>
-using block = BN<con<N,3,3,1,1,relu<BN<con<N,3,3,stride,stride,SUBNET>>>>>;
-
-
-template <int N, typename SUBNET> using res = relu<residual<block,N,bn_con,SUBNET>>;
-template <int N, typename SUBNET> using ares = relu<residual<block,N,affine,SUBNET>>;
-template <int N, typename SUBNET> using res_down = relu<residual_down<block,N,bn_con,SUBNET>>;
-template <int N, typename SUBNET> using ares_down = relu<residual_down<block,N,affine,SUBNET>>;
-
-
-// ----------------------------------------------------------------------------------------
-
-template <typename SUBNET> using level1 = res<512,res<512,res_down<512,SUBNET>>>;
-template <typename SUBNET> using level2 = res<256,res<256,res<256,res<256,res<256,res_down<256,SUBNET>>>>>>;
-template <typename SUBNET> using level3 = res<128,res<128,res<128,res_down<128,SUBNET>>>>;
-template <typename SUBNET> using level4 = res<64,res<64,res<64,SUBNET>>>;
-
-template <typename SUBNET> using alevel1 = ares<512,ares<512,ares_down<512,SUBNET>>>;
-template <typename SUBNET> using alevel2 = ares<256,ares<256,ares<256,ares<256,ares<256,ares_down<256,SUBNET>>>>>>;
-template <typename SUBNET> using alevel3 = ares<128,ares<128,ares<128,ares_down<128,SUBNET>>>>;
-template <typename SUBNET> using alevel4 = ares<64,ares<64,ares<64,SUBNET>>>;
-
-// training network type
-using net_type = loss_multiclass_log<fc<1000,avg_pool_everything<
- level1<
- level2<
- level3<
- level4<
- max_pool<3,3,2,2,relu<bn_con<con<64,7,7,2,2,
- input_rgb_image_sized<227>
- >>>>>>>>>>>;
-
-// testing network type (replaced batch normalization with fixed affine transforms)
-using anet_type = loss_multiclass_log<fc<1000,avg_pool_everything<
- alevel1<
- alevel2<
- alevel3<
- alevel4<
- max_pool<3,3,2,2,relu<affine<con<64,7,7,2,2,
- input_rgb_image_sized<227>
- >>>>>>>>>>>;
-
-// ----------------------------------------------------------------------------------------
-
-rectangle make_random_cropping_rect_resnet(
- const matrix<rgb_pixel>& img,
- dlib::rand& rnd
-)
-{
- // figure out what rectangle we want to crop from the image
- double mins = 0.466666666, maxs = 0.875;
- auto scale = mins + rnd.get_random_double()*(maxs-mins);
- auto size = scale*std::min(img.nr(), img.nc());
- rectangle rect(size, size);
- // randomly shift the box around
- point offset(rnd.get_random_32bit_number()%(img.nc()-rect.width()),
- rnd.get_random_32bit_number()%(img.nr()-rect.height()));
- return move_rect(rect, offset);
-}
-
-// ----------------------------------------------------------------------------------------
-
-void randomly_crop_image (
- const matrix<rgb_pixel>& img,
- matrix<rgb_pixel>& crop,
- dlib::rand& rnd
-)
-{
- auto rect = make_random_cropping_rect_resnet(img, rnd);
-
- // now crop it out as a 227x227 image.
- extract_image_chip(img, chip_details(rect, chip_dims(227,227)), crop);
-
- // Also randomly flip the image
- if (rnd.get_random_double() > 0.5)
- crop = fliplr(crop);
-
- // And then randomly adjust the colors.
- apply_random_color_offset(crop, rnd);
-}
-
-void randomly_crop_images (
- const matrix<rgb_pixel>& img,
- dlib::array<matrix<rgb_pixel>>& crops,
- dlib::rand& rnd,
- long num_crops
-)
-{
- std::vector<chip_details> dets;
- for (long i = 0; i < num_crops; ++i)
- {
- auto rect = make_random_cropping_rect_resnet(img, rnd);
- dets.push_back(chip_details(rect, chip_dims(227,227)));
- }
-
- extract_image_chips(img, dets, crops);
-
- for (auto&& img : crops)
- {
- // Also randomly flip the image
- if (rnd.get_random_double() > 0.5)
- img = fliplr(img);
-
- // And then randomly adjust the colors.
- apply_random_color_offset(img, rnd);
- }
-}
-
-// ----------------------------------------------------------------------------------------
-
-struct image_info
-{
- string filename;
- string label;
- long numeric_label;
-};
-
-std::vector<image_info> get_imagenet_train_listing(
- const std::string& images_folder
-)
-{
- std::vector<image_info> results;
- image_info temp;
- temp.numeric_label = 0;
- // We will loop over all the label types in the dataset, each is contained in a subfolder.
- auto subdirs = directory(images_folder).get_dirs();
- // But first, sort the sub directories so the numeric labels will be assigned in sorted order.
- std::sort(subdirs.begin(), subdirs.end());
- for (auto subdir : subdirs)
- {
- // Now get all the images in this label type
- temp.label = subdir.name();
- for (auto image_file : subdir.get_files())
- {
- temp.filename = image_file;
- results.push_back(temp);
- }
- ++temp.numeric_label;
- }
- return results;
-}
-
-std::vector<image_info> get_imagenet_val_listing(
- const std::string& imagenet_root_dir,
- const std::string& validation_images_file
-)
-{
- ifstream fin(validation_images_file);
- string label, filename;
- std::vector<image_info> results;
- image_info temp;
- temp.numeric_label = -1;
- while(fin >> label >> filename)
- {
- temp.filename = imagenet_root_dir+"/"+filename;
- if (!file_exists(temp.filename))
- {
- cerr << "file doesn't exist! " << temp.filename << endl;
- exit(1);
- }
- if (label != temp.label)
- ++temp.numeric_label;
-
- temp.label = label;
- results.push_back(temp);
- }
-
- return results;
-}
-
-// ----------------------------------------------------------------------------------------
-
-int main(int argc, char** argv) try
-{
- if (argc != 3)
- {
- cout << "To run this program you need a copy of the imagenet ILSVRC2015 dataset and" << endl;
- cout << "also the file http://dlib.net/files/imagenet2015_validation_images.txt.bz2" << endl;
- cout << endl;
- cout << "With those things, you call this program like this: " << endl;
- cout << "./dnn_imagenet_train_ex /path/to/ILSVRC2015 imagenet2015_validation_images.txt" << endl;
- return 1;
- }
-
- cout << "\nSCANNING IMAGENET DATASET\n" << endl;
-
- auto listing = get_imagenet_train_listing(string(argv[1])+"/Data/CLS-LOC/train/");
- cout << "images in dataset: " << listing.size() << endl;
- const auto number_of_classes = listing.back().numeric_label+1;
- if (listing.size() == 0 || number_of_classes != 1000)
- {
- cout << "Didn't find the imagenet dataset. " << endl;
- return 1;
- }
-
- set_dnn_prefer_smallest_algorithms();
-
-
- const double initial_learning_rate = 0.1;
- const double weight_decay = 0.0001;
- const double momentum = 0.9;
-
- net_type net;
- dnn_trainer<net_type> trainer(net,sgd(weight_decay, momentum));
- trainer.be_verbose();
- trainer.set_learning_rate(initial_learning_rate);
- trainer.set_synchronization_file("imagenet_trainer_state_file.dat", std::chrono::minutes(10));
- // This threshold is probably excessively large. You could likely get good results
- // with a smaller value but if you aren't in a hurry this value will surely work well.
- trainer.set_iterations_without_progress_threshold(20000);
- // Since the progress threshold is so large might as well set the batch normalization
- // stats window to something big too.
- set_all_bn_running_stats_window_sizes(net, 1000);
-
- std::vector<matrix<rgb_pixel>> samples;
- std::vector<unsigned long> labels;
-
- // Start a bunch of threads that read images from disk and pull out random crops. It's
- // important to be sure to feed the GPU fast enough to keep it busy. Using multiple
- // thread for this kind of data preparation helps us do that. Each thread puts the
- // crops into the data queue.
- dlib::pipe<std::pair<image_info,matrix<rgb_pixel>>> data(200);
- auto f = [&data, &listing](time_t seed)
- {
- dlib::rand rnd(time(0)+seed);
- matrix<rgb_pixel> img;
- std::pair<image_info, matrix<rgb_pixel>> temp;
- while(data.is_enabled())
- {
- temp.first = listing[rnd.get_random_32bit_number()%listing.size()];
- load_image(img, temp.first.filename);
- randomly_crop_image(img, temp.second, rnd);
- data.enqueue(temp);
- }
- };
- std::thread data_loader1([f](){ f(1); });
- std::thread data_loader2([f](){ f(2); });
- std::thread data_loader3([f](){ f(3); });
- std::thread data_loader4([f](){ f(4); });
-
- // The main training loop. Keep making mini-batches and giving them to the trainer.
- // We will run until the learning rate has dropped by a factor of 1e-3.
- while(trainer.get_learning_rate() >= initial_learning_rate*1e-3)
- {
- samples.clear();
- labels.clear();
-
- // make a 160 image mini-batch
- std::pair<image_info, matrix<rgb_pixel>> img;
- while(samples.size() < 160)
- {
- data.dequeue(img);
-
- samples.push_back(std::move(img.second));
- labels.push_back(img.first.numeric_label);
- }
-
- trainer.train_one_step(samples, labels);
- }
-
- // Training done, tell threads to stop and make sure to wait for them to finish before
- // moving on.
- data.disable();
- data_loader1.join();
- data_loader2.join();
- data_loader3.join();
- data_loader4.join();
-
- // also wait for threaded processing to stop in the trainer.
- trainer.get_net();
-
- net.clean();
- cout << "saving network" << endl;
- serialize("resnet34.dnn") << net;
-
-
-
-
-
-
- // Now test the network on the imagenet validation dataset. First, make a testing
- // network with softmax as the final layer. We don't have to do this if we just wanted
- // to test the "top1 accuracy" since the normal network outputs the class prediction.
- // But this snet object will make getting the top5 predictions easy as it directly
- // outputs the probability of each class as its final output.
- softmax<anet_type::subnet_type> snet; snet.subnet() = net.subnet();
-
- cout << "Testing network on imagenet validation dataset..." << endl;
- int num_right = 0;
- int num_wrong = 0;
- int num_right_top1 = 0;
- int num_wrong_top1 = 0;
- dlib::rand rnd(time(0));
- // loop over all the imagenet validation images
- for (auto l : get_imagenet_val_listing(argv[1], argv[2]))
- {
- dlib::array<matrix<rgb_pixel>> images;
- matrix<rgb_pixel> img;
- load_image(img, l.filename);
- // Grab 16 random crops from the image. We will run all of them through the
- // network and average the results.
- const int num_crops = 16;
- randomly_crop_images(img, images, rnd, num_crops);
- // p(i) == the probability the image contains object of class i.
- matrix<float,1,1000> p = sum_rows(mat(snet(images.begin(), images.end())))/num_crops;
-
- // check top 1 accuracy
- if (index_of_max(p) == l.numeric_label)
- ++num_right_top1;
- else
- ++num_wrong_top1;
-
- // check top 5 accuracy
- bool found_match = false;
- for (int k = 0; k < 5; ++k)
- {
- long predicted_label = index_of_max(p);
- p(predicted_label) = 0;
- if (predicted_label == l.numeric_label)
- {
- found_match = true;
- break;
- }
-
- }
- if (found_match)
- ++num_right;
- else
- ++num_wrong;
- }
- cout << "val top5 accuracy: " << num_right/(double)(num_right+num_wrong) << endl;
- cout << "val top1 accuracy: " << num_right_top1/(double)(num_right_top1+num_wrong_top1) << endl;
-}
-catch(std::exception& e)
-{
- cout << e.what() << endl;
-}
-
diff --git a/ml/dlib/examples/dnn_inception_ex.cpp b/ml/dlib/examples/dnn_inception_ex.cpp
deleted file mode 100644
index 6b2c1727a..000000000
--- a/ml/dlib/examples/dnn_inception_ex.cpp
+++ /dev/null
@@ -1,154 +0,0 @@
-// The contents of this file are in the public domain. See LICENSE_FOR_EXAMPLE_PROGRAMS.txt
-/*
- This is an example illustrating the use of the deep learning tools from the
- dlib C++ Library. I'm assuming you have already read the introductory
- dnn_introduction_ex.cpp and dnn_introduction2_ex.cpp examples. In this
- example we are going to show how to create inception networks.
-
- An inception network is composed of inception blocks of the form:
-
- input from SUBNET
- / | \
- / | \
- block1 block2 ... blockN
- \ | /
- \ | /
- concatenate tensors from blocks
- |
- output
-
- That is, an inception block runs a number of smaller networks (e.g. block1,
- block2) and then concatenates their results. For further reading refer to:
- Szegedy, Christian, et al. "Going deeper with convolutions." Proceedings of
- the IEEE Conference on Computer Vision and Pattern Recognition. 2015.
-*/
-
-#include <dlib/dnn.h>
-#include <iostream>
-#include <dlib/data_io.h>
-
-using namespace std;
-using namespace dlib;
-
-// Inception layer has some different convolutions inside. Here we define
-// blocks as convolutions with different kernel size that we will use in
-// inception layer block.
-template <typename SUBNET> using block_a1 = relu<con<10,1,1,1,1,SUBNET>>;
-template <typename SUBNET> using block_a2 = relu<con<10,3,3,1,1,relu<con<16,1,1,1,1,SUBNET>>>>;
-template <typename SUBNET> using block_a3 = relu<con<10,5,5,1,1,relu<con<16,1,1,1,1,SUBNET>>>>;
-template <typename SUBNET> using block_a4 = relu<con<10,1,1,1,1,max_pool<3,3,1,1,SUBNET>>>;
-
-// Here is inception layer definition. It uses different blocks to process input
-// and returns combined output. Dlib includes a number of these inceptionN
-// layer types which are themselves created using concat layers.
-template <typename SUBNET> using incept_a = inception4<block_a1,block_a2,block_a3,block_a4, SUBNET>;
-
-// Network can have inception layers of different structure. It will work
-// properly so long as all the sub-blocks inside a particular inception block
-// output tensors with the same number of rows and columns.
-template <typename SUBNET> using block_b1 = relu<con<4,1,1,1,1,SUBNET>>;
-template <typename SUBNET> using block_b2 = relu<con<4,3,3,1,1,SUBNET>>;
-template <typename SUBNET> using block_b3 = relu<con<4,1,1,1,1,max_pool<3,3,1,1,SUBNET>>>;
-template <typename SUBNET> using incept_b = inception3<block_b1,block_b2,block_b3,SUBNET>;
-
-// Now we can define a simple network for classifying MNIST digits. We will
-// train and test this network in the code below.
-using net_type = loss_multiclass_log<
- fc<10,
- relu<fc<32,
- max_pool<2,2,2,2,incept_b<
- max_pool<2,2,2,2,incept_a<
- input<matrix<unsigned char>>
- >>>>>>>>;
-
-int main(int argc, char** argv) try
-{
- // This example is going to run on the MNIST dataset.
- if (argc != 2)
- {
- cout << "This example needs the MNIST dataset to run!" << endl;
- cout << "You can get MNIST from http://yann.lecun.com/exdb/mnist/" << endl;
- cout << "Download the 4 files that comprise the dataset, decompress them, and" << endl;
- cout << "put them in a folder. Then give that folder as input to this program." << endl;
- return 1;
- }
-
-
- std::vector<matrix<unsigned char>> training_images;
- std::vector<unsigned long> training_labels;
- std::vector<matrix<unsigned char>> testing_images;
- std::vector<unsigned long> testing_labels;
- load_mnist_dataset(argv[1], training_images, training_labels, testing_images, testing_labels);
-
-
- // Make an instance of our inception network.
- net_type net;
- cout << "The net has " << net.num_layers << " layers in it." << endl;
- cout << net << endl;
-
-
- cout << "Traning NN..." << endl;
- dnn_trainer<net_type> trainer(net);
- trainer.set_learning_rate(0.01);
- trainer.set_min_learning_rate(0.00001);
- trainer.set_mini_batch_size(128);
- trainer.be_verbose();
- trainer.set_synchronization_file("inception_sync", std::chrono::seconds(20));
- // Train the network. This might take a few minutes...
- trainer.train(training_images, training_labels);
-
- // At this point our net object should have learned how to classify MNIST images. But
- // before we try it out let's save it to disk. Note that, since the trainer has been
- // running images through the network, net will have a bunch of state in it related to
- // the last batch of images it processed (e.g. outputs from each layer). Since we
- // don't care about saving that kind of stuff to disk we can tell the network to forget
- // about that kind of transient data so that our file will be smaller. We do this by
- // "cleaning" the network before saving it.
- net.clean();
- serialize("mnist_network_inception.dat") << net;
- // Now if we later wanted to recall the network from disk we can simply say:
- // deserialize("mnist_network_inception.dat") >> net;
-
-
- // Now let's run the training images through the network. This statement runs all the
- // images through it and asks the loss layer to convert the network's raw output into
- // labels. In our case, these labels are the numbers between 0 and 9.
- std::vector<unsigned long> predicted_labels = net(training_images);
- int num_right = 0;
- int num_wrong = 0;
- // And then let's see if it classified them correctly.
- for (size_t i = 0; i < training_images.size(); ++i)
- {
- if (predicted_labels[i] == training_labels[i])
- ++num_right;
- else
- ++num_wrong;
-
- }
- cout << "training num_right: " << num_right << endl;
- cout << "training num_wrong: " << num_wrong << endl;
- cout << "training accuracy: " << num_right/(double)(num_right+num_wrong) << endl;
-
- // Let's also see if the network can correctly classify the testing images.
- // Since MNIST is an easy dataset, we should see 99% accuracy.
- predicted_labels = net(testing_images);
- num_right = 0;
- num_wrong = 0;
- for (size_t i = 0; i < testing_images.size(); ++i)
- {
- if (predicted_labels[i] == testing_labels[i])
- ++num_right;
- else
- ++num_wrong;
-
- }
- cout << "testing num_right: " << num_right << endl;
- cout << "testing num_wrong: " << num_wrong << endl;
- cout << "testing accuracy: " << num_right/(double)(num_right+num_wrong) << endl;
-
-}
-catch(std::exception& e)
-{
- cout << e.what() << endl;
-}
-
diff --git a/ml/dlib/examples/dnn_introduction2_ex.cpp b/ml/dlib/examples/dnn_introduction2_ex.cpp
deleted file mode 100644
index 70b6edee7..000000000
--- a/ml/dlib/examples/dnn_introduction2_ex.cpp
+++ /dev/null
@@ -1,388 +0,0 @@
-// The contents of this file are in the public domain. See LICENSE_FOR_EXAMPLE_PROGRAMS.txt
-/*
- This is an example illustrating the use of the deep learning tools from the
- dlib C++ Library. I'm assuming you have already read the dnn_introduction_ex.cpp
- example. So in this example program I'm going to go over a number of more
- advanced parts of the API, including:
- - Using multiple GPUs
- - Training on large datasets that don't fit in memory
- - Defining large networks
- - Accessing and configuring layers in a network
-*/
-
-#include <dlib/dnn.h>
-#include <iostream>
-#include <dlib/data_io.h>
-
-using namespace std;
-using namespace dlib;
-
-// ----------------------------------------------------------------------------------------
-
-// Let's start by showing how you can conveniently define large and complex
-// networks. The most important tool for doing this are C++'s alias templates.
-// These let us define new layer types that are combinations of a bunch of other
-// layers. These will form the building blocks for more complex networks.
-
-// So let's begin by defining the building block of a residual network (see
-// Figure 2 in Deep Residual Learning for Image Recognition by He, Zhang, Ren,
-// and Sun). We are going to decompose the residual block into a few alias
-// statements. First, we define the core block.
-
-// Here we have parameterized the "block" layer on a BN layer (nominally some
-// kind of batch normalization), the number of filter outputs N, and the stride
-// the block operates at.
-template <
- int N,
- template <typename> class BN,
- int stride,
- typename SUBNET
- >
-using block = BN<con<N,3,3,1,1,relu<BN<con<N,3,3,stride,stride,SUBNET>>>>>;
-
-// Next, we need to define the skip layer mechanism used in the residual network
-// paper. They create their blocks by adding the input tensor to the output of
-// each block. So we define an alias statement that takes a block and wraps it
-// with this skip/add structure.
-
-// Note the tag layer. This layer doesn't do any computation. It exists solely
-// so other layers can refer to it. In this case, the add_prev1 layer looks for
-// the tag1 layer and will take the tag1 output and add it to the input of the
-// add_prev1 layer. This combination allows us to implement skip and residual
-// style networks. We have also set the block stride to 1 in this statement.
-// The significance of that is explained next.
-template <
- template <int,template<typename>class,int,typename> class block,
- int N,
- template<typename>class BN,
- typename SUBNET
- >
-using residual = add_prev1<block<N,BN,1,tag1<SUBNET>>>;
-
-// Some residual blocks do downsampling. They do this by using a stride of 2
-// instead of 1. However, when downsampling we need to also take care to
-// downsample the part of the network that adds the original input to the output
-// or the sizes won't make sense (the network will still run, but the results
-// aren't as good). So here we define a downsampling version of residual. In
-// it, we make use of the skip1 layer. This layer simply outputs whatever is
-// output by the tag1 layer. Therefore, the skip1 layer (there are also skip2,
-// skip3, etc. in dlib) allows you to create branching network structures.
-
-// residual_down creates a network structure like this:
-/*
- input from SUBNET
- / \
- / \
- block downsample(using avg_pool)
- \ /
- \ /
- add tensors (using add_prev2 which adds the output of tag2 with avg_pool's output)
- |
- output
-*/
-template <
- template <int,template<typename>class,int,typename> class block,
- int N,
- template<typename>class BN,
- typename SUBNET
- >
-using residual_down = add_prev2<avg_pool<2,2,2,2,skip1<tag2<block<N,BN,2,tag1<SUBNET>>>>>>;
-
-
-
-// Now we can define 4 different residual blocks we will use in this example.
-// The first two are non-downsampling residual blocks while the last two
-// downsample. Also, res and res_down use batch normalization while ares and
-// ares_down have had the batch normalization replaced with simple affine
-// layers. We will use the affine version of the layers when testing our
-// networks.
-template <typename SUBNET> using res = relu<residual<block,8,bn_con,SUBNET>>;
-template <typename SUBNET> using ares = relu<residual<block,8,affine,SUBNET>>;
-template <typename SUBNET> using res_down = relu<residual_down<block,8,bn_con,SUBNET>>;
-template <typename SUBNET> using ares_down = relu<residual_down<block,8,affine,SUBNET>>;
-
-
-
-// Now that we have these convenient aliases, we can define a residual network
-// without a lot of typing. Note the use of a repeat layer. This special layer
-// type allows us to type repeat<9,res,SUBNET> instead of
-// res<res<res<res<res<res<res<res<res<SUBNET>>>>>>>>>. It will also prevent
-// the compiler from complaining about super deep template nesting when creating
-// large networks.
-const unsigned long number_of_classes = 10;
-using net_type = loss_multiclass_log<fc<number_of_classes,
- avg_pool_everything<
- res<res<res<res_down<
- repeat<9,res, // repeat this layer 9 times
- res_down<
- res<
- input<matrix<unsigned char>>
- >>>>>>>>>>;
-
-
-// And finally, let's define a residual network building block that uses
-// parametric ReLU units instead of regular ReLU.
-template <typename SUBNET>
-using pres = prelu<add_prev1<bn_con<con<8,3,3,1,1,prelu<bn_con<con<8,3,3,1,1,tag1<SUBNET>>>>>>>>;
-
-// ----------------------------------------------------------------------------------------
-
-int main(int argc, char** argv) try
-{
- if (argc != 2)
- {
- cout << "This example needs the MNIST dataset to run!" << endl;
- cout << "You can get MNIST from http://yann.lecun.com/exdb/mnist/" << endl;
- cout << "Download the 4 files that comprise the dataset, decompress them, and" << endl;
- cout << "put them in a folder. Then give that folder as input to this program." << endl;
- return 1;
- }
-
- std::vector<matrix<unsigned char>> training_images;
- std::vector<unsigned long> training_labels;
- std::vector<matrix<unsigned char>> testing_images;
- std::vector<unsigned long> testing_labels;
- load_mnist_dataset(argv[1], training_images, training_labels, testing_images, testing_labels);
-
-
- // dlib uses cuDNN under the covers. One of the features of cuDNN is the
- // option to use slower methods that use less RAM or faster methods that use
- // a lot of RAM. If you find that you run out of RAM on your graphics card
- // then you can call this function and we will request the slower but more
- // RAM frugal cuDNN algorithms.
- set_dnn_prefer_smallest_algorithms();
-
-
- // Create a network as defined above. This network will produce 10 outputs
- // because that's how we defined net_type. However, fc layers can have the
- // number of outputs they produce changed at runtime.
- net_type net;
- // So if you wanted to use the same network but override the number of
- // outputs at runtime you can do so like this:
- net_type net2(num_fc_outputs(15));
-
- // Now, let's imagine we wanted to replace some of the relu layers with
- // prelu layers. We might do it like this:
- using net_type2 = loss_multiclass_log<fc<number_of_classes,
- avg_pool_everything<
- pres<res<res<res_down< // 2 prelu layers here
- tag4<repeat<9,pres, // 9 groups, each containing 2 prelu layers
- res_down<
- res<
- input<matrix<unsigned char>>
- >>>>>>>>>>>;
-
- // prelu layers have a floating point parameter. If you want to set it to
- // something other than its default value you can do so like this:
- net_type2 pnet(prelu_(0.2),
- prelu_(0.25),
- repeat_group(prelu_(0.3),prelu_(0.4)) // Initialize all the prelu instances in the repeat
- // layer. repeat_group() is needed to group the
- // things that are part of repeat's block.
- );
- // As you can see, a network will greedily assign things given to its
- // constructor to the layers inside itself. The assignment is done in the
- // order the layers are defined, but it will skip layers where the
- // assignment doesn't make sense.
-
- // Now let's print the details of the pnet to the screen and inspect it.
- cout << "The pnet has " << pnet.num_layers << " layers in it." << endl;
- cout << pnet << endl;
- // These print statements will output this (I've truncated it since it's
- // long, but you get the idea):
- /*
- The pnet has 131 layers in it.
- layer<0> loss_multiclass_log
- layer<1> fc (num_outputs=10) learning_rate_mult=1 weight_decay_mult=1 bias_learning_rate_mult=1 bias_weight_decay_mult=0
- layer<2> avg_pool (nr=0, nc=0, stride_y=1, stride_x=1, padding_y=0, padding_x=0)
- layer<3> prelu (initial_param_value=0.2)
- layer<4> add_prev1
- layer<5> bn_con eps=1e-05 learning_rate_mult=1 weight_decay_mult=0 bias_learning_rate_mult=1 bias_weight_decay_mult=1
- layer<6> con (num_filters=8, nr=3, nc=3, stride_y=1, stride_x=1, padding_y=1, padding_x=1) learning_rate_mult=1 weight_decay_mult=1 bias_learning_rate_mult=1 bias_weight_decay_mult=0
- layer<7> prelu (initial_param_value=0.25)
- layer<8> bn_con eps=1e-05 learning_rate_mult=1 weight_decay_mult=0 bias_learning_rate_mult=1 bias_weight_decay_mult=1
- layer<9> con (num_filters=8, nr=3, nc=3, stride_y=1, stride_x=1, padding_y=1, padding_x=1) learning_rate_mult=1 weight_decay_mult=1 bias_learning_rate_mult=1 bias_weight_decay_mult=0
- layer<10> tag1
- ...
- layer<34> relu
- layer<35> bn_con eps=1e-05 learning_rate_mult=1 weight_decay_mult=0 bias_learning_rate_mult=1 bias_weight_decay_mult=1
- layer<36> con (num_filters=8, nr=3, nc=3, stride_y=2, stride_x=2, padding_y=0, padding_x=0) learning_rate_mult=1 weight_decay_mult=1 bias_learning_rate_mult=1 bias_weight_decay_mult=0
- layer<37> tag1
- layer<38> tag4
- layer<39> prelu (initial_param_value=0.3)
- layer<40> add_prev1
- layer<41> bn_con eps=1e-05 learning_rate_mult=1 weight_decay_mult=0 bias_learning_rate_mult=1 bias_weight_decay_mult=1
- ...
- layer<118> relu
- layer<119> bn_con eps=1e-05 learning_rate_mult=1 weight_decay_mult=0 bias_learning_rate_mult=1 bias_weight_decay_mult=1
- layer<120> con (num_filters=8, nr=3, nc=3, stride_y=2, stride_x=2, padding_y=0, padding_x=0) learning_rate_mult=1 weight_decay_mult=1 bias_learning_rate_mult=1 bias_weight_decay_mult=0
- layer<121> tag1
- layer<122> relu
- layer<123> add_prev1
- layer<124> bn_con eps=1e-05 learning_rate_mult=1 weight_decay_mult=0 bias_learning_rate_mult=1 bias_weight_decay_mult=1
- layer<125> con (num_filters=8, nr=3, nc=3, stride_y=1, stride_x=1, padding_y=1, padding_x=1) learning_rate_mult=1 weight_decay_mult=1 bias_learning_rate_mult=1 bias_weight_decay_mult=0
- layer<126> relu
- layer<127> bn_con eps=1e-05 learning_rate_mult=1 weight_decay_mult=0 bias_learning_rate_mult=1 bias_weight_decay_mult=1
- layer<128> con (num_filters=8, nr=3, nc=3, stride_y=1, stride_x=1, padding_y=1, padding_x=1) learning_rate_mult=1 weight_decay_mult=1 bias_learning_rate_mult=1 bias_weight_decay_mult=0
- layer<129> tag1
- layer<130> input<matrix>
- */
-
- // Now that we know the index numbers for each layer, we can access them
- // individually using layer<index>(pnet). For example, to access the output
- // tensor for the first prelu layer we can say:
- layer<3>(pnet).get_output();
- // Or to print the prelu parameter for layer 7 we can say:
- cout << "prelu param: "<< layer<7>(pnet).layer_details().get_initial_param_value() << endl;
-
- // We can also access layers by their type. This next statement finds the
- // first tag1 layer in pnet, and is therefore equivalent to calling
- // layer<10>(pnet):
- layer<tag1>(pnet);
- // The tag layers don't do anything at all and exist simply so you can tag
- // parts of your network and access them by layer<tag>(). You can also
- // index relative to a tag. So for example, to access the layer immediately
- // after tag4 you can say:
- layer<tag4,1>(pnet); // Equivalent to layer<38+1>(pnet).
-
- // Or to access the layer 2 layers after tag4:
- layer<tag4,2>(pnet);
- // Tagging is a very useful tool for making complex network structures. For
- // example, the add_prev1 layer is implemented internally by using a call to
- // layer<tag1>().
-
-
-
- // Ok, that's enough talk about defining and inspecting networks. Let's
- // talk about training networks!
-
- // The dnn_trainer will use SGD by default, but you can tell it to use
- // different solvers like adam with a weight decay of 0.0005 and the given
- // momentum parameters.
- dnn_trainer<net_type,adam> trainer(net,adam(0.0005, 0.9, 0.999));
- // Also, if you have multiple graphics cards you can tell the trainer to use
- // them together to make the training faster. For example, replacing the
- // above constructor call with this one would cause it to use GPU cards 0
- // and 1.
- //dnn_trainer<net_type,adam> trainer(net,adam(0.0005, 0.9, 0.999), {0,1});
-
- trainer.be_verbose();
- // While the trainer is running it keeps an eye on the training error. If
- // it looks like the error hasn't decreased for the last 2000 iterations it
- // will automatically reduce the learning rate by 0.1. You can change these
- // default parameters to some other values by calling these functions. Or
- // disable the automatic shrinking entirely by setting the shrink factor to 1.
- trainer.set_iterations_without_progress_threshold(2000);
- trainer.set_learning_rate_shrink_factor(0.1);
- // The learning rate will start at 1e-3.
- trainer.set_learning_rate(1e-3);
- trainer.set_synchronization_file("mnist_resnet_sync", std::chrono::seconds(100));
-
-
- // Now, what if your training dataset is so big it doesn't fit in RAM? You
- // make mini-batches yourself, any way you like, and you send them to the
- // trainer by repeatedly calling trainer.train_one_step().
- //
- // For example, the loop below stream MNIST data to out trainer.
- std::vector<matrix<unsigned char>> mini_batch_samples;
- std::vector<unsigned long> mini_batch_labels;
- dlib::rand rnd(time(0));
- // Loop until the trainer's automatic shrinking has shrunk the learning rate to 1e-6.
- // Given our settings, this means it will stop training after it has shrunk the
- // learning rate 3 times.
- while(trainer.get_learning_rate() >= 1e-6)
- {
- mini_batch_samples.clear();
- mini_batch_labels.clear();
-
- // make a 128 image mini-batch
- while(mini_batch_samples.size() < 128)
- {
- auto idx = rnd.get_random_32bit_number()%training_images.size();
- mini_batch_samples.push_back(training_images[idx]);
- mini_batch_labels.push_back(training_labels[idx]);
- }
-
- // Tell the trainer to update the network given this mini-batch
- trainer.train_one_step(mini_batch_samples, mini_batch_labels);
-
- // You can also feed validation data into the trainer by periodically
- // calling trainer.test_one_step(samples,labels). Unlike train_one_step(),
- // test_one_step() doesn't modify the network, it only computes the testing
- // error which it records internally. This testing error will then be print
- // in the verbose logging and will also determine when the trainer's
- // automatic learning rate shrinking happens. Therefore, test_one_step()
- // can be used to perform automatic early stopping based on held out data.
- }
-
- // When you call train_one_step(), the trainer will do its processing in a
- // separate thread. This allows the main thread to work on loading data
- // while the trainer is busy executing the mini-batches in parallel.
- // However, this also means we need to wait for any mini-batches that are
- // still executing to stop before we mess with the net object. Calling
- // get_net() performs the necessary synchronization.
- trainer.get_net();
-
-
- net.clean();
- serialize("mnist_res_network.dat") << net;
-
-
- // Now we have a trained network. However, it has batch normalization
- // layers in it. As is customary, we should replace these with simple
- // affine layers before we use the network. This can be accomplished by
- // making a network type which is identical to net_type but with the batch
- // normalization layers replaced with affine. For example:
- using test_net_type = loss_multiclass_log<fc<number_of_classes,
- avg_pool_everything<
- ares<ares<ares<ares_down<
- repeat<9,ares,
- ares_down<
- ares<
- input<matrix<unsigned char>>
- >>>>>>>>>>;
- // Then we can simply assign our trained net to our testing net.
- test_net_type tnet = net;
- // Or if you only had a file with your trained network you could deserialize
- // it directly into your testing network.
- deserialize("mnist_res_network.dat") >> tnet;
-
-
- // And finally, we can run the testing network over our data.
-
- std::vector<unsigned long> predicted_labels = tnet(training_images);
- int num_right = 0;
- int num_wrong = 0;
- for (size_t i = 0; i < training_images.size(); ++i)
- {
- if (predicted_labels[i] == training_labels[i])
- ++num_right;
- else
- ++num_wrong;
-
- }
- cout << "training num_right: " << num_right << endl;
- cout << "training num_wrong: " << num_wrong << endl;
- cout << "training accuracy: " << num_right/(double)(num_right+num_wrong) << endl;
-
- predicted_labels = tnet(testing_images);
- num_right = 0;
- num_wrong = 0;
- for (size_t i = 0; i < testing_images.size(); ++i)
- {
- if (predicted_labels[i] == testing_labels[i])
- ++num_right;
- else
- ++num_wrong;
-
- }
- cout << "testing num_right: " << num_right << endl;
- cout << "testing num_wrong: " << num_wrong << endl;
- cout << "testing accuracy: " << num_right/(double)(num_right+num_wrong) << endl;
-
-}
-catch(std::exception& e)
-{
- cout << e.what() << endl;
-}
-
diff --git a/ml/dlib/examples/dnn_introduction_ex.cpp b/ml/dlib/examples/dnn_introduction_ex.cpp
deleted file mode 100644
index 6ae3ddf73..000000000
--- a/ml/dlib/examples/dnn_introduction_ex.cpp
+++ /dev/null
@@ -1,170 +0,0 @@
-// The contents of this file are in the public domain. See LICENSE_FOR_EXAMPLE_PROGRAMS.txt
-/*
- This is an example illustrating the use of the deep learning tools from the
- dlib C++ Library. In it, we will train the venerable LeNet convolutional
- neural network to recognize hand written digits. The network will take as
- input a small image and classify it as one of the 10 numeric digits between
- 0 and 9.
-
- The specific network we will run is from the paper
- LeCun, Yann, et al. "Gradient-based learning applied to document recognition."
- Proceedings of the IEEE 86.11 (1998): 2278-2324.
- except that we replace the sigmoid non-linearities with rectified linear units.
-
- These tools will use CUDA and cuDNN to drastically accelerate network
- training and testing. CMake should automatically find them if they are
- installed and configure things appropriately. If not, the program will
- still run but will be much slower to execute.
-*/
-
-
-#include <dlib/dnn.h>
-#include <iostream>
-#include <dlib/data_io.h>
-
-using namespace std;
-using namespace dlib;
-
-int main(int argc, char** argv) try
-{
- // This example is going to run on the MNIST dataset.
- if (argc != 2)
- {
- cout << "This example needs the MNIST dataset to run!" << endl;
- cout << "You can get MNIST from http://yann.lecun.com/exdb/mnist/" << endl;
- cout << "Download the 4 files that comprise the dataset, decompress them, and" << endl;
- cout << "put them in a folder. Then give that folder as input to this program." << endl;
- return 1;
- }
-
-
- // MNIST is broken into two parts, a training set of 60000 images and a test set of
- // 10000 images. Each image is labeled so that we know what hand written digit is
- // depicted. These next statements load the dataset into memory.
- std::vector<matrix<unsigned char>> training_images;
- std::vector<unsigned long> training_labels;
- std::vector<matrix<unsigned char>> testing_images;
- std::vector<unsigned long> testing_labels;
- load_mnist_dataset(argv[1], training_images, training_labels, testing_images, testing_labels);
-
-
- // Now let's define the LeNet. Broadly speaking, there are 3 parts to a network
- // definition. The loss layer, a bunch of computational layers, and then an input
- // layer. You can see these components in the network definition below.
- //
- // The input layer here says the network expects to be given matrix<unsigned char>
- // objects as input. In general, you can use any dlib image or matrix type here, or
- // even define your own types by creating custom input layers.
- //
- // Then the middle layers define the computation the network will do to transform the
- // input into whatever we want. Here we run the image through multiple convolutions,
- // ReLU units, max pooling operations, and then finally a fully connected layer that
- // converts the whole thing into just 10 numbers.
- //
- // Finally, the loss layer defines the relationship between the network outputs, our 10
- // numbers, and the labels in our dataset. Since we selected loss_multiclass_log it
- // means we want to do multiclass classification with our network. Moreover, the
- // number of network outputs (i.e. 10) is the number of possible labels. Whichever
- // network output is largest is the predicted label. So for example, if the first
- // network output is largest then the predicted digit is 0, if the last network output
- // is largest then the predicted digit is 9.
- using net_type = loss_multiclass_log<
- fc<10,
- relu<fc<84,
- relu<fc<120,
- max_pool<2,2,2,2,relu<con<16,5,5,1,1,
- max_pool<2,2,2,2,relu<con<6,5,5,1,1,
- input<matrix<unsigned char>>
- >>>>>>>>>>>>;
- // This net_type defines the entire network architecture. For example, the block
- // relu<fc<84,SUBNET>> means we take the output from the subnetwork, pass it through a
- // fully connected layer with 84 outputs, then apply ReLU. Similarly, a block of
- // max_pool<2,2,2,2,relu<con<16,5,5,1,1,SUBNET>>> means we apply 16 convolutions with a
- // 5x5 filter size and 1x1 stride to the output of a subnetwork, then apply ReLU, then
- // perform max pooling with a 2x2 window and 2x2 stride.
-
-
-
- // So with that out of the way, we can make a network instance.
- net_type net;
- // And then train it using the MNIST data. The code below uses mini-batch stochastic
- // gradient descent with an initial learning rate of 0.01 to accomplish this.
- dnn_trainer<net_type> trainer(net);
- trainer.set_learning_rate(0.01);
- trainer.set_min_learning_rate(0.00001);
- trainer.set_mini_batch_size(128);
- trainer.be_verbose();
- // Since DNN training can take a long time, we can ask the trainer to save its state to
- // a file named "mnist_sync" every 20 seconds. This way, if we kill this program and
- // start it again it will begin where it left off rather than restarting the training
- // from scratch. This is because, when the program restarts, this call to
- // set_synchronization_file() will automatically reload the settings from mnist_sync if
- // the file exists.
- trainer.set_synchronization_file("mnist_sync", std::chrono::seconds(20));
- // Finally, this line begins training. By default, it runs SGD with our specified
- // learning rate until the loss stops decreasing. Then it reduces the learning rate by
- // a factor of 10 and continues running until the loss stops decreasing again. It will
- // keep doing this until the learning rate has dropped below the min learning rate
- // defined above or the maximum number of epochs as been executed (defaulted to 10000).
- trainer.train(training_images, training_labels);
-
- // At this point our net object should have learned how to classify MNIST images. But
- // before we try it out let's save it to disk. Note that, since the trainer has been
- // running images through the network, net will have a bunch of state in it related to
- // the last batch of images it processed (e.g. outputs from each layer). Since we
- // don't care about saving that kind of stuff to disk we can tell the network to forget
- // about that kind of transient data so that our file will be smaller. We do this by
- // "cleaning" the network before saving it.
- net.clean();
- serialize("mnist_network.dat") << net;
- // Now if we later wanted to recall the network from disk we can simply say:
- // deserialize("mnist_network.dat") >> net;
-
-
- // Now let's run the training images through the network. This statement runs all the
- // images through it and asks the loss layer to convert the network's raw output into
- // labels. In our case, these labels are the numbers between 0 and 9.
- std::vector<unsigned long> predicted_labels = net(training_images);
- int num_right = 0;
- int num_wrong = 0;
- // And then let's see if it classified them correctly.
- for (size_t i = 0; i < training_images.size(); ++i)
- {
- if (predicted_labels[i] == training_labels[i])
- ++num_right;
- else
- ++num_wrong;
-
- }
- cout << "training num_right: " << num_right << endl;
- cout << "training num_wrong: " << num_wrong << endl;
- cout << "training accuracy: " << num_right/(double)(num_right+num_wrong) << endl;
-
- // Let's also see if the network can correctly classify the testing images. Since
- // MNIST is an easy dataset, we should see at least 99% accuracy.
- predicted_labels = net(testing_images);
- num_right = 0;
- num_wrong = 0;
- for (size_t i = 0; i < testing_images.size(); ++i)
- {
- if (predicted_labels[i] == testing_labels[i])
- ++num_right;
- else
- ++num_wrong;
-
- }
- cout << "testing num_right: " << num_right << endl;
- cout << "testing num_wrong: " << num_wrong << endl;
- cout << "testing accuracy: " << num_right/(double)(num_right+num_wrong) << endl;
-
-
- // Finally, you can also save network parameters to XML files if you want to do
- // something with the network in another tool. For example, you could use dlib's
- // tools/convert_dlib_nets_to_caffe to convert the network to a caffe model.
- net_to_xml(net, "lenet.xml");
-}
-catch(std::exception& e)
-{
- cout << e.what() << endl;
-}
-
diff --git a/ml/dlib/examples/dnn_metric_learning_ex.cpp b/ml/dlib/examples/dnn_metric_learning_ex.cpp
deleted file mode 100644
index 54f2e6e8b..000000000
--- a/ml/dlib/examples/dnn_metric_learning_ex.cpp
+++ /dev/null
@@ -1,128 +0,0 @@
-// The contents of this file are in the public domain. See LICENSE_FOR_EXAMPLE_PROGRAMS.txt
-/*
- This is an example illustrating the use of the deep learning tools from the
- dlib C++ Library. In it, we will show how to use the loss_metric layer to do
- metric learning.
-
- The main reason you might want to use this kind of algorithm is because you
- would like to use a k-nearest neighbor classifier or similar algorithm, but
- you don't know a good way to calculate the distance between two things. A
- popular example would be face recognition. There are a whole lot of papers
- that train some kind of deep metric learning algorithm that embeds face
- images in some vector space where images of the same person are close to each
- other and images of different people are far apart. Then in that vector
- space it's very easy to do face recognition with some kind of k-nearest
- neighbor classifier.
-
- To keep this example as simple as possible we won't do face recognition.
- Instead, we will create a very simple network and use it to learn a mapping
- from 8D vectors to 2D vectors such that vectors with the same class labels
- are near each other. If you want to see a more complex example that learns
- the kind of network you would use for something like face recognition read
- the dnn_metric_learning_on_images_ex.cpp example.
-
- You should also have read the examples that introduce the dlib DNN API before
- continuing. These are dnn_introduction_ex.cpp and dnn_introduction2_ex.cpp.
-*/
-
-
-#include <dlib/dnn.h>
-#include <iostream>
-
-using namespace std;
-using namespace dlib;
-
-
-int main() try
-{
- // The API for doing metric learning is very similar to the API for
- // multi-class classification. In fact, the inputs are the same, a bunch of
- // labeled objects. So here we create our dataset. We make up some simple
- // vectors and label them with the integers 1,2,3,4. The specific values of
- // the integer labels don't matter.
- std::vector<matrix<double,0,1>> samples;
- std::vector<unsigned long> labels;
-
- // class 1 training vectors
- samples.push_back({1,0,0,0,0,0,0,0}); labels.push_back(1);
- samples.push_back({0,1,0,0,0,0,0,0}); labels.push_back(1);
-
- // class 2 training vectors
- samples.push_back({0,0,1,0,0,0,0,0}); labels.push_back(2);
- samples.push_back({0,0,0,1,0,0,0,0}); labels.push_back(2);
-
- // class 3 training vectors
- samples.push_back({0,0,0,0,1,0,0,0}); labels.push_back(3);
- samples.push_back({0,0,0,0,0,1,0,0}); labels.push_back(3);
-
- // class 4 training vectors
- samples.push_back({0,0,0,0,0,0,1,0}); labels.push_back(4);
- samples.push_back({0,0,0,0,0,0,0,1}); labels.push_back(4);
-
-
- // Make a network that simply learns a linear mapping from 8D vectors to 2D
- // vectors.
- using net_type = loss_metric<fc<2,input<matrix<double,0,1>>>>;
- net_type net;
- dnn_trainer<net_type> trainer(net);
- trainer.set_learning_rate(0.1);
-
- // It should be emphasized out that it's really important that each mini-batch contain
- // multiple instances of each class of object. This is because the metric learning
- // algorithm needs to consider pairs of objects that should be close as well as pairs
- // of objects that should be far apart during each training step. Here we just keep
- // training on the same small batch so this constraint is trivially satisfied.
- while(trainer.get_learning_rate() >= 1e-4)
- trainer.train_one_step(samples, labels);
-
- // Wait for training threads to stop
- trainer.get_net();
- cout << "done training" << endl;
-
-
- // Run all the samples through the network to get their 2D vector embeddings.
- std::vector<matrix<float,0,1>> embedded = net(samples);
-
- // Print the embedding for each sample to the screen. If you look at the
- // outputs carefully you should notice that they are grouped together in 2D
- // space according to their label.
- for (size_t i = 0; i < embedded.size(); ++i)
- cout << "label: " << labels[i] << "\t" << trans(embedded[i]);
-
- // Now, check if the embedding puts things with the same labels near each other and
- // things with different labels far apart.
- int num_right = 0;
- int num_wrong = 0;
- for (size_t i = 0; i < embedded.size(); ++i)
- {
- for (size_t j = i+1; j < embedded.size(); ++j)
- {
- if (labels[i] == labels[j])
- {
- // The loss_metric layer will cause things with the same label to be less
- // than net.loss_details().get_distance_threshold() distance from each
- // other. So we can use that distance value as our testing threshold for
- // "being near to each other".
- if (length(embedded[i]-embedded[j]) < net.loss_details().get_distance_threshold())
- ++num_right;
- else
- ++num_wrong;
- }
- else
- {
- if (length(embedded[i]-embedded[j]) >= net.loss_details().get_distance_threshold())
- ++num_right;
- else
- ++num_wrong;
- }
- }
- }
-
- cout << "num_right: "<< num_right << endl;
- cout << "num_wrong: "<< num_wrong << endl;
-}
-catch(std::exception& e)
-{
- cout << e.what() << endl;
-}
-
diff --git a/ml/dlib/examples/dnn_metric_learning_on_images_ex.cpp b/ml/dlib/examples/dnn_metric_learning_on_images_ex.cpp
deleted file mode 100644
index 4c3856ac6..000000000
--- a/ml/dlib/examples/dnn_metric_learning_on_images_ex.cpp
+++ /dev/null
@@ -1,340 +0,0 @@
-// The contents of this file are in the public domain. See LICENSE_FOR_EXAMPLE_PROGRAMS.txt
-/*
- This is an example illustrating the use of the deep learning tools from the
- dlib C++ Library. In it, we will show how to use the loss_metric layer to do
- metric learning on images.
-
- The main reason you might want to use this kind of algorithm is because you
- would like to use a k-nearest neighbor classifier or similar algorithm, but
- you don't know a good way to calculate the distance between two things. A
- popular example would be face recognition. There are a whole lot of papers
- that train some kind of deep metric learning algorithm that embeds face
- images in some vector space where images of the same person are close to each
- other and images of different people are far apart. Then in that vector
- space it's very easy to do face recognition with some kind of k-nearest
- neighbor classifier.
-
- In this example we will use a version of the ResNet network from the
- dnn_imagenet_ex.cpp example to learn to map images into some vector space where
- pictures of the same person are close and pictures of different people are far
- apart.
-
- You might want to read the simpler introduction to the deep metric learning
- API, dnn_metric_learning_ex.cpp, before reading this example. You should
- also have read the examples that introduce the dlib DNN API before
- continuing. These are dnn_introduction_ex.cpp and dnn_introduction2_ex.cpp.
-
-*/
-
-#include <dlib/dnn.h>
-#include <dlib/image_io.h>
-#include <dlib/misc_api.h>
-
-using namespace dlib;
-using namespace std;
-
-// ----------------------------------------------------------------------------------------
-
-// We will need to create some functions for loading data. This program will
-// expect to be given a directory structured as follows:
-// top_level_directory/
-// person1/
-// image1.jpg
-// image2.jpg
-// image3.jpg
-// person2/
-// image4.jpg
-// image5.jpg
-// image6.jpg
-// person3/
-// image7.jpg
-// image8.jpg
-// image9.jpg
-//
-// The specific folder and image names don't matter, nor does the number of folders or
-// images. What does matter is that there is a top level folder, which contains
-// subfolders, and each subfolder contains images of a single person.
-
-// This function spiders the top level directory and obtains a list of all the
-// image files.
-std::vector<std::vector<string>> load_objects_list (
- const string& dir
-)
-{
- std::vector<std::vector<string>> objects;
- for (auto subdir : directory(dir).get_dirs())
- {
- std::vector<string> imgs;
- for (auto img : subdir.get_files())
- imgs.push_back(img);
-
- if (imgs.size() != 0)
- objects.push_back(imgs);
- }
- return objects;
-}
-
-// This function takes the output of load_objects_list() as input and randomly
-// selects images for training. It should also be pointed out that it's really
-// important that each mini-batch contain multiple images of each person. This
-// is because the metric learning algorithm needs to consider pairs of images
-// that should be close (i.e. images of the same person) as well as pairs of
-// images that should be far apart (i.e. images of different people) during each
-// training step.
-void load_mini_batch (
- const size_t num_people, // how many different people to include
- const size_t samples_per_id, // how many images per person to select.
- dlib::rand& rnd,
- const std::vector<std::vector<string>>& objs,
- std::vector<matrix<rgb_pixel>>& images,
- std::vector<unsigned long>& labels
-)
-{
- images.clear();
- labels.clear();
- DLIB_CASSERT(num_people <= objs.size(), "The dataset doesn't have that many people in it.");
-
- std::vector<bool> already_selected(objs.size(), false);
- matrix<rgb_pixel> image;
- for (size_t i = 0; i < num_people; ++i)
- {
- size_t id = rnd.get_random_32bit_number()%objs.size();
- // don't pick a person we already added to the mini-batch
- while(already_selected[id])
- id = rnd.get_random_32bit_number()%objs.size();
- already_selected[id] = true;
-
- for (size_t j = 0; j < samples_per_id; ++j)
- {
- const auto& obj = objs[id][rnd.get_random_32bit_number()%objs[id].size()];
- load_image(image, obj);
- images.push_back(std::move(image));
- labels.push_back(id);
- }
- }
-
- // You might want to do some data augmentation at this point. Here we do some simple
- // color augmentation.
- for (auto&& crop : images)
- {
- disturb_colors(crop,rnd);
- // Jitter most crops
- if (rnd.get_random_double() > 0.1)
- crop = jitter_image(crop,rnd);
- }
-
-
- // All the images going into a mini-batch have to be the same size. And really, all
- // the images in your entire training dataset should be the same size for what we are
- // doing to make the most sense.
- DLIB_CASSERT(images.size() > 0);
- for (auto&& img : images)
- {
- DLIB_CASSERT(img.nr() == images[0].nr() && img.nc() == images[0].nc(),
- "All the images in a single mini-batch must be the same size.");
- }
-}
-
-// ----------------------------------------------------------------------------------------
-
-// The next page of code defines a ResNet network. It's basically copied
-// and pasted from the dnn_imagenet_ex.cpp example, except we replaced the loss
-// layer with loss_metric and make the network somewhat smaller.
-
-template <template <int,template<typename>class,int,typename> class block, int N, template<typename>class BN, typename SUBNET>
-using residual = add_prev1<block<N,BN,1,tag1<SUBNET>>>;
-
-template <template <int,template<typename>class,int,typename> class block, int N, template<typename>class BN, typename SUBNET>
-using residual_down = add_prev2<avg_pool<2,2,2,2,skip1<tag2<block<N,BN,2,tag1<SUBNET>>>>>>;
-
-template <int N, template <typename> class BN, int stride, typename SUBNET>
-using block = BN<con<N,3,3,1,1,relu<BN<con<N,3,3,stride,stride,SUBNET>>>>>;
-
-
-template <int N, typename SUBNET> using res = relu<residual<block,N,bn_con,SUBNET>>;
-template <int N, typename SUBNET> using ares = relu<residual<block,N,affine,SUBNET>>;
-template <int N, typename SUBNET> using res_down = relu<residual_down<block,N,bn_con,SUBNET>>;
-template <int N, typename SUBNET> using ares_down = relu<residual_down<block,N,affine,SUBNET>>;
-
-// ----------------------------------------------------------------------------------------
-
-template <typename SUBNET> using level0 = res_down<256,SUBNET>;
-template <typename SUBNET> using level1 = res<256,res<256,res_down<256,SUBNET>>>;
-template <typename SUBNET> using level2 = res<128,res<128,res_down<128,SUBNET>>>;
-template <typename SUBNET> using level3 = res<64,res<64,res<64,res_down<64,SUBNET>>>>;
-template <typename SUBNET> using level4 = res<32,res<32,res<32,SUBNET>>>;
-
-template <typename SUBNET> using alevel0 = ares_down<256,SUBNET>;
-template <typename SUBNET> using alevel1 = ares<256,ares<256,ares_down<256,SUBNET>>>;
-template <typename SUBNET> using alevel2 = ares<128,ares<128,ares_down<128,SUBNET>>>;
-template <typename SUBNET> using alevel3 = ares<64,ares<64,ares<64,ares_down<64,SUBNET>>>>;
-template <typename SUBNET> using alevel4 = ares<32,ares<32,ares<32,SUBNET>>>;
-
-
-// training network type
-using net_type = loss_metric<fc_no_bias<128,avg_pool_everything<
- level0<
- level1<
- level2<
- level3<
- level4<
- max_pool<3,3,2,2,relu<bn_con<con<32,7,7,2,2,
- input_rgb_image
- >>>>>>>>>>>>;
-
-// testing network type (replaced batch normalization with fixed affine transforms)
-using anet_type = loss_metric<fc_no_bias<128,avg_pool_everything<
- alevel0<
- alevel1<
- alevel2<
- alevel3<
- alevel4<
- max_pool<3,3,2,2,relu<affine<con<32,7,7,2,2,
- input_rgb_image
- >>>>>>>>>>>>;
-
-// ----------------------------------------------------------------------------------------
-
-int main(int argc, char** argv)
-{
- if (argc != 2)
- {
- cout << "Give a folder as input. It should contain sub-folders of images and we will " << endl;
- cout << "learn to distinguish between these sub-folders with metric learning. " << endl;
- cout << "For example, you can run this program on the very small examples/johns dataset" << endl;
- cout << "that comes with dlib by running this command:" << endl;
- cout << " ./dnn_metric_learning_on_images_ex johns" << endl;
- return 1;
- }
-
- auto objs = load_objects_list(argv[1]);
-
- cout << "objs.size(): "<< objs.size() << endl;
-
- std::vector<matrix<rgb_pixel>> images;
- std::vector<unsigned long> labels;
-
-
- net_type net;
-
- dnn_trainer<net_type> trainer(net, sgd(0.0001, 0.9));
- trainer.set_learning_rate(0.1);
- trainer.be_verbose();
- trainer.set_synchronization_file("face_metric_sync", std::chrono::minutes(5));
- // I've set this to something really small to make the example terminate
- // sooner. But when you really want to train a good model you should set
- // this to something like 10000 so training doesn't terminate too early.
- trainer.set_iterations_without_progress_threshold(300);
-
- // If you have a lot of data then it might not be reasonable to load it all
- // into RAM. So you will need to be sure you are decompressing your images
- // and loading them fast enough to keep the GPU occupied. I like to do this
- // using the following coding pattern: create a bunch of threads that dump
- // mini-batches into dlib::pipes.
- dlib::pipe<std::vector<matrix<rgb_pixel>>> qimages(4);
- dlib::pipe<std::vector<unsigned long>> qlabels(4);
- auto data_loader = [&qimages, &qlabels, &objs](time_t seed)
- {
- dlib::rand rnd(time(0)+seed);
- std::vector<matrix<rgb_pixel>> images;
- std::vector<unsigned long> labels;
- while(qimages.is_enabled())
- {
- try
- {
- load_mini_batch(5, 5, rnd, objs, images, labels);
- qimages.enqueue(images);
- qlabels.enqueue(labels);
- }
- catch(std::exception& e)
- {
- cout << "EXCEPTION IN LOADING DATA" << endl;
- cout << e.what() << endl;
- }
- }
- };
- // Run the data_loader from 5 threads. You should set the number of threads
- // relative to the number of CPU cores you have.
- std::thread data_loader1([data_loader](){ data_loader(1); });
- std::thread data_loader2([data_loader](){ data_loader(2); });
- std::thread data_loader3([data_loader](){ data_loader(3); });
- std::thread data_loader4([data_loader](){ data_loader(4); });
- std::thread data_loader5([data_loader](){ data_loader(5); });
-
-
- // Here we do the training. We keep passing mini-batches to the trainer until the
- // learning rate has dropped low enough.
- while(trainer.get_learning_rate() >= 1e-4)
- {
- qimages.dequeue(images);
- qlabels.dequeue(labels);
- trainer.train_one_step(images, labels);
- }
-
- // Wait for training threads to stop
- trainer.get_net();
- cout << "done training" << endl;
-
- // Save the network to disk
- net.clean();
- serialize("metric_network_renset.dat") << net;
-
- // stop all the data loading threads and wait for them to terminate.
- qimages.disable();
- qlabels.disable();
- data_loader1.join();
- data_loader2.join();
- data_loader3.join();
- data_loader4.join();
- data_loader5.join();
-
-
-
-
-
- // Now, just to show an example of how you would use the network, let's check how well
- // it performs on the training data.
- dlib::rand rnd(time(0));
- load_mini_batch(5, 5, rnd, objs, images, labels);
-
- // Normally you would use the non-batch-normalized version of the network to do
- // testing, which is what we do here.
- anet_type testing_net = net;
-
- // Run all the images through the network to get their vector embeddings.
- std::vector<matrix<float,0,1>> embedded = testing_net(images);
-
- // Now, check if the embedding puts images with the same labels near each other and
- // images with different labels far apart.
- int num_right = 0;
- int num_wrong = 0;
- for (size_t i = 0; i < embedded.size(); ++i)
- {
- for (size_t j = i+1; j < embedded.size(); ++j)
- {
- if (labels[i] == labels[j])
- {
- // The loss_metric layer will cause images with the same label to be less
- // than net.loss_details().get_distance_threshold() distance from each
- // other. So we can use that distance value as our testing threshold.
- if (length(embedded[i]-embedded[j]) < testing_net.loss_details().get_distance_threshold())
- ++num_right;
- else
- ++num_wrong;
- }
- else
- {
- if (length(embedded[i]-embedded[j]) >= testing_net.loss_details().get_distance_threshold())
- ++num_right;
- else
- ++num_wrong;
- }
- }
- }
-
- cout << "num_right: "<< num_right << endl;
- cout << "num_wrong: "<< num_wrong << endl;
-
-}
-
-
diff --git a/ml/dlib/examples/dnn_mmod_dog_hipsterizer.cpp b/ml/dlib/examples/dnn_mmod_dog_hipsterizer.cpp
deleted file mode 100644
index 22829d338..000000000
--- a/ml/dlib/examples/dnn_mmod_dog_hipsterizer.cpp
+++ /dev/null
@@ -1,180 +0,0 @@
-// The contents of this file are in the public domain. See LICENSE_FOR_EXAMPLE_PROGRAMS.txt
-/*
- This example shows how to run a CNN based dog face detector using dlib. The
- example loads a pretrained model and uses it to find dog faces in images.
- We also use the dlib::shape_predictor to find the location of the eyes and
- nose and then draw glasses and a mustache onto each dog found :)
-
-
- Users who are just learning about dlib's deep learning API should read the
- dnn_introduction_ex.cpp and dnn_introduction2_ex.cpp examples to learn how
- the API works. For an introduction to the object detection method you
- should read dnn_mmod_ex.cpp
-
-
-
- TRAINING THE MODEL
- Finally, users interested in how the dog face detector was trained should
- read the dnn_mmod_ex.cpp example program. It should be noted that the
- dog face detector used in this example uses a bigger training dataset and
- larger CNN architecture than what is shown in dnn_mmod_ex.cpp, but
- otherwise training is the same. If you compare the net_type statements
- in this file and dnn_mmod_ex.cpp you will see that they are very similar
- except that the number of parameters has been increased.
-
- Additionally, the following training parameters were different during
- training: The following lines in dnn_mmod_ex.cpp were changed from
- mmod_options options(face_boxes_train, 40,40);
- trainer.set_iterations_without_progress_threshold(300);
- to the following when training the model used in this example:
- mmod_options options(face_boxes_train, 80,80);
- trainer.set_iterations_without_progress_threshold(8000);
-
- Also, the random_cropper was left at its default settings, So we didn't
- call these functions:
- cropper.set_chip_dims(200, 200);
- cropper.set_min_object_size(40,40);
-
- The training data used to create the model is also available at
- http://dlib.net/files/data/CU_dogs_fully_labeled.tar.gz
-
- Lastly, the shape_predictor was trained with default settings except we
- used the following non-default settings: cascade depth=20, tree
- depth=5, padding=0.2
-*/
-
-
-#include <iostream>
-#include <dlib/dnn.h>
-#include <dlib/data_io.h>
-#include <dlib/image_processing.h>
-#include <dlib/gui_widgets.h>
-
-
-using namespace std;
-using namespace dlib;
-
-// ----------------------------------------------------------------------------------------
-
-template <long num_filters, typename SUBNET> using con5d = con<num_filters,5,5,2,2,SUBNET>;
-template <long num_filters, typename SUBNET> using con5 = con<num_filters,5,5,1,1,SUBNET>;
-
-template <typename SUBNET> using downsampler = relu<affine<con5d<32, relu<affine<con5d<32, relu<affine<con5d<16,SUBNET>>>>>>>>>;
-template <typename SUBNET> using rcon5 = relu<affine<con5<45,SUBNET>>>;
-
-using net_type = loss_mmod<con<1,9,9,1,1,rcon5<rcon5<rcon5<downsampler<input_rgb_image_pyramid<pyramid_down<6>>>>>>>>;
-
-// ----------------------------------------------------------------------------------------
-
-int main(int argc, char** argv) try
-{
- if (argc < 3)
- {
- cout << "Call this program like this:" << endl;
- cout << "./dnn_mmod_dog_hipsterizer mmod_dog_hipsterizer.dat faces/dogs.jpg" << endl;
- cout << "\nYou can get the mmod_dog_hipsterizer.dat file from:\n";
- cout << "http://dlib.net/files/mmod_dog_hipsterizer.dat.bz2" << endl;
- return 0;
- }
-
-
- // load the models as well as glasses and mustache.
- net_type net;
- shape_predictor sp;
- matrix<rgb_alpha_pixel> glasses, mustache;
- deserialize(argv[1]) >> net >> sp >> glasses >> mustache;
- pyramid_up(glasses);
- pyramid_up(mustache);
-
- image_window win1(glasses);
- image_window win2(mustache);
- image_window win_wireframe, win_hipster;
-
- // Now process each image, find dogs, and hipsterize them by drawing glasses and a
- // mustache on each dog :)
- for (int i = 2; i < argc; ++i)
- {
- matrix<rgb_pixel> img;
- load_image(img, argv[i]);
-
- // Upsampling the image will allow us to find smaller dog faces but will use more
- // computational resources.
- //pyramid_up(img);
-
- auto dets = net(img);
- win_wireframe.clear_overlay();
- win_wireframe.set_image(img);
- // We will also draw a wireframe on each dog's face so you can see where the
- // shape_predictor is identifying face landmarks.
- std::vector<image_window::overlay_line> lines;
- for (auto&& d : dets)
- {
- // get the landmarks for this dog's face
- auto shape = sp(img, d.rect);
-
- const rgb_pixel color(0,255,0);
- auto top = shape.part(0);
- auto lear = shape.part(1);
- auto leye = shape.part(2);
- auto nose = shape.part(3);
- auto rear = shape.part(4);
- auto reye = shape.part(5);
-
- // The locations of the left and right ends of the mustache.
- auto lmustache = 1.3*(leye-reye)/2 + nose;
- auto rmustache = 1.3*(reye-leye)/2 + nose;
-
- // Draw the glasses onto the image.
- std::vector<point> from = {2*point(176,36), 2*point(59,35)}, to = {leye, reye};
- auto tform = find_similarity_transform(from, to);
- for (long r = 0; r < glasses.nr(); ++r)
- {
- for (long c = 0; c < glasses.nc(); ++c)
- {
- point p = tform(point(c,r));
- if (get_rect(img).contains(p))
- assign_pixel(img(p.y(),p.x()), glasses(r,c));
- }
- }
-
- // Draw the mustache onto the image right under the dog's nose.
- auto mrect = get_rect(mustache);
- from = {mrect.tl_corner(), mrect.tr_corner()};
- to = {rmustache, lmustache};
- tform = find_similarity_transform(from, to);
- for (long r = 0; r < mustache.nr(); ++r)
- {
- for (long c = 0; c < mustache.nc(); ++c)
- {
- point p = tform(point(c,r));
- if (get_rect(img).contains(p))
- assign_pixel(img(p.y(),p.x()), mustache(r,c));
- }
- }
-
-
- // Record the lines needed for the face wire frame.
- lines.push_back(image_window::overlay_line(leye, nose, color));
- lines.push_back(image_window::overlay_line(nose, reye, color));
- lines.push_back(image_window::overlay_line(reye, leye, color));
- lines.push_back(image_window::overlay_line(reye, rear, color));
- lines.push_back(image_window::overlay_line(rear, top, color));
- lines.push_back(image_window::overlay_line(top, lear, color));
- lines.push_back(image_window::overlay_line(lear, leye, color));
- }
-
- win_wireframe.add_overlay(lines);
- win_hipster.set_image(img);
-
- cout << "Hit enter to process the next image." << endl;
- cin.get();
- }
-}
-catch(std::exception& e)
-{
- cout << e.what() << endl;
-}
-
-
-
-
diff --git a/ml/dlib/examples/dnn_mmod_ex.cpp b/ml/dlib/examples/dnn_mmod_ex.cpp
deleted file mode 100644
index 9565d514c..000000000
--- a/ml/dlib/examples/dnn_mmod_ex.cpp
+++ /dev/null
@@ -1,230 +0,0 @@
-// The contents of this file are in the public domain. See LICENSE_FOR_EXAMPLE_PROGRAMS.txt
-/*
- This example shows how to train a CNN based object detector using dlib's
- loss_mmod loss layer. This loss layer implements the Max-Margin Object
- Detection loss as described in the paper:
- Max-Margin Object Detection by Davis E. King (http://arxiv.org/abs/1502.00046).
- This is the same loss used by the popular SVM+HOG object detector in dlib
- (see fhog_object_detector_ex.cpp) except here we replace the HOG features
- with a CNN and train the entire detector end-to-end. This allows us to make
- much more powerful detectors.
-
- It would be a good idea to become familiar with dlib's DNN tooling before
- reading this example. So you should read dnn_introduction_ex.cpp and
- dnn_introduction2_ex.cpp before reading this example program.
-
- Just like in the fhog_object_detector_ex.cpp example, we are going to train
- a simple face detector based on the very small training dataset in the
- examples/faces folder. As we will see, even with this small dataset the
- MMOD method is able to make a working face detector. However, for real
- applications you should train with more data for an even better result.
-*/
-
-
-#include <iostream>
-#include <dlib/dnn.h>
-#include <dlib/data_io.h>
-#include <dlib/gui_widgets.h>
-
-using namespace std;
-using namespace dlib;
-
-// The first thing we do is define our CNN. The CNN is going to be evaluated
-// convolutionally over an entire image pyramid. Think of it like a normal
-// sliding window classifier. This means you need to define a CNN that can look
-// at some part of an image and decide if it is an object of interest. In this
-// example I've defined a CNN with a receptive field of a little over 50x50
-// pixels. This is reasonable for face detection since you can clearly tell if
-// a 50x50 image contains a face. Other applications may benefit from CNNs with
-// different architectures.
-//
-// In this example our CNN begins with 3 downsampling layers. These layers will
-// reduce the size of the image by 8x and output a feature map with
-// 32 dimensions. Then we will pass that through 4 more convolutional layers to
-// get the final output of the network. The last layer has only 1 channel and
-// the values in that last channel are large when the network thinks it has
-// found an object at a particular location.
-
-
-// Let's begin the network definition by creating some network blocks.
-
-// A 5x5 conv layer that does 2x downsampling
-template <long num_filters, typename SUBNET> using con5d = con<num_filters,5,5,2,2,SUBNET>;
-// A 3x3 conv layer that doesn't do any downsampling
-template <long num_filters, typename SUBNET> using con3 = con<num_filters,3,3,1,1,SUBNET>;
-
-// Now we can define the 8x downsampling block in terms of conv5d blocks. We
-// also use relu and batch normalization in the standard way.
-template <typename SUBNET> using downsampler = relu<bn_con<con5d<32, relu<bn_con<con5d<32, relu<bn_con<con5d<32,SUBNET>>>>>>>>>;
-
-// The rest of the network will be 3x3 conv layers with batch normalization and
-// relu. So we define the 3x3 block we will use here.
-template <typename SUBNET> using rcon3 = relu<bn_con<con3<32,SUBNET>>>;
-
-// Finally, we define the entire network. The special input_rgb_image_pyramid
-// layer causes the network to operate over a spatial pyramid, making the detector
-// scale invariant.
-using net_type = loss_mmod<con<1,6,6,1,1,rcon3<rcon3<rcon3<downsampler<input_rgb_image_pyramid<pyramid_down<6>>>>>>>>;
-
-// ----------------------------------------------------------------------------------------
-
-int main(int argc, char** argv) try
-{
- // In this example we are going to train a face detector based on the
- // small faces dataset in the examples/faces directory. So the first
- // thing we do is load that dataset. This means you need to supply the
- // path to this faces folder as a command line argument so we will know
- // where it is.
- if (argc != 2)
- {
- cout << "Give the path to the examples/faces directory as the argument to this" << endl;
- cout << "program. For example, if you are in the examples folder then execute " << endl;
- cout << "this program by running: " << endl;
- cout << " ./dnn_mmod_ex faces" << endl;
- cout << endl;
- return 0;
- }
- const std::string faces_directory = argv[1];
- // The faces directory contains a training dataset and a separate
- // testing dataset. The training data consists of 4 images, each
- // annotated with rectangles that bound each human face. The idea is
- // to use this training data to learn to identify human faces in new
- // images.
- //
- // Once you have trained an object detector it is always important to
- // test it on data it wasn't trained on. Therefore, we will also load
- // a separate testing set of 5 images. Once we have a face detector
- // created from the training data we will see how well it works by
- // running it on the testing images.
- //
- // So here we create the variables that will hold our dataset.
- // images_train will hold the 4 training images and face_boxes_train
- // holds the locations of the faces in the training images. So for
- // example, the image images_train[0] has the faces given by the
- // rectangles in face_boxes_train[0].
- std::vector<matrix<rgb_pixel>> images_train, images_test;
- std::vector<std::vector<mmod_rect>> face_boxes_train, face_boxes_test;
-
- // Now we load the data. These XML files list the images in each dataset
- // and also contain the positions of the face boxes. Obviously you can use
- // any kind of input format you like so long as you store the data into
- // images_train and face_boxes_train. But for convenience dlib comes with
- // tools for creating and loading XML image datasets. Here you see how to
- // load the data. To create the XML files you can use the imglab tool which
- // can be found in the tools/imglab folder. It is a simple graphical tool
- // for labeling objects in images with boxes. To see how to use it read the
- // tools/imglab/README.txt file.
- load_image_dataset(images_train, face_boxes_train, faces_directory+"/training.xml");
- load_image_dataset(images_test, face_boxes_test, faces_directory+"/testing.xml");
-
-
- cout << "num training images: " << images_train.size() << endl;
- cout << "num testing images: " << images_test.size() << endl;
-
-
- // The MMOD algorithm has some options you can set to control its behavior. However,
- // you can also call the constructor with your training annotations and a "target
- // object size" and it will automatically configure itself in a reasonable way for your
- // problem. Here we are saying that faces are still recognizably faces when they are
- // 40x40 pixels in size. You should generally pick the smallest size where this is
- // true. Based on this information the mmod_options constructor will automatically
- // pick a good sliding window width and height. It will also automatically set the
- // non-max-suppression parameters to something reasonable. For further details see the
- // mmod_options documentation.
- mmod_options options(face_boxes_train, 40,40);
- // The detector will automatically decide to use multiple sliding windows if needed.
- // For the face data, only one is needed however.
- cout << "num detector windows: "<< options.detector_windows.size() << endl;
- for (auto& w : options.detector_windows)
- cout << "detector window width by height: " << w.width << " x " << w.height << endl;
- cout << "overlap NMS IOU thresh: " << options.overlaps_nms.get_iou_thresh() << endl;
- cout << "overlap NMS percent covered thresh: " << options.overlaps_nms.get_percent_covered_thresh() << endl;
-
- // Now we are ready to create our network and trainer.
- net_type net(options);
- // The MMOD loss requires that the number of filters in the final network layer equal
- // options.detector_windows.size(). So we set that here as well.
- net.subnet().layer_details().set_num_filters(options.detector_windows.size());
- dnn_trainer<net_type> trainer(net);
- trainer.set_learning_rate(0.1);
- trainer.be_verbose();
- trainer.set_synchronization_file("mmod_sync", std::chrono::minutes(5));
- trainer.set_iterations_without_progress_threshold(300);
-
-
- // Now let's train the network. We are going to use mini-batches of 150
- // images. The images are random crops from our training set (see
- // random_cropper_ex.cpp for a discussion of the random_cropper).
- std::vector<matrix<rgb_pixel>> mini_batch_samples;
- std::vector<std::vector<mmod_rect>> mini_batch_labels;
- random_cropper cropper;
- cropper.set_chip_dims(200, 200);
- // Usually you want to give the cropper whatever min sizes you passed to the
- // mmod_options constructor, which is what we do here.
- cropper.set_min_object_size(40,40);
- dlib::rand rnd;
- // Run the trainer until the learning rate gets small. This will probably take several
- // hours.
- while(trainer.get_learning_rate() >= 1e-4)
- {
- cropper(150, images_train, face_boxes_train, mini_batch_samples, mini_batch_labels);
- // We can also randomly jitter the colors and that often helps a detector
- // generalize better to new images.
- for (auto&& img : mini_batch_samples)
- disturb_colors(img, rnd);
-
- trainer.train_one_step(mini_batch_samples, mini_batch_labels);
- }
- // wait for training threads to stop
- trainer.get_net();
- cout << "done training" << endl;
-
- // Save the network to disk
- net.clean();
- serialize("mmod_network.dat") << net;
-
-
- // Now that we have a face detector we can test it. The first statement tests it
- // on the training data. It will print the precision, recall, and then average precision.
- // This statement should indicate that the network works perfectly on the
- // training data.
- cout << "training results: " << test_object_detection_function(net, images_train, face_boxes_train) << endl;
- // However, to get an idea if it really worked without overfitting we need to run
- // it on images it wasn't trained on. The next line does this. Happily,
- // this statement indicates that the detector finds most of the faces in the
- // testing data.
- cout << "testing results: " << test_object_detection_function(net, images_test, face_boxes_test) << endl;
-
-
- // If you are running many experiments, it's also useful to log the settings used
- // during the training experiment. This statement will print the settings we used to
- // the screen.
- cout << trainer << cropper << endl;
-
- // Now lets run the detector on the testing images and look at the outputs.
- image_window win;
- for (auto&& img : images_test)
- {
- pyramid_up(img);
- auto dets = net(img);
- win.clear_overlay();
- win.set_image(img);
- for (auto&& d : dets)
- win.add_overlay(d);
- cin.get();
- }
- return 0;
-
- // Now that you finished this example, you should read dnn_mmod_train_find_cars_ex.cpp,
- // which is a more advanced example. It discusses many issues surrounding properly
- // setting the MMOD parameters and creating a good training dataset.
-
-}
-catch(std::exception& e)
-{
- cout << e.what() << endl;
-}
-
-
-
-
diff --git a/ml/dlib/examples/dnn_mmod_face_detection_ex.cpp b/ml/dlib/examples/dnn_mmod_face_detection_ex.cpp
deleted file mode 100644
index 3cdf4fcc7..000000000
--- a/ml/dlib/examples/dnn_mmod_face_detection_ex.cpp
+++ /dev/null
@@ -1,114 +0,0 @@
-// The contents of this file are in the public domain. See LICENSE_FOR_EXAMPLE_PROGRAMS.txt
-/*
- This example shows how to run a CNN based face detector using dlib. The
- example loads a pretrained model and uses it to find faces in images. The
- CNN model is much more accurate than the HOG based model shown in the
- face_detection_ex.cpp example, but takes much more computational power to
- run, and is meant to be executed on a GPU to attain reasonable speed. For
- example, on a NVIDIA Titan X GPU, this example program processes images at
- about the same speed as face_detection_ex.cpp.
-
- Also, users who are just learning about dlib's deep learning API should read
- the dnn_introduction_ex.cpp and dnn_introduction2_ex.cpp examples to learn
- how the API works. For an introduction to the object detection method you
- should read dnn_mmod_ex.cpp
-
-
-
- TRAINING THE MODEL
- Finally, users interested in how the face detector was trained should
- read the dnn_mmod_ex.cpp example program. It should be noted that the
- face detector used in this example uses a bigger training dataset and
- larger CNN architecture than what is shown in dnn_mmod_ex.cpp, but
- otherwise training is the same. If you compare the net_type statements
- in this file and dnn_mmod_ex.cpp you will see that they are very similar
- except that the number of parameters has been increased.
-
- Additionally, the following training parameters were different during
- training: The following lines in dnn_mmod_ex.cpp were changed from
- mmod_options options(face_boxes_train, 40,40);
- trainer.set_iterations_without_progress_threshold(300);
- to the following when training the model used in this example:
- mmod_options options(face_boxes_train, 80,80);
- trainer.set_iterations_without_progress_threshold(8000);
-
- Also, the random_cropper was left at its default settings, So we didn't
- call these functions:
- cropper.set_chip_dims(200, 200);
- cropper.set_min_object_size(40,40);
-
- The training data used to create the model is also available at
- http://dlib.net/files/data/dlib_face_detection_dataset-2016-09-30.tar.gz
-*/
-
-
-#include <iostream>
-#include <dlib/dnn.h>
-#include <dlib/data_io.h>
-#include <dlib/image_processing.h>
-#include <dlib/gui_widgets.h>
-
-
-using namespace std;
-using namespace dlib;
-
-// ----------------------------------------------------------------------------------------
-
-template <long num_filters, typename SUBNET> using con5d = con<num_filters,5,5,2,2,SUBNET>;
-template <long num_filters, typename SUBNET> using con5 = con<num_filters,5,5,1,1,SUBNET>;
-
-template <typename SUBNET> using downsampler = relu<affine<con5d<32, relu<affine<con5d<32, relu<affine<con5d<16,SUBNET>>>>>>>>>;
-template <typename SUBNET> using rcon5 = relu<affine<con5<45,SUBNET>>>;
-
-using net_type = loss_mmod<con<1,9,9,1,1,rcon5<rcon5<rcon5<downsampler<input_rgb_image_pyramid<pyramid_down<6>>>>>>>>;
-
-// ----------------------------------------------------------------------------------------
-
-
-int main(int argc, char** argv) try
-{
- if (argc == 1)
- {
- cout << "Call this program like this:" << endl;
- cout << "./dnn_mmod_face_detection_ex mmod_human_face_detector.dat faces/*.jpg" << endl;
- cout << "\nYou can get the mmod_human_face_detector.dat file from:\n";
- cout << "http://dlib.net/files/mmod_human_face_detector.dat.bz2" << endl;
- return 0;
- }
-
-
- net_type net;
- deserialize(argv[1]) >> net;
-
- image_window win;
- for (int i = 2; i < argc; ++i)
- {
- matrix<rgb_pixel> img;
- load_image(img, argv[i]);
-
- // Upsampling the image will allow us to detect smaller faces but will cause the
- // program to use more RAM and run longer.
- while(img.size() < 1800*1800)
- pyramid_up(img);
-
- // Note that you can process a bunch of images in a std::vector at once and it runs
- // much faster, since this will form mini-batches of images and therefore get
- // better parallelism out of your GPU hardware. However, all the images must be
- // the same size. To avoid this requirement on images being the same size we
- // process them individually in this example.
- auto dets = net(img);
- win.clear_overlay();
- win.set_image(img);
- for (auto&& d : dets)
- win.add_overlay(d);
-
- cout << "Hit enter to process the next image." << endl;
- cin.get();
- }
-}
-catch(std::exception& e)
-{
- cout << e.what() << endl;
-}
-
-
diff --git a/ml/dlib/examples/dnn_mmod_find_cars2_ex.cpp b/ml/dlib/examples/dnn_mmod_find_cars2_ex.cpp
deleted file mode 100644
index b9fffbba0..000000000
--- a/ml/dlib/examples/dnn_mmod_find_cars2_ex.cpp
+++ /dev/null
@@ -1,96 +0,0 @@
-// The contents of this file are in the public domain. See LICENSE_FOR_EXAMPLE_PROGRAMS.txt
-/*
- This example shows how to run a CNN based vehicle detector using dlib. The
- example loads a pretrained model and uses it to find the front and rear ends
- of cars in an image. The model used by this example was trained by the
- dnn_mmod_train_find_cars_ex.cpp example program on this dataset:
- http://dlib.net/files/data/dlib_front_and_rear_vehicles_v1.tar
-
- Users who are just learning about dlib's deep learning API should read
- the dnn_introduction_ex.cpp and dnn_introduction2_ex.cpp examples to learn
- how the API works. For an introduction to the object detection method you
- should read dnn_mmod_ex.cpp.
-
- You can also see a video of this vehicle detector running on YouTube:
- https://www.youtube.com/watch?v=OHbJ7HhbG74
-*/
-
-
-#include <iostream>
-#include <dlib/dnn.h>
-#include <dlib/image_io.h>
-#include <dlib/gui_widgets.h>
-#include <dlib/image_processing.h>
-
-using namespace std;
-using namespace dlib;
-
-
-
-// The front and rear view vehicle detector network
-template <long num_filters, typename SUBNET> using con5d = con<num_filters,5,5,2,2,SUBNET>;
-template <long num_filters, typename SUBNET> using con5 = con<num_filters,5,5,1,1,SUBNET>;
-template <typename SUBNET> using downsampler = relu<affine<con5d<32, relu<affine<con5d<32, relu<affine<con5d<16,SUBNET>>>>>>>>>;
-template <typename SUBNET> using rcon5 = relu<affine<con5<55,SUBNET>>>;
-using net_type = loss_mmod<con<1,9,9,1,1,rcon5<rcon5<rcon5<downsampler<input_rgb_image_pyramid<pyramid_down<6>>>>>>>>;
-
-// ----------------------------------------------------------------------------------------
-
-int main() try
-{
- net_type net;
- shape_predictor sp;
- // You can get this file from http://dlib.net/files/mmod_front_and_rear_end_vehicle_detector.dat.bz2
- // This network was produced by the dnn_mmod_train_find_cars_ex.cpp example program.
- // As you can see, the file also includes a separately trained shape_predictor. To see
- // a generic example of how to train those refer to train_shape_predictor_ex.cpp.
- deserialize("mmod_front_and_rear_end_vehicle_detector.dat") >> net >> sp;
-
- matrix<rgb_pixel> img;
- load_image(img, "../mmod_cars_test_image2.jpg");
-
- image_window win;
- win.set_image(img);
-
- // Run the detector on the image and show us the output.
- for (auto&& d : net(img))
- {
- // We use a shape_predictor to refine the exact shape and location of the detection
- // box. This shape_predictor is trained to simply output the 4 corner points of
- // the box. So all we do is make a rectangle that tightly contains those 4 points
- // and that rectangle is our refined detection position.
- auto fd = sp(img,d);
- rectangle rect;
- for (unsigned long j = 0; j < fd.num_parts(); ++j)
- rect += fd.part(j);
-
- if (d.label == "rear")
- win.add_overlay(rect, rgb_pixel(255,0,0), d.label);
- else
- win.add_overlay(rect, rgb_pixel(255,255,0), d.label);
- }
-
-
-
-
- cout << "Hit enter to end program" << endl;
- cin.get();
-}
-catch(image_load_error& e)
-{
- cout << e.what() << endl;
- cout << "The test image is located in the examples folder. So you should run this program from a sub folder so that the relative path is correct." << endl;
-}
-catch(serialization_error& e)
-{
- cout << e.what() << endl;
- cout << "The correct model file can be obtained from: http://dlib.net/files/mmod_front_and_rear_end_vehicle_detector.dat.bz2" << endl;
-}
-catch(std::exception& e)
-{
- cout << e.what() << endl;
-}
-
-
-
-
diff --git a/ml/dlib/examples/dnn_mmod_find_cars_ex.cpp b/ml/dlib/examples/dnn_mmod_find_cars_ex.cpp
deleted file mode 100644
index b11b1cfd1..000000000
--- a/ml/dlib/examples/dnn_mmod_find_cars_ex.cpp
+++ /dev/null
@@ -1,236 +0,0 @@
-// The contents of this file are in the public domain. See LICENSE_FOR_EXAMPLE_PROGRAMS.txt
-/*
- This example shows how to run a CNN based vehicle detector using dlib. The
- example loads a pretrained model and uses it to find the rear ends of cars in
- an image. We will also visualize some of the detector's processing steps by
- plotting various intermediate images on the screen. Viewing these can help
- you understand how the detector works.
-
- The model used by this example was trained by the dnn_mmod_train_find_cars_ex.cpp
- example. Also, since this is a CNN, you really should use a GPU to get the
- best execution speed. For instance, when run on a NVIDIA 1080ti, this detector
- runs at 98fps when run on the provided test image. That's more than an order
- of magnitude faster than when run on the CPU.
-
- Users who are just learning about dlib's deep learning API should read
- the dnn_introduction_ex.cpp and dnn_introduction2_ex.cpp examples to learn
- how the API works. For an introduction to the object detection method you
- should read dnn_mmod_ex.cpp.
-
- You can also see some videos of this vehicle detector running on YouTube:
- https://www.youtube.com/watch?v=4B3bzmxMAZU
- https://www.youtube.com/watch?v=bP2SUo5vSlc
-*/
-
-
-#include <iostream>
-#include <dlib/dnn.h>
-#include <dlib/image_io.h>
-#include <dlib/gui_widgets.h>
-#include <dlib/image_processing.h>
-
-using namespace std;
-using namespace dlib;
-
-
-
-// The rear view vehicle detector network
-template <long num_filters, typename SUBNET> using con5d = con<num_filters,5,5,2,2,SUBNET>;
-template <long num_filters, typename SUBNET> using con5 = con<num_filters,5,5,1,1,SUBNET>;
-template <typename SUBNET> using downsampler = relu<affine<con5d<32, relu<affine<con5d<32, relu<affine<con5d<16,SUBNET>>>>>>>>>;
-template <typename SUBNET> using rcon5 = relu<affine<con5<55,SUBNET>>>;
-using net_type = loss_mmod<con<1,9,9,1,1,rcon5<rcon5<rcon5<downsampler<input_rgb_image_pyramid<pyramid_down<6>>>>>>>>;
-
-// ----------------------------------------------------------------------------------------
-
-int main() try
-{
- net_type net;
- shape_predictor sp;
- // You can get this file from http://dlib.net/files/mmod_rear_end_vehicle_detector.dat.bz2
- // This network was produced by the dnn_mmod_train_find_cars_ex.cpp example program.
- // As you can see, the file also includes a separately trained shape_predictor. To see
- // a generic example of how to train those refer to train_shape_predictor_ex.cpp.
- deserialize("mmod_rear_end_vehicle_detector.dat") >> net >> sp;
-
- matrix<rgb_pixel> img;
- load_image(img, "../mmod_cars_test_image.jpg");
-
- image_window win;
- win.set_image(img);
-
- // Run the detector on the image and show us the output.
- for (auto&& d : net(img))
- {
- // We use a shape_predictor to refine the exact shape and location of the detection
- // box. This shape_predictor is trained to simply output the 4 corner points of
- // the box. So all we do is make a rectangle that tightly contains those 4 points
- // and that rectangle is our refined detection position.
- auto fd = sp(img,d);
- rectangle rect;
- for (unsigned long j = 0; j < fd.num_parts(); ++j)
- rect += fd.part(j);
- win.add_overlay(rect, rgb_pixel(255,0,0));
- }
-
-
-
- cout << "Hit enter to view the intermediate processing steps" << endl;
- cin.get();
-
-
- // Now let's look at how the detector works. The high level processing steps look like:
- // 1. Create an image pyramid and pack the pyramid into one big image. We call this
- // image the "tiled pyramid".
- // 2. Run the tiled pyramid image through the CNN. The CNN outputs a new image where
- // bright pixels in the output image indicate the presence of cars.
- // 3. Find pixels in the CNN's output image with a value > 0. Those locations are your
- // preliminary car detections.
- // 4. Perform non-maximum suppression on the preliminary detections to produce the
- // final output.
- //
- // We will be plotting the images from steps 1 and 2 so you can visualize what's
- // happening. For the CNN's output image, we will use the jet colormap so that "bright"
- // outputs, i.e. pixels with big values, appear in red and "dim" outputs appear as a
- // cold blue color. To do this we pick a range of CNN output values for the color
- // mapping. The specific values don't matter. They are just selected to give a nice
- // looking output image.
- const float lower = -2.5;
- const float upper = 0.0;
- cout << "jet color mapping range: lower="<< lower << " upper="<< upper << endl;
-
-
-
- // Create a tiled pyramid image and display it on the screen.
- std::vector<rectangle> rects;
- matrix<rgb_pixel> tiled_img;
- // Get the type of pyramid the CNN used
- using pyramid_type = std::remove_reference<decltype(input_layer(net))>::type::pyramid_type;
- // And tell create_tiled_pyramid to create the pyramid using that pyramid type.
- create_tiled_pyramid<pyramid_type>(img, tiled_img, rects,
- input_layer(net).get_pyramid_padding(),
- input_layer(net).get_pyramid_outer_padding());
- image_window winpyr(tiled_img, "Tiled pyramid");
-
-
-
- // This CNN detector represents a sliding window detector with 3 sliding windows. Each
- // of the 3 windows has a different aspect ratio, allowing it to find vehicles which
- // are either tall and skinny, squarish, or short and wide. The aspect ratio of a
- // detection is determined by which channel in the output image triggers the detection.
- // Here we are just going to max pool the channels together to get one final image for
- // our display. In this image, a pixel will be bright if any of the sliding window
- // detectors thinks there is a car at that location.
- cout << "Number of channels in final tensor image: " << net.subnet().get_output().k() << endl;
- matrix<float> network_output = image_plane(net.subnet().get_output(),0,0);
- for (long k = 1; k < net.subnet().get_output().k(); ++k)
- network_output = max_pointwise(network_output, image_plane(net.subnet().get_output(),0,k));
- // We will also upsample the CNN's output image. The CNN we defined has an 8x
- // downsampling layer at the beginning. In the code below we are going to overlay this
- // CNN output image on top of the raw input image. To make that look nice it helps to
- // upsample the CNN output image back to the same resolution as the input image, which
- // we do here.
- const double network_output_scale = img.nc()/(double)network_output.nc();
- resize_image(network_output_scale, network_output);
-
-
- // Display the network's output as a color image.
- image_window win_output(jet(network_output, upper, lower), "Output tensor from the network");
-
-
- // Also, overlay network_output on top of the tiled image pyramid and display it.
- for (long r = 0; r < tiled_img.nr(); ++r)
- {
- for (long c = 0; c < tiled_img.nc(); ++c)
- {
- dpoint tmp(c,r);
- tmp = input_tensor_to_output_tensor(net, tmp);
- tmp = point(network_output_scale*tmp);
- if (get_rect(network_output).contains(tmp))
- {
- float val = network_output(tmp.y(),tmp.x());
- // alpha blend the network output pixel with the RGB image to make our
- // overlay.
- rgb_alpha_pixel p;
- assign_pixel(p , colormap_jet(val,lower,upper));
- p.alpha = 120;
- assign_pixel(tiled_img(r,c), p);
- }
- }
- }
- // If you look at this image you can see that the vehicles have bright red blobs on
- // them. That's the CNN saying "there is a car here!". You will also notice there is
- // a certain scale at which it finds cars. They have to be not too big or too small,
- // which is why we have an image pyramid. The pyramid allows us to find cars of all
- // scales.
- image_window win_pyr_overlay(tiled_img, "Detection scores on image pyramid");
-
-
-
-
- // Finally, we can collapse the pyramid back into the original image. The CNN doesn't
- // actually do this step, since it's enough to threshold the tiled pyramid image to get
- // the detections. However, it makes a nice visualization and clearly indicates that
- // the detector is firing for all the cars.
- matrix<float> collapsed(img.nr(), img.nc());
- resizable_tensor input_tensor;
- input_layer(net).to_tensor(&img, &img+1, input_tensor);
- for (long r = 0; r < collapsed.nr(); ++r)
- {
- for (long c = 0; c < collapsed.nc(); ++c)
- {
- // Loop over a bunch of scale values and look up what part of network_output
- // corresponds to the point(c,r) in the original image, then take the max
- // detection score over all the scales and save it at pixel point(c,r).
- float max_score = -1e30;
- for (double scale = 1; scale > 0.2; scale *= 5.0/6.0)
- {
- // Map from input image coordinates to tiled pyramid coordinates.
- dpoint tmp = center(input_layer(net).image_space_to_tensor_space(input_tensor,scale, drectangle(dpoint(c,r))));
- // Now map from pyramid coordinates to network_output coordinates.
- tmp = point(network_output_scale*input_tensor_to_output_tensor(net, tmp));
-
- if (get_rect(network_output).contains(tmp))
- {
- float val = network_output(tmp.y(),tmp.x());
- if (val > max_score)
- max_score = val;
- }
- }
-
- collapsed(r,c) = max_score;
-
- // Also blend the scores into the original input image so we can view it as
- // an overlay on the cars.
- rgb_alpha_pixel p;
- assign_pixel(p , colormap_jet(max_score,lower,upper));
- p.alpha = 120;
- assign_pixel(img(r,c), p);
- }
- }
-
- image_window win_collapsed(jet(collapsed, upper, lower), "Collapsed output tensor from the network");
- image_window win_img_and_sal(img, "Collapsed detection scores on raw image");
-
-
- cout << "Hit enter to end program" << endl;
- cin.get();
-}
-catch(image_load_error& e)
-{
- cout << e.what() << endl;
- cout << "The test image is located in the examples folder. So you should run this program from a sub folder so that the relative path is correct." << endl;
-}
-catch(serialization_error& e)
-{
- cout << e.what() << endl;
- cout << "The correct model file can be obtained from: http://dlib.net/files/mmod_rear_end_vehicle_detector.dat.bz2" << endl;
-}
-catch(std::exception& e)
-{
- cout << e.what() << endl;
-}
-
-
-
-
diff --git a/ml/dlib/examples/dnn_mmod_train_find_cars_ex.cpp b/ml/dlib/examples/dnn_mmod_train_find_cars_ex.cpp
deleted file mode 100644
index b97e25a85..000000000
--- a/ml/dlib/examples/dnn_mmod_train_find_cars_ex.cpp
+++ /dev/null
@@ -1,425 +0,0 @@
-// The contents of this file are in the public domain. See LICENSE_FOR_EXAMPLE_PROGRAMS.txt
-/*
- This example shows how to train a CNN based object detector using dlib's
- loss_mmod loss layer. This loss layer implements the Max-Margin Object
- Detection loss as described in the paper:
- Max-Margin Object Detection by Davis E. King (http://arxiv.org/abs/1502.00046).
- This is the same loss used by the popular SVM+HOG object detector in dlib
- (see fhog_object_detector_ex.cpp) except here we replace the HOG features
- with a CNN and train the entire detector end-to-end. This allows us to make
- much more powerful detectors.
-
- It would be a good idea to become familiar with dlib's DNN tooling before reading this
- example. So you should read dnn_introduction_ex.cpp and dnn_introduction2_ex.cpp
- before reading this example program. You should also read the introductory DNN+MMOD
- example dnn_mmod_ex.cpp as well before proceeding.
-
-
- This example is essentially a more complex version of dnn_mmod_ex.cpp. In it we train
- a detector that finds the rear ends of motor vehicles. I will also discuss some
- aspects of data preparation useful when training this kind of detector.
-
-*/
-
-
-#include <iostream>
-#include <dlib/dnn.h>
-#include <dlib/data_io.h>
-
-using namespace std;
-using namespace dlib;
-
-
-
-template <long num_filters, typename SUBNET> using con5d = con<num_filters,5,5,2,2,SUBNET>;
-template <long num_filters, typename SUBNET> using con5 = con<num_filters,5,5,1,1,SUBNET>;
-template <typename SUBNET> using downsampler = relu<bn_con<con5d<32, relu<bn_con<con5d<32, relu<bn_con<con5d<16,SUBNET>>>>>>>>>;
-template <typename SUBNET> using rcon5 = relu<bn_con<con5<55,SUBNET>>>;
-using net_type = loss_mmod<con<1,9,9,1,1,rcon5<rcon5<rcon5<downsampler<input_rgb_image_pyramid<pyramid_down<6>>>>>>>>;
-
-
-// ----------------------------------------------------------------------------------------
-
-int ignore_overlapped_boxes(
- std::vector<mmod_rect>& boxes,
- const test_box_overlap& overlaps
-)
-/*!
- ensures
- - Whenever two rectangles in boxes overlap, according to overlaps(), we set the
- smallest box to ignore.
- - returns the number of newly ignored boxes.
-!*/
-{
- int num_ignored = 0;
- for (size_t i = 0; i < boxes.size(); ++i)
- {
- if (boxes[i].ignore)
- continue;
- for (size_t j = i+1; j < boxes.size(); ++j)
- {
- if (boxes[j].ignore)
- continue;
- if (overlaps(boxes[i], boxes[j]))
- {
- ++num_ignored;
- if(boxes[i].rect.area() < boxes[j].rect.area())
- boxes[i].ignore = true;
- else
- boxes[j].ignore = true;
- }
- }
- }
- return num_ignored;
-}
-
-// ----------------------------------------------------------------------------------------
-
-int main(int argc, char** argv) try
-{
- if (argc != 2)
- {
- cout << "Give the path to a folder containing training.xml and testing.xml files." << endl;
- cout << "This example program is specifically designed to run on the dlib vehicle " << endl;
- cout << "detection dataset, which is available at this URL: " << endl;
- cout << " http://dlib.net/files/data/dlib_rear_end_vehicles_v1.tar" << endl;
- cout << endl;
- cout << "So download that dataset, extract it somewhere, and then run this program" << endl;
- cout << "with the dlib_rear_end_vehicles folder as an argument. E.g. if you extract" << endl;
- cout << "the dataset to the current folder then you should run this example program" << endl;
- cout << "by typing: " << endl;
- cout << " ./dnn_mmod_train_find_cars_ex dlib_rear_end_vehicles" << endl;
- cout << endl;
- cout << "It takes about a day to finish if run on a high end GPU like a 1080ti." << endl;
- cout << endl;
- return 0;
- }
- const std::string data_directory = argv[1];
-
-
- std::vector<matrix<rgb_pixel>> images_train, images_test;
- std::vector<std::vector<mmod_rect>> boxes_train, boxes_test;
- load_image_dataset(images_train, boxes_train, data_directory+"/training.xml");
- load_image_dataset(images_test, boxes_test, data_directory+"/testing.xml");
-
- // When I was creating the dlib vehicle detection dataset I had to label all the cars
- // in each image. MMOD requires all cars to be labeled, since any unlabeled part of an
- // image is implicitly assumed to be not a car, and the algorithm will use it as
- // negative training data. So every car must be labeled, either with a normal
- // rectangle or an "ignore" rectangle that tells MMOD to simply ignore it (i.e. neither
- // treat it as a thing to detect nor as negative training data).
- //
- // In our present case, many images contain very tiny cars in the distance, ones that
- // are essentially just dark smudges. It's not reasonable to expect the CNN
- // architecture we defined to detect such vehicles. However, I erred on the side of
- // having more complete annotations when creating the dataset. So when I labeled these
- // images I labeled many of these really difficult cases as vehicles to detect.
- //
- // So the first thing we are going to do is clean up our dataset a little bit. In
- // particular, we are going to mark boxes smaller than 35*35 pixels as ignore since
- // only really small and blurry cars appear at those sizes. We will also mark boxes
- // that are heavily overlapped by another box as ignore. We do this because we want to
- // allow for stronger non-maximum suppression logic in the learned detector, since that
- // will help make it easier to learn a good detector.
- //
- // To explain this non-max suppression idea further it's important to understand how
- // the detector works. Essentially, sliding window detectors scan all image locations
- // and ask "is there a car here?". If there really is a car in a specific location in
- // an image then usually many slightly different sliding window locations will produce
- // high detection scores, indicating that there is a car at those locations. If we
- // just stopped there then each car would produce multiple detections. But that isn't
- // what we want. We want each car to produce just one detection. So it's common for
- // detectors to include "non-maximum suppression" logic which simply takes the
- // strongest detection and then deletes all detections "close to" the strongest. This
- // is a simple post-processing step that can eliminate duplicate detections. However,
- // we have to define what "close to" means. We can do this by looking at your training
- // data and checking how close the closest target boxes are to each other, and then
- // picking a "close to" measure that doesn't suppress those target boxes but is
- // otherwise as tight as possible. This is exactly what the mmod_options object does
- // by default.
- //
- // Importantly, this means that if your training dataset contains an image with two
- // target boxes that really overlap a whole lot, then the non-maximum suppression
- // "close to" measure will be configured to allow detections to really overlap a whole
- // lot. On the other hand, if your dataset didn't contain any overlapped boxes at all,
- // then the non-max suppression logic would be configured to filter out any boxes that
- // overlapped at all, and thus would be performing a much stronger non-max suppression.
- //
- // Why does this matter? Well, remember that we want to avoid duplicate detections.
- // If non-max suppression just kills everything in a really wide area around a car then
- // the CNN doesn't really need to learn anything about avoiding duplicate detections.
- // However, if non-max suppression only suppresses a tiny area around each detection
- // then the CNN will need to learn to output small detection scores for those areas of
- // the image not suppressed. The smaller the non-max suppression region the more the
- // CNN has to learn and the more difficult the learning problem will become. This is
- // why we remove highly overlapped objects from the training dataset. That is, we do
- // it so the non-max suppression logic will be able to be reasonably effective. Here
- // we are ensuring that any boxes that are entirely contained by another are
- // suppressed. We also ensure that boxes with an intersection over union of 0.5 or
- // greater are suppressed. This will improve the resulting detector since it will be
- // able to use more aggressive non-max suppression settings.
-
- int num_overlapped_ignored_test = 0;
- for (auto& v : boxes_test)
- num_overlapped_ignored_test += ignore_overlapped_boxes(v, test_box_overlap(0.50, 0.95));
-
- int num_overlapped_ignored = 0;
- int num_additional_ignored = 0;
- for (auto& v : boxes_train)
- {
- num_overlapped_ignored += ignore_overlapped_boxes(v, test_box_overlap(0.50, 0.95));
- for (auto& bb : v)
- {
- if (bb.rect.width() < 35 && bb.rect.height() < 35)
- {
- if (!bb.ignore)
- {
- bb.ignore = true;
- ++num_additional_ignored;
- }
- }
-
- // The dlib vehicle detection dataset doesn't contain any detections with
- // really extreme aspect ratios. However, some datasets do, often because of
- // bad labeling. So it's a good idea to check for that and either eliminate
- // those boxes or set them to ignore. Although, this depends on your
- // application.
- //
- // For instance, if your dataset has boxes with an aspect ratio
- // of 10 then you should think about what that means for the network
- // architecture. Does the receptive field even cover the entirety of the box
- // in those cases? Do you care about these boxes? Are they labeling errors?
- // I find that many people will download some dataset from the internet and
- // just take it as given. They run it through some training algorithm and take
- // the dataset as unchallengeable truth. But many datasets are full of
- // labeling errors. There are also a lot of datasets that aren't full of
- // errors, but are annotated in a sloppy and inconsistent way. Fixing those
- // errors and inconsistencies can often greatly improve models trained from
- // such data. It's almost always worth the time to try and improve your
- // training dataset.
- //
- // In any case, my point is that there are other types of dataset cleaning you
- // could put here. What exactly you need depends on your application. But you
- // should carefully consider it and not take your dataset as a given. The work
- // of creating a good detector is largely about creating a high quality
- // training dataset.
- }
- }
-
- // When modifying a dataset like this, it's a really good idea to print a log of how
- // many boxes you ignored. It's easy to accidentally ignore a huge block of data, so
- // you should always look and see that things are doing what you expect.
- cout << "num_overlapped_ignored: "<< num_overlapped_ignored << endl;
- cout << "num_additional_ignored: "<< num_additional_ignored << endl;
- cout << "num_overlapped_ignored_test: "<< num_overlapped_ignored_test << endl;
-
-
- cout << "num training images: " << images_train.size() << endl;
- cout << "num testing images: " << images_test.size() << endl;
-
-
- // Our vehicle detection dataset has basically 3 different types of boxes. Square
- // boxes, tall and skinny boxes (e.g. semi trucks), and short and wide boxes (e.g.
- // sedans). Here we are telling the MMOD algorithm that a vehicle is recognizable as
- // long as the longest box side is at least 70 pixels long and the shortest box side is
- // at least 30 pixels long. mmod_options will use these parameters to decide how large
- // each of the sliding windows needs to be so as to be able to detect all the vehicles.
- // Since our dataset has basically these 3 different aspect ratios, it will decide to
- // use 3 different sliding windows. This means the final con layer in the network will
- // have 3 filters, one for each of these aspect ratios.
- //
- // Another thing to consider when setting the sliding window size is the "stride" of
- // your network. The network we defined above downsamples the image by a factor of 8x
- // in the first few layers. So when the sliding windows are scanning the image, they
- // are stepping over it with a stride of 8 pixels. If you set the sliding window size
- // too small then the stride will become an issue. For instance, if you set the
- // sliding window size to 4 pixels, then it means a 4x4 window will be moved by 8
- // pixels at a time when scanning. This is obviously a problem since 75% of the image
- // won't even be visited by the sliding window. So you need to set the window size to
- // be big enough relative to the stride of your network. In our case, the windows are
- // at least 30 pixels in length, so being moved by 8 pixel steps is fine.
- mmod_options options(boxes_train, 70, 30);
-
-
- // This setting is very important and dataset specific. The vehicle detection dataset
- // contains boxes that are marked as "ignore", as we discussed above. Some of them are
- // ignored because we set ignore to true in the above code. However, the xml files
- // also contained a lot of ignore boxes. Some of them are large boxes that encompass
- // large parts of an image and the intention is to have everything inside those boxes
- // be ignored. Therefore, we need to tell the MMOD algorithm to do that, which we do
- // by setting options.overlaps_ignore appropriately.
- //
- // But first, we need to understand exactly what this option does. The MMOD loss
- // is essentially counting the number of false alarms + missed detections produced by
- // the detector for each image. During training, the code is running the detector on
- // each image in a mini-batch and looking at its output and counting the number of
- // mistakes. The optimizer tries to find parameters settings that minimize the number
- // of detector mistakes.
- //
- // This overlaps_ignore option allows you to tell the loss that some outputs from the
- // detector should be totally ignored, as if they never happened. In particular, if a
- // detection overlaps a box in the training data with ignore==true then that detection
- // is ignored. This overlap is determined by calling
- // options.overlaps_ignore(the_detection, the_ignored_training_box). If it returns
- // true then that detection is ignored.
- //
- // You should read the documentation for test_box_overlap, the class type for
- // overlaps_ignore for full details. However, the gist is that the default behavior is
- // to only consider boxes as overlapping if their intersection over union is > 0.5.
- // However, the dlib vehicle detection dataset contains large boxes that are meant to
- // mask out large areas of an image. So intersection over union isn't an appropriate
- // way to measure "overlaps with box" in this case. We want any box that is contained
- // inside one of these big regions to be ignored, even if the detection box is really
- // small. So we set overlaps_ignore to behave that way with this line.
- options.overlaps_ignore = test_box_overlap(0.5, 0.95);
-
- net_type net(options);
-
- // The final layer of the network must be a con layer that contains
- // options.detector_windows.size() filters. This is because these final filters are
- // what perform the final "sliding window" detection in the network. For the dlib
- // vehicle dataset, there will be 3 sliding window detectors, so we will be setting
- // num_filters to 3 here.
- net.subnet().layer_details().set_num_filters(options.detector_windows.size());
-
-
- dnn_trainer<net_type> trainer(net,sgd(0.0001,0.9));
- trainer.set_learning_rate(0.1);
- trainer.be_verbose();
-
-
- // While training, we are going to use early stopping. That is, we will be checking
- // how good the detector is performing on our test data and when it stops getting
- // better on the test data we will drop the learning rate. We will keep doing that
- // until the learning rate is less than 1e-4. These two settings tell the trainer to
- // do that. Essentially, we are setting the first argument to infinity, and only the
- // test iterations without progress threshold will matter. In particular, it says that
- // once we observe 1000 testing mini-batches where the test loss clearly isn't
- // decreasing we will lower the learning rate.
- trainer.set_iterations_without_progress_threshold(50000);
- trainer.set_test_iterations_without_progress_threshold(1000);
-
- const string sync_filename = "mmod_cars_sync";
- trainer.set_synchronization_file(sync_filename, std::chrono::minutes(5));
-
-
-
-
- std::vector<matrix<rgb_pixel>> mini_batch_samples;
- std::vector<std::vector<mmod_rect>> mini_batch_labels;
- random_cropper cropper;
- cropper.set_seed(time(0));
- cropper.set_chip_dims(350, 350);
- // Usually you want to give the cropper whatever min sizes you passed to the
- // mmod_options constructor, or very slightly smaller sizes, which is what we do here.
- cropper.set_min_object_size(69,28);
- cropper.set_max_rotation_degrees(2);
- dlib::rand rnd;
-
- // Log the training parameters to the console
- cout << trainer << cropper << endl;
-
- int cnt = 1;
- // Run the trainer until the learning rate gets small.
- while(trainer.get_learning_rate() >= 1e-4)
- {
- // Every 30 mini-batches we do a testing mini-batch.
- if (cnt%30 != 0 || images_test.size() == 0)
- {
- cropper(87, images_train, boxes_train, mini_batch_samples, mini_batch_labels);
- // We can also randomly jitter the colors and that often helps a detector
- // generalize better to new images.
- for (auto&& img : mini_batch_samples)
- disturb_colors(img, rnd);
-
- // It's a good idea to, at least once, put code here that displays the images
- // and boxes the random cropper is generating. You should look at them and
- // think about if the output makes sense for your problem. Most of the time
- // it will be fine, but sometimes you will realize that the pattern of cropping
- // isn't really appropriate for your problem and you will need to make some
- // change to how the mini-batches are being generated. Maybe you will tweak
- // some of the cropper's settings, or write your own entirely separate code to
- // create mini-batches. But either way, if you don't look you will never know.
- // An easy way to do this is to create a dlib::image_window to display the
- // images and boxes.
-
- trainer.train_one_step(mini_batch_samples, mini_batch_labels);
- }
- else
- {
- cropper(87, images_test, boxes_test, mini_batch_samples, mini_batch_labels);
- // We can also randomly jitter the colors and that often helps a detector
- // generalize better to new images.
- for (auto&& img : mini_batch_samples)
- disturb_colors(img, rnd);
-
- trainer.test_one_step(mini_batch_samples, mini_batch_labels);
- }
- ++cnt;
- }
- // wait for training threads to stop
- trainer.get_net();
- cout << "done training" << endl;
-
- // Save the network to disk
- net.clean();
- serialize("mmod_rear_end_vehicle_detector.dat") << net;
-
-
- // It's a really good idea to print the training parameters. This is because you will
- // invariably be running multiple rounds of training and should be logging the output
- // to a file. This print statement will include many of the training parameters in
- // your log.
- cout << trainer << cropper << endl;
-
- cout << "\nsync_filename: " << sync_filename << endl;
- cout << "num training images: "<< images_train.size() << endl;
- cout << "training results: " << test_object_detection_function(net, images_train, boxes_train, test_box_overlap(), 0, options.overlaps_ignore);
- // Upsampling the data will allow the detector to find smaller cars. Recall that
- // we configured it to use a sliding window nominally 70 pixels in size. So upsampling
- // here will let it find things nominally 35 pixels in size. Although we include a
- // limit of 1800*1800 here which means "don't upsample an image if it's already larger
- // than 1800*1800". We do this so we don't run out of RAM, which is a concern because
- // some of the images in the dlib vehicle dataset are really high resolution.
- upsample_image_dataset<pyramid_down<2>>(images_train, boxes_train, 1800*1800);
- cout << "training upsampled results: " << test_object_detection_function(net, images_train, boxes_train, test_box_overlap(), 0, options.overlaps_ignore);
-
-
- cout << "num testing images: "<< images_test.size() << endl;
- cout << "testing results: " << test_object_detection_function(net, images_test, boxes_test, test_box_overlap(), 0, options.overlaps_ignore);
- upsample_image_dataset<pyramid_down<2>>(images_test, boxes_test, 1800*1800);
- cout << "testing upsampled results: " << test_object_detection_function(net, images_test, boxes_test, test_box_overlap(), 0, options.overlaps_ignore);
-
- /*
- This program takes many hours to execute on a high end GPU. It took about a day to
- train on a NVIDIA 1080ti. The resulting model file is available at
- http://dlib.net/files/mmod_rear_end_vehicle_detector.dat.bz2
- It should be noted that this file on dlib.net has a dlib::shape_predictor appended
- onto the end of it (see dnn_mmod_find_cars_ex.cpp for an example of its use). This
- explains why the model file on dlib.net is larger than the
- mmod_rear_end_vehicle_detector.dat output by this program.
-
- You can see some videos of this vehicle detector running on YouTube:
- https://www.youtube.com/watch?v=4B3bzmxMAZU
- https://www.youtube.com/watch?v=bP2SUo5vSlc
-
- Also, the training and testing accuracies were:
- num training images: 2217
- training results: 0.990738 0.736431 0.736073
- training upsampled results: 0.986837 0.937694 0.936912
- num testing images: 135
- testing results: 0.988827 0.471372 0.470806
- testing upsampled results: 0.987879 0.651132 0.650399
- */
-
- return 0;
-
-}
-catch(std::exception& e)
-{
- cout << e.what() << endl;
-}
-
-
-
-
diff --git a/ml/dlib/examples/dnn_semantic_segmentation_ex.cpp b/ml/dlib/examples/dnn_semantic_segmentation_ex.cpp
deleted file mode 100644
index fa49c5a9e..000000000
--- a/ml/dlib/examples/dnn_semantic_segmentation_ex.cpp
+++ /dev/null
@@ -1,172 +0,0 @@
-// The contents of this file are in the public domain. See LICENSE_FOR_EXAMPLE_PROGRAMS.txt
-/*
- This example shows how to do semantic segmentation on an image using net pretrained
- on the PASCAL VOC2012 dataset. For an introduction to what segmentation is, see the
- accompanying header file dnn_semantic_segmentation_ex.h.
-
- Instructions how to run the example:
- 1. Download the PASCAL VOC2012 data, and untar it somewhere.
- http://host.robots.ox.ac.uk/pascal/VOC/voc2012/VOCtrainval_11-May-2012.tar
- 2. Build the dnn_semantic_segmentation_train_ex example program.
- 3. Run:
- ./dnn_semantic_segmentation_train_ex /path/to/VOC2012
- 4. Wait while the network is being trained.
- 5. Build the dnn_semantic_segmentation_ex example program.
- 6. Run:
- ./dnn_semantic_segmentation_ex /path/to/VOC2012-or-other-images
-
- An alternative to steps 2-4 above is to download a pre-trained network
- from here: http://dlib.net/files/semantic_segmentation_voc2012net.dnn
-
- It would be a good idea to become familiar with dlib's DNN tooling before reading this
- example. So you should read dnn_introduction_ex.cpp and dnn_introduction2_ex.cpp
- before reading this example program.
-*/
-
-#include "dnn_semantic_segmentation_ex.h"
-
-#include <iostream>
-#include <dlib/data_io.h>
-#include <dlib/gui_widgets.h>
-
-using namespace std;
-using namespace dlib;
-
-// ----------------------------------------------------------------------------------------
-
-// The PASCAL VOC2012 dataset contains 20 ground-truth classes + background. Each class
-// is represented using an RGB color value. We associate each class also to an index in the
-// range [0, 20], used internally by the network. To generate nice RGB representations of
-// inference results, we need to be able to convert the index values to the corresponding
-// RGB values.
-
-// Given an index in the range [0, 20], find the corresponding PASCAL VOC2012 class
-// (e.g., 'dog').
-const Voc2012class& find_voc2012_class(const uint16_t& index_label)
-{
- return find_voc2012_class(
- [&index_label](const Voc2012class& voc2012class)
- {
- return index_label == voc2012class.index;
- }
- );
-}
-
-// Convert an index in the range [0, 20] to a corresponding RGB class label.
-inline rgb_pixel index_label_to_rgb_label(uint16_t index_label)
-{
- return find_voc2012_class(index_label).rgb_label;
-}
-
-// Convert an image containing indexes in the range [0, 20] to a corresponding
-// image containing RGB class labels.
-void index_label_image_to_rgb_label_image(
- const matrix<uint16_t>& index_label_image,
- matrix<rgb_pixel>& rgb_label_image
-)
-{
- const long nr = index_label_image.nr();
- const long nc = index_label_image.nc();
-
- rgb_label_image.set_size(nr, nc);
-
- for (long r = 0; r < nr; ++r)
- {
- for (long c = 0; c < nc; ++c)
- {
- rgb_label_image(r, c) = index_label_to_rgb_label(index_label_image(r, c));
- }
- }
-}
-
-// Find the most prominent class label from amongst the per-pixel predictions.
-std::string get_most_prominent_non_background_classlabel(const matrix<uint16_t>& index_label_image)
-{
- const long nr = index_label_image.nr();
- const long nc = index_label_image.nc();
-
- std::vector<unsigned int> counters(class_count);
-
- for (long r = 0; r < nr; ++r)
- {
- for (long c = 0; c < nc; ++c)
- {
- const uint16_t label = index_label_image(r, c);
- ++counters[label];
- }
- }
-
- const auto max_element = std::max_element(counters.begin() + 1, counters.end());
- const uint16_t most_prominent_index_label = max_element - counters.begin();
-
- return find_voc2012_class(most_prominent_index_label).classlabel;
-}
-
-// ----------------------------------------------------------------------------------------
-
-int main(int argc, char** argv) try
-{
- if (argc != 2)
- {
- cout << "You call this program like this: " << endl;
- cout << "./dnn_semantic_segmentation_train_ex /path/to/images" << endl;
- cout << endl;
- cout << "You will also need a trained 'semantic_segmentation_voc2012net.dnn' file." << endl;
- cout << "You can either train it yourself (see example program" << endl;
- cout << "dnn_semantic_segmentation_train_ex), or download a" << endl;
- cout << "copy from here: http://dlib.net/files/semantic_segmentation_voc2012net.dnn" << endl;
- return 1;
- }
-
- // Read the file containing the trained network from the working directory.
- anet_type net;
- deserialize("semantic_segmentation_voc2012net.dnn") >> net;
-
- // Show inference results in a window.
- image_window win;
-
- matrix<rgb_pixel> input_image;
- matrix<uint16_t> index_label_image;
- matrix<rgb_pixel> rgb_label_image;
-
- // Find supported image files.
- const std::vector<file> files = dlib::get_files_in_directory_tree(argv[1],
- dlib::match_endings(".jpeg .jpg .png"));
-
- cout << "Found " << files.size() << " images, processing..." << endl;
-
- for (const file& file : files)
- {
- // Load the input image.
- load_image(input_image, file.full_name());
-
- // Create predictions for each pixel. At this point, the type of each prediction
- // is an index (a value between 0 and 20). Note that the net may return an image
- // that is not exactly the same size as the input.
- const matrix<uint16_t> temp = net(input_image);
-
- // Crop the returned image to be exactly the same size as the input.
- const chip_details chip_details(
- centered_rect(temp.nc() / 2, temp.nr() / 2, input_image.nc(), input_image.nr()),
- chip_dims(input_image.nr(), input_image.nc())
- );
- extract_image_chip(temp, chip_details, index_label_image, interpolate_nearest_neighbor());
-
- // Convert the indexes to RGB values.
- index_label_image_to_rgb_label_image(index_label_image, rgb_label_image);
-
- // Show the input image on the left, and the predicted RGB labels on the right.
- win.set_image(join_rows(input_image, rgb_label_image));
-
- // Find the most prominent class label from amongst the per-pixel predictions.
- const std::string classlabel = get_most_prominent_non_background_classlabel(index_label_image);
-
- cout << file.name() << " : " << classlabel << " - hit enter to process the next image";
- cin.get();
- }
-}
-catch(std::exception& e)
-{
- cout << e.what() << endl;
-}
-
diff --git a/ml/dlib/examples/dnn_semantic_segmentation_ex.h b/ml/dlib/examples/dnn_semantic_segmentation_ex.h
deleted file mode 100644
index 47fc102c9..000000000
--- a/ml/dlib/examples/dnn_semantic_segmentation_ex.h
+++ /dev/null
@@ -1,200 +0,0 @@
-// The contents of this file are in the public domain. See LICENSE_FOR_EXAMPLE_PROGRAMS.txt
-/*
- Semantic segmentation using the PASCAL VOC2012 dataset.
-
- In segmentation, the task is to assign each pixel of an input image
- a label - for example, 'dog'. Then, the idea is that neighboring
- pixels having the same label can be connected together to form a
- larger region, representing a complete (or partially occluded) dog.
- So technically, segmentation can be viewed as classification of
- individual pixels (using the relevant context in the input images),
- however the goal usually is to identify meaningful regions that
- represent complete entities of interest (such as dogs).
-
- Instructions how to run the example:
- 1. Download the PASCAL VOC2012 data, and untar it somewhere.
- http://host.robots.ox.ac.uk/pascal/VOC/voc2012/VOCtrainval_11-May-2012.tar
- 2. Build the dnn_semantic_segmentation_train_ex example program.
- 3. Run:
- ./dnn_semantic_segmentation_train_ex /path/to/VOC2012
- 4. Wait while the network is being trained.
- 5. Build the dnn_semantic_segmentation_ex example program.
- 6. Run:
- ./dnn_semantic_segmentation_ex /path/to/VOC2012-or-other-images
-
- An alternative to steps 2-4 above is to download a pre-trained network
- from here: http://dlib.net/files/semantic_segmentation_voc2012net.dnn
-
- It would be a good idea to become familiar with dlib's DNN tooling before reading this
- example. So you should read dnn_introduction_ex.cpp and dnn_introduction2_ex.cpp
- before reading this example program.
-*/
-
-#ifndef DLIB_DNn_SEMANTIC_SEGMENTATION_EX_H_
-#define DLIB_DNn_SEMANTIC_SEGMENTATION_EX_H_
-
-#include <dlib/dnn.h>
-
-// ----------------------------------------------------------------------------------------
-
-inline bool operator == (const dlib::rgb_pixel& a, const dlib::rgb_pixel& b)
-{
- return a.red == b.red && a.green == b.green && a.blue == b.blue;
-}
-
-// ----------------------------------------------------------------------------------------
-
-// The PASCAL VOC2012 dataset contains 20 ground-truth classes + background. Each class
-// is represented using an RGB color value. We associate each class also to an index in the
-// range [0, 20], used internally by the network.
-
-struct Voc2012class {
- Voc2012class(uint16_t index, const dlib::rgb_pixel& rgb_label, const std::string& classlabel)
- : index(index), rgb_label(rgb_label), classlabel(classlabel)
- {}
-
- // The index of the class. In the PASCAL VOC 2012 dataset, indexes from 0 to 20 are valid.
- const uint16_t index = 0;
-
- // The corresponding RGB representation of the class.
- const dlib::rgb_pixel rgb_label;
-
- // The label of the class in plain text.
- const std::string classlabel;
-};
-
-namespace {
- constexpr int class_count = 21; // background + 20 classes
-
- const std::vector<Voc2012class> classes = {
- Voc2012class(0, dlib::rgb_pixel(0, 0, 0), ""), // background
-
- // The cream-colored `void' label is used in border regions and to mask difficult objects
- // (see http://host.robots.ox.ac.uk/pascal/VOC/voc2012/htmldoc/devkit_doc.html)
- Voc2012class(dlib::loss_multiclass_log_per_pixel_::label_to_ignore,
- dlib::rgb_pixel(224, 224, 192), "border"),
-
- Voc2012class(1, dlib::rgb_pixel(128, 0, 0), "aeroplane"),
- Voc2012class(2, dlib::rgb_pixel( 0, 128, 0), "bicycle"),
- Voc2012class(3, dlib::rgb_pixel(128, 128, 0), "bird"),
- Voc2012class(4, dlib::rgb_pixel( 0, 0, 128), "boat"),
- Voc2012class(5, dlib::rgb_pixel(128, 0, 128), "bottle"),
- Voc2012class(6, dlib::rgb_pixel( 0, 128, 128), "bus"),
- Voc2012class(7, dlib::rgb_pixel(128, 128, 128), "car"),
- Voc2012class(8, dlib::rgb_pixel( 64, 0, 0), "cat"),
- Voc2012class(9, dlib::rgb_pixel(192, 0, 0), "chair"),
- Voc2012class(10, dlib::rgb_pixel( 64, 128, 0), "cow"),
- Voc2012class(11, dlib::rgb_pixel(192, 128, 0), "diningtable"),
- Voc2012class(12, dlib::rgb_pixel( 64, 0, 128), "dog"),
- Voc2012class(13, dlib::rgb_pixel(192, 0, 128), "horse"),
- Voc2012class(14, dlib::rgb_pixel( 64, 128, 128), "motorbike"),
- Voc2012class(15, dlib::rgb_pixel(192, 128, 128), "person"),
- Voc2012class(16, dlib::rgb_pixel( 0, 64, 0), "pottedplant"),
- Voc2012class(17, dlib::rgb_pixel(128, 64, 0), "sheep"),
- Voc2012class(18, dlib::rgb_pixel( 0, 192, 0), "sofa"),
- Voc2012class(19, dlib::rgb_pixel(128, 192, 0), "train"),
- Voc2012class(20, dlib::rgb_pixel( 0, 64, 128), "tvmonitor"),
- };
-}
-
-template <typename Predicate>
-const Voc2012class& find_voc2012_class(Predicate predicate)
-{
- const auto i = std::find_if(classes.begin(), classes.end(), predicate);
-
- if (i != classes.end())
- {
- return *i;
- }
- else
- {
- throw std::runtime_error("Unable to find a matching VOC2012 class");
- }
-}
-
-// ----------------------------------------------------------------------------------------
-
-// Introduce the building blocks used to define the segmentation network.
-// The network first does residual downsampling (similar to the dnn_imagenet_(train_)ex
-// example program), and then residual upsampling. The network could be improved e.g.
-// by introducing skip connections from the input image, and/or the first layers, to the
-// last layer(s). (See Long et al., Fully Convolutional Networks for Semantic Segmentation,
-// https://people.eecs.berkeley.edu/~jonlong/long_shelhamer_fcn.pdf)
-
-template <int N, template <typename> class BN, int stride, typename SUBNET>
-using block = BN<dlib::con<N,3,3,1,1, dlib::relu<BN<dlib::con<N,3,3,stride,stride,SUBNET>>>>>;
-
-template <int N, template <typename> class BN, int stride, typename SUBNET>
-using blockt = BN<dlib::cont<N,3,3,1,1,dlib::relu<BN<dlib::cont<N,3,3,stride,stride,SUBNET>>>>>;
-
-template <template <int,template<typename>class,int,typename> class block, int N, template<typename>class BN, typename SUBNET>
-using residual = dlib::add_prev1<block<N,BN,1,dlib::tag1<SUBNET>>>;
-
-template <template <int,template<typename>class,int,typename> class block, int N, template<typename>class BN, typename SUBNET>
-using residual_down = dlib::add_prev2<dlib::avg_pool<2,2,2,2,dlib::skip1<dlib::tag2<block<N,BN,2,dlib::tag1<SUBNET>>>>>>;
-
-template <template <int,template<typename>class,int,typename> class block, int N, template<typename>class BN, typename SUBNET>
-using residual_up = dlib::add_prev2<dlib::cont<N,2,2,2,2,dlib::skip1<dlib::tag2<blockt<N,BN,2,dlib::tag1<SUBNET>>>>>>;
-
-template <int N, typename SUBNET> using res = dlib::relu<residual<block,N,dlib::bn_con,SUBNET>>;
-template <int N, typename SUBNET> using ares = dlib::relu<residual<block,N,dlib::affine,SUBNET>>;
-template <int N, typename SUBNET> using res_down = dlib::relu<residual_down<block,N,dlib::bn_con,SUBNET>>;
-template <int N, typename SUBNET> using ares_down = dlib::relu<residual_down<block,N,dlib::affine,SUBNET>>;
-template <int N, typename SUBNET> using res_up = dlib::relu<residual_up<block,N,dlib::bn_con,SUBNET>>;
-template <int N, typename SUBNET> using ares_up = dlib::relu<residual_up<block,N,dlib::affine,SUBNET>>;
-
-// ----------------------------------------------------------------------------------------
-
-template <typename SUBNET> using res512 = res<512, SUBNET>;
-template <typename SUBNET> using res256 = res<256, SUBNET>;
-template <typename SUBNET> using res128 = res<128, SUBNET>;
-template <typename SUBNET> using res64 = res<64, SUBNET>;
-template <typename SUBNET> using ares512 = ares<512, SUBNET>;
-template <typename SUBNET> using ares256 = ares<256, SUBNET>;
-template <typename SUBNET> using ares128 = ares<128, SUBNET>;
-template <typename SUBNET> using ares64 = ares<64, SUBNET>;
-
-
-template <typename SUBNET> using level1 = dlib::repeat<2,res512,res_down<512,SUBNET>>;
-template <typename SUBNET> using level2 = dlib::repeat<2,res256,res_down<256,SUBNET>>;
-template <typename SUBNET> using level3 = dlib::repeat<2,res128,res_down<128,SUBNET>>;
-template <typename SUBNET> using level4 = dlib::repeat<2,res64,res<64,SUBNET>>;
-
-template <typename SUBNET> using alevel1 = dlib::repeat<2,ares512,ares_down<512,SUBNET>>;
-template <typename SUBNET> using alevel2 = dlib::repeat<2,ares256,ares_down<256,SUBNET>>;
-template <typename SUBNET> using alevel3 = dlib::repeat<2,ares128,ares_down<128,SUBNET>>;
-template <typename SUBNET> using alevel4 = dlib::repeat<2,ares64,ares<64,SUBNET>>;
-
-template <typename SUBNET> using level1t = dlib::repeat<2,res512,res_up<512,SUBNET>>;
-template <typename SUBNET> using level2t = dlib::repeat<2,res256,res_up<256,SUBNET>>;
-template <typename SUBNET> using level3t = dlib::repeat<2,res128,res_up<128,SUBNET>>;
-template <typename SUBNET> using level4t = dlib::repeat<2,res64,res_up<64,SUBNET>>;
-
-template <typename SUBNET> using alevel1t = dlib::repeat<2,ares512,ares_up<512,SUBNET>>;
-template <typename SUBNET> using alevel2t = dlib::repeat<2,ares256,ares_up<256,SUBNET>>;
-template <typename SUBNET> using alevel3t = dlib::repeat<2,ares128,ares_up<128,SUBNET>>;
-template <typename SUBNET> using alevel4t = dlib::repeat<2,ares64,ares_up<64,SUBNET>>;
-
-// ----------------------------------------------------------------------------------------
-
-// training network type
-using net_type = dlib::loss_multiclass_log_per_pixel<
- dlib::cont<class_count,7,7,2,2,
- level4t<level3t<level2t<level1t<
- level1<level2<level3<level4<
- dlib::max_pool<3,3,2,2,dlib::relu<dlib::bn_con<dlib::con<64,7,7,2,2,
- dlib::input<dlib::matrix<dlib::rgb_pixel>>
- >>>>>>>>>>>>>>;
-
-// testing network type (replaced batch normalization with fixed affine transforms)
-using anet_type = dlib::loss_multiclass_log_per_pixel<
- dlib::cont<class_count,7,7,2,2,
- alevel4t<alevel3t<alevel2t<alevel1t<
- alevel1<alevel2<alevel3<alevel4<
- dlib::max_pool<3,3,2,2,dlib::relu<dlib::affine<dlib::con<64,7,7,2,2,
- dlib::input<dlib::matrix<dlib::rgb_pixel>>
- >>>>>>>>>>>>>>;
-
-// ----------------------------------------------------------------------------------------
-
-#endif // DLIB_DNn_SEMANTIC_SEGMENTATION_EX_H_
diff --git a/ml/dlib/examples/dnn_semantic_segmentation_train_ex.cpp b/ml/dlib/examples/dnn_semantic_segmentation_train_ex.cpp
deleted file mode 100644
index 0de8c9f43..000000000
--- a/ml/dlib/examples/dnn_semantic_segmentation_train_ex.cpp
+++ /dev/null
@@ -1,390 +0,0 @@
-// The contents of this file are in the public domain. See LICENSE_FOR_EXAMPLE_PROGRAMS.txt
-/*
- This example shows how to train a semantic segmentation net using the PASCAL VOC2012
- dataset. For an introduction to what segmentation is, see the accompanying header file
- dnn_semantic_segmentation_ex.h.
-
- Instructions how to run the example:
- 1. Download the PASCAL VOC2012 data, and untar it somewhere.
- http://host.robots.ox.ac.uk/pascal/VOC/voc2012/VOCtrainval_11-May-2012.tar
- 2. Build the dnn_semantic_segmentation_train_ex example program.
- 3. Run:
- ./dnn_semantic_segmentation_train_ex /path/to/VOC2012
- 4. Wait while the network is being trained.
- 5. Build the dnn_semantic_segmentation_ex example program.
- 6. Run:
- ./dnn_semantic_segmentation_ex /path/to/VOC2012-or-other-images
-
- It would be a good idea to become familiar with dlib's DNN tooling before reading this
- example. So you should read dnn_introduction_ex.cpp and dnn_introduction2_ex.cpp
- before reading this example program.
-*/
-
-#include "dnn_semantic_segmentation_ex.h"
-
-#include <iostream>
-#include <dlib/data_io.h>
-#include <dlib/image_transforms.h>
-#include <dlib/dir_nav.h>
-#include <iterator>
-#include <thread>
-
-using namespace std;
-using namespace dlib;
-
-// A single training sample. A mini-batch comprises many of these.
-struct training_sample
-{
- matrix<rgb_pixel> input_image;
- matrix<uint16_t> label_image; // The ground-truth label of each pixel.
-};
-
-// ----------------------------------------------------------------------------------------
-
-rectangle make_random_cropping_rect_resnet(
- const matrix<rgb_pixel>& img,
- dlib::rand& rnd
-)
-{
- // figure out what rectangle we want to crop from the image
- double mins = 0.466666666, maxs = 0.875;
- auto scale = mins + rnd.get_random_double()*(maxs-mins);
- auto size = scale*std::min(img.nr(), img.nc());
- rectangle rect(size, size);
- // randomly shift the box around
- point offset(rnd.get_random_32bit_number()%(img.nc()-rect.width()),
- rnd.get_random_32bit_number()%(img.nr()-rect.height()));
- return move_rect(rect, offset);
-}
-
-// ----------------------------------------------------------------------------------------
-
-void randomly_crop_image (
- const matrix<rgb_pixel>& input_image,
- const matrix<uint16_t>& label_image,
- training_sample& crop,
- dlib::rand& rnd
-)
-{
- const auto rect = make_random_cropping_rect_resnet(input_image, rnd);
-
- const chip_details chip_details(rect, chip_dims(227, 227));
-
- // Crop the input image.
- extract_image_chip(input_image, chip_details, crop.input_image, interpolate_bilinear());
-
- // Crop the labels correspondingly. However, note that here bilinear
- // interpolation would make absolutely no sense - you wouldn't say that
- // a bicycle is half-way between an aeroplane and a bird, would you?
- extract_image_chip(label_image, chip_details, crop.label_image, interpolate_nearest_neighbor());
-
- // Also randomly flip the input image and the labels.
- if (rnd.get_random_double() > 0.5)
- {
- crop.input_image = fliplr(crop.input_image);
- crop.label_image = fliplr(crop.label_image);
- }
-
- // And then randomly adjust the colors.
- apply_random_color_offset(crop.input_image, rnd);
-}
-
-// ----------------------------------------------------------------------------------------
-
-// The names of the input image and the associated RGB label image in the PASCAL VOC 2012
-// data set.
-struct image_info
-{
- string image_filename;
- string label_filename;
-};
-
-// Read the list of image files belonging to either the "train", "trainval", or "val" set
-// of the PASCAL VOC2012 data.
-std::vector<image_info> get_pascal_voc2012_listing(
- const std::string& voc2012_folder,
- const std::string& file = "train" // "train", "trainval", or "val"
-)
-{
- std::ifstream in(voc2012_folder + "/ImageSets/Segmentation/" + file + ".txt");
-
- std::vector<image_info> results;
-
- while (in)
- {
- std::string basename;
- in >> basename;
-
- if (!basename.empty())
- {
- image_info image_info;
- image_info.image_filename = voc2012_folder + "/JPEGImages/" + basename + ".jpg";
- image_info.label_filename = voc2012_folder + "/SegmentationClass/" + basename + ".png";
- results.push_back(image_info);
- }
- }
-
- return results;
-}
-
-// Read the list of image files belong to the "train" set of the PASCAL VOC2012 data.
-std::vector<image_info> get_pascal_voc2012_train_listing(
- const std::string& voc2012_folder
-)
-{
- return get_pascal_voc2012_listing(voc2012_folder, "train");
-}
-
-// Read the list of image files belong to the "val" set of the PASCAL VOC2012 data.
-std::vector<image_info> get_pascal_voc2012_val_listing(
- const std::string& voc2012_folder
-)
-{
- return get_pascal_voc2012_listing(voc2012_folder, "val");
-}
-
-// ----------------------------------------------------------------------------------------
-
-// The PASCAL VOC2012 dataset contains 20 ground-truth classes + background. Each class
-// is represented using an RGB color value. We associate each class also to an index in the
-// range [0, 20], used internally by the network. To convert the ground-truth data to
-// something that the network can efficiently digest, we need to be able to map the RGB
-// values to the corresponding indexes.
-
-// Given an RGB representation, find the corresponding PASCAL VOC2012 class
-// (e.g., 'dog').
-const Voc2012class& find_voc2012_class(const dlib::rgb_pixel& rgb_label)
-{
- return find_voc2012_class(
- [&rgb_label](const Voc2012class& voc2012class)
- {
- return rgb_label == voc2012class.rgb_label;
- }
- );
-}
-
-// Convert an RGB class label to an index in the range [0, 20].
-inline uint16_t rgb_label_to_index_label(const dlib::rgb_pixel& rgb_label)
-{
- return find_voc2012_class(rgb_label).index;
-}
-
-// Convert an image containing RGB class labels to a corresponding
-// image containing indexes in the range [0, 20].
-void rgb_label_image_to_index_label_image(
- const dlib::matrix<dlib::rgb_pixel>& rgb_label_image,
- dlib::matrix<uint16_t>& index_label_image
-)
-{
- const long nr = rgb_label_image.nr();
- const long nc = rgb_label_image.nc();
-
- index_label_image.set_size(nr, nc);
-
- for (long r = 0; r < nr; ++r)
- {
- for (long c = 0; c < nc; ++c)
- {
- index_label_image(r, c) = rgb_label_to_index_label(rgb_label_image(r, c));
- }
- }
-}
-
-// ----------------------------------------------------------------------------------------
-
-// Calculate the per-pixel accuracy on a dataset whose file names are supplied as a parameter.
-double calculate_accuracy(anet_type& anet, const std::vector<image_info>& dataset)
-{
- int num_right = 0;
- int num_wrong = 0;
-
- matrix<rgb_pixel> input_image;
- matrix<rgb_pixel> rgb_label_image;
- matrix<uint16_t> index_label_image;
- matrix<uint16_t> net_output;
-
- for (const auto& image_info : dataset)
- {
- // Load the input image.
- load_image(input_image, image_info.image_filename);
-
- // Load the ground-truth (RGB) labels.
- load_image(rgb_label_image, image_info.label_filename);
-
- // Create predictions for each pixel. At this point, the type of each prediction
- // is an index (a value between 0 and 20). Note that the net may return an image
- // that is not exactly the same size as the input.
- const matrix<uint16_t> temp = anet(input_image);
-
- // Convert the indexes to RGB values.
- rgb_label_image_to_index_label_image(rgb_label_image, index_label_image);
-
- // Crop the net output to be exactly the same size as the input.
- const chip_details chip_details(
- centered_rect(temp.nc() / 2, temp.nr() / 2, input_image.nc(), input_image.nr()),
- chip_dims(input_image.nr(), input_image.nc())
- );
- extract_image_chip(temp, chip_details, net_output, interpolate_nearest_neighbor());
-
- const long nr = index_label_image.nr();
- const long nc = index_label_image.nc();
-
- // Compare the predicted values to the ground-truth values.
- for (long r = 0; r < nr; ++r)
- {
- for (long c = 0; c < nc; ++c)
- {
- const uint16_t truth = index_label_image(r, c);
- if (truth != dlib::loss_multiclass_log_per_pixel_::label_to_ignore)
- {
- const uint16_t prediction = net_output(r, c);
- if (prediction == truth)
- {
- ++num_right;
- }
- else
- {
- ++num_wrong;
- }
- }
- }
- }
- }
-
- // Return the accuracy estimate.
- return num_right / static_cast<double>(num_right + num_wrong);
-}
-
-// ----------------------------------------------------------------------------------------
-
-int main(int argc, char** argv) try
-{
- if (argc != 2)
- {
- cout << "To run this program you need a copy of the PASCAL VOC2012 dataset." << endl;
- cout << endl;
- cout << "You call this program like this: " << endl;
- cout << "./dnn_semantic_segmentation_train_ex /path/to/VOC2012" << endl;
- return 1;
- }
-
- cout << "\nSCANNING PASCAL VOC2012 DATASET\n" << endl;
-
- const auto listing = get_pascal_voc2012_train_listing(argv[1]);
- cout << "images in dataset: " << listing.size() << endl;
- if (listing.size() == 0)
- {
- cout << "Didn't find the VOC2012 dataset. " << endl;
- return 1;
- }
-
-
- const double initial_learning_rate = 0.1;
- const double weight_decay = 0.0001;
- const double momentum = 0.9;
-
- net_type net;
- dnn_trainer<net_type> trainer(net,sgd(weight_decay, momentum));
- trainer.be_verbose();
- trainer.set_learning_rate(initial_learning_rate);
- trainer.set_synchronization_file("pascal_voc2012_trainer_state_file.dat", std::chrono::minutes(10));
- // This threshold is probably excessively large.
- trainer.set_iterations_without_progress_threshold(5000);
- // Since the progress threshold is so large might as well set the batch normalization
- // stats window to something big too.
- set_all_bn_running_stats_window_sizes(net, 1000);
-
- // Output training parameters.
- cout << endl << trainer << endl;
-
- std::vector<matrix<rgb_pixel>> samples;
- std::vector<matrix<uint16_t>> labels;
-
- // Start a bunch of threads that read images from disk and pull out random crops. It's
- // important to be sure to feed the GPU fast enough to keep it busy. Using multiple
- // thread for this kind of data preparation helps us do that. Each thread puts the
- // crops into the data queue.
- dlib::pipe<training_sample> data(200);
- auto f = [&data, &listing](time_t seed)
- {
- dlib::rand rnd(time(0)+seed);
- matrix<rgb_pixel> input_image;
- matrix<rgb_pixel> rgb_label_image;
- matrix<uint16_t> index_label_image;
- training_sample temp;
- while(data.is_enabled())
- {
- // Pick a random input image.
- const image_info& image_info = listing[rnd.get_random_32bit_number()%listing.size()];
-
- // Load the input image.
- load_image(input_image, image_info.image_filename);
-
- // Load the ground-truth (RGB) labels.
- load_image(rgb_label_image, image_info.label_filename);
-
- // Convert the indexes to RGB values.
- rgb_label_image_to_index_label_image(rgb_label_image, index_label_image);
-
- // Randomly pick a part of the image.
- randomly_crop_image(input_image, index_label_image, temp, rnd);
-
- // Push the result to be used by the trainer.
- data.enqueue(temp);
- }
- };
- std::thread data_loader1([f](){ f(1); });
- std::thread data_loader2([f](){ f(2); });
- std::thread data_loader3([f](){ f(3); });
- std::thread data_loader4([f](){ f(4); });
-
- // The main training loop. Keep making mini-batches and giving them to the trainer.
- // We will run until the learning rate has dropped by a factor of 1e-4.
- while(trainer.get_learning_rate() >= 1e-4)
- {
- samples.clear();
- labels.clear();
-
- // make a 30-image mini-batch
- training_sample temp;
- while(samples.size() < 30)
- {
- data.dequeue(temp);
-
- samples.push_back(std::move(temp.input_image));
- labels.push_back(std::move(temp.label_image));
- }
-
- trainer.train_one_step(samples, labels);
- }
-
- // Training done, tell threads to stop and make sure to wait for them to finish before
- // moving on.
- data.disable();
- data_loader1.join();
- data_loader2.join();
- data_loader3.join();
- data_loader4.join();
-
- // also wait for threaded processing to stop in the trainer.
- trainer.get_net();
-
- net.clean();
- cout << "saving network" << endl;
- serialize("semantic_segmentation_voc2012net.dnn") << net;
-
-
- // Make a copy of the network to use it for inference.
- anet_type anet = net;
-
- cout << "Testing the network..." << endl;
-
- // Find the accuracy of the newly trained network on both the training and the validation sets.
- cout << "train accuracy : " << calculate_accuracy(anet, get_pascal_voc2012_train_listing(argv[1])) << endl;
- cout << "val accuracy : " << calculate_accuracy(anet, get_pascal_voc2012_val_listing(argv[1])) << endl;
-}
-catch(std::exception& e)
-{
- cout << e.what() << endl;
-}
-
diff --git a/ml/dlib/examples/empirical_kernel_map_ex.cpp b/ml/dlib/examples/empirical_kernel_map_ex.cpp
deleted file mode 100644
index 9f7b1a579..000000000
--- a/ml/dlib/examples/empirical_kernel_map_ex.cpp
+++ /dev/null
@@ -1,355 +0,0 @@
-// The contents of this file are in the public domain. See LICENSE_FOR_EXAMPLE_PROGRAMS.txt
-/*
-
- This is an example illustrating the use of the empirical_kernel_map
- from the dlib C++ Library.
-
- This example program assumes you are familiar with some general elements of
- the library. In particular, you should have at least read the svm_ex.cpp
- and matrix_ex.cpp examples.
-
-
- Most of the machine learning algorithms in dlib are some flavor of "kernel machine".
- This means they are all simple linear algorithms that have been formulated such
- that the only way they look at the data given by a user is via dot products between
- the data samples. These algorithms are made more useful via the application of the
- so-called kernel trick. This trick is to replace the dot product with a user
- supplied function which takes two samples and returns a real number. This function
- is the kernel that is required by so many algorithms. The most basic kernel is the
- linear_kernel which is simply a normal dot product. More interesting, however,
- are kernels which first apply some nonlinear transformation to the user's data samples
- and then compute a dot product. In this way, a simple algorithm that finds a linear
- plane to separate data (e.g. the SVM algorithm) can be made to solve complex
- nonlinear learning problems.
-
- An important element of the kernel trick is that these kernel functions perform
- the nonlinear transformation implicitly. That is, if you look at the implementations
- of these kernel functions you won't see code that transforms two input vectors in
- some way and then computes their dot products. Instead you will see a simple function
- that takes two input vectors and just computes a single real number via some simple
- process. You can basically think of this as an optimization. Imagine that originally
- we wrote out the entire procedure to perform the nonlinear transformation and then
- compute the dot product but then noticed we could cancel a few terms here and there
- and simplify the whole thing down into a more compact and easily evaluated form.
- The result is a nice function that computes what we want but we no longer get to see
- what those nonlinearly transformed input vectors are.
-
- The empirical_kernel_map is a tool that undoes this. It allows you to obtain these
- nonlinearly transformed vectors. It does this by taking a set of data samples from
- the user (referred to as basis samples), applying the nonlinear transformation to all
- of them, and then constructing a set of orthonormal basis vectors which spans the space
- occupied by those transformed input samples. Then if we wish to obtain the nonlinear
- version of any data sample we can simply project it onto this orthonormal basis and
- we obtain a regular vector of real numbers which represents the nonlinearly transformed
- version of the data sample. The empirical_kernel_map has been formulated to use only
- dot products between data samples so it is capable of performing this service for any
- user supplied kernel function.
-
- The empirical_kernel_map is useful because it is often difficult to formulate an
- algorithm in a way that uses only dot products. So the empirical_kernel_map lets
- us easily kernelize any algorithm we like by using this object during a preprocessing
- step. However, it should be noted that the algorithm is only practical when used
- with at most a few thousand basis samples. Fortunately, most datasets live in
- subspaces that are relatively low dimensional. So for these datasets, using the
- empirical_kernel_map is practical assuming an appropriate set of basis samples can be
- selected by the user. To help with this dlib supplies the linearly_independent_subset_finder.
- I also often find that just picking a random subset of the data as a basis works well.
-
-
-
- In what follows, we walk through the process of creating an empirical_kernel_map,
- projecting data to obtain the nonlinearly transformed vectors, and then doing a
- few interesting things with the data.
-*/
-
-
-
-
-#include <dlib/svm.h>
-#include <dlib/rand.h>
-#include <iostream>
-#include <vector>
-
-
-using namespace std;
-using namespace dlib;
-
-// ----------------------------------------------------------------------------------------
-
-// First let's make a typedef for the kind of samples we will be using.
-typedef matrix<double, 0, 1> sample_type;
-
-// We will be using the radial_basis_kernel in this example program.
-typedef radial_basis_kernel<sample_type> kernel_type;
-
-// ----------------------------------------------------------------------------------------
-
-void generate_concentric_circles (
- std::vector<sample_type>& samples,
- std::vector<double>& labels,
- const int num_points
-);
-/*!
- requires
- - num_points > 0
- ensures
- - generates two circles centered at the point (0,0), one of radius 1 and
- the other of radius 5. These points are stored into samples. labels will
- tell you if a given samples is from the smaller circle (its label will be 1)
- or from the larger circle (its label will be 2).
- - each circle will be made up of num_points
-!*/
-
-// ----------------------------------------------------------------------------------------
-
-void test_empirical_kernel_map (
- const std::vector<sample_type>& samples,
- const std::vector<double>& labels,
- const empirical_kernel_map<kernel_type>& ekm
-);
-/*!
- This function computes various interesting things with the empirical_kernel_map.
- See its implementation below for details.
-!*/
-
-// ----------------------------------------------------------------------------------------
-
-int main()
-{
- std::vector<sample_type> samples;
- std::vector<double> labels;
-
- // Declare an instance of the kernel we will be using.
- const kernel_type kern(0.1);
-
- // create a dataset with two concentric circles. There will be 100 points on each circle.
- generate_concentric_circles(samples, labels, 100);
-
- empirical_kernel_map<kernel_type> ekm;
-
-
- // Here we create an empirical_kernel_map using all of our data samples as basis samples.
- cout << "\n\nBuilding an empirical_kernel_map with " << samples.size() << " basis samples." << endl;
- ekm.load(kern, samples);
- cout << "Test the empirical_kernel_map when loaded with every sample." << endl;
- test_empirical_kernel_map(samples, labels, ekm);
-
-
-
-
-
-
- // create a new dataset with two concentric circles. There will be 1000 points on each circle.
- generate_concentric_circles(samples, labels, 1000);
- // Rather than use all 2000 samples as basis samples we are going to use the
- // linearly_independent_subset_finder to pick out a good basis set. The idea behind this
- // object is to try and find the 40 or so samples that best spans the subspace containing all the
- // data.
- linearly_independent_subset_finder<kernel_type> lisf(kern, 40);
- // populate lisf with samples. We have configured it to allow at most 40 samples but this function
- // may determine that fewer samples are necessary to form a good basis. In this example program
- // it will select only 26.
- fill_lisf(lisf, samples);
-
- // Now reload the empirical_kernel_map but this time using only our small basis
- // selected using the linearly_independent_subset_finder.
- cout << "\n\nBuilding an empirical_kernel_map with " << lisf.size() << " basis samples." << endl;
- ekm.load(lisf);
- cout << "Test the empirical_kernel_map when loaded with samples from the lisf object." << endl;
- test_empirical_kernel_map(samples, labels, ekm);
-
-
- cout << endl;
-}
-
-// ----------------------------------------------------------------------------------------
-
-void test_empirical_kernel_map (
- const std::vector<sample_type>& samples,
- const std::vector<double>& labels,
- const empirical_kernel_map<kernel_type>& ekm
-)
-{
-
- std::vector<sample_type> projected_samples;
-
- // The first thing we do is compute the nonlinearly projected vectors using the
- // empirical_kernel_map.
- for (unsigned long i = 0; i < samples.size(); ++i)
- {
- projected_samples.push_back(ekm.project(samples[i]));
- }
-
- // Note that a kernel matrix is just a matrix M such that M(i,j) == kernel(samples[i],samples[j]).
- // So below we are computing the normal kernel matrix as given by the radial_basis_kernel and the
- // input samples. We also compute the kernel matrix for all the projected_samples as given by the
- // linear_kernel. Note that the linear_kernel just computes normal dot products. So what we want to
- // see is that the dot products between all the projected_samples samples are the same as the outputs
- // of the kernel function for their respective untransformed input samples. If they match then
- // we know that the empirical_kernel_map is working properly.
- const matrix<double> normal_kernel_matrix = kernel_matrix(ekm.get_kernel(), samples);
- const matrix<double> new_kernel_matrix = kernel_matrix(linear_kernel<sample_type>(), projected_samples);
-
- cout << "Max kernel matrix error: " << max(abs(normal_kernel_matrix - new_kernel_matrix)) << endl;
- cout << "Mean kernel matrix error: " << mean(abs(normal_kernel_matrix - new_kernel_matrix)) << endl;
- /*
- Example outputs from these cout statements.
- For the case where we use all samples as basis samples:
- Max kernel matrix error: 7.32747e-15
- Mean kernel matrix error: 7.47789e-16
-
- For the case where we use only 26 samples as basis samples:
- Max kernel matrix error: 0.000953573
- Mean kernel matrix error: 2.26008e-05
-
-
- Note that if we use enough basis samples we can perfectly span the space of input samples.
- In that case we get errors that are essentially just rounding noise (Moreover, using all the
- samples is always enough since they are always within their own span). Once we start
- to use fewer basis samples we may begin to get approximation error. In the second case we
- used 26 and we can see that the data doesn't really lay exactly in a 26 dimensional subspace.
- But it is pretty close.
- */
-
-
-
- // Now let's do something more interesting. The following loop finds the centroids
- // of the two classes of data.
- sample_type class1_center;
- sample_type class2_center;
- for (unsigned long i = 0; i < projected_samples.size(); ++i)
- {
- if (labels[i] == 1)
- class1_center += projected_samples[i];
- else
- class2_center += projected_samples[i];
- }
-
- const int points_per_class = samples.size()/2;
- class1_center /= points_per_class;
- class2_center /= points_per_class;
-
-
- // Now classify points by which center they are nearest. Recall that the data
- // is made up of two concentric circles. Normally you can't separate two concentric
- // circles by checking which points are nearest to each center since they have the same
- // centers. However, the kernel trick makes the data separable and the loop below will
- // perfectly classify each data point.
- for (unsigned long i = 0; i < projected_samples.size(); ++i)
- {
- double distance_to_class1 = length(projected_samples[i] - class1_center);
- double distance_to_class2 = length(projected_samples[i] - class2_center);
-
- bool predicted_as_class_1 = (distance_to_class1 < distance_to_class2);
-
- // Now print a message for any misclassified points.
- if (predicted_as_class_1 == true && labels[i] != 1)
- cout << "A point was misclassified" << endl;
-
- if (predicted_as_class_1 == false && labels[i] != 2)
- cout << "A point was misclassified" << endl;
- }
-
-
-
- // Next, note that classifying a point based on its distance between two other
- // points is the same thing as using the plane that lies between those two points
- // as a decision boundary. So let's compute that decision plane and use it to classify
- // all the points.
-
- sample_type plane_normal_vector = class1_center - class2_center;
- // The point right in the center of our two classes should be on the deciding plane, not
- // on one side or the other. This consideration brings us to the formula for the bias.
- double bias = dot((class1_center+class2_center)/2, plane_normal_vector);
-
- // Now classify points by which side of the plane they are on.
- for (unsigned long i = 0; i < projected_samples.size(); ++i)
- {
- double side = dot(plane_normal_vector, projected_samples[i]) - bias;
-
- bool predicted_as_class_1 = (side > 0);
-
- // Now print a message for any misclassified points.
- if (predicted_as_class_1 == true && labels[i] != 1)
- cout << "A point was misclassified" << endl;
-
- if (predicted_as_class_1 == false && labels[i] != 2)
- cout << "A point was misclassified" << endl;
- }
-
-
- // It would be nice to convert this decision rule into a normal decision_function object and
- // dispense with the empirical_kernel_map. Happily, it is possible to do so. Consider the
- // following example code:
- decision_function<kernel_type> dec_funct = ekm.convert_to_decision_function(plane_normal_vector);
- // The dec_funct now computes dot products between plane_normal_vector and the projection
- // of any sample point given to it. All that remains is to account for the bias.
- dec_funct.b = bias;
-
- // now classify points by which side of the plane they are on.
- for (unsigned long i = 0; i < samples.size(); ++i)
- {
- double side = dec_funct(samples[i]);
-
- // And let's just check that the dec_funct really does compute the same thing as the previous equation.
- double side_alternate_equation = dot(plane_normal_vector, projected_samples[i]) - bias;
- if (abs(side-side_alternate_equation) > 1e-14)
- cout << "dec_funct error: " << abs(side-side_alternate_equation) << endl;
-
- bool predicted_as_class_1 = (side > 0);
-
- // Now print a message for any misclassified points.
- if (predicted_as_class_1 == true && labels[i] != 1)
- cout << "A point was misclassified" << endl;
-
- if (predicted_as_class_1 == false && labels[i] != 2)
- cout << "A point was misclassified" << endl;
- }
-
-}
-
-// ----------------------------------------------------------------------------------------
-
-void generate_concentric_circles (
- std::vector<sample_type>& samples,
- std::vector<double>& labels,
- const int num
-)
-{
- sample_type m(2,1);
- samples.clear();
- labels.clear();
-
- dlib::rand rnd;
-
- // make some samples near the origin
- double radius = 1.0;
- for (long i = 0; i < num; ++i)
- {
- double sign = 1;
- if (rnd.get_random_double() < 0.5)
- sign = -1;
- m(0) = 2*radius*rnd.get_random_double()-radius;
- m(1) = sign*sqrt(radius*radius - m(0)*m(0));
-
- samples.push_back(m);
- labels.push_back(1);
- }
-
- // make some samples in a circle around the origin but far away
- radius = 5.0;
- for (long i = 0; i < num; ++i)
- {
- double sign = 1;
- if (rnd.get_random_double() < 0.5)
- sign = -1;
- m(0) = 2*radius*rnd.get_random_double()-radius;
- m(1) = sign*sqrt(radius*radius - m(0)*m(0));
-
- samples.push_back(m);
- labels.push_back(2);
- }
-}
-
-// ----------------------------------------------------------------------------------------
-
diff --git a/ml/dlib/examples/face_detection_ex.cpp b/ml/dlib/examples/face_detection_ex.cpp
deleted file mode 100644
index 9569d44e9..000000000
--- a/ml/dlib/examples/face_detection_ex.cpp
+++ /dev/null
@@ -1,103 +0,0 @@
-// The contents of this file are in the public domain. See LICENSE_FOR_EXAMPLE_PROGRAMS.txt
-/*
-
- This example program shows how to find frontal human faces in an image. In
- particular, this program shows how you can take a list of images from the
- command line and display each on the screen with red boxes overlaid on each
- human face.
-
- The examples/faces folder contains some jpg images of people. You can run
- this program on them and see the detections by executing the following command:
- ./face_detection_ex faces/*.jpg
-
-
- This face detector is made using the now classic Histogram of Oriented
- Gradients (HOG) feature combined with a linear classifier, an image pyramid,
- and sliding window detection scheme. This type of object detector is fairly
- general and capable of detecting many types of semi-rigid objects in
- addition to human faces. Therefore, if you are interested in making your
- own object detectors then read the fhog_object_detector_ex.cpp example
- program. It shows how to use the machine learning tools which were used to
- create dlib's face detector.
-
-
- Finally, note that the face detector is fastest when compiled with at least
- SSE2 instructions enabled. So if you are using a PC with an Intel or AMD
- chip then you should enable at least SSE2 instructions. If you are using
- cmake to compile this program you can enable them by using one of the
- following commands when you create the build project:
- cmake path_to_dlib_root/examples -DUSE_SSE2_INSTRUCTIONS=ON
- cmake path_to_dlib_root/examples -DUSE_SSE4_INSTRUCTIONS=ON
- cmake path_to_dlib_root/examples -DUSE_AVX_INSTRUCTIONS=ON
- This will set the appropriate compiler options for GCC, clang, Visual
- Studio, or the Intel compiler. If you are using another compiler then you
- need to consult your compiler's manual to determine how to enable these
- instructions. Note that AVX is the fastest but requires a CPU from at least
- 2011. SSE4 is the next fastest and is supported by most current machines.
-*/
-
-
-#include <dlib/image_processing/frontal_face_detector.h>
-#include <dlib/gui_widgets.h>
-#include <dlib/image_io.h>
-#include <iostream>
-
-using namespace dlib;
-using namespace std;
-
-// ----------------------------------------------------------------------------------------
-
-int main(int argc, char** argv)
-{
- try
- {
- if (argc == 1)
- {
- cout << "Give some image files as arguments to this program." << endl;
- return 0;
- }
-
- frontal_face_detector detector = get_frontal_face_detector();
- image_window win;
-
- // Loop over all the images provided on the command line.
- for (int i = 1; i < argc; ++i)
- {
- cout << "processing image " << argv[i] << endl;
- array2d<unsigned char> img;
- load_image(img, argv[i]);
- // Make the image bigger by a factor of two. This is useful since
- // the face detector looks for faces that are about 80 by 80 pixels
- // or larger. Therefore, if you want to find faces that are smaller
- // than that then you need to upsample the image as we do here by
- // calling pyramid_up(). So this will allow it to detect faces that
- // are at least 40 by 40 pixels in size. We could call pyramid_up()
- // again to find even smaller faces, but note that every time we
- // upsample the image we make the detector run slower since it must
- // process a larger image.
- pyramid_up(img);
-
- // Now tell the face detector to give us a list of bounding boxes
- // around all the faces it can find in the image.
- std::vector<rectangle> dets = detector(img);
-
- cout << "Number of faces detected: " << dets.size() << endl;
- // Now we show the image on the screen and the face detections as
- // red overlay boxes.
- win.clear_overlay();
- win.set_image(img);
- win.add_overlay(dets, rgb_pixel(255,0,0));
-
- cout << "Hit enter to process the next image..." << endl;
- cin.get();
- }
- }
- catch (exception& e)
- {
- cout << "\nexception thrown!" << endl;
- cout << e.what() << endl;
- }
-}
-
-// ----------------------------------------------------------------------------------------
-
diff --git a/ml/dlib/examples/face_landmark_detection_ex.cpp b/ml/dlib/examples/face_landmark_detection_ex.cpp
deleted file mode 100644
index 6ab7fdf9d..000000000
--- a/ml/dlib/examples/face_landmark_detection_ex.cpp
+++ /dev/null
@@ -1,144 +0,0 @@
-// The contents of this file are in the public domain. See LICENSE_FOR_EXAMPLE_PROGRAMS.txt
-/*
-
- This example program shows how to find frontal human faces in an image and
- estimate their pose. The pose takes the form of 68 landmarks. These are
- points on the face such as the corners of the mouth, along the eyebrows, on
- the eyes, and so forth.
-
-
-
- The face detector we use is made using the classic Histogram of Oriented
- Gradients (HOG) feature combined with a linear classifier, an image pyramid,
- and sliding window detection scheme. The pose estimator was created by
- using dlib's implementation of the paper:
- One Millisecond Face Alignment with an Ensemble of Regression Trees by
- Vahid Kazemi and Josephine Sullivan, CVPR 2014
- and was trained on the iBUG 300-W face landmark dataset (see
- https://ibug.doc.ic.ac.uk/resources/facial-point-annotations/):
- C. Sagonas, E. Antonakos, G, Tzimiropoulos, S. Zafeiriou, M. Pantic.
- 300 faces In-the-wild challenge: Database and results.
- Image and Vision Computing (IMAVIS), Special Issue on Facial Landmark Localisation "In-The-Wild". 2016.
- You can get the trained model file from:
- http://dlib.net/files/shape_predictor_68_face_landmarks.dat.bz2.
- Note that the license for the iBUG 300-W dataset excludes commercial use.
- So you should contact Imperial College London to find out if it's OK for
- you to use this model file in a commercial product.
-
-
- Also, note that you can train your own models using dlib's machine learning
- tools. See train_shape_predictor_ex.cpp to see an example.
-
-
-
-
- Finally, note that the face detector is fastest when compiled with at least
- SSE2 instructions enabled. So if you are using a PC with an Intel or AMD
- chip then you should enable at least SSE2 instructions. If you are using
- cmake to compile this program you can enable them by using one of the
- following commands when you create the build project:
- cmake path_to_dlib_root/examples -DUSE_SSE2_INSTRUCTIONS=ON
- cmake path_to_dlib_root/examples -DUSE_SSE4_INSTRUCTIONS=ON
- cmake path_to_dlib_root/examples -DUSE_AVX_INSTRUCTIONS=ON
- This will set the appropriate compiler options for GCC, clang, Visual
- Studio, or the Intel compiler. If you are using another compiler then you
- need to consult your compiler's manual to determine how to enable these
- instructions. Note that AVX is the fastest but requires a CPU from at least
- 2011. SSE4 is the next fastest and is supported by most current machines.
-*/
-
-
-#include <dlib/image_processing/frontal_face_detector.h>
-#include <dlib/image_processing/render_face_detections.h>
-#include <dlib/image_processing.h>
-#include <dlib/gui_widgets.h>
-#include <dlib/image_io.h>
-#include <iostream>
-
-using namespace dlib;
-using namespace std;
-
-// ----------------------------------------------------------------------------------------
-
-int main(int argc, char** argv)
-{
- try
- {
- // This example takes in a shape model file and then a list of images to
- // process. We will take these filenames in as command line arguments.
- // Dlib comes with example images in the examples/faces folder so give
- // those as arguments to this program.
- if (argc == 1)
- {
- cout << "Call this program like this:" << endl;
- cout << "./face_landmark_detection_ex shape_predictor_68_face_landmarks.dat faces/*.jpg" << endl;
- cout << "\nYou can get the shape_predictor_68_face_landmarks.dat file from:\n";
- cout << "http://dlib.net/files/shape_predictor_68_face_landmarks.dat.bz2" << endl;
- return 0;
- }
-
- // We need a face detector. We will use this to get bounding boxes for
- // each face in an image.
- frontal_face_detector detector = get_frontal_face_detector();
- // And we also need a shape_predictor. This is the tool that will predict face
- // landmark positions given an image and face bounding box. Here we are just
- // loading the model from the shape_predictor_68_face_landmarks.dat file you gave
- // as a command line argument.
- shape_predictor sp;
- deserialize(argv[1]) >> sp;
-
-
- image_window win, win_faces;
- // Loop over all the images provided on the command line.
- for (int i = 2; i < argc; ++i)
- {
- cout << "processing image " << argv[i] << endl;
- array2d<rgb_pixel> img;
- load_image(img, argv[i]);
- // Make the image larger so we can detect small faces.
- pyramid_up(img);
-
- // Now tell the face detector to give us a list of bounding boxes
- // around all the faces in the image.
- std::vector<rectangle> dets = detector(img);
- cout << "Number of faces detected: " << dets.size() << endl;
-
- // Now we will go ask the shape_predictor to tell us the pose of
- // each face we detected.
- std::vector<full_object_detection> shapes;
- for (unsigned long j = 0; j < dets.size(); ++j)
- {
- full_object_detection shape = sp(img, dets[j]);
- cout << "number of parts: "<< shape.num_parts() << endl;
- cout << "pixel position of first part: " << shape.part(0) << endl;
- cout << "pixel position of second part: " << shape.part(1) << endl;
- // You get the idea, you can get all the face part locations if
- // you want them. Here we just store them in shapes so we can
- // put them on the screen.
- shapes.push_back(shape);
- }
-
- // Now let's view our face poses on the screen.
- win.clear_overlay();
- win.set_image(img);
- win.add_overlay(render_face_detections(shapes));
-
- // We can also extract copies of each face that are cropped, rotated upright,
- // and scaled to a standard size as shown here:
- dlib::array<array2d<rgb_pixel> > face_chips;
- extract_image_chips(img, get_face_chip_details(shapes), face_chips);
- win_faces.set_image(tile_images(face_chips));
-
- cout << "Hit enter to process the next image..." << endl;
- cin.get();
- }
- }
- catch (exception& e)
- {
- cout << "\nexception thrown!" << endl;
- cout << e.what() << endl;
- }
-}
-
-// ----------------------------------------------------------------------------------------
-
diff --git a/ml/dlib/examples/faces/2007_007763.jpg b/ml/dlib/examples/faces/2007_007763.jpg
deleted file mode 100755
index 6f19d2d67..000000000
--- a/ml/dlib/examples/faces/2007_007763.jpg
+++ /dev/null
Binary files differ
diff --git a/ml/dlib/examples/faces/2008_001009.jpg b/ml/dlib/examples/faces/2008_001009.jpg
deleted file mode 100755
index 411aeb3c6..000000000
--- a/ml/dlib/examples/faces/2008_001009.jpg
+++ /dev/null
Binary files differ
diff --git a/ml/dlib/examples/faces/2008_001322.jpg b/ml/dlib/examples/faces/2008_001322.jpg
deleted file mode 100755
index 354db0b6c..000000000
--- a/ml/dlib/examples/faces/2008_001322.jpg
+++ /dev/null
Binary files differ
diff --git a/ml/dlib/examples/faces/2008_002079.jpg b/ml/dlib/examples/faces/2008_002079.jpg
deleted file mode 100755
index 8d19673ef..000000000
--- a/ml/dlib/examples/faces/2008_002079.jpg
+++ /dev/null
Binary files differ
diff --git a/ml/dlib/examples/faces/2008_002470.jpg b/ml/dlib/examples/faces/2008_002470.jpg
deleted file mode 100755
index fb0e44cb6..000000000
--- a/ml/dlib/examples/faces/2008_002470.jpg
+++ /dev/null
Binary files differ
diff --git a/ml/dlib/examples/faces/2008_002506.jpg b/ml/dlib/examples/faces/2008_002506.jpg
deleted file mode 100755
index 7508cb959..000000000
--- a/ml/dlib/examples/faces/2008_002506.jpg
+++ /dev/null
Binary files differ
diff --git a/ml/dlib/examples/faces/2008_004176.jpg b/ml/dlib/examples/faces/2008_004176.jpg
deleted file mode 100755
index f018b743f..000000000
--- a/ml/dlib/examples/faces/2008_004176.jpg
+++ /dev/null
Binary files differ
diff --git a/ml/dlib/examples/faces/2008_007676.jpg b/ml/dlib/examples/faces/2008_007676.jpg
deleted file mode 100755
index 646196f31..000000000
--- a/ml/dlib/examples/faces/2008_007676.jpg
+++ /dev/null
Binary files differ
diff --git a/ml/dlib/examples/faces/2009_004587.jpg b/ml/dlib/examples/faces/2009_004587.jpg
deleted file mode 100755
index e10c42d97..000000000
--- a/ml/dlib/examples/faces/2009_004587.jpg
+++ /dev/null
Binary files differ
diff --git a/ml/dlib/examples/faces/Tom_Cruise_avp_2014_4.jpg b/ml/dlib/examples/faces/Tom_Cruise_avp_2014_4.jpg
deleted file mode 100644
index bb2d73327..000000000
--- a/ml/dlib/examples/faces/Tom_Cruise_avp_2014_4.jpg
+++ /dev/null
Binary files differ
diff --git a/ml/dlib/examples/faces/bald_guys.jpg b/ml/dlib/examples/faces/bald_guys.jpg
deleted file mode 100644
index dbd431f85..000000000
--- a/ml/dlib/examples/faces/bald_guys.jpg
+++ /dev/null
Binary files differ
diff --git a/ml/dlib/examples/faces/dogs.jpg b/ml/dlib/examples/faces/dogs.jpg
deleted file mode 100644
index 15667141d..000000000
--- a/ml/dlib/examples/faces/dogs.jpg
+++ /dev/null
Binary files differ
diff --git a/ml/dlib/examples/faces/image_metadata_stylesheet.xsl b/ml/dlib/examples/faces/image_metadata_stylesheet.xsl
deleted file mode 100644
index 5d4a29539..000000000
--- a/ml/dlib/examples/faces/image_metadata_stylesheet.xsl
+++ /dev/null
@@ -1,109 +0,0 @@
-<?xml version="1.0" encoding="ISO-8859-1" ?>
-
-<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
-<xsl:output method='html' version='1.0' encoding='UTF-8' indent='yes' />
-
-<!-- ************************************************************************* -->
-
- <xsl:variable name="max_images_displayed">30</xsl:variable>
-
-<!-- ************************************************************************* -->
-
- <xsl:template match="/dataset">
- <html>
- <head>
-
- <style type="text/css">
- div#box{
- position: absolute;
- border-style:solid;
- border-width:1px;
- border-color:red;
- }
-
- div#circle{
- position: absolute;
- border-style:solid;
- border-width:1px;
- border-color:red;
- border-radius:7px;
- width:1px;
- height: 1px;
- }
-
- div#label{
- position: absolute;
- color: red;
- }
-
- div#img{
- position: relative;
- margin-bottom:2em;
- }
-
-
- pre {
- color: black;
- margin: 1em 0.25in;
- padding: 0.5em;
- background: rgb(240,240,240);
- border-top: black dotted 1px;
- border-left: black dotted 1px;
- border-right: black solid 2px;
- border-bottom: black solid 2px;
- }
-
- </style>
-
- </head>
-
- <body>
- Dataset name: <b><xsl:value-of select='/dataset/name'/></b> <br/>
- Dataset comment: <pre><xsl:value-of select='/dataset/comment'/></pre> <br/>
- Number of images: <xsl:value-of select="count(images/image)"/> <br/>
- Number of boxes: <xsl:value-of select="count(images/image/box)"/> <br/>
- <br/>
- <hr/>
-
- <!-- Show a warning if we aren't going to show all the images -->
- <xsl:if test="count(images/image) &gt; $max_images_displayed">
- <h2>Only displaying the first <xsl:value-of select="$max_images_displayed"/> images.</h2>
- <hr/>
- </xsl:if>
-
-
- <xsl:for-each select="images/image">
- <!-- Don't try to display too many images. It makes your browser hang -->
- <xsl:if test="position() &lt;= $max_images_displayed">
- <b><xsl:value-of select="@file"/></b> (Number of boxes: <xsl:value-of select="count(box)"/>)
- <div id="img">
- <img src="{@file}"/>
- <xsl:for-each select="box">
- <div id="box" style="top: {@top}px; left: {@left}px; width: {@width}px; height: {@height}px;"></div>
-
- <!-- If there is a label then display it in the lower right corner. -->
- <xsl:if test="label">
- <div id="label" style="top: {@top+@height}px; left: {@left+@width}px;">
- <xsl:value-of select="label"/>
- </div>
- </xsl:if>
-
- <xsl:for-each select="part">
- <!--
- <div id="label" style="top: {@y+7}px; left: {@x}px;">
- <xsl:value-of select="@name"/>
- </div>
- -->
- <div id="circle" style="top: {(@y)}px; left: {(@x)}px; "></div>
- </xsl:for-each>
- </xsl:for-each>
- </div>
- </xsl:if>
- </xsl:for-each>
- </body>
- </html>
- </xsl:template>
-
- <!-- ************************************************************************* -->
-
-</xsl:stylesheet>
diff --git a/ml/dlib/examples/faces/testing.xml b/ml/dlib/examples/faces/testing.xml
deleted file mode 100644
index f7ef446c3..000000000
--- a/ml/dlib/examples/faces/testing.xml
+++ /dev/null
@@ -1,43 +0,0 @@
-<?xml version='1.0' encoding='ISO-8859-1'?>
-<?xml-stylesheet type='text/xsl' href='image_metadata_stylesheet.xsl'?>
-<dataset>
-<name>Testing faces</name>
-<comment>These are images from the PASCAL VOC 2011 dataset.</comment>
-<images>
- <image file='2008_002470.jpg'>
- <box top='181' left='274' width='52' height='53'/>
- <box top='156' left='55' width='44' height='44'/>
- <box top='166' left='146' width='37' height='37'/>
- <box top='55' left='329' width='44' height='44'/>
- <box top='74' left='233' width='44' height='44'/>
- <box top='86' left='178' width='37' height='37'/>
- </image>
- <image file='2008_002506.jpg'>
- <box top='78' left='329' width='109' height='109'/>
- <box top='95' left='224' width='91' height='91'/>
- <box top='65' left='125' width='90' height='91'/>
- </image>
- <image file='2008_004176.jpg'>
- <box top='230' left='206' width='37' height='37'/>
- <box top='118' left='162' width='37' height='37'/>
- <box top='82' left='190' width='37' height='37'/>
- <box top='78' left='326' width='37' height='37'/>
- <box top='98' left='222' width='37' height='37'/>
- <box top='86' left='110' width='37' height='37'/>
- <box top='102' left='282' width='37' height='37'/>
- </image>
- <image file='2008_007676.jpg'>
- <box top='62' left='226' width='37' height='37'/>
- <box top='113' left='194' width='44' height='44'/>
- <box top='130' left='262' width='37' height='37'/>
- <box top='134' left='366' width='37' height='37'/>
- <box top='122' left='314' width='37' height='37'/>
- <box top='141' left='107' width='52' height='53'/>
- <box top='84' left='137' width='44' height='44'/>
- </image>
- <image file='2009_004587.jpg'>
- <box top='46' left='154' width='75' height='76'/>
- <box top='280' left='266' width='63' height='63'/>
- </image>
-</images>
-</dataset>
diff --git a/ml/dlib/examples/faces/testing_with_face_landmarks.xml b/ml/dlib/examples/faces/testing_with_face_landmarks.xml
deleted file mode 100644
index 7589561b1..000000000
--- a/ml/dlib/examples/faces/testing_with_face_landmarks.xml
+++ /dev/null
@@ -1,1772 +0,0 @@
-<?xml version='1.0' encoding='ISO-8859-1'?>
-<?xml-stylesheet type='text/xsl' href='image_metadata_stylesheet.xsl'?>
-<dataset>
-<name>Testing faces</name>
-<comment>These are images from the PASCAL VOC 2011 dataset.
- The face landmarks are from dlib's shape_predictor_68_face_landmarks.dat
- landmarking model. The model uses the 68 landmark scheme used by the iBUG
- 300-W dataset.
-</comment>
-<images>
- <image file='2008_002470.jpg'>
- <box top='181' left='274' width='52' height='53'>
- <part name='00' x='277' y='194'/>
- <part name='01' x='278' y='200'/>
- <part name='02' x='278' y='206'/>
- <part name='03' x='279' y='212'/>
- <part name='04' x='281' y='218'/>
- <part name='05' x='285' y='223'/>
- <part name='06' x='289' y='227'/>
- <part name='07' x='294' y='231'/>
- <part name='08' x='300' y='232'/>
- <part name='09' x='306' y='231'/>
- <part name='10' x='312' y='228'/>
- <part name='11' x='317' y='223'/>
- <part name='12' x='321' y='218'/>
- <part name='13' x='323' y='212'/>
- <part name='14' x='324' y='205'/>
- <part name='15' x='325' y='198'/>
- <part name='16' x='325' y='192'/>
- <part name='17' x='280' y='190'/>
- <part name='18' x='282' y='188'/>
- <part name='19' x='286' y='187'/>
- <part name='20' x='290' y='187'/>
- <part name='21' x='294' y='189'/>
- <part name='22' x='303' y='189'/>
- <part name='23' x='306' y='187'/>
- <part name='24' x='311' y='187'/>
- <part name='25' x='315' y='188'/>
- <part name='26' x='318' y='190'/>
- <part name='27' x='298' y='194'/>
- <part name='28' x='298' y='199'/>
- <part name='29' x='298' y='204'/>
- <part name='30' x='298' y='209'/>
- <part name='31' x='293' y='210'/>
- <part name='32' x='296' y='211'/>
- <part name='33' x='298' y='212'/>
- <part name='34' x='301' y='211'/>
- <part name='35' x='304' y='210'/>
- <part name='36' x='285' y='195'/>
- <part name='37' x='287' y='194'/>
- <part name='38' x='290' y='194'/>
- <part name='39' x='292' y='195'/>
- <part name='40' x='290' y='196'/>
- <part name='41' x='287' y='196'/>
- <part name='42' x='306' y='195'/>
- <part name='43' x='308' y='194'/>
- <part name='44' x='311' y='194'/>
- <part name='45' x='313' y='195'/>
- <part name='46' x='311' y='195'/>
- <part name='47' x='308' y='196'/>
- <part name='48' x='291' y='216'/>
- <part name='49' x='294' y='216'/>
- <part name='50' x='297' y='216'/>
- <part name='51' x='299' y='216'/>
- <part name='52' x='302' y='216'/>
- <part name='53' x='306' y='216'/>
- <part name='54' x='310' y='216'/>
- <part name='55' x='306' y='220'/>
- <part name='56' x='302' y='221'/>
- <part name='57' x='299' y='221'/>
- <part name='58' x='297' y='221'/>
- <part name='59' x='293' y='220'/>
- <part name='60' x='292' y='217'/>
- <part name='61' x='297' y='218'/>
- <part name='62' x='299' y='218'/>
- <part name='63' x='302' y='217'/>
- <part name='64' x='308' y='217'/>
- <part name='65' x='302' y='218'/>
- <part name='66' x='299' y='218'/>
- <part name='67' x='297' y='218'/>
- </box>
- <box top='156' left='55' width='44' height='44'>
- <part name='00' x='54' y='170'/>
- <part name='01' x='55' y='176'/>
- <part name='02' x='55' y='182'/>
- <part name='03' x='57' y='188'/>
- <part name='04' x='59' y='193'/>
- <part name='05' x='63' y='197'/>
- <part name='06' x='68' y='201'/>
- <part name='07' x='73' y='203'/>
- <part name='08' x='79' y='204'/>
- <part name='09' x='84' y='202'/>
- <part name='10' x='88' y='199'/>
- <part name='11' x='91' y='195'/>
- <part name='12' x='94' y='191'/>
- <part name='13' x='95' y='186'/>
- <part name='14' x='96' y='181'/>
- <part name='15' x='97' y='176'/>
- <part name='16' x='97' y='171'/>
- <part name='17' x='61' y='166'/>
- <part name='18' x='64' y='164'/>
- <part name='19' x='68' y='163'/>
- <part name='20' x='72' y='163'/>
- <part name='21' x='76' y='165'/>
- <part name='22' x='85' y='166'/>
- <part name='23' x='88' y='164'/>
- <part name='24' x='91' y='164'/>
- <part name='25' x='94' y='165'/>
- <part name='26' x='96' y='167'/>
- <part name='27' x='80' y='170'/>
- <part name='28' x='81' y='173'/>
- <part name='29' x='81' y='176'/>
- <part name='30' x='81' y='180'/>
- <part name='31' x='76' y='182'/>
- <part name='32' x='78' y='183'/>
- <part name='33' x='80' y='184'/>
- <part name='34' x='82' y='183'/>
- <part name='35' x='84' y='183'/>
- <part name='36' x='65' y='170'/>
- <part name='37' x='68' y='169'/>
- <part name='38' x='71' y='169'/>
- <part name='39' x='73' y='170'/>
- <part name='40' x='71' y='171'/>
- <part name='41' x='68' y='171'/>
- <part name='42' x='85' y='171'/>
- <part name='43' x='88' y='169'/>
- <part name='44' x='90' y='169'/>
- <part name='45' x='92' y='171'/>
- <part name='46' x='90' y='171'/>
- <part name='47' x='88' y='171'/>
- <part name='48' x='71' y='190'/>
- <part name='49' x='75' y='188'/>
- <part name='50' x='78' y='188'/>
- <part name='51' x='80' y='188'/>
- <part name='52' x='82' y='188'/>
- <part name='53' x='85' y='188'/>
- <part name='54' x='87' y='189'/>
- <part name='55' x='85' y='191'/>
- <part name='56' x='82' y='192'/>
- <part name='57' x='80' y='192'/>
- <part name='58' x='78' y='192'/>
- <part name='59' x='74' y='192'/>
- <part name='60' x='72' y='190'/>
- <part name='61' x='78' y='189'/>
- <part name='62' x='80' y='189'/>
- <part name='63' x='82' y='189'/>
- <part name='64' x='86' y='189'/>
- <part name='65' x='82' y='189'/>
- <part name='66' x='80' y='190'/>
- <part name='67' x='78' y='190'/>
- </box>
- <box top='166' left='146' width='37' height='37'>
- <part name='00' x='152' y='181'/>
- <part name='01' x='152' y='185'/>
- <part name='02' x='153' y='188'/>
- <part name='03' x='154' y='192'/>
- <part name='04' x='156' y='195'/>
- <part name='05' x='159' y='198'/>
- <part name='06' x='162' y='201'/>
- <part name='07' x='165' y='203'/>
- <part name='08' x='168' y='203'/>
- <part name='09' x='172' y='202'/>
- <part name='10' x='176' y='200'/>
- <part name='11' x='179' y='198'/>
- <part name='12' x='181' y='195'/>
- <part name='13' x='183' y='191'/>
- <part name='14' x='184' y='187'/>
- <part name='15' x='184' y='183'/>
- <part name='16' x='184' y='178'/>
- <part name='17' x='154' y='176'/>
- <part name='18' x='155' y='174'/>
- <part name='19' x='157' y='174'/>
- <part name='20' x='160' y='174'/>
- <part name='21' x='162' y='175'/>
- <part name='22' x='170' y='174'/>
- <part name='23' x='172' y='172'/>
- <part name='24' x='175' y='172'/>
- <part name='25' x='177' y='173'/>
- <part name='26' x='179' y='174'/>
- <part name='27' x='166' y='178'/>
- <part name='28' x='166' y='180'/>
- <part name='29' x='166' y='183'/>
- <part name='30' x='166' y='185'/>
- <part name='31' x='163' y='187'/>
- <part name='32' x='165' y='188'/>
- <part name='33' x='166' y='188'/>
- <part name='34' x='168' y='188'/>
- <part name='35' x='170' y='187'/>
- <part name='36' x='157' y='179'/>
- <part name='37' x='158' y='178'/>
- <part name='38' x='160' y='178'/>
- <part name='39' x='162' y='179'/>
- <part name='40' x='160' y='179'/>
- <part name='41' x='158' y='180'/>
- <part name='42' x='171' y='178'/>
- <part name='43' x='172' y='177'/>
- <part name='44' x='174' y='177'/>
- <part name='45' x='176' y='178'/>
- <part name='46' x='175' y='178'/>
- <part name='47' x='173' y='178'/>
- <part name='48' x='161' y='193'/>
- <part name='49' x='163' y='191'/>
- <part name='50' x='165' y='191'/>
- <part name='51' x='167' y='191'/>
- <part name='52' x='168' y='190'/>
- <part name='53' x='171' y='191'/>
- <part name='54' x='173' y='191'/>
- <part name='55' x='171' y='194'/>
- <part name='56' x='169' y='195'/>
- <part name='57' x='167' y='195'/>
- <part name='58' x='165' y='195'/>
- <part name='59' x='163' y='195'/>
- <part name='60' x='162' y='193'/>
- <part name='61' x='165' y='192'/>
- <part name='62' x='167' y='192'/>
- <part name='63' x='168' y='191'/>
- <part name='64' x='172' y='192'/>
- <part name='65' x='169' y='193'/>
- <part name='66' x='167' y='193'/>
- <part name='67' x='165' y='193'/>
- </box>
- <box top='55' left='329' width='44' height='44'>
- <part name='00' x='327' y='73'/>
- <part name='01' x='328' y='78'/>
- <part name='02' x='330' y='83'/>
- <part name='03' x='332' y='88'/>
- <part name='04' x='334' y='93'/>
- <part name='05' x='338' y='97'/>
- <part name='06' x='342' y='100'/>
- <part name='07' x='347' y='102'/>
- <part name='08' x='352' y='102'/>
- <part name='09' x='358' y='100'/>
- <part name='10' x='363' y='97'/>
- <part name='11' x='366' y='93'/>
- <part name='12' x='369' y='89'/>
- <part name='13' x='371' y='83'/>
- <part name='14' x='371' y='77'/>
- <part name='15' x='371' y='71'/>
- <part name='16' x='371' y='65'/>
- <part name='17' x='329' y='66'/>
- <part name='18' x='330' y='63'/>
- <part name='19' x='334' y='60'/>
- <part name='20' x='338' y='60'/>
- <part name='21' x='342' y='60'/>
- <part name='22' x='349' y='59'/>
- <part name='23' x='353' y='57'/>
- <part name='24' x='357' y='56'/>
- <part name='25' x='362' y='57'/>
- <part name='26' x='365' y='60'/>
- <part name='27' x='346' y='65'/>
- <part name='28' x='346' y='69'/>
- <part name='29' x='347' y='72'/>
- <part name='30' x='347' y='76'/>
- <part name='31' x='344' y='80'/>
- <part name='32' x='346' y='80'/>
- <part name='33' x='348' y='80'/>
- <part name='34' x='350' y='79'/>
- <part name='35' x='352' y='78'/>
- <part name='36' x='334' y='69'/>
- <part name='37' x='336' y='67'/>
- <part name='38' x='338' y='67'/>
- <part name='39' x='341' y='67'/>
- <part name='40' x='339' y='68'/>
- <part name='41' x='336' y='69'/>
- <part name='42' x='353' y='65'/>
- <part name='43' x='355' y='64'/>
- <part name='44' x='357' y='63'/>
- <part name='45' x='360' y='64'/>
- <part name='46' x='358' y='65'/>
- <part name='47' x='355' y='65'/>
- <part name='48' x='342' y='88'/>
- <part name='49' x='344' y='86'/>
- <part name='50' x='347' y='84'/>
- <part name='51' x='349' y='84'/>
- <part name='52' x='351' y='83'/>
- <part name='53' x='355' y='84'/>
- <part name='54' x='358' y='85'/>
- <part name='55' x='356' y='88'/>
- <part name='56' x='353' y='90'/>
- <part name='57' x='350' y='90'/>
- <part name='58' x='348' y='91'/>
- <part name='59' x='345' y='90'/>
- <part name='60' x='344' y='88'/>
- <part name='61' x='347' y='87'/>
- <part name='62' x='350' y='86'/>
- <part name='63' x='352' y='86'/>
- <part name='64' x='356' y='86'/>
- <part name='65' x='352' y='87'/>
- <part name='66' x='350' y='87'/>
- <part name='67' x='348' y='87'/>
- </box>
- <box top='74' left='233' width='44' height='44'>
- <part name='00' x='239' y='92'/>
- <part name='01' x='240' y='97'/>
- <part name='02' x='241' y='101'/>
- <part name='03' x='243' y='104'/>
- <part name='04' x='245' y='108'/>
- <part name='05' x='248' y='111'/>
- <part name='06' x='252' y='112'/>
- <part name='07' x='256' y='114'/>
- <part name='08' x='260' y='113'/>
- <part name='09' x='265' y='112'/>
- <part name='10' x='268' y='109'/>
- <part name='11' x='272' y='106'/>
- <part name='12' x='274' y='102'/>
- <part name='13' x='276' y='98'/>
- <part name='14' x='276' y='93'/>
- <part name='15' x='275' y='88'/>
- <part name='16' x='274' y='83'/>
- <part name='17' x='239' y='89'/>
- <part name='18' x='240' y='86'/>
- <part name='19' x='242' y='84'/>
- <part name='20' x='246' y='84'/>
- <part name='21' x='249' y='84'/>
- <part name='22' x='253' y='82'/>
- <part name='23' x='256' y='80'/>
- <part name='24' x='259' y='79'/>
- <part name='25' x='263' y='78'/>
- <part name='26' x='267' y='80'/>
- <part name='27' x='252' y='86'/>
- <part name='28' x='252' y='88'/>
- <part name='29' x='253' y='91'/>
- <part name='30' x='253' y='93'/>
- <part name='31' x='251' y='97'/>
- <part name='32' x='253' y='97'/>
- <part name='33' x='254' y='97'/>
- <part name='34' x='256' y='96'/>
- <part name='35' x='258' y='95'/>
- <part name='36' x='243' y='90'/>
- <part name='37' x='244' y='88'/>
- <part name='38' x='246' y='88'/>
- <part name='39' x='248' y='88'/>
- <part name='40' x='247' y='89'/>
- <part name='41' x='245' y='90'/>
- <part name='42' x='258' y='85'/>
- <part name='43' x='259' y='84'/>
- <part name='44' x='261' y='83'/>
- <part name='45' x='263' y='84'/>
- <part name='46' x='262' y='85'/>
- <part name='47' x='260' y='85'/>
- <part name='48' x='251' y='104'/>
- <part name='49' x='252' y='102'/>
- <part name='50' x='254' y='100'/>
- <part name='51' x='256' y='100'/>
- <part name='52' x='258' y='100'/>
- <part name='53' x='261' y='100'/>
- <part name='54' x='264' y='100'/>
- <part name='55' x='262' y='102'/>
- <part name='56' x='259' y='103'/>
- <part name='57' x='257' y='104'/>
- <part name='58' x='255' y='104'/>
- <part name='59' x='253' y='105'/>
- <part name='60' x='252' y='104'/>
- <part name='61' x='254' y='102'/>
- <part name='62' x='256' y='102'/>
- <part name='63' x='258' y='101'/>
- <part name='64' x='263' y='101'/>
- <part name='65' x='258' y='101'/>
- <part name='66' x='256' y='102'/>
- <part name='67' x='254' y='102'/>
- </box>
- <box top='86' left='178' width='37' height='37'>
- <part name='00' x='184' y='101'/>
- <part name='01' x='184' y='104'/>
- <part name='02' x='185' y='108'/>
- <part name='03' x='187' y='111'/>
- <part name='04' x='188' y='115'/>
- <part name='05' x='190' y='117'/>
- <part name='06' x='193' y='120'/>
- <part name='07' x='196' y='122'/>
- <part name='08' x='199' y='122'/>
- <part name='09' x='203' y='121'/>
- <part name='10' x='207' y='118'/>
- <part name='11' x='210' y='116'/>
- <part name='12' x='213' y='113'/>
- <part name='13' x='215' y='109'/>
- <part name='14' x='216' y='105'/>
- <part name='15' x='216' y='100'/>
- <part name='16' x='216' y='96'/>
- <part name='17' x='185' y='96'/>
- <part name='18' x='186' y='94'/>
- <part name='19' x='188' y='93'/>
- <part name='20' x='190' y='93'/>
- <part name='21' x='192' y='93'/>
- <part name='22' x='197' y='92'/>
- <part name='23' x='200' y='90'/>
- <part name='24' x='203' y='89'/>
- <part name='25' x='206' y='90'/>
- <part name='26' x='208' y='92'/>
- <part name='27' x='195' y='96'/>
- <part name='28' x='195' y='99'/>
- <part name='29' x='195' y='102'/>
- <part name='30' x='195' y='104'/>
- <part name='31' x='194' y='107'/>
- <part name='32' x='195' y='107'/>
- <part name='33' x='196' y='107'/>
- <part name='34' x='198' y='107'/>
- <part name='35' x='200' y='106'/>
- <part name='36' x='188' y='99'/>
- <part name='37' x='189' y='97'/>
- <part name='38' x='191' y='97'/>
- <part name='39' x='192' y='98'/>
- <part name='40' x='191' y='99'/>
- <part name='41' x='189' y='99'/>
- <part name='42' x='200' y='97'/>
- <part name='43' x='202' y='95'/>
- <part name='44' x='203' y='95'/>
- <part name='45' x='205' y='96'/>
- <part name='46' x='204' y='96'/>
- <part name='47' x='202' y='97'/>
- <part name='48' x='193' y='113'/>
- <part name='49' x='194' y='111'/>
- <part name='50' x='196' y='111'/>
- <part name='51' x='197' y='111'/>
- <part name='52' x='199' y='110'/>
- <part name='53' x='201' y='110'/>
- <part name='54' x='204' y='111'/>
- <part name='55' x='202' y='113'/>
- <part name='56' x='199' y='114'/>
- <part name='57' x='198' y='114'/>
- <part name='58' x='196' y='114'/>
- <part name='59' x='195' y='114'/>
- <part name='60' x='194' y='113'/>
- <part name='61' x='196' y='112'/>
- <part name='62' x='197' y='112'/>
- <part name='63' x='199' y='112'/>
- <part name='64' x='203' y='111'/>
- <part name='65' x='199' y='112'/>
- <part name='66' x='197' y='112'/>
- <part name='67' x='196' y='112'/>
- </box>
- </image>
- <image file='2008_002506.jpg'>
- <box top='78' left='329' width='109' height='109'>
- <part name='00' x='342' y='134'/>
- <part name='01' x='345' y='145'/>
- <part name='02' x='347' y='155'/>
- <part name='03' x='351' y='165'/>
- <part name='04' x='357' y='175'/>
- <part name='05' x='365' y='183'/>
- <part name='06' x='375' y='190'/>
- <part name='07' x='386' y='194'/>
- <part name='08' x='399' y='193'/>
- <part name='09' x='411' y='188'/>
- <part name='10' x='423' y='180'/>
- <part name='11' x='434' y='172'/>
- <part name='12' x='443' y='161'/>
- <part name='13' x='447' y='149'/>
- <part name='14' x='446' y='134'/>
- <part name='15' x='443' y='120'/>
- <part name='16' x='441' y='106'/>
- <part name='17' x='342' y='125'/>
- <part name='18' x='343' y='116'/>
- <part name='19' x='350' y='109'/>
- <part name='20' x='359' y='105'/>
- <part name='21' x='368' y='105'/>
- <part name='22' x='380' y='99'/>
- <part name='23' x='390' y='93'/>
- <part name='24' x='402' y='91'/>
- <part name='25' x='413' y='92'/>
- <part name='26' x='422' y='99'/>
- <part name='27' x='375' y='112'/>
- <part name='28' x='376' y='119'/>
- <part name='29' x='376' y='126'/>
- <part name='30' x='377' y='133'/>
- <part name='31' x='372' y='142'/>
- <part name='32' x='377' y='142'/>
- <part name='33' x='382' y='142'/>
- <part name='34' x='387' y='139'/>
- <part name='35' x='393' y='136'/>
- <part name='36' x='353' y='127'/>
- <part name='37' x='356' y='122'/>
- <part name='38' x='362' y='120'/>
- <part name='39' x='368' y='120'/>
- <part name='40' x='363' y='123'/>
- <part name='41' x='358' y='125'/>
- <part name='42' x='393' y='112'/>
- <part name='43' x='397' y='107'/>
- <part name='44' x='403' y='106'/>
- <part name='45' x='409' y='107'/>
- <part name='46' x='404' y='108'/>
- <part name='47' x='399' y='110'/>
- <part name='48' x='369' y='159'/>
- <part name='49' x='373' y='154'/>
- <part name='50' x='380' y='151'/>
- <part name='51' x='386' y='150'/>
- <part name='52' x='392' y='147'/>
- <part name='53' x='403' y='146'/>
- <part name='54' x='416' y='146'/>
- <part name='55' x='407' y='156'/>
- <part name='56' x='398' y='161'/>
- <part name='57' x='391' y='163'/>
- <part name='58' x='385' y='164'/>
- <part name='59' x='377' y='165'/>
- <part name='60' x='371' y='158'/>
- <part name='61' x='381' y='152'/>
- <part name='62' x='387' y='151'/>
- <part name='63' x='394' y='149'/>
- <part name='64' x='413' y='148'/>
- <part name='65' x='395' y='157'/>
- <part name='66' x='389' y='160'/>
- <part name='67' x='383' y='161'/>
- </box>
- <box top='95' left='224' width='91' height='91'>
- <part name='00' x='227' y='134'/>
- <part name='01' x='229' y='145'/>
- <part name='02' x='231' y='155'/>
- <part name='03' x='233' y='166'/>
- <part name='04' x='238' y='175'/>
- <part name='05' x='246' y='182'/>
- <part name='06' x='255' y='188'/>
- <part name='07' x='264' y='192'/>
- <part name='08' x='274' y='193'/>
- <part name='09' x='283' y='190'/>
- <part name='10' x='291' y='184'/>
- <part name='11' x='298' y='177'/>
- <part name='12' x='304' y='169'/>
- <part name='13' x='308' y='159'/>
- <part name='14' x='308' y='148'/>
- <part name='15' x='308' y='137'/>
- <part name='16' x='308' y='125'/>
- <part name='17' x='232' y='123'/>
- <part name='18' x='236' y='118'/>
- <part name='19' x='242' y='116'/>
- <part name='20' x='249' y='116'/>
- <part name='21' x='257' y='118'/>
- <part name='22' x='273' y='117'/>
- <part name='23' x='280' y='113'/>
- <part name='24' x='287' y='111'/>
- <part name='25' x='295' y='111'/>
- <part name='26' x='301' y='116'/>
- <part name='27' x='265' y='125'/>
- <part name='28' x='266' y='130'/>
- <part name='29' x='267' y='136'/>
- <part name='30' x='268' y='142'/>
- <part name='31' x='260' y='147'/>
- <part name='32' x='264' y='148'/>
- <part name='33' x='269' y='149'/>
- <part name='34' x='273' y='147'/>
- <part name='35' x='277' y='146'/>
- <part name='36' x='241' y='129'/>
- <part name='37' x='245' y='127'/>
- <part name='38' x='250' y='126'/>
- <part name='39' x='255' y='128'/>
- <part name='40' x='250' y='129'/>
- <part name='41' x='246' y='129'/>
- <part name='42' x='278' y='126'/>
- <part name='43' x='282' y='123'/>
- <part name='44' x='287' y='122'/>
- <part name='45' x='291' y='124'/>
- <part name='46' x='287' y='125'/>
- <part name='47' x='282' y='125'/>
- <part name='48' x='253' y='164'/>
- <part name='49' x='258' y='158'/>
- <part name='50' x='265' y='156'/>
- <part name='51' x='270' y='156'/>
- <part name='52' x='275' y='155'/>
- <part name='53' x='283' y='156'/>
- <part name='54' x='290' y='160'/>
- <part name='55' x='285' y='170'/>
- <part name='56' x='278' y='174'/>
- <part name='57' x='272' y='175'/>
- <part name='58' x='266' y='175'/>
- <part name='59' x='259' y='172'/>
- <part name='60' x='255' y='163'/>
- <part name='61' x='265' y='158'/>
- <part name='62' x='270' y='158'/>
- <part name='63' x='276' y='157'/>
- <part name='64' x='288' y='160'/>
- <part name='65' x='277' y='170'/>
- <part name='66' x='271' y='170'/>
- <part name='67' x='266' y='170'/>
- </box>
- <box top='65' left='125' width='90' height='91'>
- <part name='00' x='117' y='92'/>
- <part name='01' x='116' y='105'/>
- <part name='02' x='115' y='117'/>
- <part name='03' x='115' y='130'/>
- <part name='04' x='120' y='140'/>
- <part name='05' x='129' y='147'/>
- <part name='06' x='140' y='152'/>
- <part name='07' x='151' y='157'/>
- <part name='08' x='161' y='160'/>
- <part name='09' x='170' y='161'/>
- <part name='10' x='179' y='158'/>
- <part name='11' x='187' y='154'/>
- <part name='12' x='193' y='147'/>
- <part name='13' x='198' y='139'/>
- <part name='14' x='200' y='130'/>
- <part name='15' x='202' y='121'/>
- <part name='16' x='202' y='113'/>
- <part name='17' x='137' y='76'/>
- <part name='18' x='145' y='70'/>
- <part name='19' x='155' y='68'/>
- <part name='20' x='164' y='70'/>
- <part name='21' x='173' y='75'/>
- <part name='22' x='186' y='81'/>
- <part name='23' x='193' y='81'/>
- <part name='24' x='199' y='84'/>
- <part name='25' x='204' y='90'/>
- <part name='26' x='204' y='98'/>
- <part name='27' x='179' y='90'/>
- <part name='28' x='179' y='96'/>
- <part name='29' x='180' y='102'/>
- <part name='30' x='180' y='108'/>
- <part name='31' x='165' y='112'/>
- <part name='32' x='170' y='115'/>
- <part name='33' x='174' y='117'/>
- <part name='34' x='179' y='118'/>
- <part name='35' x='183' y='117'/>
- <part name='36' x='148' y='85'/>
- <part name='37' x='153' y='84'/>
- <part name='38' x='159' y='85'/>
- <part name='39' x='163' y='90'/>
- <part name='40' x='157' y='89'/>
- <part name='41' x='152' y='87'/>
- <part name='42' x='183' y='98'/>
- <part name='43' x='188' y='96'/>
- <part name='44' x='193' y='98'/>
- <part name='45' x='196' y='103'/>
- <part name='46' x='192' y='102'/>
- <part name='47' x='187' y='100'/>
- <part name='48' x='146' y='123'/>
- <part name='49' x='157' y='121'/>
- <part name='50' x='167' y='123'/>
- <part name='51' x='171' y='125'/>
- <part name='52' x='176' y='125'/>
- <part name='53' x='181' y='129'/>
- <part name='54' x='184' y='134'/>
- <part name='55' x='178' y='139'/>
- <part name='56' x='171' y='139'/>
- <part name='57' x='167' y='138'/>
- <part name='58' x='161' y='136'/>
- <part name='59' x='153' y='132'/>
- <part name='60' x='148' y='124'/>
- <part name='61' x='165' y='125'/>
- <part name='62' x='170' y='127'/>
- <part name='63' x='174' y='128'/>
- <part name='64' x='182' y='133'/>
- <part name='65' x='173' y='135'/>
- <part name='66' x='168' y='134'/>
- <part name='67' x='163' y='133'/>
- </box>
- </image>
- <image file='2008_004176.jpg'>
- <box top='230' left='206' width='37' height='37'>
- <part name='00' x='206' y='241'/>
- <part name='01' x='206' y='245'/>
- <part name='02' x='206' y='250'/>
- <part name='03' x='206' y='254'/>
- <part name='04' x='207' y='259'/>
- <part name='05' x='209' y='262'/>
- <part name='06' x='212' y='265'/>
- <part name='07' x='216' y='267'/>
- <part name='08' x='219' y='269'/>
- <part name='09' x='224' y='269'/>
- <part name='10' x='228' y='267'/>
- <part name='11' x='232' y='264'/>
- <part name='12' x='235' y='261'/>
- <part name='13' x='237' y='257'/>
- <part name='14' x='238' y='253'/>
- <part name='15' x='239' y='249'/>
- <part name='16' x='240' y='244'/>
- <part name='17' x='209' y='237'/>
- <part name='18' x='212' y='236'/>
- <part name='19' x='214' y='236'/>
- <part name='20' x='217' y='236'/>
- <part name='21' x='219' y='238'/>
- <part name='22' x='227' y='238'/>
- <part name='23' x='229' y='237'/>
- <part name='24' x='232' y='237'/>
- <part name='25' x='235' y='238'/>
- <part name='26' x='237' y='240'/>
- <part name='27' x='222' y='241'/>
- <part name='28' x='222' y='244'/>
- <part name='29' x='222' y='247'/>
- <part name='30' x='221' y='250'/>
- <part name='31' x='218' y='251'/>
- <part name='32' x='220' y='252'/>
- <part name='33' x='221' y='252'/>
- <part name='34' x='223' y='252'/>
- <part name='35' x='225' y='252'/>
- <part name='36' x='212' y='241'/>
- <part name='37' x='214' y='240'/>
- <part name='38' x='216' y='240'/>
- <part name='39' x='218' y='242'/>
- <part name='40' x='216' y='242'/>
- <part name='41' x='214' y='242'/>
- <part name='42' x='227' y='243'/>
- <part name='43' x='229' y='242'/>
- <part name='44' x='231' y='242'/>
- <part name='45' x='233' y='243'/>
- <part name='46' x='231' y='243'/>
- <part name='47' x='229' y='243'/>
- <part name='48' x='213' y='256'/>
- <part name='49' x='216' y='254'/>
- <part name='50' x='219' y='254'/>
- <part name='51' x='221' y='255'/>
- <part name='52' x='223' y='254'/>
- <part name='53' x='226' y='255'/>
- <part name='54' x='229' y='257'/>
- <part name='55' x='226' y='260'/>
- <part name='56' x='223' y='261'/>
- <part name='57' x='221' y='261'/>
- <part name='58' x='218' y='261'/>
- <part name='59' x='215' y='259'/>
- <part name='60' x='214' y='256'/>
- <part name='61' x='219' y='255'/>
- <part name='62' x='221' y='256'/>
- <part name='63' x='223' y='256'/>
- <part name='64' x='228' y='257'/>
- <part name='65' x='223' y='260'/>
- <part name='66' x='221' y='260'/>
- <part name='67' x='218' y='259'/>
- </box>
- <box top='118' left='162' width='37' height='37'>
- <part name='00' x='164' y='132'/>
- <part name='01' x='164' y='136'/>
- <part name='02' x='165' y='139'/>
- <part name='03' x='165' y='143'/>
- <part name='04' x='167' y='147'/>
- <part name='05' x='170' y='150'/>
- <part name='06' x='173' y='152'/>
- <part name='07' x='177' y='154'/>
- <part name='08' x='181' y='155'/>
- <part name='09' x='186' y='154'/>
- <part name='10' x='190' y='152'/>
- <part name='11' x='193' y='150'/>
- <part name='12' x='196' y='147'/>
- <part name='13' x='197' y='143'/>
- <part name='14' x='198' y='139'/>
- <part name='15' x='198' y='135'/>
- <part name='16' x='197' y='131'/>
- <part name='17' x='167' y='126'/>
- <part name='18' x='169' y='124'/>
- <part name='19' x='172' y='123'/>
- <part name='20' x='175' y='123'/>
- <part name='21' x='177' y='124'/>
- <part name='22' x='183' y='125'/>
- <part name='23' x='186' y='124'/>
- <part name='24' x='189' y='123'/>
- <part name='25' x='192' y='124'/>
- <part name='26' x='194' y='126'/>
- <part name='27' x='181' y='128'/>
- <part name='28' x='181' y='131'/>
- <part name='29' x='181' y='133'/>
- <part name='30' x='181' y='136'/>
- <part name='31' x='177' y='138'/>
- <part name='32' x='179' y='139'/>
- <part name='33' x='181' y='139'/>
- <part name='34' x='182' y='138'/>
- <part name='35' x='184' y='138'/>
- <part name='36' x='171' y='129'/>
- <part name='37' x='172' y='129'/>
- <part name='38' x='174' y='129'/>
- <part name='39' x='176' y='129'/>
- <part name='40' x='174' y='130'/>
- <part name='41' x='172' y='130'/>
- <part name='42' x='185' y='129'/>
- <part name='43' x='187' y='129'/>
- <part name='44' x='189' y='129'/>
- <part name='45' x='191' y='129'/>
- <part name='46' x='189' y='130'/>
- <part name='47' x='187' y='130'/>
- <part name='48' x='174' y='143'/>
- <part name='49' x='177' y='141'/>
- <part name='50' x='179' y='141'/>
- <part name='51' x='181' y='141'/>
- <part name='52' x='183' y='141'/>
- <part name='53' x='185' y='141'/>
- <part name='54' x='188' y='142'/>
- <part name='55' x='186' y='144'/>
- <part name='56' x='183' y='144'/>
- <part name='57' x='181' y='144'/>
- <part name='58' x='179' y='144'/>
- <part name='59' x='177' y='144'/>
- <part name='60' x='175' y='143'/>
- <part name='61' x='179' y='142'/>
- <part name='62' x='181' y='142'/>
- <part name='63' x='183' y='142'/>
- <part name='64' x='187' y='143'/>
- <part name='65' x='183' y='143'/>
- <part name='66' x='181' y='143'/>
- <part name='67' x='179' y='143'/>
- </box>
- <box top='82' left='190' width='37' height='37'>
- <part name='00' x='194' y='91'/>
- <part name='01' x='195' y='95'/>
- <part name='02' x='195' y='99'/>
- <part name='03' x='196' y='104'/>
- <part name='04' x='197' y='108'/>
- <part name='05' x='199' y='111'/>
- <part name='06' x='202' y='114'/>
- <part name='07' x='206' y='116'/>
- <part name='08' x='210' y='117'/>
- <part name='09' x='213' y='116'/>
- <part name='10' x='217' y='114'/>
- <part name='11' x='220' y='111'/>
- <part name='12' x='222' y='107'/>
- <part name='13' x='223' y='103'/>
- <part name='14' x='224' y='99'/>
- <part name='15' x='224' y='96'/>
- <part name='16' x='225' y='91'/>
- <part name='17' x='197' y='88'/>
- <part name='18' x='199' y='87'/>
- <part name='19' x='202' y='86'/>
- <part name='20' x='204' y='86'/>
- <part name='21' x='207' y='87'/>
- <part name='22' x='213' y='87'/>
- <part name='23' x='215' y='86'/>
- <part name='24' x='217' y='86'/>
- <part name='25' x='220' y='87'/>
- <part name='26' x='222' y='88'/>
- <part name='27' x='210' y='90'/>
- <part name='28' x='210' y='93'/>
- <part name='29' x='210' y='96'/>
- <part name='30' x='210' y='100'/>
- <part name='31' x='206' y='100'/>
- <part name='32' x='208' y='101'/>
- <part name='33' x='209' y='102'/>
- <part name='34' x='211' y='101'/>
- <part name='35' x='212' y='101'/>
- <part name='36' x='200' y='91'/>
- <part name='37' x='202' y='90'/>
- <part name='38' x='204' y='90'/>
- <part name='39' x='205' y='91'/>
- <part name='40' x='204' y='92'/>
- <part name='41' x='202' y='92'/>
- <part name='42' x='214' y='91'/>
- <part name='43' x='215' y='90'/>
- <part name='44' x='217' y='90'/>
- <part name='45' x='219' y='91'/>
- <part name='46' x='217' y='92'/>
- <part name='47' x='215' y='92'/>
- <part name='48' x='202' y='105'/>
- <part name='49' x='205' y='104'/>
- <part name='50' x='207' y='104'/>
- <part name='51' x='209' y='104'/>
- <part name='52' x='211' y='104'/>
- <part name='53' x='214' y='104'/>
- <part name='54' x='216' y='106'/>
- <part name='55' x='214' y='109'/>
- <part name='56' x='211' y='110'/>
- <part name='57' x='209' y='111'/>
- <part name='58' x='207' y='110'/>
- <part name='59' x='204' y='109'/>
- <part name='60' x='203' y='105'/>
- <part name='61' x='207' y='105'/>
- <part name='62' x='209' y='105'/>
- <part name='63' x='211' y='105'/>
- <part name='64' x='215' y='106'/>
- <part name='65' x='211' y='109'/>
- <part name='66' x='209' y='109'/>
- <part name='67' x='207' y='109'/>
- </box>
- <box top='78' left='326' width='37' height='37'>
- <part name='00' x='330' y='94'/>
- <part name='01' x='331' y='98'/>
- <part name='02' x='332' y='101'/>
- <part name='03' x='333' y='105'/>
- <part name='04' x='334' y='109'/>
- <part name='05' x='336' y='112'/>
- <part name='06' x='338' y='115'/>
- <part name='07' x='341' y='117'/>
- <part name='08' x='345' y='118'/>
- <part name='09' x='349' y='117'/>
- <part name='10' x='353' y='115'/>
- <part name='11' x='357' y='112'/>
- <part name='12' x='360' y='108'/>
- <part name='13' x='362' y='104'/>
- <part name='14' x='363' y='99'/>
- <part name='15' x='363' y='94'/>
- <part name='16' x='363' y='89'/>
- <part name='17' x='330' y='90'/>
- <part name='18' x='330' y='88'/>
- <part name='19' x='332' y='87'/>
- <part name='20' x='335' y='87'/>
- <part name='21' x='337' y='87'/>
- <part name='22' x='342' y='86'/>
- <part name='23' x='345' y='85'/>
- <part name='24' x='348' y='85'/>
- <part name='25' x='351' y='85'/>
- <part name='26' x='354' y='86'/>
- <part name='27' x='340' y='90'/>
- <part name='28' x='340' y='92'/>
- <part name='29' x='340' y='95'/>
- <part name='30' x='340' y='98'/>
- <part name='31' x='338' y='100'/>
- <part name='32' x='339' y='101'/>
- <part name='33' x='341' y='101'/>
- <part name='34' x='343' y='100'/>
- <part name='35' x='344' y='99'/>
- <part name='36' x='332' y='92'/>
- <part name='37' x='334' y='91'/>
- <part name='38' x='335' y='90'/>
- <part name='39' x='337' y='91'/>
- <part name='40' x='336' y='92'/>
- <part name='41' x='334' y='92'/>
- <part name='42' x='346' y='90'/>
- <part name='43' x='347' y='89'/>
- <part name='44' x='349' y='89'/>
- <part name='45' x='351' y='89'/>
- <part name='46' x='349' y='90'/>
- <part name='47' x='347' y='90'/>
- <part name='48' x='338' y='107'/>
- <part name='49' x='339' y='105'/>
- <part name='50' x='340' y='104'/>
- <part name='51' x='342' y='104'/>
- <part name='52' x='343' y='104'/>
- <part name='53' x='346' y='104'/>
- <part name='54' x='349' y='105'/>
- <part name='55' x='347' y='107'/>
- <part name='56' x='345' y='109'/>
- <part name='57' x='343' y='109'/>
- <part name='58' x='341' y='109'/>
- <part name='59' x='339' y='109'/>
- <part name='60' x='339' y='107'/>
- <part name='61' x='341' y='105'/>
- <part name='62' x='342' y='105'/>
- <part name='63' x='344' y='105'/>
- <part name='64' x='348' y='105'/>
- <part name='65' x='344' y='107'/>
- <part name='66' x='343' y='107'/>
- <part name='67' x='341' y='107'/>
- </box>
- <box top='98' left='222' width='37' height='37'>
- <part name='00' x='226' y='108'/>
- <part name='01' x='226' y='112'/>
- <part name='02' x='227' y='116'/>
- <part name='03' x='228' y='119'/>
- <part name='04' x='229' y='123'/>
- <part name='05' x='230' y='126'/>
- <part name='06' x='233' y='129'/>
- <part name='07' x='236' y='131'/>
- <part name='08' x='239' y='131'/>
- <part name='09' x='243' y='131'/>
- <part name='10' x='247' y='129'/>
- <part name='11' x='251' y='127'/>
- <part name='12' x='254' y='124'/>
- <part name='13' x='256' y='120'/>
- <part name='14' x='257' y='116'/>
- <part name='15' x='258' y='112'/>
- <part name='16' x='258' y='107'/>
- <part name='17' x='227' y='104'/>
- <part name='18' x='228' y='103'/>
- <part name='19' x='230' y='102'/>
- <part name='20' x='233' y='102'/>
- <part name='21' x='235' y='103'/>
- <part name='22' x='241' y='103'/>
- <part name='23' x='244' y='102'/>
- <part name='24' x='247' y='101'/>
- <part name='25' x='250' y='102'/>
- <part name='26' x='252' y='104'/>
- <part name='27' x='238' y='106'/>
- <part name='28' x='237' y='108'/>
- <part name='29' x='237' y='111'/>
- <part name='30' x='237' y='113'/>
- <part name='31' x='235' y='115'/>
- <part name='32' x='236' y='116'/>
- <part name='33' x='237' y='116'/>
- <part name='34' x='239' y='116'/>
- <part name='35' x='241' y='115'/>
- <part name='36' x='229' y='107'/>
- <part name='37' x='231' y='106'/>
- <part name='38' x='233' y='106'/>
- <part name='39' x='234' y='107'/>
- <part name='40' x='233' y='107'/>
- <part name='41' x='231' y='107'/>
- <part name='42' x='243' y='107'/>
- <part name='43' x='245' y='106'/>
- <part name='44' x='247' y='106'/>
- <part name='45' x='249' y='107'/>
- <part name='46' x='247' y='107'/>
- <part name='47' x='245' y='107'/>
- <part name='48' x='233' y='121'/>
- <part name='49' x='234' y='119'/>
- <part name='50' x='236' y='118'/>
- <part name='51' x='238' y='118'/>
- <part name='52' x='240' y='118'/>
- <part name='53' x='243' y='119'/>
- <part name='54' x='246' y='121'/>
- <part name='55' x='243' y='123'/>
- <part name='56' x='240' y='124'/>
- <part name='57' x='238' y='124'/>
- <part name='58' x='236' y='124'/>
- <part name='59' x='234' y='123'/>
- <part name='60' x='234' y='121'/>
- <part name='61' x='236' y='119'/>
- <part name='62' x='238' y='119'/>
- <part name='63' x='240' y='119'/>
- <part name='64' x='245' y='121'/>
- <part name='65' x='240' y='122'/>
- <part name='66' x='238' y='122'/>
- <part name='67' x='236' y='122'/>
- </box>
- <box top='86' left='110' width='37' height='37'>
- <part name='00' x='107' y='92'/>
- <part name='01' x='107' y='98'/>
- <part name='02' x='108' y='103'/>
- <part name='03' x='109' y='108'/>
- <part name='04' x='111' y='112'/>
- <part name='05' x='115' y='116'/>
- <part name='06' x='119' y='119'/>
- <part name='07' x='123' y='121'/>
- <part name='08' x='128' y='122'/>
- <part name='09' x='131' y='121'/>
- <part name='10' x='133' y='118'/>
- <part name='11' x='135' y='114'/>
- <part name='12' x='137' y='111'/>
- <part name='13' x='139' y='107'/>
- <part name='14' x='140' y='104'/>
- <part name='15' x='140' y='100'/>
- <part name='16' x='141' y='97'/>
- <part name='17' x='115' y='91'/>
- <part name='18' x='119' y='89'/>
- <part name='19' x='122' y='89'/>
- <part name='20' x='126' y='90'/>
- <part name='21' x='130' y='91'/>
- <part name='22' x='135' y='92'/>
- <part name='23' x='137' y='91'/>
- <part name='24' x='139' y='91'/>
- <part name='25' x='141' y='91'/>
- <part name='26' x='141' y='93'/>
- <part name='27' x='132' y='95'/>
- <part name='28' x='132' y='98'/>
- <part name='29' x='133' y='102'/>
- <part name='30' x='133' y='105'/>
- <part name='31' x='127' y='106'/>
- <part name='32' x='129' y='106'/>
- <part name='33' x='131' y='107'/>
- <part name='34' x='133' y='107'/>
- <part name='35' x='134' y='106'/>
- <part name='36' x='119' y='95'/>
- <part name='37' x='122' y='94'/>
- <part name='38' x='124' y='94'/>
- <part name='39' x='125' y='95'/>
- <part name='40' x='123' y='96'/>
- <part name='41' x='121' y='95'/>
- <part name='42' x='134' y='96'/>
- <part name='43' x='136' y='95'/>
- <part name='44' x='138' y='95'/>
- <part name='45' x='139' y='96'/>
- <part name='46' x='138' y='97'/>
- <part name='47' x='136' y='97'/>
- <part name='48' x='122' y='110'/>
- <part name='49' x='125' y='110'/>
- <part name='50' x='128' y='110'/>
- <part name='51' x='130' y='110'/>
- <part name='52' x='131' y='109'/>
- <part name='53' x='133' y='110'/>
- <part name='54' x='133' y='110'/>
- <part name='55' x='132' y='112'/>
- <part name='56' x='131' y='113'/>
- <part name='57' x='129' y='114'/>
- <part name='58' x='128' y='113'/>
- <part name='59' x='125' y='112'/>
- <part name='60' x='123' y='110'/>
- <part name='61' x='128' y='111'/>
- <part name='62' x='130' y='111'/>
- <part name='63' x='131' y='111'/>
- <part name='64' x='133' y='111'/>
- <part name='65' x='131' y='111'/>
- <part name='66' x='130' y='112'/>
- <part name='67' x='128' y='112'/>
- </box>
- <box top='102' left='282' width='37' height='37'>
- <part name='00' x='284' y='110'/>
- <part name='01' x='284' y='113'/>
- <part name='02' x='284' y='117'/>
- <part name='03' x='284' y='121'/>
- <part name='04' x='285' y='125'/>
- <part name='05' x='287' y='129'/>
- <part name='06' x='289' y='132'/>
- <part name='07' x='291' y='135'/>
- <part name='08' x='295' y='136'/>
- <part name='09' x='299' y='136'/>
- <part name='10' x='303' y='134'/>
- <part name='11' x='307' y='132'/>
- <part name='12' x='310' y='129'/>
- <part name='13' x='313' y='126'/>
- <part name='14' x='314' y='122'/>
- <part name='15' x='315' y='117'/>
- <part name='16' x='316' y='113'/>
- <part name='17' x='286' y='107'/>
- <part name='18' x='287' y='105'/>
- <part name='19' x='290' y='105'/>
- <part name='20' x='292' y='106'/>
- <part name='21' x='294' y='107'/>
- <part name='22' x='301' y='107'/>
- <part name='23' x='304' y='107'/>
- <part name='24' x='307' y='107'/>
- <part name='25' x='310' y='108'/>
- <part name='26' x='312' y='110'/>
- <part name='27' x='297' y='110'/>
- <part name='28' x='297' y='113'/>
- <part name='29' x='296' y='115'/>
- <part name='30' x='296' y='118'/>
- <part name='31' x='293' y='119'/>
- <part name='32' x='295' y='120'/>
- <part name='33' x='296' y='121'/>
- <part name='34' x='298' y='120'/>
- <part name='35' x='299' y='120'/>
- <part name='36' x='288' y='110'/>
- <part name='37' x='290' y='109'/>
- <part name='38' x='292' y='109'/>
- <part name='39' x='294' y='111'/>
- <part name='40' x='292' y='111'/>
- <part name='41' x='290' y='111'/>
- <part name='42' x='302' y='112'/>
- <part name='43' x='304' y='110'/>
- <part name='44' x='306' y='111'/>
- <part name='45' x='308' y='112'/>
- <part name='46' x='306' y='112'/>
- <part name='47' x='304' y='112'/>
- <part name='48' x='290' y='123'/>
- <part name='49' x='292' y='122'/>
- <part name='50' x='294' y='123'/>
- <part name='51' x='296' y='123'/>
- <part name='52' x='298' y='123'/>
- <part name='53' x='301' y='123'/>
- <part name='54' x='304' y='124'/>
- <part name='55' x='301' y='127'/>
- <part name='56' x='298' y='128'/>
- <part name='57' x='296' y='128'/>
- <part name='58' x='294' y='128'/>
- <part name='59' x='292' y='126'/>
- <part name='60' x='291' y='123'/>
- <part name='61' x='294' y='123'/>
- <part name='62' x='296' y='124'/>
- <part name='63' x='298' y='124'/>
- <part name='64' x='303' y='124'/>
- <part name='65' x='298' y='126'/>
- <part name='66' x='296' y='126'/>
- <part name='67' x='294' y='126'/>
- </box>
- </image>
- <image file='2008_007676.jpg'>
- <box top='62' left='226' width='37' height='37'>
- <part name='00' x='223' y='72'/>
- <part name='01' x='224' y='77'/>
- <part name='02' x='224' y='82'/>
- <part name='03' x='225' y='87'/>
- <part name='04' x='227' y='91'/>
- <part name='05' x='230' y='95'/>
- <part name='06' x='234' y='98'/>
- <part name='07' x='239' y='100'/>
- <part name='08' x='243' y='100'/>
- <part name='09' x='248' y='99'/>
- <part name='10' x='252' y='97'/>
- <part name='11' x='255' y='94'/>
- <part name='12' x='258' y='90'/>
- <part name='13' x='259' y='85'/>
- <part name='14' x='260' y='81'/>
- <part name='15' x='260' y='76'/>
- <part name='16' x='260' y='71'/>
- <part name='17' x='230' y='67'/>
- <part name='18' x='232' y='65'/>
- <part name='19' x='235' y='64'/>
- <part name='20' x='238' y='64'/>
- <part name='21' x='241' y='64'/>
- <part name='22' x='248' y='65'/>
- <part name='23' x='251' y='64'/>
- <part name='24' x='254' y='64'/>
- <part name='25' x='256' y='65'/>
- <part name='26' x='258' y='67'/>
- <part name='27' x='245' y='70'/>
- <part name='28' x='245' y='73'/>
- <part name='29' x='246' y='76'/>
- <part name='30' x='246' y='79'/>
- <part name='31' x='242' y='81'/>
- <part name='32' x='244' y='82'/>
- <part name='33' x='245' y='82'/>
- <part name='34' x='247' y='82'/>
- <part name='35' x='248' y='81'/>
- <part name='36' x='234' y='71'/>
- <part name='37' x='236' y='71'/>
- <part name='38' x='238' y='71'/>
- <part name='39' x='240' y='71'/>
- <part name='40' x='238' y='72'/>
- <part name='41' x='236' y='72'/>
- <part name='42' x='249' y='71'/>
- <part name='43' x='251' y='71'/>
- <part name='44' x='253' y='71'/>
- <part name='45' x='255' y='71'/>
- <part name='46' x='253' y='71'/>
- <part name='47' x='251' y='71'/>
- <part name='48' x='236' y='87'/>
- <part name='49' x='239' y='85'/>
- <part name='50' x='243' y='85'/>
- <part name='51' x='245' y='85'/>
- <part name='52' x='247' y='85'/>
- <part name='53' x='249' y='85'/>
- <part name='54' x='251' y='87'/>
- <part name='55' x='249' y='90'/>
- <part name='56' x='247' y='92'/>
- <part name='57' x='245' y='92'/>
- <part name='58' x='242' y='92'/>
- <part name='59' x='239' y='91'/>
- <part name='60' x='237' y='87'/>
- <part name='61' x='243' y='86'/>
- <part name='62' x='245' y='86'/>
- <part name='63' x='247' y='86'/>
- <part name='64' x='250' y='87'/>
- <part name='65' x='247' y='89'/>
- <part name='66' x='245' y='90'/>
- <part name='67' x='242' y='90'/>
- </box>
- <box top='113' left='194' width='44' height='44'>
- <part name='00' x='191' y='124'/>
- <part name='01' x='191' y='131'/>
- <part name='02' x='191' y='137'/>
- <part name='03' x='191' y='143'/>
- <part name='04' x='193' y='149'/>
- <part name='05' x='197' y='154'/>
- <part name='06' x='202' y='157'/>
- <part name='07' x='207' y='160'/>
- <part name='08' x='213' y='161'/>
- <part name='09' x='218' y='161'/>
- <part name='10' x='223' y='158'/>
- <part name='11' x='227' y='155'/>
- <part name='12' x='230' y='150'/>
- <part name='13' x='232' y='145'/>
- <part name='14' x='233' y='140'/>
- <part name='15' x='234' y='134'/>
- <part name='16' x='235' y='128'/>
- <part name='17' x='199' y='120'/>
- <part name='18' x='203' y='118'/>
- <part name='19' x='206' y='118'/>
- <part name='20' x='210' y='118'/>
- <part name='21' x='214' y='120'/>
- <part name='22' x='222' y='122'/>
- <part name='23' x='226' y='121'/>
- <part name='24' x='229' y='121'/>
- <part name='25' x='232' y='123'/>
- <part name='26' x='234' y='125'/>
- <part name='27' x='217' y='126'/>
- <part name='28' x='217' y='130'/>
- <part name='29' x='217' y='133'/>
- <part name='30' x='217' y='137'/>
- <part name='31' x='212' y='139'/>
- <part name='32' x='214' y='139'/>
- <part name='33' x='216' y='140'/>
- <part name='34' x='218' y='140'/>
- <part name='35' x='220' y='139'/>
- <part name='36' x='204' y='126'/>
- <part name='37' x='207' y='126'/>
- <part name='38' x='209' y='126'/>
- <part name='39' x='211' y='127'/>
- <part name='40' x='209' y='127'/>
- <part name='41' x='206' y='127'/>
- <part name='42' x='222' y='128'/>
- <part name='43' x='225' y='128'/>
- <part name='44' x='227' y='128'/>
- <part name='45' x='229' y='129'/>
- <part name='46' x='227' y='129'/>
- <part name='47' x='224' y='129'/>
- <part name='48' x='203' y='143'/>
- <part name='49' x='208' y='142'/>
- <part name='50' x='212' y='142'/>
- <part name='51' x='215' y='143'/>
- <part name='52' x='218' y='143'/>
- <part name='53' x='221' y='143'/>
- <part name='54' x='224' y='145'/>
- <part name='55' x='221' y='149'/>
- <part name='56' x='217' y='150'/>
- <part name='57' x='214' y='151'/>
- <part name='58' x='211' y='150'/>
- <part name='59' x='207' y='148'/>
- <part name='60' x='204' y='143'/>
- <part name='61' x='212' y='143'/>
- <part name='62' x='215' y='144'/>
- <part name='63' x='218' y='144'/>
- <part name='64' x='223' y='145'/>
- <part name='65' x='217' y='148'/>
- <part name='66' x='214' y='148'/>
- <part name='67' x='211' y='148'/>
- </box>
- <box top='130' left='262' width='37' height='37'>
- <part name='00' x='265' y='138'/>
- <part name='01' x='265' y='143'/>
- <part name='02' x='265' y='147'/>
- <part name='03' x='266' y='152'/>
- <part name='04' x='268' y='156'/>
- <part name='05' x='271' y='160'/>
- <part name='06' x='274' y='164'/>
- <part name='07' x='277' y='168'/>
- <part name='08' x='281' y='169'/>
- <part name='09' x='286' y='168'/>
- <part name='10' x='291' y='165'/>
- <part name='11' x='296' y='162'/>
- <part name='12' x='299' y='157'/>
- <part name='13' x='301' y='153'/>
- <part name='14' x='302' y='147'/>
- <part name='15' x='303' y='142'/>
- <part name='16' x='303' y='137'/>
- <part name='17' x='265' y='135'/>
- <part name='18' x='267' y='133'/>
- <part name='19' x='270' y='133'/>
- <part name='20' x='273' y='134'/>
- <part name='21' x='275' y='136'/>
- <part name='22' x='282' y='136'/>
- <part name='23' x='286' y='134'/>
- <part name='24' x='289' y='134'/>
- <part name='25' x='293' y='134'/>
- <part name='26' x='296' y='135'/>
- <part name='27' x='279' y='140'/>
- <part name='28' x='279' y='143'/>
- <part name='29' x='278' y='147'/>
- <part name='30' x='278' y='150'/>
- <part name='31' x='276' y='151'/>
- <part name='32' x='277' y='152'/>
- <part name='33' x='279' y='153'/>
- <part name='34' x='281' y='152'/>
- <part name='35' x='283' y='151'/>
- <part name='36' x='269' y='140'/>
- <part name='37' x='271' y='140'/>
- <part name='38' x='273' y='140'/>
- <part name='39' x='275' y='141'/>
- <part name='40' x='273' y='141'/>
- <part name='41' x='271' y='140'/>
- <part name='42' x='285' y='141'/>
- <part name='43' x='287' y='140'/>
- <part name='44' x='290' y='140'/>
- <part name='45' x='292' y='140'/>
- <part name='46' x='290' y='141'/>
- <part name='47' x='288' y='141'/>
- <part name='48' x='273' y='156'/>
- <part name='49' x='275' y='155'/>
- <part name='50' x='278' y='154'/>
- <part name='51' x='280' y='155'/>
- <part name='52' x='282' y='154'/>
- <part name='53' x='286' y='155'/>
- <part name='54' x='290' y='156'/>
- <part name='55' x='287' y='161'/>
- <part name='56' x='283' y='163'/>
- <part name='57' x='280' y='163'/>
- <part name='58' x='278' y='163'/>
- <part name='59' x='275' y='161'/>
- <part name='60' x='274' y='156'/>
- <part name='61' x='278' y='156'/>
- <part name='62' x='280' y='156'/>
- <part name='63' x='282' y='156'/>
- <part name='64' x='289' y='156'/>
- <part name='65' x='283' y='160'/>
- <part name='66' x='280' y='160'/>
- <part name='67' x='278' y='160'/>
- </box>
- <box top='134' left='366' width='37' height='37'>
- <part name='00' x='367' y='140'/>
- <part name='01' x='367' y='145'/>
- <part name='02' x='367' y='149'/>
- <part name='03' x='366' y='154'/>
- <part name='04' x='367' y='159'/>
- <part name='05' x='368' y='163'/>
- <part name='06' x='371' y='167'/>
- <part name='07' x='374' y='170'/>
- <part name='08' x='378' y='172'/>
- <part name='09' x='383' y='172'/>
- <part name='10' x='388' y='170'/>
- <part name='11' x='393' y='168'/>
- <part name='12' x='397' y='165'/>
- <part name='13' x='400' y='161'/>
- <part name='14' x='401' y='156'/>
- <part name='15' x='403' y='152'/>
- <part name='16' x='405' y='147'/>
- <part name='17' x='369' y='138'/>
- <part name='18' x='371' y='136'/>
- <part name='19' x='375' y='136'/>
- <part name='20' x='378' y='136'/>
- <part name='21' x='381' y='138'/>
- <part name='22' x='389' y='139'/>
- <part name='23' x='393' y='139'/>
- <part name='24' x='397' y='139'/>
- <part name='25' x='400' y='141'/>
- <part name='26' x='402' y='144'/>
- <part name='27' x='384' y='142'/>
- <part name='28' x='383' y='145'/>
- <part name='29' x='382' y='147'/>
- <part name='30' x='381' y='150'/>
- <part name='31' x='378' y='151'/>
- <part name='32' x='379' y='152'/>
- <part name='33' x='381' y='153'/>
- <part name='34' x='383' y='153'/>
- <part name='35' x='386' y='152'/>
- <part name='36' x='373' y='141'/>
- <part name='37' x='375' y='140'/>
- <part name='38' x='377' y='140'/>
- <part name='39' x='379' y='142'/>
- <part name='40' x='377' y='142'/>
- <part name='41' x='375' y='141'/>
- <part name='42' x='390' y='143'/>
- <part name='43' x='392' y='142'/>
- <part name='44' x='395' y='143'/>
- <part name='45' x='396' y='144'/>
- <part name='46' x='394' y='144'/>
- <part name='47' x='392' y='144'/>
- <part name='48' x='372' y='155'/>
- <part name='49' x='375' y='154'/>
- <part name='50' x='379' y='155'/>
- <part name='51' x='381' y='155'/>
- <part name='52' x='384' y='155'/>
- <part name='53' x='387' y='156'/>
- <part name='54' x='391' y='158'/>
- <part name='55' x='387' y='162'/>
- <part name='56' x='383' y='163'/>
- <part name='57' x='380' y='163'/>
- <part name='58' x='377' y='162'/>
- <part name='59' x='374' y='160'/>
- <part name='60' x='373' y='156'/>
- <part name='61' x='378' y='156'/>
- <part name='62' x='381' y='156'/>
- <part name='63' x='384' y='156'/>
- <part name='64' x='390' y='158'/>
- <part name='65' x='383' y='161'/>
- <part name='66' x='380' y='161'/>
- <part name='67' x='378' y='160'/>
- </box>
- <box top='122' left='314' width='37' height='37'>
- <part name='00' x='319' y='132'/>
- <part name='01' x='319' y='137'/>
- <part name='02' x='320' y='141'/>
- <part name='03' x='321' y='145'/>
- <part name='04' x='322' y='149'/>
- <part name='05' x='324' y='153'/>
- <part name='06' x='327' y='156'/>
- <part name='07' x='330' y='159'/>
- <part name='08' x='334' y='159'/>
- <part name='09' x='338' y='158'/>
- <part name='10' x='343' y='155'/>
- <part name='11' x='347' y='152'/>
- <part name='12' x='350' y='148'/>
- <part name='13' x='352' y='143'/>
- <part name='14' x='352' y='138'/>
- <part name='15' x='353' y='133'/>
- <part name='16' x='353' y='128'/>
- <part name='17' x='319' y='129'/>
- <part name='18' x='320' y='127'/>
- <part name='19' x='322' y='126'/>
- <part name='20' x='324' y='126'/>
- <part name='21' x='327' y='127'/>
- <part name='22' x='334' y='125'/>
- <part name='23' x='337' y='124'/>
- <part name='24' x='340' y='124'/>
- <part name='25' x='343' y='124'/>
- <part name='26' x='346' y='126'/>
- <part name='27' x='330' y='130'/>
- <part name='28' x='330' y='133'/>
- <part name='29' x='330' y='135'/>
- <part name='30' x='330' y='138'/>
- <part name='31' x='328' y='140'/>
- <part name='32' x='329' y='141'/>
- <part name='33' x='331' y='141'/>
- <part name='34' x='333' y='140'/>
- <part name='35' x='335' y='140'/>
- <part name='36' x='322' y='132'/>
- <part name='37' x='324' y='130'/>
- <part name='38' x='326' y='130'/>
- <part name='39' x='328' y='131'/>
- <part name='40' x='326' y='132'/>
- <part name='41' x='324' y='132'/>
- <part name='42' x='336' y='130'/>
- <part name='43' x='338' y='128'/>
- <part name='44' x='340' y='128'/>
- <part name='45' x='342' y='129'/>
- <part name='46' x='341' y='130'/>
- <part name='47' x='338' y='130'/>
- <part name='48' x='326' y='146'/>
- <part name='49' x='327' y='144'/>
- <part name='50' x='330' y='144'/>
- <part name='51' x='332' y='144'/>
- <part name='52' x='334' y='143'/>
- <part name='53' x='338' y='143'/>
- <part name='54' x='341' y='144'/>
- <part name='55' x='338' y='148'/>
- <part name='56' x='335' y='150'/>
- <part name='57' x='333' y='151'/>
- <part name='58' x='330' y='151'/>
- <part name='59' x='328' y='150'/>
- <part name='60' x='327' y='146'/>
- <part name='61' x='330' y='144'/>
- <part name='62' x='332' y='145'/>
- <part name='63' x='334' y='144'/>
- <part name='64' x='340' y='145'/>
- <part name='65' x='335' y='148'/>
- <part name='66' x='332' y='149'/>
- <part name='67' x='330' y='149'/>
- </box>
- <box top='141' left='107' width='52' height='53'>
- <part name='00' x='107' y='151'/>
- <part name='01' x='106' y='158'/>
- <part name='02' x='106' y='165'/>
- <part name='03' x='106' y='171'/>
- <part name='04' x='108' y='178'/>
- <part name='05' x='112' y='184'/>
- <part name='06' x='117' y='188'/>
- <part name='07' x='122' y='192'/>
- <part name='08' x='128' y='194'/>
- <part name='09' x='133' y='193'/>
- <part name='10' x='138' y='191'/>
- <part name='11' x='143' y='187'/>
- <part name='12' x='147' y='183'/>
- <part name='13' x='150' y='177'/>
- <part name='14' x='151' y='172'/>
- <part name='15' x='153' y='166'/>
- <part name='16' x='154' y='161'/>
- <part name='17' x='115' y='148'/>
- <part name='18' x='119' y='145'/>
- <part name='19' x='124' y='144'/>
- <part name='20' x='129' y='146'/>
- <part name='21' x='132' y='148'/>
- <part name='22' x='141' y='150'/>
- <part name='23' x='144' y='149'/>
- <part name='24' x='149' y='149'/>
- <part name='25' x='152' y='152'/>
- <part name='26' x='153' y='155'/>
- <part name='27' x='136' y='153'/>
- <part name='28' x='136' y='157'/>
- <part name='29' x='135' y='161'/>
- <part name='30' x='135' y='165'/>
- <part name='31' x='128' y='166'/>
- <part name='32' x='131' y='167'/>
- <part name='33' x='133' y='169'/>
- <part name='34' x='136' y='168'/>
- <part name='35' x='138' y='168'/>
- <part name='36' x='120' y='152'/>
- <part name='37' x='123' y='151'/>
- <part name='38' x='126' y='152'/>
- <part name='39' x='128' y='154'/>
- <part name='40' x='125' y='154'/>
- <part name='41' x='122' y='153'/>
- <part name='42' x='140' y='157'/>
- <part name='43' x='143' y='155'/>
- <part name='44' x='146' y='155'/>
- <part name='45' x='148' y='158'/>
- <part name='46' x='146' y='158'/>
- <part name='47' x='143' y='158'/>
- <part name='48' x='119' y='172'/>
- <part name='49' x='124' y='170'/>
- <part name='50' x='129' y='170'/>
- <part name='51' x='131' y='171'/>
- <part name='52' x='135' y='171'/>
- <part name='53' x='138' y='173'/>
- <part name='54' x='141' y='176'/>
- <part name='55' x='137' y='180'/>
- <part name='56' x='133' y='181'/>
- <part name='57' x='130' y='180'/>
- <part name='58' x='127' y='179'/>
- <part name='59' x='122' y='177'/>
- <part name='60' x='120' y='172'/>
- <part name='61' x='128' y='171'/>
- <part name='62' x='131' y='172'/>
- <part name='63' x='134' y='173'/>
- <part name='64' x='139' y='175'/>
- <part name='65' x='134' y='178'/>
- <part name='66' x='130' y='178'/>
- <part name='67' x='127' y='177'/>
- </box>
- <box top='84' left='137' width='44' height='44'>
- <part name='00' x='131' y='97'/>
- <part name='01' x='133' y='103'/>
- <part name='02' x='134' y='109'/>
- <part name='03' x='137' y='115'/>
- <part name='04' x='141' y='119'/>
- <part name='05' x='147' y='123'/>
- <part name='06' x='153' y='126'/>
- <part name='07' x='159' y='128'/>
- <part name='08' x='165' y='128'/>
- <part name='09' x='169' y='126'/>
- <part name='10' x='172' y='122'/>
- <part name='11' x='174' y='117'/>
- <part name='12' x='176' y='112'/>
- <part name='13' x='177' y='107'/>
- <part name='14' x='177' y='102'/>
- <part name='15' x='176' y='97'/>
- <part name='16' x='175' y='92'/>
- <part name='17' x='140' y='92'/>
- <part name='18' x='143' y='89'/>
- <part name='19' x='147' y='88'/>
- <part name='20' x='151' y='88'/>
- <part name='21' x='156' y='88'/>
- <part name='22' x='163' y='88'/>
- <part name='23' x='165' y='86'/>
- <part name='24' x='168' y='85'/>
- <part name='25' x='171' y='85'/>
- <part name='26' x='173' y='87'/>
- <part name='27' x='160' y='92'/>
- <part name='28' x='161' y='95'/>
- <part name='29' x='162' y='99'/>
- <part name='30' x='163' y='102'/>
- <part name='31' x='158' y='105'/>
- <part name='32' x='160' y='106'/>
- <part name='33' x='163' y='106'/>
- <part name='34' x='164' y='105'/>
- <part name='35' x='166' y='104'/>
- <part name='36' x='146' y='94'/>
- <part name='37' x='148' y='93'/>
- <part name='38' x='150' y='92'/>
- <part name='39' x='153' y='94'/>
- <part name='40' x='150' y='94'/>
- <part name='41' x='148' y='94'/>
- <part name='42' x='164' y='92'/>
- <part name='43' x='166' y='90'/>
- <part name='44' x='168' y='90'/>
- <part name='45' x='170' y='91'/>
- <part name='46' x='168' y='92'/>
- <part name='47' x='166' y='92'/>
- <part name='48' x='152' y='113'/>
- <part name='49' x='156' y='110'/>
- <part name='50' x='160' y='109'/>
- <part name='51' x='163' y='109'/>
- <part name='52' x='165' y='108'/>
- <part name='53' x='168' y='108'/>
- <part name='54' x='170' y='110'/>
- <part name='55' x='169' y='114'/>
- <part name='56' x='166' y='116'/>
- <part name='57' x='164' y='117'/>
- <part name='58' x='161' y='117'/>
- <part name='59' x='156' y='116'/>
- <part name='60' x='153' y='113'/>
- <part name='61' x='160' y='111'/>
- <part name='62' x='163' y='111'/>
- <part name='63' x='165' y='110'/>
- <part name='64' x='169' y='110'/>
- <part name='65' x='166' y='114'/>
- <part name='66' x='163' y='115'/>
- <part name='67' x='160' y='115'/>
- </box>
- </image>
- <image file='2009_004587.jpg'>
- <box top='46' left='154' width='75' height='76'>
- <part name='00' x='147' y='74'/>
- <part name='01' x='147' y='84'/>
- <part name='02' x='148' y='94'/>
- <part name='03' x='150' y='104'/>
- <part name='04' x='154' y='113'/>
- <part name='05' x='162' y='121'/>
- <part name='06' x='171' y='127'/>
- <part name='07' x='180' y='132'/>
- <part name='08' x='191' y='133'/>
- <part name='09' x='201' y='132'/>
- <part name='10' x='208' y='126'/>
- <part name='11' x='214' y='119'/>
- <part name='12' x='218' y='111'/>
- <part name='13' x='221' y='102'/>
- <part name='14' x='222' y='93'/>
- <part name='15' x='222' y='85'/>
- <part name='16' x='222' y='77'/>
- <part name='17' x='160' y='65'/>
- <part name='18' x='165' y='60'/>
- <part name='19' x='172' y='57'/>
- <part name='20' x='180' y='57'/>
- <part name='21' x='187' y='59'/>
- <part name='22' x='200' y='60'/>
- <part name='23' x='206' y='59'/>
- <part name='24' x='213' y='60'/>
- <part name='25' x='217' y='64'/>
- <part name='26' x='219' y='69'/>
- <part name='27' x='194' y='67'/>
- <part name='28' x='194' y='72'/>
- <part name='29' x='195' y='77'/>
- <part name='30' x='196' y='83'/>
- <part name='31' x='186' y='89'/>
- <part name='32' x='190' y='91'/>
- <part name='33' x='194' y='92'/>
- <part name='34' x='198' y='91'/>
- <part name='35' x='201' y='90'/>
- <part name='36' x='169' y='69'/>
- <part name='37' x='173' y='67'/>
- <part name='38' x='178' y='67'/>
- <part name='39' x='182' y='70'/>
- <part name='40' x='178' y='70'/>
- <part name='41' x='173' y='70'/>
- <part name='42' x='201' y='71'/>
- <part name='43' x='205' y='70'/>
- <part name='44' x='209' y='70'/>
- <part name='45' x='213' y='73'/>
- <part name='46' x='209' y='73'/>
- <part name='47' x='205' y='73'/>
- <part name='48' x='174' y='100'/>
- <part name='49' x='182' y='99'/>
- <part name='50' x='189' y='99'/>
- <part name='51' x='194' y='100'/>
- <part name='52' x='198' y='99'/>
- <part name='53' x='203' y='101'/>
- <part name='54' x='207' y='104'/>
- <part name='55' x='202' y='107'/>
- <part name='56' x='197' y='109'/>
- <part name='57' x='192' y='108'/>
- <part name='58' x='188' y='108'/>
- <part name='59' x='181' y='105'/>
- <part name='60' x='176' y='101'/>
- <part name='61' x='189' y='101'/>
- <part name='62' x='193' y='102'/>
- <part name='63' x='198' y='102'/>
- <part name='64' x='205' y='104'/>
- <part name='65' x='197' y='105'/>
- <part name='66' x='193' y='105'/>
- <part name='67' x='188' y='104'/>
- </box>
- <box top='280' left='266' width='63' height='63'>
- <part name='00' x='267' y='303'/>
- <part name='01' x='267' y='311'/>
- <part name='02' x='269' y='319'/>
- <part name='03' x='271' y='327'/>
- <part name='04' x='275' y='334'/>
- <part name='05' x='281' y='340'/>
- <part name='06' x='288' y='345'/>
- <part name='07' x='296' y='348'/>
- <part name='08' x='304' y='348'/>
- <part name='09' x='311' y='345'/>
- <part name='10' x='316' y='339'/>
- <part name='11' x='320' y='332'/>
- <part name='12' x='323' y='325'/>
- <part name='13' x='325' y='318'/>
- <part name='14' x='325' y='311'/>
- <part name='15' x='325' y='304'/>
- <part name='16' x='324' y='297'/>
- <part name='17' x='272' y='294'/>
- <part name='18' x='277' y='291'/>
- <part name='19' x='282' y='290'/>
- <part name='20' x='287' y='290'/>
- <part name='21' x='293' y='292'/>
- <part name='22' x='305' y='291'/>
- <part name='23' x='309' y='288'/>
- <part name='24' x='313' y='287'/>
- <part name='25' x='318' y='287'/>
- <part name='26' x='321' y='290'/>
- <part name='27' x='300' y='297'/>
- <part name='28' x='301' y='302'/>
- <part name='29' x='302' y='307'/>
- <part name='30' x='303' y='313'/>
- <part name='31' x='296' y='316'/>
- <part name='32' x='299' y='317'/>
- <part name='33' x='303' y='318'/>
- <part name='34' x='306' y='317'/>
- <part name='35' x='308' y='315'/>
- <part name='36' x='279' y='298'/>
- <part name='37' x='283' y='296'/>
- <part name='38' x='287' y='296'/>
- <part name='39' x='291' y='299'/>
- <part name='40' x='287' y='300'/>
- <part name='41' x='283' y='300'/>
- <part name='42' x='306' y='298'/>
- <part name='43' x='310' y='294'/>
- <part name='44' x='314' y='293'/>
- <part name='45' x='318' y='296'/>
- <part name='46' x='315' y='297'/>
- <part name='47' x='311' y='298'/>
- <part name='48' x='286' y='324'/>
- <part name='49' x='292' y='322'/>
- <part name='50' x='299' y='322'/>
- <part name='51' x='303' y='322'/>
- <part name='52' x='307' y='321'/>
- <part name='53' x='311' y='321'/>
- <part name='54' x='315' y='322'/>
- <part name='55' x='312' y='329'/>
- <part name='56' x='308' y='333'/>
- <part name='57' x='303' y='334'/>
- <part name='58' x='299' y='333'/>
- <part name='59' x='292' y='331'/>
- <part name='60' x='288' y='324'/>
- <part name='61' x='299' y='324'/>
- <part name='62' x='303' y='324'/>
- <part name='63' x='307' y='324'/>
- <part name='64' x='313' y='323'/>
- <part name='65' x='307' y='329'/>
- <part name='66' x='303' y='330'/>
- <part name='67' x='299' y='329'/>
- </box>
- </image>
-</images>
-</dataset>
diff --git a/ml/dlib/examples/faces/training.xml b/ml/dlib/examples/faces/training.xml
deleted file mode 100644
index b7e1d0071..000000000
--- a/ml/dlib/examples/faces/training.xml
+++ /dev/null
@@ -1,34 +0,0 @@
-<?xml version='1.0' encoding='ISO-8859-1'?>
-<?xml-stylesheet type='text/xsl' href='image_metadata_stylesheet.xsl'?>
-<dataset>
-<name>Training faces</name>
-<comment>These are images from the PASCAL VOC 2011 dataset.</comment>
-<images>
- <image file='2007_007763.jpg'>
- <box top='90' left='194' width='37' height='37'/>
- <box top='114' left='158' width='37' height='37'/>
- <box top='89' left='381' width='45' height='44'/>
- <box top='198' left='94' width='37' height='37'/>
- <box top='214' left='178' width='37' height='37'/>
- <box top='86' left='294' width='37' height='37'/>
- <box top='233' left='309' width='45' height='44'/>
- </image>
- <image file='2008_002079.jpg'>
- <box top='166' left='407' width='37' height='37'/>
- <box top='134' left='122' width='37' height='37'/>
- <box top='138' left='346' width='37' height='37'/>
- <box top='171' left='433' width='53' height='52'/>
- <box top='134' left='62' width='37' height='37'/>
- <box top='194' left='41' width='44' height='44'/>
- </image>
- <image file='2008_001009.jpg'>
- <box top='79' left='145' width='76' height='76'/>
- <box top='214' left='125' width='90' height='91'/>
- </image>
- <image file='2008_001322.jpg'>
- <box top='162' left='104' width='76' height='76'/>
- <box top='218' left='232' width='63' height='63'/>
- <box top='155' left='344' width='90' height='90'/>
- </image>
-</images>
-</dataset> \ No newline at end of file
diff --git a/ml/dlib/examples/faces/training_with_face_landmarks.xml b/ml/dlib/examples/faces/training_with_face_landmarks.xml
deleted file mode 100644
index b87e75350..000000000
--- a/ml/dlib/examples/faces/training_with_face_landmarks.xml
+++ /dev/null
@@ -1,1280 +0,0 @@
-<?xml version='1.0' encoding='ISO-8859-1'?>
-<?xml-stylesheet type='text/xsl' href='image_metadata_stylesheet.xsl'?>
-<dataset>
-<name>Training faces</name>
-<comment>These are images from the PASCAL VOC 2011 dataset.
- The face landmarks are from dlib's shape_predictor_68_face_landmarks.dat
- landmarking model. The model uses the 68 landmark scheme used by the iBUG
- 300-W dataset.
-</comment>
-<images>
- <image file='2007_007763.jpg'>
- <box top='90' left='194' width='37' height='37'>
- <part name='00' x='201' y='107'/>
- <part name='01' x='201' y='110'/>
- <part name='02' x='201' y='113'/>
- <part name='03' x='202' y='117'/>
- <part name='04' x='204' y='120'/>
- <part name='05' x='206' y='123'/>
- <part name='06' x='208' y='126'/>
- <part name='07' x='210' y='129'/>
- <part name='08' x='213' y='129'/>
- <part name='09' x='217' y='129'/>
- <part name='10' x='220' y='127'/>
- <part name='11' x='224' y='124'/>
- <part name='12' x='228' y='121'/>
- <part name='13' x='230' y='118'/>
- <part name='14' x='231' y='114'/>
- <part name='15' x='231' y='109'/>
- <part name='16' x='231' y='105'/>
- <part name='17' x='201' y='102'/>
- <part name='18' x='202' y='101'/>
- <part name='19' x='204' y='100'/>
- <part name='20' x='206' y='100'/>
- <part name='21' x='207' y='101'/>
- <part name='22' x='211' y='101'/>
- <part name='23' x='214' y='100'/>
- <part name='24' x='217' y='99'/>
- <part name='25' x='220' y='100'/>
- <part name='26' x='223' y='102'/>
- <part name='27' x='209' y='105'/>
- <part name='28' x='209' y='108'/>
- <part name='29' x='208' y='111'/>
- <part name='30' x='208' y='114'/>
- <part name='31' x='206' y='115'/>
- <part name='32' x='208' y='116'/>
- <part name='33' x='209' y='116'/>
- <part name='34' x='211' y='116'/>
- <part name='35' x='213' y='115'/>
- <part name='36' x='203' y='106'/>
- <part name='37' x='204' y='105'/>
- <part name='38' x='206' y='105'/>
- <part name='39' x='207' y='106'/>
- <part name='40' x='206' y='106'/>
- <part name='41' x='204' y='106'/>
- <part name='42' x='215' y='106'/>
- <part name='43' x='216' y='105'/>
- <part name='44' x='218' y='105'/>
- <part name='45' x='220' y='106'/>
- <part name='46' x='218' y='106'/>
- <part name='47' x='216' y='106'/>
- <part name='48' x='207' y='120'/>
- <part name='49' x='207' y='119'/>
- <part name='50' x='209' y='119'/>
- <part name='51' x='210' y='119'/>
- <part name='52' x='212' y='118'/>
- <part name='53' x='215' y='119'/>
- <part name='54' x='218' y='119'/>
- <part name='55' x='216' y='122'/>
- <part name='56' x='213' y='123'/>
- <part name='57' x='211' y='123'/>
- <part name='58' x='210' y='123'/>
- <part name='59' x='208' y='122'/>
- <part name='60' x='208' y='120'/>
- <part name='61' x='209' y='120'/>
- <part name='62' x='211' y='120'/>
- <part name='63' x='212' y='119'/>
- <part name='64' x='217' y='119'/>
- <part name='65' x='213' y='121'/>
- <part name='66' x='211' y='122'/>
- <part name='67' x='209' y='121'/>
- </box>
- <box top='114' left='158' width='37' height='37'>
- <part name='00' x='165' y='131'/>
- <part name='01' x='164' y='134'/>
- <part name='02' x='165' y='137'/>
- <part name='03' x='166' y='141'/>
- <part name='04' x='167' y='144'/>
- <part name='05' x='169' y='147'/>
- <part name='06' x='172' y='149'/>
- <part name='07' x='174' y='151'/>
- <part name='08' x='177' y='152'/>
- <part name='09' x='181' y='152'/>
- <part name='10' x='184' y='150'/>
- <part name='11' x='188' y='147'/>
- <part name='12' x='191' y='145'/>
- <part name='13' x='193' y='142'/>
- <part name='14' x='194' y='138'/>
- <part name='15' x='194' y='134'/>
- <part name='16' x='194' y='130'/>
- <part name='17' x='165' y='127'/>
- <part name='18' x='166' y='125'/>
- <part name='19' x='167' y='125'/>
- <part name='20' x='169' y='125'/>
- <part name='21' x='171' y='126'/>
- <part name='22' x='175' y='125'/>
- <part name='23' x='178' y='124'/>
- <part name='24' x='181' y='124'/>
- <part name='25' x='184' y='125'/>
- <part name='26' x='186' y='126'/>
- <part name='27' x='173' y='130'/>
- <part name='28' x='173' y='132'/>
- <part name='29' x='173' y='134'/>
- <part name='30' x='173' y='137'/>
- <part name='31' x='171' y='139'/>
- <part name='32' x='172' y='139'/>
- <part name='33' x='174' y='140'/>
- <part name='34' x='175' y='139'/>
- <part name='35' x='177' y='139'/>
- <part name='36' x='167' y='131'/>
- <part name='37' x='168' y='130'/>
- <part name='38' x='170' y='130'/>
- <part name='39' x='171' y='131'/>
- <part name='40' x='170' y='131'/>
- <part name='41' x='168' y='131'/>
- <part name='42' x='178' y='130'/>
- <part name='43' x='179' y='129'/>
- <part name='44' x='181' y='129'/>
- <part name='45' x='183' y='130'/>
- <part name='46' x='181' y='130'/>
- <part name='47' x='179' y='130'/>
- <part name='48' x='171' y='143'/>
- <part name='49' x='172' y='143'/>
- <part name='50' x='173' y='143'/>
- <part name='51' x='174' y='143'/>
- <part name='52' x='176' y='142'/>
- <part name='53' x='178' y='142'/>
- <part name='54' x='182' y='142'/>
- <part name='55' x='179' y='145'/>
- <part name='56' x='176' y='146'/>
- <part name='57' x='175' y='146'/>
- <part name='58' x='174' y='146'/>
- <part name='59' x='172' y='145'/>
- <part name='60' x='172' y='143'/>
- <part name='61' x='174' y='143'/>
- <part name='62' x='175' y='144'/>
- <part name='63' x='176' y='143'/>
- <part name='64' x='181' y='143'/>
- <part name='65' x='176' y='144'/>
- <part name='66' x='175' y='144'/>
- <part name='67' x='174' y='144'/>
- </box>
- <box top='89' left='381' width='45' height='44'>
- <part name='00' x='393' y='107'/>
- <part name='01' x='393' y='111'/>
- <part name='02' x='393' y='116'/>
- <part name='03' x='395' y='120'/>
- <part name='04' x='398' y='123'/>
- <part name='05' x='400' y='127'/>
- <part name='06' x='401' y='132'/>
- <part name='07' x='403' y='136'/>
- <part name='08' x='406' y='137'/>
- <part name='09' x='411' y='137'/>
- <part name='10' x='416' y='134'/>
- <part name='11' x='422' y='130'/>
- <part name='12' x='427' y='126'/>
- <part name='13' x='430' y='120'/>
- <part name='14' x='432' y='114'/>
- <part name='15' x='431' y='107'/>
- <part name='16' x='431' y='100'/>
- <part name='17' x='391' y='98'/>
- <part name='18' x='392' y='97'/>
- <part name='19' x='393' y='97'/>
- <part name='20' x='394' y='97'/>
- <part name='21' x='396' y='99'/>
- <part name='22' x='401' y='98'/>
- <part name='23' x='404' y='96'/>
- <part name='24' x='408' y='95'/>
- <part name='25' x='412' y='96'/>
- <part name='26' x='415' y='97'/>
- <part name='27' x='399' y='104'/>
- <part name='28' x='398' y='107'/>
- <part name='29' x='397' y='111'/>
- <part name='30' x='396' y='114'/>
- <part name='31' x='396' y='116'/>
- <part name='32' x='397' y='117'/>
- <part name='33' x='399' y='118'/>
- <part name='34' x='401' y='117'/>
- <part name='35' x='403' y='116'/>
- <part name='36' x='394' y='104'/>
- <part name='37' x='395' y='103'/>
- <part name='38' x='396' y='103'/>
- <part name='39' x='398' y='104'/>
- <part name='40' x='396' y='104'/>
- <part name='41' x='395' y='104'/>
- <part name='42' x='405' y='103'/>
- <part name='43' x='406' y='102'/>
- <part name='44' x='408' y='102'/>
- <part name='45' x='411' y='102'/>
- <part name='46' x='409' y='103'/>
- <part name='47' x='407' y='103'/>
- <part name='48' x='399' y='123'/>
- <part name='49' x='397' y='121'/>
- <part name='50' x='399' y='121'/>
- <part name='51' x='400' y='121'/>
- <part name='52' x='402' y='121'/>
- <part name='53' x='407' y='121'/>
- <part name='54' x='411' y='122'/>
- <part name='55' x='408' y='126'/>
- <part name='56' x='404' y='129'/>
- <part name='57' x='402' y='129'/>
- <part name='58' x='400' y='129'/>
- <part name='59' x='399' y='127'/>
- <part name='60' x='399' y='123'/>
- <part name='61' x='399' y='122'/>
- <part name='62' x='401' y='122'/>
- <part name='63' x='403' y='122'/>
- <part name='64' x='410' y='122'/>
- <part name='65' x='403' y='126'/>
- <part name='66' x='402' y='126'/>
- <part name='67' x='400' y='126'/>
- </box>
- <box top='198' left='94' width='37' height='37'>
- <part name='00' x='100' y='208'/>
- <part name='01' x='100' y='211'/>
- <part name='02' x='100' y='215'/>
- <part name='03' x='100' y='218'/>
- <part name='04' x='101' y='222'/>
- <part name='05' x='103' y='225'/>
- <part name='06' x='105' y='227'/>
- <part name='07' x='107' y='229'/>
- <part name='08' x='110' y='231'/>
- <part name='09' x='114' y='230'/>
- <part name='10' x='118' y='229'/>
- <part name='11' x='122' y='227'/>
- <part name='12' x='126' y='224'/>
- <part name='13' x='128' y='221'/>
- <part name='14' x='129' y='217'/>
- <part name='15' x='130' y='213'/>
- <part name='16' x='130' y='209'/>
- <part name='17' x='101' y='204'/>
- <part name='18' x='102' y='203'/>
- <part name='19' x='104' y='203'/>
- <part name='20' x='106' y='203'/>
- <part name='21' x='108' y='204'/>
- <part name='22' x='112' y='204'/>
- <part name='23' x='115' y='203'/>
- <part name='24' x='118' y='203'/>
- <part name='25' x='121' y='204'/>
- <part name='26' x='123' y='205'/>
- <part name='27' x='110' y='207'/>
- <part name='28' x='110' y='210'/>
- <part name='29' x='109' y='212'/>
- <part name='30' x='109' y='215'/>
- <part name='31' x='107' y='216'/>
- <part name='32' x='108' y='217'/>
- <part name='33' x='109' y='218'/>
- <part name='34' x='111' y='217'/>
- <part name='35' x='113' y='217'/>
- <part name='36' x='103' y='207'/>
- <part name='37' x='104' y='207'/>
- <part name='38' x='106' y='207'/>
- <part name='39' x='107' y='208'/>
- <part name='40' x='106' y='208'/>
- <part name='41' x='104' y='208'/>
- <part name='42' x='115' y='208'/>
- <part name='43' x='116' y='207'/>
- <part name='44' x='118' y='207'/>
- <part name='45' x='119' y='208'/>
- <part name='46' x='118' y='209'/>
- <part name='47' x='116' y='208'/>
- <part name='48' x='106' y='221'/>
- <part name='49' x='107' y='220'/>
- <part name='50' x='108' y='220'/>
- <part name='51' x='110' y='220'/>
- <part name='52' x='111' y='220'/>
- <part name='53' x='114' y='221'/>
- <part name='54' x='117' y='221'/>
- <part name='55' x='114' y='223'/>
- <part name='56' x='111' y='223'/>
- <part name='57' x='110' y='223'/>
- <part name='58' x='108' y='223'/>
- <part name='59' x='107' y='222'/>
- <part name='60' x='107' y='221'/>
- <part name='61' x='108' y='221'/>
- <part name='62' x='110' y='221'/>
- <part name='63' x='111' y='221'/>
- <part name='64' x='115' y='221'/>
- <part name='65' x='111' y='221'/>
- <part name='66' x='110' y='221'/>
- <part name='67' x='108' y='221'/>
- </box>
- <box top='214' left='178' width='37' height='37'>
- <part name='00' x='186' y='225'/>
- <part name='01' x='185' y='228'/>
- <part name='02' x='184' y='231'/>
- <part name='03' x='184' y='235'/>
- <part name='04' x='184' y='238'/>
- <part name='05' x='185' y='241'/>
- <part name='06' x='186' y='245'/>
- <part name='07' x='187' y='248'/>
- <part name='08' x='190' y='249'/>
- <part name='09' x='194' y='250'/>
- <part name='10' x='198' y='249'/>
- <part name='11' x='203' y='247'/>
- <part name='12' x='207' y='245'/>
- <part name='13' x='210' y='242'/>
- <part name='14' x='212' y='238'/>
- <part name='15' x='213' y='234'/>
- <part name='16' x='214' y='229'/>
- <part name='17' x='186' y='221'/>
- <part name='18' x='188' y='220'/>
- <part name='19' x='190' y='220'/>
- <part name='20' x='191' y='221'/>
- <part name='21' x='193' y='223'/>
- <part name='22' x='197' y='224'/>
- <part name='23' x='200' y='224'/>
- <part name='24' x='203' y='224'/>
- <part name='25' x='205' y='225'/>
- <part name='26' x='207' y='227'/>
- <part name='27' x='194' y='226'/>
- <part name='28' x='193' y='229'/>
- <part name='29' x='192' y='231'/>
- <part name='30' x='191' y='234'/>
- <part name='31' x='189' y='234'/>
- <part name='32' x='190' y='236'/>
- <part name='33' x='192' y='237'/>
- <part name='34' x='194' y='236'/>
- <part name='35' x='195' y='236'/>
- <part name='36' x='188' y='224'/>
- <part name='37' x='189' y='224'/>
- <part name='38' x='191' y='225'/>
- <part name='39' x='192' y='226'/>
- <part name='40' x='190' y='225'/>
- <part name='41' x='189' y='225'/>
- <part name='42' x='199' y='227'/>
- <part name='43' x='201' y='227'/>
- <part name='44' x='202' y='228'/>
- <part name='45' x='204' y='229'/>
- <part name='46' x='202' y='229'/>
- <part name='47' x='200' y='228'/>
- <part name='48' x='188' y='238'/>
- <part name='49' x='189' y='238'/>
- <part name='50' x='190' y='239'/>
- <part name='51' x='192' y='239'/>
- <part name='52' x='194' y='239'/>
- <part name='53' x='196' y='240'/>
- <part name='54' x='199' y='241'/>
- <part name='55' x='196' y='243'/>
- <part name='56' x='193' y='243'/>
- <part name='57' x='191' y='243'/>
- <part name='58' x='189' y='242'/>
- <part name='59' x='188' y='241'/>
- <part name='60' x='188' y='239'/>
- <part name='61' x='190' y='240'/>
- <part name='62' x='192' y='240'/>
- <part name='63' x='193' y='240'/>
- <part name='64' x='198' y='241'/>
- <part name='65' x='193' y='241'/>
- <part name='66' x='191' y='241'/>
- <part name='67' x='190' y='240'/>
- </box>
- <box top='86' left='294' width='37' height='37'>
- <part name='00' x='299' y='101'/>
- <part name='01' x='299' y='105'/>
- <part name='02' x='299' y='109'/>
- <part name='03' x='300' y='113'/>
- <part name='04' x='302' y='116'/>
- <part name='05' x='304' y='120'/>
- <part name='06' x='306' y='124'/>
- <part name='07' x='308' y='127'/>
- <part name='08' x='312' y='128'/>
- <part name='09' x='316' y='127'/>
- <part name='10' x='321' y='125'/>
- <part name='11' x='325' y='121'/>
- <part name='12' x='329' y='118'/>
- <part name='13' x='332' y='113'/>
- <part name='14' x='333' y='108'/>
- <part name='15' x='334' y='102'/>
- <part name='16' x='334' y='96'/>
- <part name='17' x='298' y='97'/>
- <part name='18' x='298' y='95'/>
- <part name='19' x='300' y='94'/>
- <part name='20' x='302' y='94'/>
- <part name='21' x='305' y='95'/>
- <part name='22' x='309' y='94'/>
- <part name='23' x='313' y='92'/>
- <part name='24' x='316' y='91'/>
- <part name='25' x='320' y='92'/>
- <part name='26' x='324' y='94'/>
- <part name='27' x='307' y='98'/>
- <part name='28' x='307' y='101'/>
- <part name='29' x='306' y='104'/>
- <part name='30' x='306' y='107'/>
- <part name='31' x='304' y='109'/>
- <part name='32' x='306' y='110'/>
- <part name='33' x='308' y='110'/>
- <part name='34' x='310' y='109'/>
- <part name='35' x='312' y='108'/>
- <part name='36' x='301' y='100'/>
- <part name='37' x='302' y='99'/>
- <part name='38' x='303' y='99'/>
- <part name='39' x='305' y='99'/>
- <part name='40' x='304' y='100'/>
- <part name='41' x='302' y='100'/>
- <part name='42' x='314' y='98'/>
- <part name='43' x='315' y='97'/>
- <part name='44' x='317' y='97'/>
- <part name='45' x='319' y='97'/>
- <part name='46' x='317' y='98'/>
- <part name='47' x='315' y='98'/>
- <part name='48' x='305' y='115'/>
- <part name='49' x='306' y='114'/>
- <part name='50' x='307' y='113'/>
- <part name='51' x='309' y='113'/>
- <part name='52' x='310' y='112'/>
- <part name='53' x='314' y='112'/>
- <part name='54' x='318' y='113'/>
- <part name='55' x='315' y='117'/>
- <part name='56' x='312' y='118'/>
- <part name='57' x='310' y='119'/>
- <part name='58' x='308' y='119'/>
- <part name='59' x='307' y='118'/>
- <part name='60' x='306' y='115'/>
- <part name='61' x='307' y='114'/>
- <part name='62' x='309' y='114'/>
- <part name='63' x='311' y='113'/>
- <part name='64' x='317' y='113'/>
- <part name='65' x='311' y='117'/>
- <part name='66' x='309' y='117'/>
- <part name='67' x='308' y='117'/>
- </box>
- <box top='233' left='309' width='45' height='44'>
- <part name='00' x='322' y='246'/>
- <part name='01' x='320' y='249'/>
- <part name='02' x='318' y='253'/>
- <part name='03' x='318' y='258'/>
- <part name='04' x='318' y='262'/>
- <part name='05' x='318' y='267'/>
- <part name='06' x='319' y='271'/>
- <part name='07' x='320' y='276'/>
- <part name='08' x='323' y='278'/>
- <part name='09' x='328' y='279'/>
- <part name='10' x='334' y='279'/>
- <part name='11' x='340' y='278'/>
- <part name='12' x='346' y='276'/>
- <part name='13' x='350' y='273'/>
- <part name='14' x='354' y='268'/>
- <part name='15' x='356' y='263'/>
- <part name='16' x='359' y='257'/>
- <part name='17' x='323' y='239'/>
- <part name='18' x='325' y='238'/>
- <part name='19' x='327' y='238'/>
- <part name='20' x='328' y='240'/>
- <part name='21' x='329' y='242'/>
- <part name='22' x='336' y='244'/>
- <part name='23' x='339' y='244'/>
- <part name='24' x='343' y='244'/>
- <part name='25' x='347' y='246'/>
- <part name='26' x='349' y='249'/>
- <part name='27' x='331' y='248'/>
- <part name='28' x='329' y='251'/>
- <part name='29' x='328' y='254'/>
- <part name='30' x='326' y='257'/>
- <part name='31' x='324' y='259'/>
- <part name='32' x='325' y='260'/>
- <part name='33' x='326' y='261'/>
- <part name='34' x='328' y='261'/>
- <part name='35' x='331' y='262'/>
- <part name='36' x='324' y='246'/>
- <part name='37' x='325' y='246'/>
- <part name='38' x='327' y='247'/>
- <part name='39' x='328' y='248'/>
- <part name='40' x='326' y='248'/>
- <part name='41' x='325' y='247'/>
- <part name='42' x='337' y='251'/>
- <part name='43' x='339' y='251'/>
- <part name='44' x='341' y='252'/>
- <part name='45' x='343' y='253'/>
- <part name='46' x='341' y='253'/>
- <part name='47' x='339' y='252'/>
- <part name='48' x='322' y='264'/>
- <part name='49' x='322' y='264'/>
- <part name='50' x='324' y='264'/>
- <part name='51' x='325' y='265'/>
- <part name='52' x='327' y='265'/>
- <part name='53' x='331' y='267'/>
- <part name='54' x='334' y='270'/>
- <part name='55' x='330' y='271'/>
- <part name='56' x='326' y='271'/>
- <part name='57' x='324' y='270'/>
- <part name='58' x='323' y='270'/>
- <part name='59' x='322' y='268'/>
- <part name='60' x='322' y='265'/>
- <part name='61' x='324' y='265'/>
- <part name='62' x='325' y='266'/>
- <part name='63' x='327' y='267'/>
- <part name='64' x='333' y='269'/>
- <part name='65' x='327' y='269'/>
- <part name='66' x='325' y='269'/>
- <part name='67' x='323' y='267'/>
- </box>
- </image>
- <image file='2008_002079.jpg'>
- <box top='166' left='406' width='37' height='37'>
- <part name='00' x='412' y='179'/>
- <part name='01' x='411' y='183'/>
- <part name='02' x='412' y='187'/>
- <part name='03' x='412' y='190'/>
- <part name='04' x='413' y='194'/>
- <part name='05' x='415' y='197'/>
- <part name='06' x='418' y='200'/>
- <part name='07' x='421' y='203'/>
- <part name='08' x='424' y='204'/>
- <part name='09' x='428' y='203'/>
- <part name='10' x='433' y='202'/>
- <part name='11' x='437' y='200'/>
- <part name='12' x='441' y='197'/>
- <part name='13' x='443' y='193'/>
- <part name='14' x='445' y='188'/>
- <part name='15' x='446' y='184'/>
- <part name='16' x='446' y='179'/>
- <part name='17' x='413' y='174'/>
- <part name='18' x='414' y='172'/>
- <part name='19' x='416' y='171'/>
- <part name='20' x='419' y='171'/>
- <part name='21' x='421' y='172'/>
- <part name='22' x='427' y='171'/>
- <part name='23' x='431' y='171'/>
- <part name='24' x='434' y='170'/>
- <part name='25' x='437' y='171'/>
- <part name='26' x='440' y='173'/>
- <part name='27' x='424' y='176'/>
- <part name='28' x='423' y='179'/>
- <part name='29' x='422' y='182'/>
- <part name='30' x='422' y='185'/>
- <part name='31' x='421' y='186'/>
- <part name='32' x='422' y='187'/>
- <part name='33' x='423' y='188'/>
- <part name='34' x='425' y='187'/>
- <part name='35' x='427' y='186'/>
- <part name='36' x='415' y='177'/>
- <part name='37' x='417' y='176'/>
- <part name='38' x='419' y='176'/>
- <part name='39' x='421' y='177'/>
- <part name='40' x='419' y='178'/>
- <part name='41' x='417' y='178'/>
- <part name='42' x='430' y='177'/>
- <part name='43' x='432' y='175'/>
- <part name='44' x='434' y='175'/>
- <part name='45' x='436' y='176'/>
- <part name='46' x='434' y='177'/>
- <part name='47' x='432' y='177'/>
- <part name='48' x='418' y='192'/>
- <part name='49' x='420' y='190'/>
- <part name='50' x='422' y='190'/>
- <part name='51' x='424' y='190'/>
- <part name='52' x='426' y='189'/>
- <part name='53' x='430' y='190'/>
- <part name='54' x='433' y='191'/>
- <part name='55' x='430' y='194'/>
- <part name='56' x='426' y='195'/>
- <part name='57' x='424' y='195'/>
- <part name='58' x='422' y='195'/>
- <part name='59' x='420' y='194'/>
- <part name='60' x='419' y='192'/>
- <part name='61' x='422' y='191'/>
- <part name='62' x='424' y='191'/>
- <part name='63' x='426' y='191'/>
- <part name='64' x='432' y='191'/>
- <part name='65' x='426' y='193'/>
- <part name='66' x='424' y='194'/>
- <part name='67' x='422' y='193'/>
- </box>
- <box top='134' left='122' width='37' height='37'>
- <part name='00' x='123' y='143'/>
- <part name='01' x='123' y='148'/>
- <part name='02' x='123' y='152'/>
- <part name='03' x='124' y='156'/>
- <part name='04' x='125' y='160'/>
- <part name='05' x='128' y='163'/>
- <part name='06' x='131' y='167'/>
- <part name='07' x='134' y='169'/>
- <part name='08' x='137' y='170'/>
- <part name='09' x='140' y='170'/>
- <part name='10' x='143' y='167'/>
- <part name='11' x='145' y='164'/>
- <part name='12' x='147' y='161'/>
- <part name='13' x='148' y='158'/>
- <part name='14' x='150' y='155'/>
- <part name='15' x='150' y='151'/>
- <part name='16' x='151' y='148'/>
- <part name='17' x='131' y='141'/>
- <part name='18' x='133' y='140'/>
- <part name='19' x='136' y='140'/>
- <part name='20' x='139' y='141'/>
- <part name='21' x='141' y='142'/>
- <part name='22' x='145' y='143'/>
- <part name='23' x='147' y='143'/>
- <part name='24' x='149' y='143'/>
- <part name='25' x='150' y='143'/>
- <part name='26' x='151' y='145'/>
- <part name='27' x='143' y='146'/>
- <part name='28' x='143' y='148'/>
- <part name='29' x='143' y='150'/>
- <part name='30' x='143' y='152'/>
- <part name='31' x='139' y='154'/>
- <part name='32' x='140' y='154'/>
- <part name='33' x='142' y='155'/>
- <part name='34' x='143' y='155'/>
- <part name='35' x='144' y='154'/>
- <part name='36' x='134' y='144'/>
- <part name='37' x='135' y='144'/>
- <part name='38' x='137' y='144'/>
- <part name='39' x='138' y='145'/>
- <part name='40' x='137' y='145'/>
- <part name='41' x='135' y='145'/>
- <part name='42' x='144' y='147'/>
- <part name='43' x='146' y='146'/>
- <part name='44' x='148' y='146'/>
- <part name='45' x='149' y='147'/>
- <part name='46' x='147' y='148'/>
- <part name='47' x='146' y='147'/>
- <part name='48' x='134' y='158'/>
- <part name='49' x='137' y='157'/>
- <part name='50' x='140' y='158'/>
- <part name='51' x='141' y='158'/>
- <part name='52' x='142' y='158'/>
- <part name='53' x='144' y='159'/>
- <part name='54' x='144' y='160'/>
- <part name='55' x='143' y='162'/>
- <part name='56' x='141' y='163'/>
- <part name='57' x='140' y='163'/>
- <part name='58' x='138' y='162'/>
- <part name='59' x='136' y='161'/>
- <part name='60' x='135' y='158'/>
- <part name='61' x='139' y='158'/>
- <part name='62' x='141' y='159'/>
- <part name='63' x='142' y='159'/>
- <part name='64' x='143' y='160'/>
- <part name='65' x='142' y='161'/>
- <part name='66' x='140' y='161'/>
- <part name='67' x='139' y='161'/>
- </box>
- <box top='138' left='346' width='37' height='37'>
- <part name='00' x='351' y='147'/>
- <part name='01' x='351' y='151'/>
- <part name='02' x='351' y='154'/>
- <part name='03' x='351' y='158'/>
- <part name='04' x='352' y='162'/>
- <part name='05' x='353' y='165'/>
- <part name='06' x='355' y='168'/>
- <part name='07' x='358' y='170'/>
- <part name='08' x='361' y='171'/>
- <part name='09' x='365' y='171'/>
- <part name='10' x='369' y='169'/>
- <part name='11' x='373' y='168'/>
- <part name='12' x='375' y='165'/>
- <part name='13' x='377' y='161'/>
- <part name='14' x='378' y='158'/>
- <part name='15' x='379' y='154'/>
- <part name='16' x='380' y='150'/>
- <part name='17' x='352' y='144'/>
- <part name='18' x='354' y='142'/>
- <part name='19' x='356' y='142'/>
- <part name='20' x='358' y='142'/>
- <part name='21' x='360' y='144'/>
- <part name='22' x='368' y='144'/>
- <part name='23' x='371' y='143'/>
- <part name='24' x='373' y='143'/>
- <part name='25' x='375' y='144'/>
- <part name='26' x='377' y='146'/>
- <part name='27' x='364' y='147'/>
- <part name='28' x='363' y='150'/>
- <part name='29' x='363' y='152'/>
- <part name='30' x='363' y='155'/>
- <part name='31' x='360' y='156'/>
- <part name='32' x='361' y='156'/>
- <part name='33' x='363' y='157'/>
- <part name='34' x='364' y='157'/>
- <part name='35' x='365' y='156'/>
- <part name='36' x='354' y='148'/>
- <part name='37' x='356' y='147'/>
- <part name='38' x='358' y='147'/>
- <part name='39' x='360' y='148'/>
- <part name='40' x='358' y='148'/>
- <part name='41' x='356' y='148'/>
- <part name='42' x='368' y='149'/>
- <part name='43' x='370' y='148'/>
- <part name='44' x='372' y='148'/>
- <part name='45' x='374' y='149'/>
- <part name='46' x='372' y='149'/>
- <part name='47' x='370' y='149'/>
- <part name='48' x='357' y='161'/>
- <part name='49' x='359' y='159'/>
- <part name='50' x='361' y='159'/>
- <part name='51' x='363' y='159'/>
- <part name='52' x='365' y='159'/>
- <part name='53' x='367' y='160'/>
- <part name='54' x='369' y='161'/>
- <part name='55' x='367' y='163'/>
- <part name='56' x='364' y='164'/>
- <part name='57' x='362' y='164'/>
- <part name='58' x='360' y='164'/>
- <part name='59' x='358' y='163'/>
- <part name='60' x='358' y='161'/>
- <part name='61' x='361' y='160'/>
- <part name='62' x='363' y='160'/>
- <part name='63' x='364' y='160'/>
- <part name='64' x='368' y='161'/>
- <part name='65' x='364' y='163'/>
- <part name='66' x='362' y='163'/>
- <part name='67' x='361' y='162'/>
- </box>
- <box top='175' left='439' width='44' height='44'>
- <part name='00' x='444' y='189'/>
- <part name='01' x='443' y='193'/>
- <part name='02' x='442' y='198'/>
- <part name='03' x='442' y='203'/>
- <part name='04' x='444' y='209'/>
- <part name='05' x='446' y='214'/>
- <part name='06' x='449' y='218'/>
- <part name='07' x='452' y='222'/>
- <part name='08' x='457' y='224'/>
- <part name='09' x='463' y='224'/>
- <part name='10' x='470' y='222'/>
- <part name='11' x='477' y='219'/>
- <part name='12' x='483' y='215'/>
- <part name='13' x='487' y='209'/>
- <part name='14' x='489' y='202'/>
- <part name='15' x='490' y='195'/>
- <part name='16' x='491' y='188'/>
- <part name='17' x='444' y='184'/>
- <part name='18' x='445' y='181'/>
- <part name='19' x='448' y='181'/>
- <part name='20' x='451' y='181'/>
- <part name='21' x='454' y='183'/>
- <part name='22' x='461' y='182'/>
- <part name='23' x='465' y='181'/>
- <part name='24' x='470' y='180'/>
- <part name='25' x='475' y='181'/>
- <part name='26' x='479' y='184'/>
- <part name='27' x='456' y='187'/>
- <part name='28' x='455' y='190'/>
- <part name='29' x='454' y='193'/>
- <part name='30' x='453' y='197'/>
- <part name='31' x='451' y='199'/>
- <part name='32' x='452' y='200'/>
- <part name='33' x='455' y='201'/>
- <part name='34' x='458' y='200'/>
- <part name='35' x='461' y='200'/>
- <part name='36' x='447' y='187'/>
- <part name='37' x='449' y='186'/>
- <part name='38' x='451' y='186'/>
- <part name='39' x='454' y='188'/>
- <part name='40' x='451' y='188'/>
- <part name='41' x='449' y='188'/>
- <part name='42' x='465' y='188'/>
- <part name='43' x='467' y='186'/>
- <part name='44' x='470' y='186'/>
- <part name='45' x='473' y='187'/>
- <part name='46' x='470' y='188'/>
- <part name='47' x='467' y='188'/>
- <part name='48' x='449' y='206'/>
- <part name='49' x='451' y='205'/>
- <part name='50' x='453' y='204'/>
- <part name='51' x='456' y='205'/>
- <part name='52' x='458' y='204'/>
- <part name='53' x='463' y='205'/>
- <part name='54' x='470' y='206'/>
- <part name='55' x='464' y='210'/>
- <part name='56' x='459' y='211'/>
- <part name='57' x='456' y='211'/>
- <part name='58' x='454' y='211'/>
- <part name='59' x='451' y='209'/>
- <part name='60' x='450' y='206'/>
- <part name='61' x='453' y='206'/>
- <part name='62' x='456' y='206'/>
- <part name='63' x='458' y='205'/>
- <part name='64' x='468' y='206'/>
- <part name='65' x='459' y='209'/>
- <part name='66' x='456' y='209'/>
- <part name='67' x='454' y='209'/>
- </box>
- <box top='134' left='62' width='37' height='37'>
- <part name='00' x='59' y='147'/>
- <part name='01' x='60' y='153'/>
- <part name='02' x='62' y='158'/>
- <part name='03' x='64' y='163'/>
- <part name='04' x='67' y='167'/>
- <part name='05' x='72' y='170'/>
- <part name='06' x='77' y='171'/>
- <part name='07' x='83' y='173'/>
- <part name='08' x='87' y='172'/>
- <part name='09' x='90' y='171'/>
- <part name='10' x='92' y='167'/>
- <part name='11' x='92' y='163'/>
- <part name='12' x='93' y='159'/>
- <part name='13' x='94' y='155'/>
- <part name='14' x='94' y='151'/>
- <part name='15' x='94' y='148'/>
- <part name='16' x='93' y='144'/>
- <part name='17' x='67' y='141'/>
- <part name='18' x='70' y='138'/>
- <part name='19' x='73' y='137'/>
- <part name='20' x='77' y='136'/>
- <part name='21' x='81' y='137'/>
- <part name='22' x='87' y='137'/>
- <part name='23' x='89' y='136'/>
- <part name='24' x='91' y='136'/>
- <part name='25' x='92' y='136'/>
- <part name='26' x='93' y='138'/>
- <part name='27' x='85' y='142'/>
- <part name='28' x='86' y='144'/>
- <part name='29' x='87' y='147'/>
- <part name='30' x='89' y='150'/>
- <part name='31' x='83' y='153'/>
- <part name='32' x='85' y='153'/>
- <part name='33' x='87' y='154'/>
- <part name='34' x='89' y='153'/>
- <part name='35' x='90' y='152'/>
- <part name='36' x='72' y='144'/>
- <part name='37' x='74' y='142'/>
- <part name='38' x='76' y='142'/>
- <part name='39' x='78' y='143'/>
- <part name='40' x='76' y='144'/>
- <part name='41' x='74' y='144'/>
- <part name='42' x='86' y='143'/>
- <part name='43' x='88' y='142'/>
- <part name='44' x='90' y='142'/>
- <part name='45' x='92' y='143'/>
- <part name='46' x='90' y='144'/>
- <part name='47' x='89' y='144'/>
- <part name='48' x='78' y='159'/>
- <part name='49' x='82' y='157'/>
- <part name='50' x='85' y='157'/>
- <part name='51' x='87' y='157'/>
- <part name='52' x='88' y='157'/>
- <part name='53' x='90' y='157'/>
- <part name='54' x='90' y='159'/>
- <part name='55' x='90' y='161'/>
- <part name='56' x='88' y='163'/>
- <part name='57' x='87' y='163'/>
- <part name='58' x='85' y='163'/>
- <part name='59' x='82' y='162'/>
- <part name='60' x='79' y='160'/>
- <part name='61' x='85' y='158'/>
- <part name='62' x='87' y='158'/>
- <part name='63' x='88' y='158'/>
- <part name='64' x='90' y='159'/>
- <part name='65' x='88' y='160'/>
- <part name='66' x='87' y='161'/>
- <part name='67' x='85' y='161'/>
- </box>
- <box top='194' left='41' width='44' height='44'>
- <part name='00' x='34' y='207'/>
- <part name='01' x='35' y='214'/>
- <part name='02' x='36' y='221'/>
- <part name='03' x='39' y='227'/>
- <part name='04' x='43' y='232'/>
- <part name='05' x='48' y='236'/>
- <part name='06' x='55' y='240'/>
- <part name='07' x='62' y='242'/>
- <part name='08' x='68' y='242'/>
- <part name='09' x='72' y='240'/>
- <part name='10' x='74' y='235'/>
- <part name='11' x='75' y='230'/>
- <part name='12' x='77' y='225'/>
- <part name='13' x='78' y='220'/>
- <part name='14' x='78' y='215'/>
- <part name='15' x='78' y='210'/>
- <part name='16' x='77' y='205'/>
- <part name='17' x='46' y='204'/>
- <part name='18' x='50' y='201'/>
- <part name='19' x='55' y='200'/>
- <part name='20' x='60' y='199'/>
- <part name='21' x='65' y='200'/>
- <part name='22' x='70' y='199'/>
- <part name='23' x='72' y='197'/>
- <part name='24' x='75' y='196'/>
- <part name='25' x='77' y='196'/>
- <part name='26' x='78' y='197'/>
- <part name='27' x='69' y='205'/>
- <part name='28' x='70' y='209'/>
- <part name='29' x='72' y='212'/>
- <part name='30' x='73' y='216'/>
- <part name='31' x='67' y='219'/>
- <part name='32' x='69' y='220'/>
- <part name='33' x='71' y='220'/>
- <part name='34' x='73' y='220'/>
- <part name='35' x='74' y='218'/>
- <part name='36' x='53' y='207'/>
- <part name='37' x='56' y='206'/>
- <part name='38' x='59' y='205'/>
- <part name='39' x='61' y='206'/>
- <part name='40' x='59' y='207'/>
- <part name='41' x='56' y='208'/>
- <part name='42' x='70' y='205'/>
- <part name='43' x='72' y='203'/>
- <part name='44' x='74' y='202'/>
- <part name='45' x='75' y='203'/>
- <part name='46' x='75' y='204'/>
- <part name='47' x='73' y='205'/>
- <part name='48' x='61' y='228'/>
- <part name='49' x='65' y='226'/>
- <part name='50' x='69' y='225'/>
- <part name='51' x='70' y='225'/>
- <part name='52' x='72' y='224'/>
- <part name='53' x='73' y='225'/>
- <part name='54' x='73' y='226'/>
- <part name='55' x='73' y='228'/>
- <part name='56' x='72' y='230'/>
- <part name='57' x='70' y='230'/>
- <part name='58' x='68' y='230'/>
- <part name='59' x='65' y='230'/>
- <part name='60' x='63' y='228'/>
- <part name='61' x='69' y='227'/>
- <part name='62' x='70' y='227'/>
- <part name='63' x='72' y='226'/>
- <part name='64' x='72' y='226'/>
- <part name='65' x='72' y='226'/>
- <part name='66' x='70' y='227'/>
- <part name='67' x='68' y='227'/>
- </box>
- </image>
- <image file='2008_001009.jpg'>
- <box top='79' left='145' width='76' height='76'>
- <part name='00' x='145' y='115'/>
- <part name='01' x='148' y='124'/>
- <part name='02' x='151' y='133'/>
- <part name='03' x='154' y='141'/>
- <part name='04' x='160' y='148'/>
- <part name='05' x='167' y='154'/>
- <part name='06' x='174' y='159'/>
- <part name='07' x='183' y='163'/>
- <part name='08' x='191' y='163'/>
- <part name='09' x='199' y='161'/>
- <part name='10' x='205' y='154'/>
- <part name='11' x='210' y='147'/>
- <part name='12' x='214' y='139'/>
- <part name='13' x='216' y='130'/>
- <part name='14' x='216' y='120'/>
- <part name='15' x='215' y='111'/>
- <part name='16' x='214' y='102'/>
- <part name='17' x='152' y='104'/>
- <part name='18' x='155' y='99'/>
- <part name='19' x='161' y='95'/>
- <part name='20' x='167' y='95'/>
- <part name='21' x='173' y='96'/>
- <part name='22' x='186' y='94'/>
- <part name='23' x='190' y='90'/>
- <part name='24' x='196' y='89'/>
- <part name='25' x='201' y='90'/>
- <part name='26' x='206' y='94'/>
- <part name='27' x='181' y='102'/>
- <part name='28' x='182' y='107'/>
- <part name='29' x='184' y='111'/>
- <part name='30' x='185' y='116'/>
- <part name='31' x='179' y='122'/>
- <part name='32' x='182' y='123'/>
- <part name='33' x='186' y='123'/>
- <part name='34' x='189' y='121'/>
- <part name='35' x='192' y='119'/>
- <part name='36' x='161' y='108'/>
- <part name='37' x='164' y='105'/>
- <part name='38' x='168' y='104'/>
- <part name='39' x='172' y='106'/>
- <part name='40' x='169' y='107'/>
- <part name='41' x='165' y='108'/>
- <part name='42' x='190' y='103'/>
- <part name='43' x='193' y='100'/>
- <part name='44' x='197' y='99'/>
- <part name='45' x='201' y='100'/>
- <part name='46' x='198' y='102'/>
- <part name='47' x='194' y='103'/>
- <part name='48' x='171' y='138'/>
- <part name='49' x='176' y='132'/>
- <part name='50' x='182' y='129'/>
- <part name='51' x='187' y='129'/>
- <part name='52' x='191' y='127'/>
- <part name='53' x='197' y='128'/>
- <part name='54' x='202' y='133'/>
- <part name='55' x='199' y='144'/>
- <part name='56' x='193' y='148'/>
- <part name='57' x='189' y='149'/>
- <part name='58' x='184' y='150'/>
- <part name='59' x='177' y='147'/>
- <part name='60' x='174' y='138'/>
- <part name='61' x='183' y='131'/>
- <part name='62' x='187' y='131'/>
- <part name='63' x='191' y='130'/>
- <part name='64' x='199' y='134'/>
- <part name='65' x='192' y='143'/>
- <part name='66' x='188' y='144'/>
- <part name='67' x='183' y='145'/>
- </box>
- <box top='214' left='125' width='90' height='91'>
- <part name='00' x='133' y='248'/>
- <part name='01' x='134' y='257'/>
- <part name='02' x='137' y='267'/>
- <part name='03' x='140' y='277'/>
- <part name='04' x='145' y='286'/>
- <part name='05' x='152' y='294'/>
- <part name='06' x='159' y='300'/>
- <part name='07' x='168' y='305'/>
- <part name='08' x='178' y='305'/>
- <part name='09' x='189' y='302'/>
- <part name='10' x='198' y='296'/>
- <part name='11' x='207' y='289'/>
- <part name='12' x='213' y='280'/>
- <part name='13' x='216' y='269'/>
- <part name='14' x='217' y='257'/>
- <part name='15' x='216' y='245'/>
- <part name='16' x='215' y='233'/>
- <part name='17' x='135' y='236'/>
- <part name='18' x='138' y='231'/>
- <part name='19' x='143' y='228'/>
- <part name='20' x='149' y='227'/>
- <part name='21' x='155' y='228'/>
- <part name='22' x='171' y='224'/>
- <part name='23' x='177' y='220'/>
- <part name='24' x='185' y='218'/>
- <part name='25' x='192' y='219'/>
- <part name='26' x='199' y='223'/>
- <part name='27' x='164' y='236'/>
- <part name='28' x='165' y='241'/>
- <part name='29' x='165' y='246'/>
- <part name='30' x='166' y='251'/>
- <part name='31' x='160' y='260'/>
- <part name='32' x='164' y='260'/>
- <part name='33' x='169' y='260'/>
- <part name='34' x='173' y='258'/>
- <part name='35' x='177' y='257'/>
- <part name='36' x='144' y='243'/>
- <part name='37' x='147' y='239'/>
- <part name='38' x='151' y='238'/>
- <part name='39' x='156' y='240'/>
- <part name='40' x='152' y='241'/>
- <part name='41' x='148' y='242'/>
- <part name='42' x='178' y='235'/>
- <part name='43' x='181' y='232'/>
- <part name='44' x='186' y='231'/>
- <part name='45' x='191' y='232'/>
- <part name='46' x='187' y='233'/>
- <part name='47' x='182' y='234'/>
- <part name='48' x='157' y='277'/>
- <part name='49' x='161' y='271'/>
- <part name='50' x='166' y='267'/>
- <part name='51' x='171' y='267'/>
- <part name='52' x='175' y='266'/>
- <part name='53' x='184' y='266'/>
- <part name='54' x='192' y='271'/>
- <part name='55' x='186' y='280'/>
- <part name='56' x='179' y='283'/>
- <part name='57' x='174' y='285'/>
- <part name='58' x='169' y='285'/>
- <part name='59' x='162' y='284'/>
- <part name='60' x='159' y='276'/>
- <part name='61' x='167' y='270'/>
- <part name='62' x='171' y='270'/>
- <part name='63' x='176' y='269'/>
- <part name='64' x='190' y='271'/>
- <part name='65' x='177' y='279'/>
- <part name='66' x='173' y='280'/>
- <part name='67' x='168' y='280'/>
- </box>
- </image>
- <image file='2008_001322.jpg'>
- <box top='162' left='104' width='76' height='76'>
- <part name='00' x='106' y='183'/>
- <part name='01' x='106' y='193'/>
- <part name='02' x='106' y='203'/>
- <part name='03' x='106' y='213'/>
- <part name='04' x='107' y='222'/>
- <part name='05' x='111' y='230'/>
- <part name='06' x='117' y='238'/>
- <part name='07' x='125' y='243'/>
- <part name='08' x='135' y='245'/>
- <part name='09' x='144' y='245'/>
- <part name='10' x='152' y='241'/>
- <part name='11' x='158' y='235'/>
- <part name='12' x='163' y='228'/>
- <part name='13' x='167' y='220'/>
- <part name='14' x='169' y='211'/>
- <part name='15' x='172' y='202'/>
- <part name='16' x='174' y='192'/>
- <part name='17' x='114' y='175'/>
- <part name='18' x='118' y='169'/>
- <part name='19' x='124' y='166'/>
- <part name='20' x='132' y='167'/>
- <part name='21' x='139' y='169'/>
- <part name='22' x='151' y='170'/>
- <part name='23' x='158' y='170'/>
- <part name='24' x='164' y='172'/>
- <part name='25' x='170' y='175'/>
- <part name='26' x='171' y='182'/>
- <part name='27' x='145' y='178'/>
- <part name='28' x='144' y='183'/>
- <part name='29' x='144' y='188'/>
- <part name='30' x='144' y='193'/>
- <part name='31' x='135' y='200'/>
- <part name='32' x='138' y='201'/>
- <part name='33' x='142' y='202'/>
- <part name='34' x='146' y='202'/>
- <part name='35' x='149' y='201'/>
- <part name='36' x='121' y='180'/>
- <part name='37' x='125' y='178'/>
- <part name='38' x='129' y='178'/>
- <part name='39' x='133' y='181'/>
- <part name='40' x='129' y='181'/>
- <part name='41' x='125' y='181'/>
- <part name='42' x='153' y='183'/>
- <part name='43' x='157' y='181'/>
- <part name='44' x='161' y='182'/>
- <part name='45' x='163' y='185'/>
- <part name='46' x='160' y='185'/>
- <part name='47' x='156' y='184'/>
- <part name='48' x='124' y='217'/>
- <part name='49' x='130' y='214'/>
- <part name='50' x='136' y='213'/>
- <part name='51' x='140' y='214'/>
- <part name='52' x='144' y='214'/>
- <part name='53' x='148' y='216'/>
- <part name='54' x='152' y='221'/>
- <part name='55' x='147' y='223'/>
- <part name='56' x='143' y='224'/>
- <part name='57' x='139' y='223'/>
- <part name='58' x='134' y='223'/>
- <part name='59' x='129' y='221'/>
- <part name='60' x='126' y='217'/>
- <part name='61' x='136' y='217'/>
- <part name='62' x='140' y='218'/>
- <part name='63' x='144' y='217'/>
- <part name='64' x='150' y='220'/>
- <part name='65' x='143' y='220'/>
- <part name='66' x='139' y='220'/>
- <part name='67' x='135' y='219'/>
- </box>
- <box top='218' left='232' width='63' height='63'>
- <part name='00' x='234' y='235'/>
- <part name='01' x='233' y='243'/>
- <part name='02' x='234' y='251'/>
- <part name='03' x='235' y='259'/>
- <part name='04' x='237' y='267'/>
- <part name='05' x='241' y='274'/>
- <part name='06' x='246' y='281'/>
- <part name='07' x='253' y='286'/>
- <part name='08' x='261' y='287'/>
- <part name='09' x='270' y='286'/>
- <part name='10' x='278' y='282'/>
- <part name='11' x='285' y='276'/>
- <part name='12' x='290' y='269'/>
- <part name='13' x='293' y='261'/>
- <part name='14' x='294' y='252'/>
- <part name='15' x='295' y='243'/>
- <part name='16' x='296' y='234'/>
- <part name='17' x='237' y='228'/>
- <part name='18' x='239' y='225'/>
- <part name='19' x='244' y='224'/>
- <part name='20' x='249' y='225'/>
- <part name='21' x='253' y='227'/>
- <part name='22' x='265' y='226'/>
- <part name='23' x='270' y='223'/>
- <part name='24' x='276' y='222'/>
- <part name='25' x='282' y='223'/>
- <part name='26' x='286' y='227'/>
- <part name='27' x='259' y='232'/>
- <part name='28' x='258' y='237'/>
- <part name='29' x='258' y='243'/>
- <part name='30' x='257' y='248'/>
- <part name='31' x='253' y='252'/>
- <part name='32' x='256' y='253'/>
- <part name='33' x='259' y='254'/>
- <part name='34' x='262' y='253'/>
- <part name='35' x='265' y='252'/>
- <part name='36' x='242' y='233'/>
- <part name='37' x='245' y='231'/>
- <part name='38' x='248' y='231'/>
- <part name='39' x='252' y='234'/>
- <part name='40' x='248' y='234'/>
- <part name='41' x='245' y='234'/>
- <part name='42' x='269' y='233'/>
- <part name='43' x='272' y='230'/>
- <part name='44' x='276' y='230'/>
- <part name='45' x='279' y='232'/>
- <part name='46' x='276' y='233'/>
- <part name='47' x='272' y='233'/>
- <part name='48' x='247' y='262'/>
- <part name='49' x='250' y='260'/>
- <part name='50' x='255' y='260'/>
- <part name='51' x='259' y='260'/>
- <part name='52' x='263' y='260'/>
- <part name='53' x='270' y='260'/>
- <part name='54' x='276' y='262'/>
- <part name='55' x='270' y='268'/>
- <part name='56' x='264' y='270'/>
- <part name='57' x='260' y='271'/>
- <part name='58' x='255' y='271'/>
- <part name='59' x='251' y='268'/>
- <part name='60' x='249' y='262'/>
- <part name='61' x='255' y='262'/>
- <part name='62' x='259' y='262'/>
- <part name='63' x='263' y='262'/>
- <part name='64' x='275' y='262'/>
- <part name='65' x='264' y='267'/>
- <part name='66' x='260' y='267'/>
- <part name='67' x='255' y='267'/>
- </box>
- <box top='155' left='344' width='90' height='90'>
- <part name='00' x='357' y='199'/>
- <part name='01' x='359' y='209'/>
- <part name='02' x='361' y='219'/>
- <part name='03' x='364' y='229'/>
- <part name='04' x='370' y='238'/>
- <part name='05' x='379' y='245'/>
- <part name='06' x='388' y='251'/>
- <part name='07' x='397' y='256'/>
- <part name='08' x='407' y='256'/>
- <part name='09' x='417' y='253'/>
- <part name='10' x='425' y='246'/>
- <part name='11' x='432' y='238'/>
- <part name='12' x='438' y='228'/>
- <part name='13' x='441' y='217'/>
- <part name='14' x='441' y='205'/>
- <part name='15' x='439' y='192'/>
- <part name='16' x='437' y='180'/>
- <part name='17' x='360' y='188'/>
- <part name='18' x='361' y='181'/>
- <part name='19' x='367' y='178'/>
- <part name='20' x='373' y='177'/>
- <part name='21' x='380' y='178'/>
- <part name='22' x='396' y='175'/>
- <part name='23' x='404' y='171'/>
- <part name='24' x='411' y='169'/>
- <part name='25' x='418' y='169'/>
- <part name='26' x='423' y='173'/>
- <part name='27' x='390' y='185'/>
- <part name='28' x='391' y='192'/>
- <part name='29' x='392' y='198'/>
- <part name='30' x='393' y='205'/>
- <part name='31' x='387' y='210'/>
- <part name='32' x='391' y='212'/>
- <part name='33' x='396' y='212'/>
- <part name='34' x='401' y='210'/>
- <part name='35' x='405' y='207'/>
- <part name='36' x='369' y='191'/>
- <part name='37' x='373' y='188'/>
- <part name='38' x='377' y='187'/>
- <part name='39' x='381' y='188'/>
- <part name='40' x='378' y='190'/>
- <part name='41' x='373' y='191'/>
- <part name='42' x='403' y='184'/>
- <part name='43' x='406' y='181'/>
- <part name='44' x='410' y='180'/>
- <part name='45' x='414' y='182'/>
- <part name='46' x='411' y='183'/>
- <part name='47' x='407' y='184'/>
- <part name='48' x='384' y='224'/>
- <part name='49' x='388' y='220'/>
- <part name='50' x='393' y='219'/>
- <part name='51' x='398' y='218'/>
- <part name='52' x='403' y='217'/>
- <part name='53' x='411' y='216'/>
- <part name='54' x='418' y='217'/>
- <part name='55' x='413' y='225'/>
- <part name='56' x='407' y='229'/>
- <part name='57' x='401' y='231'/>
- <part name='58' x='396' y='231'/>
- <part name='59' x='390' y='230'/>
- <part name='60' x='386' y='224'/>
- <part name='61' x='394' y='220'/>
- <part name='62' x='399' y='220'/>
- <part name='63' x='404' y='219'/>
- <part name='64' x='416' y='218'/>
- <part name='65' x='405' y='225'/>
- <part name='66' x='400' y='226'/>
- <part name='67' x='395' y='227'/>
- </box>
- </image>
-</images>
-</dataset>
diff --git a/ml/dlib/examples/fhog_ex.cpp b/ml/dlib/examples/fhog_ex.cpp
deleted file mode 100644
index 1e8d5a80d..000000000
--- a/ml/dlib/examples/fhog_ex.cpp
+++ /dev/null
@@ -1,88 +0,0 @@
-// The contents of this file are in the public domain. See LICENSE_FOR_EXAMPLE_PROGRAMS.txt
-/*
-
- This is an example illustrating the use of the extract_fhog_features() routine from
- the dlib C++ Library.
-
-
- The extract_fhog_features() routine performs the style of HOG feature extraction
- described in the paper:
- Object Detection with Discriminatively Trained Part Based Models by
- P. Felzenszwalb, R. Girshick, D. McAllester, D. Ramanan
- IEEE Transactions on Pattern Analysis and Machine Intelligence, Vol. 32, No. 9, Sep. 2010
- This means that it takes an input image and outputs Felzenszwalb's
- 31 dimensional version of HOG features. We show its use below.
-*/
-
-
-
-#include <dlib/gui_widgets.h>
-#include <dlib/image_io.h>
-#include <dlib/image_transforms.h>
-
-
-using namespace std;
-using namespace dlib;
-
-// ----------------------------------------------------------------------------
-
-int main(int argc, char** argv)
-{
- try
- {
- // Make sure the user entered an argument to this program. It should be the
- // filename for an image.
- if (argc != 2)
- {
- cout << "error, you have to enter a BMP file as an argument to this program" << endl;
- return 1;
- }
-
- // Here we declare an image object that can store color rgb_pixels.
- array2d<rgb_pixel> img;
-
- // Now load the image file into our image. If something is wrong then
- // load_image() will throw an exception. Also, if you linked with libpng
- // and libjpeg then load_image() can load PNG and JPEG files in addition
- // to BMP files.
- load_image(img, argv[1]);
-
-
- // Now convert the image into a FHOG feature image. The output, hog, is a 2D array
- // of 31 dimensional vectors.
- array2d<matrix<float,31,1> > hog;
- extract_fhog_features(img, hog);
-
- cout << "hog image has " << hog.nr() << " rows and " << hog.nc() << " columns." << endl;
-
- // Let's see what the image and FHOG features look like.
- image_window win(img);
- image_window winhog(draw_fhog(hog));
-
- // Another thing you might want to do is map between the pixels in img and the
- // cells in the hog image. dlib provides the image_to_fhog() and fhog_to_image()
- // routines for this. Their use is demonstrated in the following loop which
- // responds to the user clicking on pixels in the image img.
- point p; // A 2D point, used to represent pixel locations.
- while (win.get_next_double_click(p))
- {
- point hp = image_to_fhog(p);
- cout << "The point " << p << " in the input image corresponds to " << hp << " in hog space." << endl;
- cout << "FHOG features at this point: " << trans(hog[hp.y()][hp.x()]) << endl;
- }
-
- // Finally, sometimes you want to get a planar representation of the HOG features
- // rather than the explicit vector (i.e. interlaced) representation used above.
- dlib::array<array2d<float> > planar_hog;
- extract_fhog_features(img, planar_hog);
- // Now we have an array of 31 float valued image planes, each representing one of
- // the dimensions of the HOG feature vector.
- }
- catch (exception& e)
- {
- cout << "exception thrown: " << e.what() << endl;
- }
-}
-
-// ----------------------------------------------------------------------------
-
diff --git a/ml/dlib/examples/fhog_object_detector_ex.cpp b/ml/dlib/examples/fhog_object_detector_ex.cpp
deleted file mode 100644
index 152f57d09..000000000
--- a/ml/dlib/examples/fhog_object_detector_ex.cpp
+++ /dev/null
@@ -1,269 +0,0 @@
-// The contents of this file are in the public domain. See LICENSE_FOR_EXAMPLE_PROGRAMS.txt
-/*
-
- This example program shows how you can use dlib to make an object detector
- for things like faces, pedestrians, and any other semi-rigid object. In
- particular, we go though the steps to train the kind of sliding window
- object detector first published by Dalal and Triggs in 2005 in the paper
- Histograms of Oriented Gradients for Human Detection.
-
- Note that this program executes fastest when compiled with at least SSE2
- instructions enabled. So if you are using a PC with an Intel or AMD chip
- then you should enable at least SSE2 instructions. If you are using cmake
- to compile this program you can enable them by using one of the following
- commands when you create the build project:
- cmake path_to_dlib_root/examples -DUSE_SSE2_INSTRUCTIONS=ON
- cmake path_to_dlib_root/examples -DUSE_SSE4_INSTRUCTIONS=ON
- cmake path_to_dlib_root/examples -DUSE_AVX_INSTRUCTIONS=ON
- This will set the appropriate compiler options for GCC, clang, Visual
- Studio, or the Intel compiler. If you are using another compiler then you
- need to consult your compiler's manual to determine how to enable these
- instructions. Note that AVX is the fastest but requires a CPU from at least
- 2011. SSE4 is the next fastest and is supported by most current machines.
-
-*/
-
-
-#include <dlib/svm_threaded.h>
-#include <dlib/gui_widgets.h>
-#include <dlib/image_processing.h>
-#include <dlib/data_io.h>
-
-#include <iostream>
-#include <fstream>
-
-
-using namespace std;
-using namespace dlib;
-
-// ----------------------------------------------------------------------------------------
-
-int main(int argc, char** argv)
-{
-
- try
- {
- // In this example we are going to train a face detector based on the
- // small faces dataset in the examples/faces directory. So the first
- // thing we do is load that dataset. This means you need to supply the
- // path to this faces folder as a command line argument so we will know
- // where it is.
- if (argc != 2)
- {
- cout << "Give the path to the examples/faces directory as the argument to this" << endl;
- cout << "program. For example, if you are in the examples folder then execute " << endl;
- cout << "this program by running: " << endl;
- cout << " ./fhog_object_detector_ex faces" << endl;
- cout << endl;
- return 0;
- }
- const std::string faces_directory = argv[1];
- // The faces directory contains a training dataset and a separate
- // testing dataset. The training data consists of 4 images, each
- // annotated with rectangles that bound each human face. The idea is
- // to use this training data to learn to identify human faces in new
- // images.
- //
- // Once you have trained an object detector it is always important to
- // test it on data it wasn't trained on. Therefore, we will also load
- // a separate testing set of 5 images. Once we have a face detector
- // created from the training data we will see how well it works by
- // running it on the testing images.
- //
- // So here we create the variables that will hold our dataset.
- // images_train will hold the 4 training images and face_boxes_train
- // holds the locations of the faces in the training images. So for
- // example, the image images_train[0] has the faces given by the
- // rectangles in face_boxes_train[0].
- dlib::array<array2d<unsigned char> > images_train, images_test;
- std::vector<std::vector<rectangle> > face_boxes_train, face_boxes_test;
-
- // Now we load the data. These XML files list the images in each
- // dataset and also contain the positions of the face boxes. Obviously
- // you can use any kind of input format you like so long as you store
- // the data into images_train and face_boxes_train. But for convenience
- // dlib comes with tools for creating and loading XML image dataset
- // files. Here you see how to load the data. To create the XML files
- // you can use the imglab tool which can be found in the tools/imglab
- // folder. It is a simple graphical tool for labeling objects in images
- // with boxes. To see how to use it read the tools/imglab/README.txt
- // file.
- load_image_dataset(images_train, face_boxes_train, faces_directory+"/training.xml");
- load_image_dataset(images_test, face_boxes_test, faces_directory+"/testing.xml");
-
- // Now we do a little bit of pre-processing. This is optional but for
- // this training data it improves the results. The first thing we do is
- // increase the size of the images by a factor of two. We do this
- // because it will allow us to detect smaller faces than otherwise would
- // be practical (since the faces are all now twice as big). Note that,
- // in addition to resizing the images, these functions also make the
- // appropriate adjustments to the face boxes so that they still fall on
- // top of the faces after the images are resized.
- upsample_image_dataset<pyramid_down<2> >(images_train, face_boxes_train);
- upsample_image_dataset<pyramid_down<2> >(images_test, face_boxes_test);
- // Since human faces are generally left-right symmetric we can increase
- // our training dataset by adding mirrored versions of each image back
- // into images_train. So this next step doubles the size of our
- // training dataset. Again, this is obviously optional but is useful in
- // many object detection tasks.
- add_image_left_right_flips(images_train, face_boxes_train);
- cout << "num training images: " << images_train.size() << endl;
- cout << "num testing images: " << images_test.size() << endl;
-
-
- // Finally we get to the training code. dlib contains a number of
- // object detectors. This typedef tells it that you want to use the one
- // based on Felzenszwalb's version of the Histogram of Oriented
- // Gradients (commonly called HOG) detector. The 6 means that you want
- // it to use an image pyramid that downsamples the image at a ratio of
- // 5/6. Recall that HOG detectors work by creating an image pyramid and
- // then running the detector over each pyramid level in a sliding window
- // fashion.
- typedef scan_fhog_pyramid<pyramid_down<6> > image_scanner_type;
- image_scanner_type scanner;
- // The sliding window detector will be 80 pixels wide and 80 pixels tall.
- scanner.set_detection_window_size(80, 80);
- structural_object_detection_trainer<image_scanner_type> trainer(scanner);
- // Set this to the number of processing cores on your machine.
- trainer.set_num_threads(4);
- // The trainer is a kind of support vector machine and therefore has the usual SVM
- // C parameter. In general, a bigger C encourages it to fit the training data
- // better but might lead to overfitting. You must find the best C value
- // empirically by checking how well the trained detector works on a test set of
- // images you haven't trained on. Don't just leave the value set at 1. Try a few
- // different C values and see what works best for your data.
- trainer.set_c(1);
- // We can tell the trainer to print it's progress to the console if we want.
- trainer.be_verbose();
- // The trainer will run until the "risk gap" is less than 0.01. Smaller values
- // make the trainer solve the SVM optimization problem more accurately but will
- // take longer to train. For most problems a value in the range of 0.1 to 0.01 is
- // plenty accurate. Also, when in verbose mode the risk gap is printed on each
- // iteration so you can see how close it is to finishing the training.
- trainer.set_epsilon(0.01);
-
-
- // Now we run the trainer. For this example, it should take on the order of 10
- // seconds to train.
- object_detector<image_scanner_type> detector = trainer.train(images_train, face_boxes_train);
-
- // Now that we have a face detector we can test it. The first statement tests it
- // on the training data. It will print the precision, recall, and then average precision.
- cout << "training results: " << test_object_detection_function(detector, images_train, face_boxes_train) << endl;
- // However, to get an idea if it really worked without overfitting we need to run
- // it on images it wasn't trained on. The next line does this. Happily, we see
- // that the object detector works perfectly on the testing images.
- cout << "testing results: " << test_object_detection_function(detector, images_test, face_boxes_test) << endl;
-
-
- // If you have read any papers that use HOG you have probably seen the nice looking
- // "sticks" visualization of a learned HOG detector. This next line creates a
- // window with such a visualization of our detector. It should look somewhat like
- // a face.
- image_window hogwin(draw_fhog(detector), "Learned fHOG detector");
-
- // Now for the really fun part. Let's display the testing images on the screen and
- // show the output of the face detector overlaid on each image. You will see that
- // it finds all the faces without false alarming on any non-faces.
- image_window win;
- for (unsigned long i = 0; i < images_test.size(); ++i)
- {
- // Run the detector and get the face detections.
- std::vector<rectangle> dets = detector(images_test[i]);
- win.clear_overlay();
- win.set_image(images_test[i]);
- win.add_overlay(dets, rgb_pixel(255,0,0));
- cout << "Hit enter to process the next image..." << endl;
- cin.get();
- }
-
-
- // Like everything in dlib, you can save your detector to disk using the
- // serialize() function.
- serialize("face_detector.svm") << detector;
-
- // Then you can recall it using the deserialize() function.
- object_detector<image_scanner_type> detector2;
- deserialize("face_detector.svm") >> detector2;
-
-
-
-
- // Now let's talk about some optional features of this training tool as well as some
- // important points you should understand.
- //
- // The first thing that should be pointed out is that, since this is a sliding
- // window classifier, it can't output an arbitrary rectangle as a detection. In
- // this example our sliding window is 80 by 80 pixels and is run over an image
- // pyramid. This means that it can only output detections that are at least 80 by
- // 80 pixels in size (recall that this is why we upsampled the images after loading
- // them). It also means that the aspect ratio of the outputs is 1. So if,
- // for example, you had a box in your training data that was 200 pixels by 10
- // pixels then it would simply be impossible for the detector to learn to detect
- // it. Similarly, if you had a really small box it would be unable to learn to
- // detect it.
- //
- // So the training code performs an input validation check on the training data and
- // will throw an exception if it detects any boxes that are impossible to detect
- // given your setting of scanning window size and image pyramid resolution. You
- // can use a statement like:
- // remove_unobtainable_rectangles(trainer, images_train, face_boxes_train)
- // to automatically discard these impossible boxes from your training dataset
- // before running the trainer. This will avoid getting the "impossible box"
- // exception. However, I would recommend you be careful that you are not throwing
- // away truth boxes you really care about. The remove_unobtainable_rectangles()
- // will return the set of removed rectangles so you can visually inspect them and
- // make sure you are OK that they are being removed.
- //
- // Next, note that any location in the images not marked with a truth box is
- // implicitly treated as a negative example. This means that when creating
- // training data it is critical that you label all the objects you want to detect.
- // So for example, if you are making a face detector then you must mark all the
- // faces in each image. However, sometimes there are objects in images you are
- // unsure about or simply don't care if the detector identifies or not. For these
- // objects you can pass in a set of "ignore boxes" as a third argument to the
- // trainer.train() function. The trainer will simply disregard any detections that
- // happen to hit these boxes.
- //
- // Another useful thing you can do is evaluate multiple HOG detectors together. The
- // benefit of this is increased testing speed since it avoids recomputing the HOG
- // features for each run of the detector. You do this by storing your detectors
- // into a std::vector and then invoking evaluate_detectors() like so:
- std::vector<object_detector<image_scanner_type> > my_detectors;
- my_detectors.push_back(detector);
- std::vector<rectangle> dets = evaluate_detectors(my_detectors, images_train[0]);
- //
- //
- // Finally, you can add a nuclear norm regularizer to the SVM trainer. Doing has
- // two benefits. First, it can cause the learned HOG detector to be composed of
- // separable filters and therefore makes it execute faster when detecting objects.
- // It can also help with generalization since it tends to make the learned HOG
- // filters smoother. To enable this option you call the following function before
- // you create the trainer object:
- // scanner.set_nuclear_norm_regularization_strength(1.0);
- // The argument determines how important it is to have a small nuclear norm. A
- // bigger regularization strength means it is more important. The smaller the
- // nuclear norm the smoother and faster the learned HOG filters will be, but if the
- // regularization strength value is too large then the SVM will not fit the data
- // well. This is analogous to giving a C value that is too small.
- //
- // You can see how many separable filters are inside your detector like so:
- cout << "num filters: "<< num_separable_filters(detector) << endl;
- // You can also control how many filters there are by explicitly thresholding the
- // singular values of the filters like this:
- detector = threshold_filter_singular_values(detector,0.1);
- // That removes filter components with singular values less than 0.1. The bigger
- // this number the fewer separable filters you will have and the faster the
- // detector will run. However, a large enough threshold will hurt detection
- // accuracy.
-
- }
- catch (exception& e)
- {
- cout << "\nexception thrown!" << endl;
- cout << e.what() << endl;
- }
-}
-
-// ----------------------------------------------------------------------------------------
-
diff --git a/ml/dlib/examples/file_to_code_ex.cpp b/ml/dlib/examples/file_to_code_ex.cpp
deleted file mode 100644
index ce49bde7a..000000000
--- a/ml/dlib/examples/file_to_code_ex.cpp
+++ /dev/null
@@ -1,111 +0,0 @@
-// The contents of this file are in the public domain. See LICENSE_FOR_EXAMPLE_PROGRAMS.txt
-/*
- This is an example illustrating the use of the compress_stream and
- base64 components from the dlib C++ Library.
-
- It reads in a file from the disk and compresses it in an in memory buffer and
- then converts that buffer into base64 text. The final step is to output to
- the screen some C++ code that contains this base64 encoded text and can decompress
- it back into its original form.
-*/
-
-
-#include <iostream>
-#include <fstream>
-#include <sstream>
-#include <string>
-#include <cstdlib>
-#include <dlib/compress_stream.h>
-#include <dlib/base64.h>
-
-
-using namespace std;
-using namespace dlib;
-
-int main(int argc, char** argv)
-{
- if (argc != 2)
- {
- cout << "You must give a file name as the argument to this program.\n" << endl;
- cout << "This program reads in a file from the disk and compresses\n"
- << "it in an in memory buffer and then converts that buffer \n"
- << "into base64 text. The final step is to output to the screen\n"
- << "some C++ code that contains this base64 encoded text and can\n"
- << "decompress it back into its original form.\n" << endl;
-
- return EXIT_FAILURE;
- }
-
- // open the file the user specified on the command line
- ifstream fin(argv[1], ios::binary);
- if (!fin) {
- cout << "can't open file " << argv[1] << endl;
- return EXIT_FAILURE;
- }
-
- ostringstream sout;
- istringstream sin;
-
- // this is the object we will use to do the base64 encoding
- base64 base64_coder;
- // this is the object we will use to do the data compression
- compress_stream::kernel_1ea compressor;
-
- // compress the contents of the file and store the results in the string stream sout
- compressor.compress(fin,sout);
- sin.str(sout.str());
- sout.clear();
- sout.str("");
-
- // now base64 encode the compressed data
- base64_coder.encode(sin,sout);
-
- sin.clear();
- sin.str(sout.str());
- sout.str("");
-
- // the following is a little funny looking but all it does is output some C++ code
- // that contains the compressed/base64 data and the C++ code that can decode it back
- // into its original form.
- sout << "#include <sstream>\n";
- sout << "#include <dlib/compress_stream.h>\n";
- sout << "#include <dlib/base64.h>\n";
- sout << "\n";
- sout << "// This function returns the contents of the file '" << argv[1] << "'\n";
- sout << "const std::string get_decoded_string()\n";
- sout << "{\n";
- sout << " dlib::base64 base64_coder;\n";
- sout << " dlib::compress_stream::kernel_1ea compressor;\n";
- sout << " std::ostringstream sout;\n";
- sout << " std::istringstream sin;\n\n";
-
-
- sout << " // The base64 encoded data from the file '" << argv[1] << "' we want to decode and return.\n";
- string temp;
- getline(sin,temp);
- while (sin && temp.size() > 0)
- {
- sout << " sout << \"" << temp << "\";\n";
- getline(sin,temp);
- }
-
- sout << "\n";
- sout << " // Put the data into the istream sin\n";
- sout << " sin.str(sout.str());\n";
- sout << " sout.str(\"\");\n\n";
- sout << " // Decode the base64 text into its compressed binary form\n";
- sout << " base64_coder.decode(sin,sout);\n";
- sout << " sin.clear();\n";
- sout << " sin.str(sout.str());\n";
- sout << " sout.str(\"\");\n\n";
- sout << " // Decompress the data into its original form\n";
- sout << " compressor.decompress(sin,sout);\n\n";
- sout << " // Return the decoded and decompressed data\n";
- sout << " return sout.str();\n";
- sout << "}\n";
-
-
- // finally output our encoded data and its C++ code to the screen
- cout << sout.str() << endl;
-}
-
diff --git a/ml/dlib/examples/graph_labeling_ex.cpp b/ml/dlib/examples/graph_labeling_ex.cpp
deleted file mode 100644
index 984a93bf5..000000000
--- a/ml/dlib/examples/graph_labeling_ex.cpp
+++ /dev/null
@@ -1,259 +0,0 @@
-// The contents of this file are in the public domain. See LICENSE_FOR_EXAMPLE_PROGRAMS.txt
-/*
-
- This is an example illustrating the use of the graph_labeler and
- structural_graph_labeling_trainer objects.
-
- Suppose you have a bunch of objects and you need to label each of them as true or
- false. Suppose further that knowing the labels of some of these objects tells you
- something about the likely label of the others. This is common in a number of domains.
- For example, in image segmentation problems you need to label each pixel, and knowing
- the labels of neighboring pixels gives you information about the likely label since
- neighboring pixels will often have the same label.
-
- We can generalize this problem by saying that we have a graph and our task is to label
- each node in the graph as true or false. Additionally, the edges in the graph connect
- nodes which are likely to share the same label. In this example program, each node
- will have a feature vector which contains information which helps tell if the node
- should be labeled as true or false. The edges also contain feature vectors which give
- information indicating how strong the edge's labeling consistency constraint should be.
- This is useful since some nodes will have uninformative feature vectors and the only
- way to tell how they should be labeled is by looking at their neighbor's labels.
-
- Therefore, this program will show you how to learn two things using machine learning.
- The first is a linear classifier which operates on each node and predicts if it should
- be labeled as true or false. The second thing is a linear function of the edge
- vectors. This function outputs a penalty for giving two nodes connected by an edge
- differing labels. The graph_labeler object puts these two things together and uses
- them to compute a labeling which takes both into account. In what follows, we will use
- a structural SVM method to find the parameters of these linear functions which minimize
- the number of mistakes made by a graph_labeler.
-
-
- Finally, you might also consider reading the book Structured Prediction and Learning in
- Computer Vision by Sebastian Nowozin and Christoph H. Lampert since it contains a good
- introduction to machine learning methods such as the algorithm implemented by the
- structural_graph_labeling_trainer.
-*/
-
-#include <dlib/svm_threaded.h>
-#include <iostream>
-
-using namespace std;
-using namespace dlib;
-
-// ----------------------------------------------------------------------------------------
-
-// The first thing we do is define the kind of graph object we will be using.
-// Here we are saying there will be 2-D vectors at each node and 1-D vectors at
-// each edge. (You should read the matrix_ex.cpp example program for an introduction
-// to the matrix object.)
-typedef matrix<double,2,1> node_vector_type;
-typedef matrix<double,1,1> edge_vector_type;
-typedef graph<node_vector_type, edge_vector_type>::kernel_1a_c graph_type;
-
-// ----------------------------------------------------------------------------------------
-
-template <
- typename graph_type,
- typename labels_type
- >
-void make_training_examples(
- dlib::array<graph_type>& samples,
- labels_type& labels
-)
-{
- /*
- This function makes 3 graphs we will use for training. All of them
- will contain 4 nodes and have the structure shown below:
-
- (0)-----(1)
- | |
- | |
- | |
- (3)-----(2)
-
- In this example, each node has a 2-D vector. The first element of this vector
- is 1 when the node should have a label of false while the second element has
- a value of 1 when the node should have a label of true. Additionally, the
- edge vectors will contain a value of 1 when the nodes connected by the edge
- should share the same label and a value of 0 otherwise.
-
- We want to see that the machine learning method is able to figure out how
- these features relate to the labels. If it is successful it will create a
- graph_labeler which can predict the correct labels for these and other
- similarly constructed graphs.
-
- Finally, note that these tools require all values in the edge vectors to be >= 0.
- However, the node vectors may contain both positive and negative values.
- */
-
- samples.clear();
- labels.clear();
-
- std::vector<bool> label;
- graph_type g;
-
- // ---------------------------
- g.set_number_of_nodes(4);
- label.resize(g.number_of_nodes());
- // store the vector [0,1] into node 0. Also label it as true.
- g.node(0).data = 0, 1; label[0] = true;
- // store the vector [0,0] into node 1.
- g.node(1).data = 0, 0; label[1] = true; // Note that this node's vector doesn't tell us how to label it.
- // We need to take the edges into account to get it right.
- // store the vector [1,0] into node 2.
- g.node(2).data = 1, 0; label[2] = false;
- // store the vector [0,0] into node 3.
- g.node(3).data = 0, 0; label[3] = false;
-
- // Add the 4 edges as shown in the ASCII art above.
- g.add_edge(0,1);
- g.add_edge(1,2);
- g.add_edge(2,3);
- g.add_edge(3,0);
-
- // set the 1-D vector for the edge between node 0 and 1 to the value of 1.
- edge(g,0,1) = 1;
- // set the 1-D vector for the edge between node 1 and 2 to the value of 0.
- edge(g,1,2) = 0;
- edge(g,2,3) = 1;
- edge(g,3,0) = 0;
- // output the graph and its label.
- samples.push_back(g);
- labels.push_back(label);
-
- // ---------------------------
- g.set_number_of_nodes(4);
- label.resize(g.number_of_nodes());
- g.node(0).data = 0, 1; label[0] = true;
- g.node(1).data = 0, 1; label[1] = true;
- g.node(2).data = 1, 0; label[2] = false;
- g.node(3).data = 1, 0; label[3] = false;
-
- g.add_edge(0,1);
- g.add_edge(1,2);
- g.add_edge(2,3);
- g.add_edge(3,0);
-
- // This time, we have strong edges between all the nodes. The machine learning
- // tools will have to learn that when the node information conflicts with the
- // edge constraints that the node information should dominate.
- edge(g,0,1) = 1;
- edge(g,1,2) = 1;
- edge(g,2,3) = 1;
- edge(g,3,0) = 1;
- samples.push_back(g);
- labels.push_back(label);
- // ---------------------------
-
- g.set_number_of_nodes(4);
- label.resize(g.number_of_nodes());
- g.node(0).data = 1, 0; label[0] = false;
- g.node(1).data = 1, 0; label[1] = false;
- g.node(2).data = 1, 0; label[2] = false;
- g.node(3).data = 0, 0; label[3] = false;
-
- g.add_edge(0,1);
- g.add_edge(1,2);
- g.add_edge(2,3);
- g.add_edge(3,0);
-
- edge(g,0,1) = 0;
- edge(g,1,2) = 0;
- edge(g,2,3) = 1;
- edge(g,3,0) = 0;
- samples.push_back(g);
- labels.push_back(label);
- // ---------------------------
-
-}
-
-// ----------------------------------------------------------------------------------------
-
-int main()
-{
- try
- {
- // Get the training samples we defined above.
- dlib::array<graph_type> samples;
- std::vector<std::vector<bool> > labels;
- make_training_examples(samples, labels);
-
-
- // Create a structural SVM trainer for graph labeling problems. The vector_type
- // needs to be set to a type capable of holding node or edge vectors.
- typedef matrix<double,0,1> vector_type;
- structural_graph_labeling_trainer<vector_type> trainer;
- // This is the usual SVM C parameter. Larger values make the trainer try
- // harder to fit the training data but might result in overfitting. You
- // should set this value to whatever gives the best cross-validation results.
- trainer.set_c(10);
-
- // Do 3-fold cross-validation and print the results. In this case it will
- // indicate that all nodes were correctly classified.
- cout << "3-fold cross-validation: " << cross_validate_graph_labeling_trainer(trainer, samples, labels, 3) << endl;
-
- // Since the trainer is working well. Let's have it make a graph_labeler
- // based on the training data.
- graph_labeler<vector_type> labeler = trainer.train(samples, labels);
-
-
- /*
- Let's try the graph_labeler on a new test graph. In particular, let's
- use one with 5 nodes as shown below:
-
- (0 F)-----(1 T)
- | |
- | |
- | |
- (3 T)-----(2 T)------(4 T)
-
- I have annotated each node with either T or F to indicate the correct
- output (true or false).
- */
- graph_type g;
- g.set_number_of_nodes(5);
- g.node(0).data = 1, 0; // Node data indicates a false node.
- g.node(1).data = 0, 1; // Node data indicates a true node.
- g.node(2).data = 0, 0; // Node data is ambiguous.
- g.node(3).data = 0, 0; // Node data is ambiguous.
- g.node(4).data = 0.1, 0; // Node data slightly indicates a false node.
-
- g.add_edge(0,1);
- g.add_edge(1,2);
- g.add_edge(2,3);
- g.add_edge(3,0);
- g.add_edge(2,4);
-
- // Set the edges up so nodes 1, 2, 3, and 4 are all strongly connected.
- edge(g,0,1) = 0;
- edge(g,1,2) = 1;
- edge(g,2,3) = 1;
- edge(g,3,0) = 0;
- edge(g,2,4) = 1;
-
- // The output of this shows all the nodes are correctly labeled.
- cout << "Predicted labels: " << endl;
- std::vector<bool> temp = labeler(g);
- for (unsigned long i = 0; i < temp.size(); ++i)
- cout << " " << i << ": " << temp[i] << endl;
-
-
-
- // Breaking the strong labeling consistency link between node 1 and 2 causes
- // nodes 2, 3, and 4 to flip to false. This is because of their connection
- // to node 4 which has a small preference for false.
- edge(g,1,2) = 0;
- cout << "Predicted labels: " << endl;
- temp = labeler(g);
- for (unsigned long i = 0; i < temp.size(); ++i)
- cout << " " << i << ": " << temp[i] << endl;
- }
- catch (std::exception& e)
- {
- cout << "Error, an exception was thrown!" << endl;
- cout << e.what() << endl;
- }
-}
-
diff --git a/ml/dlib/examples/gui_api_ex.cpp b/ml/dlib/examples/gui_api_ex.cpp
deleted file mode 100644
index 4d947b756..000000000
--- a/ml/dlib/examples/gui_api_ex.cpp
+++ /dev/null
@@ -1,231 +0,0 @@
-// The contents of this file are in the public domain. See LICENSE_FOR_EXAMPLE_PROGRAMS.txt
-/*
-
- This is an example illustrating the use of the gui api from the dlib C++ Library.
-
-
- This is a pretty simple example. It makes a window with a user
- defined widget (a draggable colored box) and a button. You can drag the
- box around or click the button which increments a counter.
-*/
-
-
-
-
-#include <dlib/gui_widgets.h>
-#include <sstream>
-#include <string>
-
-
-using namespace std;
-using namespace dlib;
-
-// ----------------------------------------------------------------------------
-
-class color_box : public draggable
-{
- /*
- Here I am defining a custom drawable widget that is a colored box that
- you can drag around on the screen. draggable is a special kind of drawable
- object that, as the name implies, is draggable by the user via the mouse.
- To make my color_box draggable all I need to do is inherit from draggable.
- */
- unsigned char red, green,blue;
-
-public:
- color_box (
- drawable_window& w,
- rectangle area,
- unsigned char red_,
- unsigned char green_,
- unsigned char blue_
- ) :
- draggable(w),
- red(red_),
- green(green_),
- blue(blue_)
- {
- rect = area;
- set_draggable_area(rectangle(10,10,400,400));
-
- // Whenever you make your own drawable widget (or inherit from any drawable widget
- // or interface such as draggable) you have to remember to call this function to
- // enable the events. The idea here is that you can perform whatever setup you
- // need to do to get your object into a valid state without needing to worry about
- // event handlers triggering before you are ready.
- enable_events();
- }
-
- ~color_box (
- )
- {
- // Disable all further events for this drawable object. We have to do this
- // because we don't want any events (like draw()) coming to this object while or
- // after it has been destructed.
- disable_events();
-
- // Tell the parent window to redraw its area that previously contained this
- // drawable object.
- parent.invalidate_rectangle(rect);
- }
-
-private:
-
- void draw (
- const canvas& c
- ) const
- {
- // The canvas is an object that represents a part of the parent window
- // that needs to be redrawn.
-
- // The first thing I usually do is check if the draw call is for part
- // of the window that overlaps with my widget. We don't have to do this
- // but it is usually good to do as a speed hack. Also, the reason
- // I don't have it set to only give you draw calls when it does indeed
- // overlap is because you might want to do some drawing outside of your
- // widget's rectangle. But usually you don't want to do that :)
- rectangle area = c.intersect(rect);
- if (area.is_empty() == true)
- return;
-
- // This simple widget is just going to draw a box on the screen.
- fill_rect(c,rect,rgb_pixel(red,green,blue));
- }
-};
-
-// ----------------------------------------------------------------------------
-
-class win : public drawable_window
-{
- /*
- Here I am going to define our window. In general, you can define as
- many window types as you like and make as many instances of them as you want.
- In this example I am only making one though.
- */
-public:
- win(
- ) : // All widgets take their parent window as an argument to their constructor.
- c(*this),
- b(*this),
- cb(*this,rectangle(100,100,200,200),0,0,255), // the color_box will be blue and 101 pixels wide and tall
- mbar(*this)
- {
- // tell our button to put itself at the position (10,60).
- b.set_pos(10,60);
- b.set_name("button");
-
- // let's put the label 5 pixels below the button
- c.set_pos(b.left(),b.bottom()+5);
-
-
- // set which function should get called when the button gets clicked. In this case we want
- // the on_button_clicked member to be called on *this.
- b.set_click_handler(*this,&win::on_button_clicked);
- // Alternatively, if you have a compiler which supports the lambda functions from the
- // new C++ standard then you can use a lambda function instead of telling the click
- // handler to call one of the member functions. So for example, you could do this
- // instead (uncomment the code if you have C++0x support):
- /*
- b.set_click_handler([&](){
- ++counter;
- ostringstream sout;
- sout << "Counter: " << counter;
- c.set_text(sout.str());
- });
- */
- // In general, all the functions which register events can take either member
- // functions or lambda functions.
-
-
- // Let's also make a simple menu bar.
- // First we say how many menus we want in our menu bar. In this example we only want 1.
- mbar.set_number_of_menus(1);
- // Now we set the name of our menu. The 'M' means that the M in Menu will be underlined
- // and the user will be able to select it by hitting alt+M
- mbar.set_menu_name(0,"Menu",'M');
-
- // Now we add some items to the menu. Note that items in a menu are listed in the
- // order in which they were added.
-
- // First let's make a menu item that does the same thing as our button does when it is clicked.
- // Again, the 'C' means the C in Click is underlined in the menu.
- mbar.menu(0).add_menu_item(menu_item_text("Click Button!",*this,&win::on_button_clicked,'C'));
- // let's add a separator (i.e. a horizontal separating line) to the menu
- mbar.menu(0).add_menu_item(menu_item_separator());
- // Now let's make a menu item that calls show_about when the user selects it.
- mbar.menu(0).add_menu_item(menu_item_text("About",*this,&win::show_about,'A'));
-
-
- // set the size of this window
- set_size(430,380);
-
- counter = 0;
-
- set_title("dlib gui example");
- show();
- }
-
- ~win(
- )
- {
- // You should always call close_window() in the destructor of window
- // objects to ensure that no events will be sent to this window while
- // it is being destructed.
- close_window();
- }
-
-private:
-
- void on_button_clicked (
- )
- {
- // when someone clicks our button it will increment the counter and
- // display it in our label c.
- ++counter;
- ostringstream sout;
- sout << "counter: " << counter;
- c.set_text(sout.str());
- }
-
- void show_about(
- )
- {
- message_box("About","This is a dlib gui example program");
- }
-
- unsigned long counter;
- label c;
- button b;
- color_box cb;
- menu_bar mbar;
-};
-
-// ----------------------------------------------------------------------------
-
-int main()
-{
- // create our window
- win my_window;
-
-
- // wait until the user closes this window before we let the program
- // terminate.
- my_window.wait_until_closed();
-
- return 0;
-}
-
-// ----------------------------------------------------------------------------
-
-// Normally, if you built this application on MS Windows in Visual Studio you
-// would see a black console window pop up when you ran it. The following
-// #pragma directives tell Visual Studio to not include a console window along
-// with your application. However, if you prefer to have the console pop up as
-// well then simply remove these #pragma statements.
-#ifdef _MSC_VER
-# pragma comment( linker, "/entry:mainCRTStartup" )
-# pragma comment( linker, "/SUBSYSTEM:WINDOWS" )
-#endif
-
-// ----------------------------------------------------------------------------
-
diff --git a/ml/dlib/examples/hough_transform_ex.cpp b/ml/dlib/examples/hough_transform_ex.cpp
deleted file mode 100644
index 1c8b9f7bd..000000000
--- a/ml/dlib/examples/hough_transform_ex.cpp
+++ /dev/null
@@ -1,84 +0,0 @@
-// The contents of this file are in the public domain. See LICENSE_FOR_EXAMPLE_PROGRAMS.txt
-/*
-
- This is an example illustrating the use of the Hough transform tool in the
- dlib C++ Library.
-
-
- In this example we are going to draw a line on an image and then use the
- Hough transform to detect the location of the line. Moreover, we do this in
- a loop that changes the line's position slightly each iteration, which gives
- a pretty animation of the Hough transform in action.
-*/
-
-#include <dlib/gui_widgets.h>
-#include <dlib/image_transforms.h>
-
-using namespace dlib;
-
-int main()
-{
- // First let's make a 400x400 image. This will form the input to the Hough transform.
- array2d<unsigned char> img(400,400);
- // Now we make a hough_transform object. The 300 here means that the Hough transform
- // will operate on a 300x300 subwindow of its input image.
- hough_transform ht(300);
-
- image_window win, win2;
- double angle1 = 0;
- double angle2 = 0;
- while(true)
- {
- // Generate a line segment that is rotating around inside the image. The line is
- // generated based on the values in angle1 and angle2. So each iteration creates a
- // slightly different line.
- angle1 += pi/130;
- angle2 += pi/400;
- const point cent = center(get_rect(img));
- // A point 90 pixels away from the center of the image but rotated by angle1.
- const point arc = rotate_point(cent, cent + point(90,0), angle1);
- // Now make a line that goes though arc but rotate it by angle2.
- const point l = rotate_point(arc, arc + point(500,0), angle2);
- const point r = rotate_point(arc, arc - point(500,0), angle2);
-
-
- // Next, blank out the input image and then draw our line on it.
- assign_all_pixels(img, 0);
- draw_line(img, l, r, 255);
-
-
- const point offset(50,50);
- array2d<int> himg;
- // pick the window inside img on which we will run the Hough transform.
- const rectangle box = translate_rect(get_rect(ht),offset);
- // Now let's compute the hough transform for a subwindow in the image. In
- // particular, we run it on the 300x300 subwindow with an upper left corner at the
- // pixel point(50,50). The output is stored in himg.
- ht(img, box, himg);
- // Now that we have the transformed image, the Hough image pixel with the largest
- // value should indicate where the line is. So we find the coordinates of the
- // largest pixel:
- point p = max_point(mat(himg));
- // And then ask the ht object for the line segment in the original image that
- // corresponds to this point in Hough transform space.
- std::pair<point,point> line = ht.get_line(p);
-
- // Finally, let's display all these things on the screen. We copy the original
- // input image into a color image and then draw the detected line on top in red.
- array2d<rgb_pixel> temp;
- assign_image(temp, img);
- // Note that we must offset the output line to account for our offset subwindow.
- // We do this by just adding in the offset to the line endpoints.
- draw_line(temp, line.first+offset, line.second+offset, rgb_pixel(255,0,0));
- win.clear_overlay();
- win.set_image(temp);
- // Also show the subwindow we ran the Hough transform on as a green box. You will
- // see that the detected line is exactly contained within this box and also
- // overlaps the original line.
- win.add_overlay(box, rgb_pixel(0,255,0));
-
- // We can also display the Hough transform itself using the jet color scheme.
- win2.set_image(jet(himg));
- }
-}
-
diff --git a/ml/dlib/examples/image_ex.cpp b/ml/dlib/examples/image_ex.cpp
deleted file mode 100644
index 148682694..000000000
--- a/ml/dlib/examples/image_ex.cpp
+++ /dev/null
@@ -1,104 +0,0 @@
-// The contents of this file are in the public domain. See LICENSE_FOR_EXAMPLE_PROGRAMS.txt
-/*
-
- This is an example illustrating the use of the GUI API as well as some
- aspects of image manipulation from the dlib C++ Library.
-
-
- This is a pretty simple example. It takes a BMP file on the command line
- and opens it up, runs a simple edge detection algorithm on it, and
- displays the results on the screen.
-*/
-
-
-
-#include <dlib/gui_widgets.h>
-#include <dlib/image_io.h>
-#include <dlib/image_transforms.h>
-#include <fstream>
-
-
-using namespace std;
-using namespace dlib;
-
-// ----------------------------------------------------------------------------
-
-int main(int argc, char** argv)
-{
- try
- {
- // make sure the user entered an argument to this program
- if (argc != 2)
- {
- cout << "error, you have to enter a BMP file as an argument to this program" << endl;
- return 1;
- }
-
- // Here we declare an image object that can store rgb_pixels. Note that in
- // dlib there is no explicit image object, just a 2D array and
- // various pixel types.
- array2d<rgb_pixel> img;
-
- // Now load the image file into our image. If something is wrong then
- // load_image() will throw an exception. Also, if you linked with libpng
- // and libjpeg then load_image() can load PNG and JPEG files in addition
- // to BMP files.
- load_image(img, argv[1]);
-
-
- // Now let's use some image functions. First let's blur the image a little.
- array2d<unsigned char> blurred_img;
- gaussian_blur(img, blurred_img);
-
- // Now find the horizontal and vertical gradient images.
- array2d<short> horz_gradient, vert_gradient;
- array2d<unsigned char> edge_image;
- sobel_edge_detector(blurred_img, horz_gradient, vert_gradient);
-
- // now we do the non-maximum edge suppression step so that our edges are nice and thin
- suppress_non_maximum_edges(horz_gradient, vert_gradient, edge_image);
-
- // Now we would like to see what our images look like. So let's use a
- // window to display them on the screen. (Note that you can zoom into
- // the window by holding CTRL and scrolling the mouse wheel)
- image_window my_window(edge_image, "Normal Edge Image");
-
- // We can also easily display the edge_image as a heatmap or using the jet color
- // scheme like so.
- image_window win_hot(heatmap(edge_image));
- image_window win_jet(jet(edge_image));
-
- // also make a window to display the original image
- image_window my_window2(img, "Original Image");
-
- // Sometimes you want to get input from the user about which pixels are important
- // for some task. You can do this easily by trapping user clicks as shown below.
- // This loop executes every time the user double clicks on some image pixel and it
- // will terminate once the user closes the window.
- point p;
- while (my_window.get_next_double_click(p))
- {
- cout << "User double clicked on pixel: " << p << endl;
- cout << "edge pixel value at this location is: " << (int)edge_image[p.y()][p.x()] << endl;
- }
-
- // wait until the user closes the windows before we let the program
- // terminate.
- win_hot.wait_until_closed();
- my_window2.wait_until_closed();
-
-
- // Finally, note that you can access the elements of an image using the normal [row][column]
- // operator like so:
- cout << horz_gradient[0][3] << endl;
- cout << "number of rows in image: " << horz_gradient.nr() << endl;
- cout << "number of columns in image: " << horz_gradient.nc() << endl;
- }
- catch (exception& e)
- {
- cout << "exception thrown: " << e.what() << endl;
- }
-}
-
-// ----------------------------------------------------------------------------
-
diff --git a/ml/dlib/examples/integrate_function_adapt_simp_ex.cpp b/ml/dlib/examples/integrate_function_adapt_simp_ex.cpp
deleted file mode 100644
index 6d2c8f76b..000000000
--- a/ml/dlib/examples/integrate_function_adapt_simp_ex.cpp
+++ /dev/null
@@ -1,89 +0,0 @@
-// The contents of this file are in the public domain. See LICENSE_FOR_EXAMPLE_PROGRAMS.txt
-/*
-
- This example demonstrates the usage of the numerical quadrature function
- integrate_function_adapt_simp(). This function takes as input a single variable
- function, the endpoints of a domain over which the function will be integrated, and a
- tolerance parameter. It outputs an approximation of the integral of this function over
- the specified domain. The algorithm is based on the adaptive Simpson method outlined in:
-
- Numerical Integration method based on the adaptive Simpson method in
- Gander, W. and W. Gautschi, "Adaptive Quadrature – Revisited,"
- BIT, Vol. 40, 2000, pp. 84-101
-
-*/
-
-#include <iostream>
-#include <dlib/matrix.h>
-#include <dlib/numeric_constants.h>
-#include <dlib/numerical_integration.h>
-
-using namespace std;
-using namespace dlib;
-
-// Here we the set of functions that we wish to integrate and comment in the domain of
-// integration.
-
-// x in [0,1]
-double gg1(double x)
-{
- return pow(e,x);
-}
-
-// x in [0,1]
-double gg2(double x)
-{
- return x*x;
-}
-
-// x in [0, pi]
-double gg3(double x)
-{
- return 1/(x*x + cos(x)*cos(x));
-}
-
-// x in [-pi, pi]
-double gg4(double x)
-{
- return sin(x);
-}
-
-// x in [0,2]
-double gg5(double x)
-{
- return 1/(1 + x*x);
-}
-
-int main()
-{
- // We first define a tolerance parameter. Roughly speaking, a lower tolerance will
- // result in a more accurate approximation of the true integral. However, there are
- // instances where too small of a tolerance may yield a less accurate approximation
- // than a larger tolerance. We recommend taking the tolerance to be in the
- // [1e-10, 1e-8] region.
-
- double tol = 1e-10;
-
-
- // Here we compute the integrals of the five functions defined above using the same
- // tolerance level for each.
-
- double m1 = integrate_function_adapt_simp(&gg1, 0.0, 1.0, tol);
- double m2 = integrate_function_adapt_simp(&gg2, 0.0, 1.0, tol);
- double m3 = integrate_function_adapt_simp(&gg3, 0.0, pi, tol);
- double m4 = integrate_function_adapt_simp(&gg4, -pi, pi, tol);
- double m5 = integrate_function_adapt_simp(&gg5, 0.0, 2.0, tol);
-
- // We finally print out the values of each of the approximated integrals to ten
- // significant digits.
-
- cout << "\nThe integral of exp(x) for x in [0,1] is " << std::setprecision(10) << m1 << endl;
- cout << "The integral of x^2 for in [0,1] is " << std::setprecision(10) << m2 << endl;
- cout << "The integral of 1/(x^2 + cos(x)^2) for in [0,pi] is " << std::setprecision(10) << m3 << endl;
- cout << "The integral of sin(x) for in [-pi,pi] is " << std::setprecision(10) << m4 << endl;
- cout << "The integral of 1/(1+x^2) for in [0,2] is " << std::setprecision(10) << m5 << endl;
- cout << endl;
-
- return 0;
-}
-
diff --git a/ml/dlib/examples/iosockstream_ex.cpp b/ml/dlib/examples/iosockstream_ex.cpp
deleted file mode 100644
index 8a5dbbb24..000000000
--- a/ml/dlib/examples/iosockstream_ex.cpp
+++ /dev/null
@@ -1,47 +0,0 @@
-// The contents of this file are in the public domain. See LICENSE_FOR_EXAMPLE_PROGRAMS.txt
-/*
-
- This is an example illustrating the use of the iosockstream object from the
- dlib C++ Library.
-
- This program simply connects to www.google.com at port 80 and requests the
- main Google web page. It then prints what it gets back from Google to the
- screen.
-
-
- For those of you curious about HTTP check out the excellent introduction at
- http://www.jmarshall.com/easy/http/
-*/
-
-#include <dlib/iosockstream.h>
-#include <iostream>
-
-using namespace std;
-using namespace dlib;
-
-int main()
-{
- try
- {
- // Connect to Google's web server which listens on port 80. If this
- // fails it will throw a dlib::socket_error exception.
- iosockstream stream("www.google.com:80");
-
- // At this point, we can use stream the same way we would use any other
- // C++ iostream object. So to test it out, let's make a HTTP GET request
- // for the main Google page.
- stream << "GET / HTTP/1.0\r\n\r\n";
-
- // Here we print each character we get back one at a time.
- while (stream.peek() != EOF)
- {
- cout << (char)stream.get();
- }
- }
- catch (exception& e)
- {
- cout << e.what() << endl;
- }
-}
-
-
diff --git a/ml/dlib/examples/johns/John_Salley/000179_02159509.jpg b/ml/dlib/examples/johns/John_Salley/000179_02159509.jpg
deleted file mode 100644
index 7bdd1e26d..000000000
--- a/ml/dlib/examples/johns/John_Salley/000179_02159509.jpg
+++ /dev/null
Binary files differ
diff --git a/ml/dlib/examples/johns/John_Salley/000183_02159543.jpg b/ml/dlib/examples/johns/John_Salley/000183_02159543.jpg
deleted file mode 100644
index f27401909..000000000
--- a/ml/dlib/examples/johns/John_Salley/000183_02159543.jpg
+++ /dev/null
Binary files differ
diff --git a/ml/dlib/examples/johns/John_Salley/000186_02159346.jpg b/ml/dlib/examples/johns/John_Salley/000186_02159346.jpg
deleted file mode 100644
index 1199b39e0..000000000
--- a/ml/dlib/examples/johns/John_Salley/000186_02159346.jpg
+++ /dev/null
Binary files differ
diff --git a/ml/dlib/examples/johns/John_Salley/000189_02159361.jpg b/ml/dlib/examples/johns/John_Salley/000189_02159361.jpg
deleted file mode 100644
index e5197e32f..000000000
--- a/ml/dlib/examples/johns/John_Salley/000189_02159361.jpg
+++ /dev/null
Binary files differ
diff --git a/ml/dlib/examples/johns/John_Salley/000190_02159501.jpg b/ml/dlib/examples/johns/John_Salley/000190_02159501.jpg
deleted file mode 100644
index 56c62c210..000000000
--- a/ml/dlib/examples/johns/John_Salley/000190_02159501.jpg
+++ /dev/null
Binary files differ
diff --git a/ml/dlib/examples/johns/John_Salley/000192_02159531.jpg b/ml/dlib/examples/johns/John_Salley/000192_02159531.jpg
deleted file mode 100644
index e0b4c2b23..000000000
--- a/ml/dlib/examples/johns/John_Salley/000192_02159531.jpg
+++ /dev/null
Binary files differ
diff --git a/ml/dlib/examples/johns/John_Salley/000194_02159572.jpg b/ml/dlib/examples/johns/John_Salley/000194_02159572.jpg
deleted file mode 100644
index 08cdce3d5..000000000
--- a/ml/dlib/examples/johns/John_Salley/000194_02159572.jpg
+++ /dev/null
Binary files differ
diff --git a/ml/dlib/examples/johns/John_Salley/000197_02159322.jpg b/ml/dlib/examples/johns/John_Salley/000197_02159322.jpg
deleted file mode 100644
index b65c1e70a..000000000
--- a/ml/dlib/examples/johns/John_Salley/000197_02159322.jpg
+++ /dev/null
Binary files differ
diff --git a/ml/dlib/examples/johns/John_Salley/000197_02159525.jpg b/ml/dlib/examples/johns/John_Salley/000197_02159525.jpg
deleted file mode 100644
index 36e072321..000000000
--- a/ml/dlib/examples/johns/John_Salley/000197_02159525.jpg
+++ /dev/null
Binary files differ
diff --git a/ml/dlib/examples/johns/John_Salley/000198_02159470.jpg b/ml/dlib/examples/johns/John_Salley/000198_02159470.jpg
deleted file mode 100644
index af3132e6e..000000000
--- a/ml/dlib/examples/johns/John_Salley/000198_02159470.jpg
+++ /dev/null
Binary files differ
diff --git a/ml/dlib/examples/johns/John_Salley/000200_02159354.jpg b/ml/dlib/examples/johns/John_Salley/000200_02159354.jpg
deleted file mode 100644
index 8e3456966..000000000
--- a/ml/dlib/examples/johns/John_Salley/000200_02159354.jpg
+++ /dev/null
Binary files differ
diff --git a/ml/dlib/examples/johns/John_Savage/000264_01099001.jpg b/ml/dlib/examples/johns/John_Savage/000264_01099001.jpg
deleted file mode 100644
index 9f0bd6c31..000000000
--- a/ml/dlib/examples/johns/John_Savage/000264_01099001.jpg
+++ /dev/null
Binary files differ
diff --git a/ml/dlib/examples/johns/John_Savage/000274_01099061.jpg b/ml/dlib/examples/johns/John_Savage/000274_01099061.jpg
deleted file mode 100644
index 6f90d3077..000000000
--- a/ml/dlib/examples/johns/John_Savage/000274_01099061.jpg
+++ /dev/null
Binary files differ
diff --git a/ml/dlib/examples/johns/John_Savage/000277_01099000.jpg b/ml/dlib/examples/johns/John_Savage/000277_01099000.jpg
deleted file mode 100644
index 51f6501b7..000000000
--- a/ml/dlib/examples/johns/John_Savage/000277_01099000.jpg
+++ /dev/null
Binary files differ
diff --git a/ml/dlib/examples/johns/John_Savage/000289_01099139.jpg b/ml/dlib/examples/johns/John_Savage/000289_01099139.jpg
deleted file mode 100644
index dc6422e31..000000000
--- a/ml/dlib/examples/johns/John_Savage/000289_01099139.jpg
+++ /dev/null
Binary files differ
diff --git a/ml/dlib/examples/johns/John_Savage/000290_01099067.jpg b/ml/dlib/examples/johns/John_Savage/000290_01099067.jpg
deleted file mode 100644
index fad9ea444..000000000
--- a/ml/dlib/examples/johns/John_Savage/000290_01099067.jpg
+++ /dev/null
Binary files differ
diff --git a/ml/dlib/examples/johns/John_Savage/000290_01099090.jpg b/ml/dlib/examples/johns/John_Savage/000290_01099090.jpg
deleted file mode 100644
index d25605bfa..000000000
--- a/ml/dlib/examples/johns/John_Savage/000290_01099090.jpg
+++ /dev/null
Binary files differ
diff --git a/ml/dlib/examples/johns/John_Savage/000291_01099023.jpg b/ml/dlib/examples/johns/John_Savage/000291_01099023.jpg
deleted file mode 100644
index 0299f0fbd..000000000
--- a/ml/dlib/examples/johns/John_Savage/000291_01099023.jpg
+++ /dev/null
Binary files differ
diff --git a/ml/dlib/examples/johns/John_Savage/000291_01099214.jpg b/ml/dlib/examples/johns/John_Savage/000291_01099214.jpg
deleted file mode 100644
index e6e6fdda9..000000000
--- a/ml/dlib/examples/johns/John_Savage/000291_01099214.jpg
+++ /dev/null
Binary files differ
diff --git a/ml/dlib/examples/johns/John_Savage/000293_01099081.jpg b/ml/dlib/examples/johns/John_Savage/000293_01099081.jpg
deleted file mode 100644
index 6feb7670f..000000000
--- a/ml/dlib/examples/johns/John_Savage/000293_01099081.jpg
+++ /dev/null
Binary files differ
diff --git a/ml/dlib/examples/johns/John_Savage/000296_01099007.jpg b/ml/dlib/examples/johns/John_Savage/000296_01099007.jpg
deleted file mode 100644
index 356e91376..000000000
--- a/ml/dlib/examples/johns/John_Savage/000296_01099007.jpg
+++ /dev/null
Binary files differ
diff --git a/ml/dlib/examples/johns/John_Savage/000299_01099008.jpg b/ml/dlib/examples/johns/John_Savage/000299_01099008.jpg
deleted file mode 100644
index 28970e840..000000000
--- a/ml/dlib/examples/johns/John_Savage/000299_01099008.jpg
+++ /dev/null
Binary files differ
diff --git a/ml/dlib/examples/johns/John_Schneider/000288_00925786.jpg b/ml/dlib/examples/johns/John_Schneider/000288_00925786.jpg
deleted file mode 100644
index bcdf2df11..000000000
--- a/ml/dlib/examples/johns/John_Schneider/000288_00925786.jpg
+++ /dev/null
Binary files differ
diff --git a/ml/dlib/examples/johns/John_Schneider/000302_00925785.jpg b/ml/dlib/examples/johns/John_Schneider/000302_00925785.jpg
deleted file mode 100644
index 01bcbe34d..000000000
--- a/ml/dlib/examples/johns/John_Schneider/000302_00925785.jpg
+++ /dev/null
Binary files differ
diff --git a/ml/dlib/examples/johns/John_Schneider/000307_00925823.jpg b/ml/dlib/examples/johns/John_Schneider/000307_00925823.jpg
deleted file mode 100644
index 996ae82bf..000000000
--- a/ml/dlib/examples/johns/John_Schneider/000307_00925823.jpg
+++ /dev/null
Binary files differ
diff --git a/ml/dlib/examples/johns/John_Schneider/000325_00925954.jpg b/ml/dlib/examples/johns/John_Schneider/000325_00925954.jpg
deleted file mode 100644
index bd44c19a8..000000000
--- a/ml/dlib/examples/johns/John_Schneider/000325_00925954.jpg
+++ /dev/null
Binary files differ
diff --git a/ml/dlib/examples/johns/John_Schneider/000326_00925765.jpg b/ml/dlib/examples/johns/John_Schneider/000326_00925765.jpg
deleted file mode 100644
index fee3a8065..000000000
--- a/ml/dlib/examples/johns/John_Schneider/000326_00925765.jpg
+++ /dev/null
Binary files differ
diff --git a/ml/dlib/examples/johns/John_Schneider/000326_00926089.jpg b/ml/dlib/examples/johns/John_Schneider/000326_00926089.jpg
deleted file mode 100644
index 5f469934f..000000000
--- a/ml/dlib/examples/johns/John_Schneider/000326_00926089.jpg
+++ /dev/null
Binary files differ
diff --git a/ml/dlib/examples/johns/John_Schneider/000326_00926128.jpg b/ml/dlib/examples/johns/John_Schneider/000326_00926128.jpg
deleted file mode 100644
index 3013a0842..000000000
--- a/ml/dlib/examples/johns/John_Schneider/000326_00926128.jpg
+++ /dev/null
Binary files differ
diff --git a/ml/dlib/examples/johns/John_Schneider/000326_00926139.jpg b/ml/dlib/examples/johns/John_Schneider/000326_00926139.jpg
deleted file mode 100644
index e24dd9e42..000000000
--- a/ml/dlib/examples/johns/John_Schneider/000326_00926139.jpg
+++ /dev/null
Binary files differ
diff --git a/ml/dlib/examples/johns/John_Schneider/000329_00925859.jpg b/ml/dlib/examples/johns/John_Schneider/000329_00925859.jpg
deleted file mode 100644
index 24fa155fa..000000000
--- a/ml/dlib/examples/johns/John_Schneider/000329_00925859.jpg
+++ /dev/null
Binary files differ
diff --git a/ml/dlib/examples/johns/John_Schneider/000329_00925963.jpg b/ml/dlib/examples/johns/John_Schneider/000329_00925963.jpg
deleted file mode 100644
index be7abafac..000000000
--- a/ml/dlib/examples/johns/John_Schneider/000329_00925963.jpg
+++ /dev/null
Binary files differ
diff --git a/ml/dlib/examples/johns/John_Schneider/000331_00926012.jpg b/ml/dlib/examples/johns/John_Schneider/000331_00926012.jpg
deleted file mode 100644
index 7e10e9544..000000000
--- a/ml/dlib/examples/johns/John_Schneider/000331_00926012.jpg
+++ /dev/null
Binary files differ
diff --git a/ml/dlib/examples/johns/John_Shimkus/000373_03228153.jpg b/ml/dlib/examples/johns/John_Shimkus/000373_03228153.jpg
deleted file mode 100644
index 1aa014804..000000000
--- a/ml/dlib/examples/johns/John_Shimkus/000373_03228153.jpg
+++ /dev/null
Binary files differ
diff --git a/ml/dlib/examples/johns/John_Shimkus/000375_03227651.jpg b/ml/dlib/examples/johns/John_Shimkus/000375_03227651.jpg
deleted file mode 100644
index d118a7897..000000000
--- a/ml/dlib/examples/johns/John_Shimkus/000375_03227651.jpg
+++ /dev/null
Binary files differ
diff --git a/ml/dlib/examples/johns/John_Shimkus/000376_02340068.jpg b/ml/dlib/examples/johns/John_Shimkus/000376_02340068.jpg
deleted file mode 100644
index 2a87e98aa..000000000
--- a/ml/dlib/examples/johns/John_Shimkus/000376_02340068.jpg
+++ /dev/null
Binary files differ
diff --git a/ml/dlib/examples/johns/John_Shimkus/000378_02340151.jpg b/ml/dlib/examples/johns/John_Shimkus/000378_02340151.jpg
deleted file mode 100644
index b835c30ea..000000000
--- a/ml/dlib/examples/johns/John_Shimkus/000378_02340151.jpg
+++ /dev/null
Binary files differ
diff --git a/ml/dlib/examples/johns/John_Shimkus/000378_03227610.jpg b/ml/dlib/examples/johns/John_Shimkus/000378_03227610.jpg
deleted file mode 100644
index b835c30ea..000000000
--- a/ml/dlib/examples/johns/John_Shimkus/000378_03227610.jpg
+++ /dev/null
Binary files differ
diff --git a/ml/dlib/examples/johns/John_Shimkus/000383_03227939.jpg b/ml/dlib/examples/johns/John_Shimkus/000383_03227939.jpg
deleted file mode 100644
index 144cc0fe1..000000000
--- a/ml/dlib/examples/johns/John_Shimkus/000383_03227939.jpg
+++ /dev/null
Binary files differ
diff --git a/ml/dlib/examples/johns/John_Shimkus/000385_03227766.jpg b/ml/dlib/examples/johns/John_Shimkus/000385_03227766.jpg
deleted file mode 100644
index e543125e4..000000000
--- a/ml/dlib/examples/johns/John_Shimkus/000385_03227766.jpg
+++ /dev/null
Binary files differ
diff --git a/ml/dlib/examples/johns/John_Shimkus/000388_03227773.jpg b/ml/dlib/examples/johns/John_Shimkus/000388_03227773.jpg
deleted file mode 100644
index d2a7f1ec8..000000000
--- a/ml/dlib/examples/johns/John_Shimkus/000388_03227773.jpg
+++ /dev/null
Binary files differ
diff --git a/ml/dlib/examples/johns/John_Shimkus/000390_03227666.jpg b/ml/dlib/examples/johns/John_Shimkus/000390_03227666.jpg
deleted file mode 100644
index f4836bad7..000000000
--- a/ml/dlib/examples/johns/John_Shimkus/000390_03227666.jpg
+++ /dev/null
Binary files differ
diff --git a/ml/dlib/examples/johns/John_Shimkus/000394_02340150.jpg b/ml/dlib/examples/johns/John_Shimkus/000394_02340150.jpg
deleted file mode 100644
index e8d22bc67..000000000
--- a/ml/dlib/examples/johns/John_Shimkus/000394_02340150.jpg
+++ /dev/null
Binary files differ
diff --git a/ml/dlib/examples/johns/John_Shimkus/000396_03227722.jpg b/ml/dlib/examples/johns/John_Shimkus/000396_03227722.jpg
deleted file mode 100644
index 03c083913..000000000
--- a/ml/dlib/examples/johns/John_Shimkus/000396_03227722.jpg
+++ /dev/null
Binary files differ
diff --git a/ml/dlib/examples/johns/John_Simm/000288_00470387.jpg b/ml/dlib/examples/johns/John_Simm/000288_00470387.jpg
deleted file mode 100644
index eab153f2e..000000000
--- a/ml/dlib/examples/johns/John_Simm/000288_00470387.jpg
+++ /dev/null
Binary files differ
diff --git a/ml/dlib/examples/johns/John_Simm/000297_00470170.jpg b/ml/dlib/examples/johns/John_Simm/000297_00470170.jpg
deleted file mode 100644
index 31f0a1c7a..000000000
--- a/ml/dlib/examples/johns/John_Simm/000297_00470170.jpg
+++ /dev/null
Binary files differ
diff --git a/ml/dlib/examples/johns/John_Simm/000300_00470148.jpg b/ml/dlib/examples/johns/John_Simm/000300_00470148.jpg
deleted file mode 100644
index 46fd170e5..000000000
--- a/ml/dlib/examples/johns/John_Simm/000300_00470148.jpg
+++ /dev/null
Binary files differ
diff --git a/ml/dlib/examples/johns/John_Simm/000304_00470122.jpg b/ml/dlib/examples/johns/John_Simm/000304_00470122.jpg
deleted file mode 100644
index cb96ad0bb..000000000
--- a/ml/dlib/examples/johns/John_Simm/000304_00470122.jpg
+++ /dev/null
Binary files differ
diff --git a/ml/dlib/examples/johns/John_Simm/000305_00470162.jpg b/ml/dlib/examples/johns/John_Simm/000305_00470162.jpg
deleted file mode 100644
index f3a08ac38..000000000
--- a/ml/dlib/examples/johns/John_Simm/000305_00470162.jpg
+++ /dev/null
Binary files differ
diff --git a/ml/dlib/examples/johns/John_Simm/000305_00470717.jpg b/ml/dlib/examples/johns/John_Simm/000305_00470717.jpg
deleted file mode 100644
index b2f7570b5..000000000
--- a/ml/dlib/examples/johns/John_Simm/000305_00470717.jpg
+++ /dev/null
Binary files differ
diff --git a/ml/dlib/examples/johns/John_Simm/000306_00470222.jpg b/ml/dlib/examples/johns/John_Simm/000306_00470222.jpg
deleted file mode 100644
index 29180d4fa..000000000
--- a/ml/dlib/examples/johns/John_Simm/000306_00470222.jpg
+++ /dev/null
Binary files differ
diff --git a/ml/dlib/examples/johns/John_Simm/000306_00470223.jpg b/ml/dlib/examples/johns/John_Simm/000306_00470223.jpg
deleted file mode 100644
index 58845f214..000000000
--- a/ml/dlib/examples/johns/John_Simm/000306_00470223.jpg
+++ /dev/null
Binary files differ
diff --git a/ml/dlib/examples/johns/John_Simm/000309_00470287.jpg b/ml/dlib/examples/johns/John_Simm/000309_00470287.jpg
deleted file mode 100644
index 2134a8e9c..000000000
--- a/ml/dlib/examples/johns/John_Simm/000309_00470287.jpg
+++ /dev/null
Binary files differ
diff --git a/ml/dlib/examples/johns/John_Simm/000310_00470421.jpg b/ml/dlib/examples/johns/John_Simm/000310_00470421.jpg
deleted file mode 100644
index b79b2d5cd..000000000
--- a/ml/dlib/examples/johns/John_Simm/000310_00470421.jpg
+++ /dev/null
Binary files differ
diff --git a/ml/dlib/examples/johns/John_Simm/000310_00470511.jpg b/ml/dlib/examples/johns/John_Simm/000310_00470511.jpg
deleted file mode 100644
index 9119e4ac4..000000000
--- a/ml/dlib/examples/johns/John_Simm/000310_00470511.jpg
+++ /dev/null
Binary files differ
diff --git a/ml/dlib/examples/kcentroid_ex.cpp b/ml/dlib/examples/kcentroid_ex.cpp
deleted file mode 100644
index 1f9311bc1..000000000
--- a/ml/dlib/examples/kcentroid_ex.cpp
+++ /dev/null
@@ -1,129 +0,0 @@
-// The contents of this file are in the public domain. See LICENSE_FOR_EXAMPLE_PROGRAMS.txt
-/*
- This is an example illustrating the use of the kcentroid object
- from the dlib C++ Library.
-
- The kcentroid object is an implementation of an algorithm that recursively
- computes the centroid (i.e. average) of a set of points. The interesting
- thing about dlib::kcentroid is that it does so in a kernel induced feature
- space. This means that you can use it as a non-linear one-class classifier.
- So you might use it to perform online novelty detection (although, it has
- other uses, see the svm_pegasos or kkmeans examples for example).
-
- This example will train an instance of it on points from the sinc function.
-
-*/
-
-#include <iostream>
-#include <vector>
-
-#include <dlib/svm.h>
-#include <dlib/statistics.h>
-
-using namespace std;
-using namespace dlib;
-
-// Here is the sinc function we will be trying to learn with the kcentroid
-// object.
-double sinc(double x)
-{
- if (x == 0)
- return 1;
- return sin(x)/x;
-}
-
-int main()
-{
- // Here we declare that our samples will be 2 dimensional column vectors.
- // (Note that if you don't know the dimensionality of your vectors at compile time
- // you can change the 2 to a 0 and then set the size at runtime)
- typedef matrix<double,2,1> sample_type;
-
- // Now we are making a typedef for the kind of kernel we want to use. I picked the
- // radial basis kernel because it only has one parameter and generally gives good
- // results without much fiddling.
- typedef radial_basis_kernel<sample_type> kernel_type;
-
- // Here we declare an instance of the kcentroid object. The kcentroid has 3 parameters
- // you need to set. The first argument to the constructor is the kernel we wish to
- // use. The second is a parameter that determines the numerical accuracy with which
- // the object will perform the centroid estimation. Generally, smaller values
- // give better results but cause the algorithm to attempt to use more dictionary vectors
- // (and thus run slower and use more memory). The third argument, however, is the
- // maximum number of dictionary vectors a kcentroid is allowed to use. So you can use
- // it to control the runtime complexity.
- kcentroid<kernel_type> test(kernel_type(0.1),0.01, 15);
-
-
- // now we train our object on a few samples of the sinc function.
- sample_type m;
- for (double x = -15; x <= 8; x += 1)
- {
- m(0) = x;
- m(1) = sinc(x);
- test.train(m);
- }
-
- running_stats<double> rs;
-
- // Now let's output the distance from the centroid to some points that are from the sinc function.
- // These numbers should all be similar. We will also calculate the statistics of these numbers
- // by accumulating them into the running_stats object called rs. This will let us easily
- // find the mean and standard deviation of the distances for use below.
- cout << "Points that are on the sinc function:\n";
- m(0) = -1.5; m(1) = sinc(m(0)); cout << " " << test(m) << endl; rs.add(test(m));
- m(0) = -1.5; m(1) = sinc(m(0)); cout << " " << test(m) << endl; rs.add(test(m));
- m(0) = -0; m(1) = sinc(m(0)); cout << " " << test(m) << endl; rs.add(test(m));
- m(0) = -0.5; m(1) = sinc(m(0)); cout << " " << test(m) << endl; rs.add(test(m));
- m(0) = -4.1; m(1) = sinc(m(0)); cout << " " << test(m) << endl; rs.add(test(m));
- m(0) = -1.5; m(1) = sinc(m(0)); cout << " " << test(m) << endl; rs.add(test(m));
- m(0) = -0.5; m(1) = sinc(m(0)); cout << " " << test(m) << endl; rs.add(test(m));
-
- cout << endl;
- // Let's output the distance from the centroid to some points that are NOT from the sinc function.
- // These numbers should all be significantly bigger than previous set of numbers. We will also
- // use the rs.scale() function to find out how many standard deviations they are away from the
- // mean of the test points from the sinc function. So in this case our criterion for "significantly bigger"
- // is > 3 or 4 standard deviations away from the above points that actually are on the sinc function.
- cout << "Points that are NOT on the sinc function:\n";
- m(0) = -1.5; m(1) = sinc(m(0))+4; cout << " " << test(m) << " is " << rs.scale(test(m)) << " standard deviations from sinc." << endl;
- m(0) = -1.5; m(1) = sinc(m(0))+3; cout << " " << test(m) << " is " << rs.scale(test(m)) << " standard deviations from sinc." << endl;
- m(0) = -0; m(1) = -sinc(m(0)); cout << " " << test(m) << " is " << rs.scale(test(m)) << " standard deviations from sinc." << endl;
- m(0) = -0.5; m(1) = -sinc(m(0)); cout << " " << test(m) << " is " << rs.scale(test(m)) << " standard deviations from sinc." << endl;
- m(0) = -4.1; m(1) = sinc(m(0))+2; cout << " " << test(m) << " is " << rs.scale(test(m)) << " standard deviations from sinc." << endl;
- m(0) = -1.5; m(1) = sinc(m(0))+0.9; cout << " " << test(m) << " is " << rs.scale(test(m)) << " standard deviations from sinc." << endl;
- m(0) = -0.5; m(1) = sinc(m(0))+1; cout << " " << test(m) << " is " << rs.scale(test(m)) << " standard deviations from sinc." << endl;
-
- // And finally print out the mean and standard deviation of points that are actually from sinc().
- cout << "\nmean: " << rs.mean() << endl;
- cout << "standard deviation: " << rs.stddev() << endl;
-
- // The output is as follows:
- /*
- Points that are on the sinc function:
- 0.869913
- 0.869913
- 0.873408
- 0.872807
- 0.870432
- 0.869913
- 0.872807
-
- Points that are NOT on the sinc function:
- 1.06366 is 119.65 standard deviations from sinc.
- 1.02212 is 93.8106 standard deviations from sinc.
- 0.921382 is 31.1458 standard deviations from sinc.
- 0.918439 is 29.3147 standard deviations from sinc.
- 0.931428 is 37.3949 standard deviations from sinc.
- 0.898018 is 16.6121 standard deviations from sinc.
- 0.914425 is 26.8183 standard deviations from sinc.
-
- mean: 0.871313
- standard deviation: 0.00160756
- */
-
- // So we can see that in this example the kcentroid object correctly indicates that
- // the non-sinc points are definitely not points from the sinc function.
-}
-
-
diff --git a/ml/dlib/examples/kkmeans_ex.cpp b/ml/dlib/examples/kkmeans_ex.cpp
deleted file mode 100644
index 76ea33cb0..000000000
--- a/ml/dlib/examples/kkmeans_ex.cpp
+++ /dev/null
@@ -1,154 +0,0 @@
-// The contents of this file are in the public domain. See LICENSE_FOR_EXAMPLE_PROGRAMS.txt
-/*
- This is an example illustrating the use of the kkmeans object
- and spectral_cluster() routine from the dlib C++ Library.
-
- The kkmeans object is an implementation of a kernelized k-means clustering
- algorithm. It is implemented by using the kcentroid object to represent
- each center found by the usual k-means clustering algorithm.
-
- So this object allows you to perform non-linear clustering in the same way
- a svm classifier finds non-linear decision surfaces.
-
- This example will make points from 3 classes and perform kernelized k-means
- clustering on those points. It will also do the same thing using spectral
- clustering.
-
- The classes are as follows:
- - points very close to the origin
- - points on the circle of radius 10 around the origin
- - points that are on a circle of radius 4 but not around the origin at all
-*/
-
-#include <iostream>
-#include <vector>
-
-#include <dlib/clustering.h>
-#include <dlib/rand.h>
-
-using namespace std;
-using namespace dlib;
-
-int main()
-{
- // Here we declare that our samples will be 2 dimensional column vectors.
- // (Note that if you don't know the dimensionality of your vectors at compile time
- // you can change the 2 to a 0 and then set the size at runtime)
- typedef matrix<double,2,1> sample_type;
-
- // Now we are making a typedef for the kind of kernel we want to use. I picked the
- // radial basis kernel because it only has one parameter and generally gives good
- // results without much fiddling.
- typedef radial_basis_kernel<sample_type> kernel_type;
-
-
- // Here we declare an instance of the kcentroid object. It is the object used to
- // represent each of the centers used for clustering. The kcentroid has 3 parameters
- // you need to set. The first argument to the constructor is the kernel we wish to
- // use. The second is a parameter that determines the numerical accuracy with which
- // the object will perform part of the learning algorithm. Generally, smaller values
- // give better results but cause the algorithm to attempt to use more dictionary vectors
- // (and thus run slower and use more memory). The third argument, however, is the
- // maximum number of dictionary vectors a kcentroid is allowed to use. So you can use
- // it to control the runtime complexity.
- kcentroid<kernel_type> kc(kernel_type(0.1),0.01, 8);
-
- // Now we make an instance of the kkmeans object and tell it to use kcentroid objects
- // that are configured with the parameters from the kc object we defined above.
- kkmeans<kernel_type> test(kc);
-
- std::vector<sample_type> samples;
- std::vector<sample_type> initial_centers;
-
- sample_type m;
-
- dlib::rand rnd;
-
- // we will make 50 points from each class
- const long num = 50;
-
- // make some samples near the origin
- double radius = 0.5;
- for (long i = 0; i < num; ++i)
- {
- double sign = 1;
- if (rnd.get_random_double() < 0.5)
- sign = -1;
- m(0) = 2*radius*rnd.get_random_double()-radius;
- m(1) = sign*sqrt(radius*radius - m(0)*m(0));
-
- // add this sample to our set of samples we will run k-means
- samples.push_back(m);
- }
-
- // make some samples in a circle around the origin but far away
- radius = 10.0;
- for (long i = 0; i < num; ++i)
- {
- double sign = 1;
- if (rnd.get_random_double() < 0.5)
- sign = -1;
- m(0) = 2*radius*rnd.get_random_double()-radius;
- m(1) = sign*sqrt(radius*radius - m(0)*m(0));
-
- // add this sample to our set of samples we will run k-means
- samples.push_back(m);
- }
-
- // make some samples in a circle around the point (25,25)
- radius = 4.0;
- for (long i = 0; i < num; ++i)
- {
- double sign = 1;
- if (rnd.get_random_double() < 0.5)
- sign = -1;
- m(0) = 2*radius*rnd.get_random_double()-radius;
- m(1) = sign*sqrt(radius*radius - m(0)*m(0));
-
- // translate this point away from the origin
- m(0) += 25;
- m(1) += 25;
-
- // add this sample to our set of samples we will run k-means
- samples.push_back(m);
- }
-
- // tell the kkmeans object we made that we want to run k-means with k set to 3.
- // (i.e. we want 3 clusters)
- test.set_number_of_centers(3);
-
- // You need to pick some initial centers for the k-means algorithm. So here
- // we will use the dlib::pick_initial_centers() function which tries to find
- // n points that are far apart (basically).
- pick_initial_centers(3, initial_centers, samples, test.get_kernel());
-
- // now run the k-means algorithm on our set of samples.
- test.train(samples,initial_centers);
-
- // now loop over all our samples and print out their predicted class. In this example
- // all points are correctly identified.
- for (unsigned long i = 0; i < samples.size()/3; ++i)
- {
- cout << test(samples[i]) << " ";
- cout << test(samples[i+num]) << " ";
- cout << test(samples[i+2*num]) << "\n";
- }
-
- // Now print out how many dictionary vectors each center used. Note that
- // the maximum number of 8 was reached. If you went back to the kcentroid
- // constructor and changed the 8 to some bigger number you would see that these
- // numbers would go up. However, 8 is all we need to correctly cluster this dataset.
- cout << "num dictionary vectors for center 0: " << test.get_kcentroid(0).dictionary_size() << endl;
- cout << "num dictionary vectors for center 1: " << test.get_kcentroid(1).dictionary_size() << endl;
- cout << "num dictionary vectors for center 2: " << test.get_kcentroid(2).dictionary_size() << endl;
-
-
- // Finally, we can also solve the same kind of non-linear clustering problem with
- // spectral_cluster(). The output is a vector that indicates which cluster each sample
- // belongs to. Just like with kkmeans, it assigns each point to the correct cluster.
- std::vector<unsigned long> assignments = spectral_cluster(kernel_type(0.1), samples, 3);
- cout << mat(assignments) << endl;
-
-}
-
-
diff --git a/ml/dlib/examples/krls_ex.cpp b/ml/dlib/examples/krls_ex.cpp
deleted file mode 100644
index 968f1a6dd..000000000
--- a/ml/dlib/examples/krls_ex.cpp
+++ /dev/null
@@ -1,94 +0,0 @@
-// The contents of this file are in the public domain. See LICENSE_FOR_EXAMPLE_PROGRAMS.txt
-/*
- This is an example illustrating the use of the krls object
- from the dlib C++ Library.
-
- The krls object allows you to perform online regression. This
- example will train an instance of it on the sinc function.
-
-*/
-
-#include <iostream>
-#include <vector>
-
-#include <dlib/svm.h>
-
-using namespace std;
-using namespace dlib;
-
-// Here is the sinc function we will be trying to learn with the krls
-// object.
-double sinc(double x)
-{
- if (x == 0)
- return 1;
- return sin(x)/x;
-}
-
-int main()
-{
- // Here we declare that our samples will be 1 dimensional column vectors. In general,
- // you can use N dimensional vectors as inputs to the krls object. But here we only
- // have 1 dimension to make the example simple. (Note that if you don't know the
- // dimensionality of your vectors at compile time you can change the first number to
- // a 0 and then set the size at runtime)
- typedef matrix<double,1,1> sample_type;
-
- // Now we are making a typedef for the kind of kernel we want to use. I picked the
- // radial basis kernel because it only has one parameter and generally gives good
- // results without much fiddling.
- typedef radial_basis_kernel<sample_type> kernel_type;
-
- // Here we declare an instance of the krls object. The first argument to the constructor
- // is the kernel we wish to use. The second is a parameter that determines the numerical
- // accuracy with which the object will perform part of the regression algorithm. Generally
- // smaller values give better results but cause the algorithm to run slower. You just have
- // to play with it to decide what balance of speed and accuracy is right for your problem.
- // Here we have set it to 0.001.
- krls<kernel_type> test(kernel_type(0.1),0.001);
-
- // now we train our object on a few samples of the sinc function.
- sample_type m;
- for (double x = -10; x <= 4; x += 1)
- {
- m(0) = x;
- test.train(m, sinc(x));
- }
-
- // now we output the value of the sinc function for a few test points as well as the
- // value predicted by krls object.
- m(0) = 2.5; cout << sinc(m(0)) << " " << test(m) << endl;
- m(0) = 0.1; cout << sinc(m(0)) << " " << test(m) << endl;
- m(0) = -4; cout << sinc(m(0)) << " " << test(m) << endl;
- m(0) = 5.0; cout << sinc(m(0)) << " " << test(m) << endl;
-
- // The output is as follows:
- // 0.239389 0.239362
- // 0.998334 0.998333
- // -0.189201 -0.189201
- // -0.191785 -0.197267
-
-
- // The first column is the true value of the sinc function and the second
- // column is the output from the krls estimate.
-
-
-
-
-
- // Another thing that is worth knowing is that just about everything in dlib is serializable.
- // So for example, you can save the test object to disk and recall it later like so:
- serialize("saved_krls_object.dat") << test;
-
- // Now let's open that file back up and load the krls object it contains.
- deserialize("saved_krls_object.dat") >> test;
-
- // If you don't want to save the whole krls object (it might be a bit large)
- // you can save just the decision function it has learned so far. You can get
- // the decision function out of it by calling test.get_decision_function() and
- // then you can serialize that object instead. E.g.
- decision_function<kernel_type> funct = test.get_decision_function();
- serialize("saved_krls_function.dat") << funct;
-}
-
-
diff --git a/ml/dlib/examples/krls_filter_ex.cpp b/ml/dlib/examples/krls_filter_ex.cpp
deleted file mode 100644
index 5bb74b183..000000000
--- a/ml/dlib/examples/krls_filter_ex.cpp
+++ /dev/null
@@ -1,109 +0,0 @@
-// The contents of this file are in the public domain. See LICENSE_FOR_EXAMPLE_PROGRAMS.txt
-/*
- This is an example illustrating the use of the krls object
- from the dlib C++ Library.
-
- The krls object allows you to perform online regression. This
- example will use the krls object to perform filtering of a signal
- corrupted by uniformly distributed noise.
-*/
-
-#include <iostream>
-
-#include <dlib/svm.h>
-#include <dlib/rand.h>
-
-using namespace std;
-using namespace dlib;
-
-// Here is the function we will be trying to learn with the krls
-// object.
-double sinc(double x)
-{
- if (x == 0)
- return 1;
-
- // also add in x just to make this function a little more complex
- return sin(x)/x + x;
-}
-
-int main()
-{
- // Here we declare that our samples will be 1 dimensional column vectors. The reason for
- // using a matrix here is that in general you can use N dimensional vectors as inputs to the
- // krls object. But here we only have 1 dimension to make the example simple.
- typedef matrix<double,1,1> sample_type;
-
-
- // Now we are making a typedef for the kind of kernel we want to use. I picked the
- // radial basis kernel because it only has one parameter and generally gives good
- // results without much fiddling.
- typedef radial_basis_kernel<sample_type> kernel_type;
-
-
- // Here we declare an instance of the krls object. The first argument to the constructor
- // is the kernel we wish to use. The second is a parameter that determines the numerical
- // accuracy with which the object will perform part of the regression algorithm. Generally
- // smaller values give better results but cause the algorithm to run slower (because it tries
- // to use more "dictionary vectors" to represent the function it is learning.
- // You just have to play with it to decide what balance of speed and accuracy is right
- // for your problem. Here we have set it to 0.001.
- //
- // The last argument is the maximum number of dictionary vectors the algorithm is allowed
- // to use. The default value for this field is 1,000,000 which is large enough that you
- // won't ever hit it in practice. However, here we have set it to the much smaller value
- // of 7. This means that once the krls object accumulates 7 dictionary vectors it will
- // start discarding old ones in favor of new ones as it goes through the training process.
- // In other words, the algorithm "forgets" about old training data and focuses on recent
- // training samples. So the bigger the maximum dictionary size the longer its memory will
- // be. But in this example program we are doing filtering so we only care about the most
- // recent data. So using a small value is appropriate here since it will result in much
- // faster filtering and won't introduce much error.
- krls<kernel_type> test(kernel_type(0.05),0.001,7);
-
- dlib::rand rnd;
-
- // Now let's loop over a big range of values from the sinc() function. Each time
- // adding some random noise to the data we send to the krls object for training.
- sample_type m;
- double mse_noise = 0;
- double mse = 0;
- double count = 0;
- for (double x = -20; x <= 20; x += 0.01)
- {
- m(0) = x;
- // get a random number between -0.5 and 0.5
- const double noise = rnd.get_random_double()-0.5;
-
- // train on this new sample
- test.train(m, sinc(x)+noise);
-
- // once we have seen a bit of data start measuring the mean squared prediction error.
- // Also measure the mean squared error due to the noise.
- if (x > -19)
- {
- ++count;
- mse += pow(sinc(x) - test(m),2);
- mse_noise += pow(noise,2);
- }
- }
-
- mse /= count;
- mse_noise /= count;
-
- // Output the ratio of the error from the noise and the mean squared prediction error.
- cout << "prediction error: " << mse << endl;
- cout << "noise: " << mse_noise << endl;
- cout << "ratio of noise to prediction error: " << mse_noise/mse << endl;
-
- // When the program runs it should print the following:
- // prediction error: 0.00735201
- // noise: 0.0821628
- // ratio of noise to prediction error: 11.1756
-
- // And we see that the noise has been significantly reduced by filtering the points
- // through the krls object.
-
-}
-
-
diff --git a/ml/dlib/examples/krr_classification_ex.cpp b/ml/dlib/examples/krr_classification_ex.cpp
deleted file mode 100644
index 42648351f..000000000
--- a/ml/dlib/examples/krr_classification_ex.cpp
+++ /dev/null
@@ -1,205 +0,0 @@
-// The contents of this file are in the public domain. See LICENSE_FOR_EXAMPLE_PROGRAMS.txt
-/*
-
- This is an example illustrating the use of the kernel ridge regression
- object from the dlib C++ Library.
-
- This example creates a simple set of data to train on and then shows
- you how to use the kernel ridge regression tool to find a good decision
- function that can classify examples in our data set.
-
-
- The data used in this example will be 2 dimensional data and will
- come from a distribution where points with a distance less than 13
- from the origin are labeled +1 and all other points are labeled
- as -1. All together, the dataset will contain 10201 sample points.
-
-*/
-
-
-#include <iostream>
-#include <dlib/svm.h>
-
-using namespace std;
-using namespace dlib;
-
-
-int main()
-{
- // This typedef declares a matrix with 2 rows and 1 column. It will be the
- // object that contains each of our 2 dimensional samples. (Note that if you wanted
- // more than 2 features in this vector you can simply change the 2 to something else.
- // Or if you don't know how many features you want until runtime then you can put a 0
- // here and use the matrix.set_size() member function)
- typedef matrix<double, 2, 1> sample_type;
-
- // This is a typedef for the type of kernel we are going to use in this example.
- // In this case I have selected the radial basis kernel that can operate on our
- // 2D sample_type objects
- typedef radial_basis_kernel<sample_type> kernel_type;
-
-
- // Now we make objects to contain our samples and their respective labels.
- std::vector<sample_type> samples;
- std::vector<double> labels;
-
- // Now let's put some data into our samples and labels objects. We do this
- // by looping over a bunch of points and labeling them according to their
- // distance from the origin.
- for (double r = -20; r <= 20; r += 0.4)
- {
- for (double c = -20; c <= 20; c += 0.4)
- {
- sample_type samp;
- samp(0) = r;
- samp(1) = c;
- samples.push_back(samp);
-
- // if this point is less than 13 from the origin
- if (sqrt((double)r*r + c*c) <= 13)
- labels.push_back(+1);
- else
- labels.push_back(-1);
-
- }
- }
-
- cout << "samples generated: " << samples.size() << endl;
- cout << " number of +1 samples: " << sum(mat(labels) > 0) << endl;
- cout << " number of -1 samples: " << sum(mat(labels) < 0) << endl;
-
- // Here we normalize all the samples by subtracting their mean and dividing by their standard deviation.
- // This is generally a good idea since it often heads off numerical stability problems and also
- // prevents one large feature from smothering others. Doing this doesn't matter much in this example
- // so I'm just doing this here so you can see an easy way to accomplish this with
- // the library.
- vector_normalizer<sample_type> normalizer;
- // let the normalizer learn the mean and standard deviation of the samples
- normalizer.train(samples);
- // now normalize each sample
- for (unsigned long i = 0; i < samples.size(); ++i)
- samples[i] = normalizer(samples[i]);
-
-
- // here we make an instance of the krr_trainer object that uses our kernel type.
- krr_trainer<kernel_type> trainer;
-
- // The krr_trainer has the ability to perform leave-one-out cross-validation.
- // It does this to automatically determine the regularization parameter. Since
- // we are performing classification instead of regression we should be sure to
- // call use_classification_loss_for_loo_cv(). This function tells it to measure
- // errors in terms of the number of classification mistakes instead of mean squared
- // error between decision function output values and labels.
- trainer.use_classification_loss_for_loo_cv();
-
-
- // Now we loop over some different gamma values to see how good they are.
- cout << "\ndoing leave-one-out cross-validation" << endl;
- for (double gamma = 0.000001; gamma <= 1; gamma *= 5)
- {
- // tell the trainer the parameters we want to use
- trainer.set_kernel(kernel_type(gamma));
-
- // loo_values will contain the LOO predictions for each sample. In the case
- // of perfect prediction it will end up being a copy of labels.
- std::vector<double> loo_values;
- trainer.train(samples, labels, loo_values);
-
- // Print gamma and the fraction of samples correctly classified during LOO cross-validation.
- const double classification_accuracy = mean_sign_agreement(labels, loo_values);
- cout << "gamma: " << gamma << " LOO accuracy: " << classification_accuracy << endl;
- }
-
-
- // From looking at the output of the above loop it turns out that a good value for
- // gamma for this problem is 0.000625. So that is what we will use.
- trainer.set_kernel(kernel_type(0.000625));
- typedef decision_function<kernel_type> dec_funct_type;
- typedef normalized_function<dec_funct_type> funct_type;
-
-
- // Here we are making an instance of the normalized_function object. This object provides a convenient
- // way to store the vector normalization information along with the decision function we are
- // going to learn.
- funct_type learned_function;
- learned_function.normalizer = normalizer; // save normalization information
- learned_function.function = trainer.train(samples, labels); // perform the actual training and save the results
-
- // print out the number of basis vectors in the resulting decision function
- cout << "\nnumber of basis vectors in our learned_function is "
- << learned_function.function.basis_vectors.size() << endl;
-
- // Now let's try this decision_function on some samples we haven't seen before.
- // The decision function will return values >= 0 for samples it predicts
- // are in the +1 class and numbers < 0 for samples it predicts to be in the -1 class.
- sample_type sample;
-
- sample(0) = 3.123;
- sample(1) = 2;
- cout << "This is a +1 class example, the classifier output is " << learned_function(sample) << endl;
-
- sample(0) = 3.123;
- sample(1) = 9.3545;
- cout << "This is a +1 class example, the classifier output is " << learned_function(sample) << endl;
-
- sample(0) = 13.123;
- sample(1) = 9.3545;
- cout << "This is a -1 class example, the classifier output is " << learned_function(sample) << endl;
-
- sample(0) = 13.123;
- sample(1) = 0;
- cout << "This is a -1 class example, the classifier output is " << learned_function(sample) << endl;
-
-
- // We can also train a decision function that reports a well conditioned probability
- // instead of just a number > 0 for the +1 class and < 0 for the -1 class. An example
- // of doing that follows:
- typedef probabilistic_decision_function<kernel_type> probabilistic_funct_type;
- typedef normalized_function<probabilistic_funct_type> pfunct_type;
-
- // The train_probabilistic_decision_function() is going to perform 3-fold cross-validation.
- // So it is important that the +1 and -1 samples be distributed uniformly across all the folds.
- // calling randomize_samples() will make sure that is the case.
- randomize_samples(samples, labels);
-
- pfunct_type learned_pfunct;
- learned_pfunct.normalizer = normalizer;
- learned_pfunct.function = train_probabilistic_decision_function(trainer, samples, labels, 3);
- // Now we have a function that returns the probability that a given sample is of the +1 class.
-
- // print out the number of basis vectors in the resulting decision function.
- // (it should be the same as in the one above)
- cout << "\nnumber of basis vectors in our learned_pfunct is "
- << learned_pfunct.function.decision_funct.basis_vectors.size() << endl;
-
- sample(0) = 3.123;
- sample(1) = 2;
- cout << "This +1 class example should have high probability. Its probability is: "
- << learned_pfunct(sample) << endl;
-
- sample(0) = 3.123;
- sample(1) = 9.3545;
- cout << "This +1 class example should have high probability. Its probability is: "
- << learned_pfunct(sample) << endl;
-
- sample(0) = 13.123;
- sample(1) = 9.3545;
- cout << "This -1 class example should have low probability. Its probability is: "
- << learned_pfunct(sample) << endl;
-
- sample(0) = 13.123;
- sample(1) = 0;
- cout << "This -1 class example should have low probability. Its probability is: "
- << learned_pfunct(sample) << endl;
-
-
-
- // Another thing that is worth knowing is that just about everything in dlib is serializable.
- // So for example, you can save the learned_pfunct object to disk and recall it later like so:
- serialize("saved_function.dat") << learned_pfunct;
-
- // Now let's open that file back up and load the function object it contains.
- deserialize("saved_function.dat") >> learned_pfunct;
-
-}
-
diff --git a/ml/dlib/examples/krr_regression_ex.cpp b/ml/dlib/examples/krr_regression_ex.cpp
deleted file mode 100644
index 26c1412d7..000000000
--- a/ml/dlib/examples/krr_regression_ex.cpp
+++ /dev/null
@@ -1,104 +0,0 @@
-// The contents of this file are in the public domain. See LICENSE_FOR_EXAMPLE_PROGRAMS.txt
-/*
- This is an example illustrating the use of the kernel ridge regression
- object from the dlib C++ Library.
-
- This example will train on data from the sinc function.
-
-*/
-
-#include <iostream>
-#include <vector>
-
-#include <dlib/svm.h>
-
-using namespace std;
-using namespace dlib;
-
-// Here is the sinc function we will be trying to learn with kernel ridge regression
-double sinc(double x)
-{
- if (x == 0)
- return 1;
- return sin(x)/x;
-}
-
-int main()
-{
- // Here we declare that our samples will be 1 dimensional column vectors.
- typedef matrix<double,1,1> sample_type;
-
- // Now sample some points from the sinc() function
- sample_type m;
- std::vector<sample_type> samples;
- std::vector<double> labels;
- for (double x = -10; x <= 4; x += 1)
- {
- m(0) = x;
- samples.push_back(m);
- labels.push_back(sinc(x));
- }
-
- // Now we are making a typedef for the kind of kernel we want to use. I picked the
- // radial basis kernel because it only has one parameter and generally gives good
- // results without much fiddling.
- typedef radial_basis_kernel<sample_type> kernel_type;
-
- // Here we declare an instance of the krr_trainer object. This is the
- // object that we will later use to do the training.
- krr_trainer<kernel_type> trainer;
-
- // Here we set the kernel we want to use for training. The radial_basis_kernel
- // has a parameter called gamma that we need to determine. As a rule of thumb, a good
- // gamma to try is 1.0/(mean squared distance between your sample points). So
- // below we are using a similar value computed from at most 2000 randomly selected
- // samples.
- const double gamma = 3.0/compute_mean_squared_distance(randomly_subsample(samples, 2000));
- cout << "using gamma of " << gamma << endl;
- trainer.set_kernel(kernel_type(gamma));
-
- // now train a function based on our sample points
- decision_function<kernel_type> test = trainer.train(samples, labels);
-
- // now we output the value of the sinc function for a few test points as well as the
- // value predicted by our regression.
- m(0) = 2.5; cout << sinc(m(0)) << " " << test(m) << endl;
- m(0) = 0.1; cout << sinc(m(0)) << " " << test(m) << endl;
- m(0) = -4; cout << sinc(m(0)) << " " << test(m) << endl;
- m(0) = 5.0; cout << sinc(m(0)) << " " << test(m) << endl;
-
- // The output is as follows:
- //using gamma of 0.075
- // 0.239389 0.239389
- // 0.998334 0.998362
- // -0.189201 -0.189254
- // -0.191785 -0.186618
-
- // The first column is the true value of the sinc function and the second
- // column is the output from the krr estimate.
-
-
- // Note that the krr_trainer has the ability to tell us the leave-one-out predictions
- // for each sample.
- std::vector<double> loo_values;
- trainer.train(samples, labels, loo_values);
- cout << "mean squared LOO error: " << mean_squared_error(labels,loo_values) << endl;
- cout << "R^2 LOO value: " << r_squared(labels,loo_values) << endl;
- // Which outputs the following:
- // mean squared LOO error: 8.29575e-07
- // R^2 LOO value: 0.999995
-
-
-
-
-
- // Another thing that is worth knowing is that just about everything in dlib is serializable.
- // So for example, you can save the test object to disk and recall it later like so:
- serialize("saved_function.dat") << test;
-
- // Now let's open that file back up and load the function object it contains.
- deserialize("saved_function.dat") >> test;
-
-}
-
-
diff --git a/ml/dlib/examples/learning_to_track_ex.cpp b/ml/dlib/examples/learning_to_track_ex.cpp
deleted file mode 100644
index 2f9f3947f..000000000
--- a/ml/dlib/examples/learning_to_track_ex.cpp
+++ /dev/null
@@ -1,354 +0,0 @@
-// The contents of this file are in the public domain. See LICENSE_FOR_EXAMPLE_PROGRAMS.txt
-/*
- This example shows how you can use the dlib machine learning tools to make
- an object tracker. Depending on your tracking application there can be a
- lot of components to a tracker. However, a central element of many trackers
- is the "detection to track" association step and this is the part of the
- tracker we discuss in this example. Therefore, in the code below we define
- simple detection and track structures and then go through the steps needed
- to learn, using training data, how to best associate detections to tracks.
-
- It should be noted that these tools are implemented essentially as wrappers
- around the more general assignment learning tools present in dlib. So if
- you want to get an idea of how they work under the covers you should read
- the assignment_learning_ex.cpp example program and its supporting
- documentation. However, to just use the learning-to-track tools you won't
- need to understand these implementation details.
-*/
-
-
-#include <iostream>
-#include <dlib/svm_threaded.h>
-#include <dlib/rand.h>
-
-using namespace std;
-using namespace dlib;
-
-// ----------------------------------------------------------------------------------------
-
-struct detection
-{
- /*
- When you use these tools you need to define two structures. One represents a
- detection and another a track. In this example we call these structures detection
- and track but you can name them however you like. Moreover, You can put anything
- you want in your detection structure. The only requirement is that detection be
- copyable and contain a public typedef named track_type that tells us the track type
- meant for use with this detection object.
- */
- typedef struct track track_type;
-
-
-
- // Again, note that this field is NOT REQUIRED by the dlib tools. You can put whatever
- // you want in your detection object. Here we are including a column vector of
- // measurements from the sensor that generated the detection. In this example we don't
- // have a real sensor so we will simulate a very basic one using a random number
- // generator. But the idea is that you should be able to use the contents of your
- // detection to somehow tell which track it goes with. So these numbers should contain
- // some identifying information about the real world object that caused this detection.
- matrix<double,0,1> measurements;
-};
-
-
-struct track
-{
- /*
- Here we define our corresponding track object. This object has more requirements
- than the detection. In particular, the dlib machine learning tools require it to
- have the following elements:
- - A typedef named feature_vector_type
- - It should be copyable and default constructable
- - The three functions: get_similarity_features(), update_track(), and propagate_track()
-
- Just like the detection object, you can also add any additional fields you like.
- In this example we keep it simple and say that a track maintains only a copy of the
- most recent sensor measurements it has seen and also a number telling us how long
- it has been since the track was updated with a detection.
- */
-
- // This type should be a dlib::matrix capable of storing column vectors or an
- // unsorted sparse vector type such as std::vector<std::pair<unsigned long,double>>.
- typedef matrix<double,0,1> feature_vector_type;
-
- track()
- {
- time_since_last_association = 0;
- }
-
- void get_similarity_features(const detection& det, feature_vector_type& feats) const
- {
- /*
- The get_similarity_features() function takes a detection and outputs a feature
- vector that tells the machine learning tools how "similar" the detection is to
- the track. The idea here is to output a set of numbers (i.e. the contents of
- feats) that can be used to decide if det should be associated with this track.
- In this example we output the difference between the last sensor measurements
- for this track and the detection's measurements. This works since we expect
- the sensor measurements to be relatively constant for each track because that's
- how our simple sensor simulator in this example works. However, in a real
- world application it's likely to be much more complex. But here we keep things
- simple.
-
- It should also be noted that get_similarity_features() must always output
- feature vectors with the same number of dimensions. Finally, the machine
- learning tools are going to learn a linear function of feats and use that to
- predict if det should associate to this track. So try and define features that
- you think would work in a linear function. There are all kinds of ways to do
- this. If you want to get really clever about it you can even use kernel
- methods like the empirical_kernel_map (see empirical_kernel_map_ex.cpp). I
- would start out with something simple first though.
- */
- feats = abs(last_measurements - det.measurements);
- }
-
- void update_track(const detection& det)
- {
- /*
- This function is called when the dlib tools have decided that det should be
- associated with this track. So the point of update_track() is to, as the name
- suggests, update the track with the given detection. In general, you can do
- whatever you want in this function. Here we simply record the last measurement
- state and reset the time since last association.
- */
- last_measurements = det.measurements;
- time_since_last_association = 0;
- }
-
- void propagate_track()
- {
- /*
- This function is called when the dlib tools have decided, for the current time
- step, that none of the available detections associate with this track. So the
- point of this function is to perform a track update without a detection. To
- say that another way. Every time you ask the dlib tools to perform detection
- to track association they will update each track by calling either
- update_track() or propagate_track(). Which function they call depends on
- whether or not a detection was associated to the track.
- */
- ++time_since_last_association;
- }
-
- matrix<double,0,1> last_measurements;
- unsigned long time_since_last_association;
-};
-
-// ----------------------------------------------------------------------------------------
-
-/*
- Now that we have defined our detection and track structures we are going to define our
- sensor simulator. In it we will imagine that there are num_objects things in the world
- and those things generate detections from our sensor. Moreover, each detection from
- the sensor comes with a measurement vector with num_properties elements.
-
- So the first function, initialize_object_properties(), just randomly generates
- num_objects and saves them in a global variable. Then when we are generating
- detections we will output copies of these objects that have been corrupted by a little
- bit of random noise.
-*/
-
-dlib::rand rnd;
-const long num_objects = 4;
-const long num_properties = 6;
-std::vector<matrix<double,0,1> > object_properties(num_objects);
-
-void initialize_object_properties()
-{
- for (unsigned long i = 0; i < object_properties.size(); ++i)
- object_properties[i] = randm(num_properties,1,rnd);
-}
-
-// So here is our function that samples a detection from our simulated sensor. You tell it
-// what object you want to sample a detection from and it returns a detection from that
-// object.
-detection sample_detection_from_sensor(long object_id)
-{
- DLIB_CASSERT(object_id < num_objects,
- "You can't ask to sample a detection from an object that doesn't exist.");
- detection temp;
- // Set the measurements equal to the object's true property values plus a little bit of
- // noise.
- temp.measurements = object_properties[object_id] + randm(num_properties,1,rnd)*0.1;
- return temp;
-}
-
-// ----------------------------------------------------------------------------------------
-
-typedef std::vector<labeled_detection<detection> > detections_at_single_time_step;
-typedef std::vector<detections_at_single_time_step> track_history;
-
-track_history make_random_tracking_data_for_training()
-{
- /*
- Since we are using machine learning we need some training data. This function
- samples data from our sensor and creates labeled track histories. In these track
- histories, each detection is labeled with its true track ID. The goal of the
- machine learning tools will then be to learn to associate all the detections with
- the same ID to the same track object.
- */
-
- track_history data;
-
- // At each time step we get a set of detections from the objects in the world.
- // Simulate 100 time steps worth of data where there are 3 objects present.
- const int num_time_steps = 100;
- for (int i = 0; i < num_time_steps; ++i)
- {
- detections_at_single_time_step dets(3);
- // sample a detection from object 0
- dets[0].det = sample_detection_from_sensor(0);
- dets[0].label = 0;
-
- // sample a detection from object 1
- dets[1].det = sample_detection_from_sensor(1);
- dets[1].label = 1;
-
- // sample a detection from object 2
- dets[2].det = sample_detection_from_sensor(2);
- dets[2].label = 2;
-
- data.push_back(dets);
- }
-
- // Now let's imagine object 1 and 2 are gone but a new object, object 3 has arrived.
- for (int i = 0; i < num_time_steps; ++i)
- {
- detections_at_single_time_step dets(2);
- // sample a detection from object 0
- dets[0].det = sample_detection_from_sensor(0);
- dets[0].label = 0;
-
- // sample a detection from object 3
- dets[1].det = sample_detection_from_sensor(3);
- dets[1].label = 3;
-
- data.push_back(dets);
- }
-
- return data;
-}
-
-// ----------------------------------------------------------------------------------------
-
-std::vector<detection> make_random_detections(long num_dets)
-{
- /*
- Finally, when we test the tracker we learned we will need to sample regular old
- unlabeled detections. This function helps us do that.
- */
- DLIB_CASSERT(num_dets <= num_objects,
- "You can't ask for more detections than there are objects in our little simulation.");
-
- std::vector<detection> dets(num_dets);
- for (unsigned long i = 0; i < dets.size(); ++i)
- {
- dets[i] = sample_detection_from_sensor(i);
- }
- return dets;
-}
-
-// ----------------------------------------------------------------------------------------
-
-int main()
-{
- initialize_object_properties();
-
-
- // Get some training data. Here we sample 5 independent track histories. In a real
- // world problem you would get this kind of data by, for example, collecting data from
- // your sensor on 5 separate days where you did an independent collection each day.
- // You can train a model with just one track history but the more you have the better.
- std::vector<track_history> data;
- data.push_back(make_random_tracking_data_for_training());
- data.push_back(make_random_tracking_data_for_training());
- data.push_back(make_random_tracking_data_for_training());
- data.push_back(make_random_tracking_data_for_training());
- data.push_back(make_random_tracking_data_for_training());
-
-
- structural_track_association_trainer trainer;
- // Note that the machine learning tools have a parameter. This is the usual SVM C
- // parameter that controls the trade-off between trying to fit the training data or
- // producing a "simpler" solution. You need to try a few different values of this
- // parameter to find out what setting works best for your problem (try values in the
- // range 0.001 to 1000000).
- trainer.set_c(100);
- // Now do the training.
- track_association_function<detection> assoc = trainer.train(data);
-
- // We can test the accuracy of the learned association function on some track history
- // data. Here we test it on the data we trained on. It outputs a single number that
- // measures the fraction of detections which were correctly associated to their tracks.
- // So a value of 1 indicates perfect tracking and a value of 0 indicates totally wrong
- // tracking.
- cout << "Association accuracy on training data: "<< test_track_association_function(assoc, data) << endl;
- // It's very important to test the output of a machine learning method on data it
- // wasn't trained on. You can do that by calling test_track_association_function() on
- // held out data. You can also use cross-validation like so:
- cout << "Association accuracy from 5-fold CV: "<< cross_validate_track_association_trainer(trainer, data, 5) << endl;
- // Unsurprisingly, the testing functions show that the assoc function we learned
- // perfectly associates all detections to tracks in this easy data.
-
-
-
-
- // OK. So how do you use this assoc thing? Let's use it to do some tracking!
-
- // tracks contains all our current tracks. Initially it is empty.
- std::vector<track> tracks;
- cout << "number of tracks: "<< tracks.size() << endl;
-
- // Sample detections from 3 objects.
- std::vector<detection> dets = make_random_detections(3);
- // Calling assoc(), the function we just learned, performs the detection to track
- // association. It will also call each track's update_track() function with the
- // associated detection. For tracks that don't get a detection, it calls
- // propagate_track().
- assoc(tracks, dets);
- // Now there are 3 things in tracks.
- cout << "number of tracks: "<< tracks.size() << endl;
-
- // Run the tracker for a few more time steps...
- dets = make_random_detections(3);
- assoc(tracks, dets);
- cout << "number of tracks: "<< tracks.size() << endl;
-
- dets = make_random_detections(3);
- assoc(tracks, dets);
- cout << "number of tracks: "<< tracks.size() << endl;
-
- // Now another object has appeared! There are 4 objects now.
- dets = make_random_detections(4);
- assoc(tracks, dets);
- // Now there are 4 tracks instead of 3!
- cout << "number of tracks: "<< tracks.size() << endl;
-
- // That 4th object just vanished. Let's look at the time_since_last_association values
- // for each track. We will see that one of the tracks isn't getting updated with
- // detections anymore since the object it corresponds to is no longer present.
- dets = make_random_detections(3);
- assoc(tracks, dets);
- cout << "number of tracks: "<< tracks.size() << endl;
- for (unsigned long i = 0; i < tracks.size(); ++i)
- cout << " time since last association: "<< tracks[i].time_since_last_association << endl;
-
- dets = make_random_detections(3);
- assoc(tracks, dets);
- cout << "number of tracks: "<< tracks.size() << endl;
- for (unsigned long i = 0; i < tracks.size(); ++i)
- cout << " time since last association: "<< tracks[i].time_since_last_association << endl;
-
-
-
-
-
-
- // Finally, you can save your track_association_function to disk like so:
- serialize("track_assoc.svm") << assoc;
-
- // And recall it from disk later like so:
- deserialize("track_assoc.svm") >> assoc;
-}
-
-// ----------------------------------------------------------------------------------------
-
diff --git a/ml/dlib/examples/least_squares_ex.cpp b/ml/dlib/examples/least_squares_ex.cpp
deleted file mode 100644
index 875790b2d..000000000
--- a/ml/dlib/examples/least_squares_ex.cpp
+++ /dev/null
@@ -1,228 +0,0 @@
-// The contents of this file are in the public domain. See LICENSE_FOR_EXAMPLE_PROGRAMS.txt
-/*
-
- This is an example illustrating the use the general purpose non-linear
- least squares optimization routines from the dlib C++ Library.
-
- This example program will demonstrate how these routines can be used for data fitting.
- In particular, we will generate a set of data and then use the least squares
- routines to infer the parameters of the model which generated the data.
-*/
-
-
-#include <dlib/optimization.h>
-#include <iostream>
-#include <vector>
-
-
-using namespace std;
-using namespace dlib;
-
-// ----------------------------------------------------------------------------------------
-
-typedef matrix<double,2,1> input_vector;
-typedef matrix<double,3,1> parameter_vector;
-
-// ----------------------------------------------------------------------------------------
-
-// We will use this function to generate data. It represents a function of 2 variables
-// and 3 parameters. The least squares procedure will be used to infer the values of
-// the 3 parameters based on a set of input/output pairs.
-double model (
- const input_vector& input,
- const parameter_vector& params
-)
-{
- const double p0 = params(0);
- const double p1 = params(1);
- const double p2 = params(2);
-
- const double i0 = input(0);
- const double i1 = input(1);
-
- const double temp = p0*i0 + p1*i1 + p2;
-
- return temp*temp;
-}
-
-// ----------------------------------------------------------------------------------------
-
-// This function is the "residual" for a least squares problem. It takes an input/output
-// pair and compares it to the output of our model and returns the amount of error. The idea
-// is to find the set of parameters which makes the residual small on all the data pairs.
-double residual (
- const std::pair<input_vector, double>& data,
- const parameter_vector& params
-)
-{
- return model(data.first, params) - data.second;
-}
-
-// ----------------------------------------------------------------------------------------
-
-// This function is the derivative of the residual() function with respect to the parameters.
-parameter_vector residual_derivative (
- const std::pair<input_vector, double>& data,
- const parameter_vector& params
-)
-{
- parameter_vector der;
-
- const double p0 = params(0);
- const double p1 = params(1);
- const double p2 = params(2);
-
- const double i0 = data.first(0);
- const double i1 = data.first(1);
-
- const double temp = p0*i0 + p1*i1 + p2;
-
- der(0) = i0*2*temp;
- der(1) = i1*2*temp;
- der(2) = 2*temp;
-
- return der;
-}
-
-// ----------------------------------------------------------------------------------------
-
-int main()
-{
- try
- {
- // randomly pick a set of parameters to use in this example
- const parameter_vector params = 10*randm(3,1);
- cout << "params: " << trans(params) << endl;
-
-
- // Now let's generate a bunch of input/output pairs according to our model.
- std::vector<std::pair<input_vector, double> > data_samples;
- input_vector input;
- for (int i = 0; i < 1000; ++i)
- {
- input = 10*randm(2,1);
- const double output = model(input, params);
-
- // save the pair
- data_samples.push_back(make_pair(input, output));
- }
-
- // Before we do anything, let's make sure that our derivative function defined above matches
- // the approximate derivative computed using central differences (via derivative()).
- // If this value is big then it means we probably typed the derivative function incorrectly.
- cout << "derivative error: " << length(residual_derivative(data_samples[0], params) -
- derivative(residual)(data_samples[0], params) ) << endl;
-
-
-
-
-
- // Now let's use the solve_least_squares_lm() routine to figure out what the
- // parameters are based on just the data_samples.
- parameter_vector x;
- x = 1;
-
- cout << "Use Levenberg-Marquardt" << endl;
- // Use the Levenberg-Marquardt method to determine the parameters which
- // minimize the sum of all squared residuals.
- solve_least_squares_lm(objective_delta_stop_strategy(1e-7).be_verbose(),
- residual,
- residual_derivative,
- data_samples,
- x);
-
- // Now x contains the solution. If everything worked it will be equal to params.
- cout << "inferred parameters: "<< trans(x) << endl;
- cout << "solution error: "<< length(x - params) << endl;
- cout << endl;
-
-
-
-
- x = 1;
- cout << "Use Levenberg-Marquardt, approximate derivatives" << endl;
- // If we didn't create the residual_derivative function then we could
- // have used this method which numerically approximates the derivatives for you.
- solve_least_squares_lm(objective_delta_stop_strategy(1e-7).be_verbose(),
- residual,
- derivative(residual),
- data_samples,
- x);
-
- // Now x contains the solution. If everything worked it will be equal to params.
- cout << "inferred parameters: "<< trans(x) << endl;
- cout << "solution error: "<< length(x - params) << endl;
- cout << endl;
-
-
-
-
- x = 1;
- cout << "Use Levenberg-Marquardt/quasi-newton hybrid" << endl;
- // This version of the solver uses a method which is appropriate for problems
- // where the residuals don't go to zero at the solution. So in these cases
- // it may provide a better answer.
- solve_least_squares(objective_delta_stop_strategy(1e-7).be_verbose(),
- residual,
- residual_derivative,
- data_samples,
- x);
-
- // Now x contains the solution. If everything worked it will be equal to params.
- cout << "inferred parameters: "<< trans(x) << endl;
- cout << "solution error: "<< length(x - params) << endl;
-
- }
- catch (std::exception& e)
- {
- cout << e.what() << endl;
- }
-}
-
-// Example output:
-/*
-params: 8.40188 3.94383 7.83099
-
-derivative error: 9.78267e-06
-Use Levenberg-Marquardt
-iteration: 0 objective: 2.14455e+10
-iteration: 1 objective: 1.96248e+10
-iteration: 2 objective: 1.39172e+10
-iteration: 3 objective: 1.57036e+09
-iteration: 4 objective: 2.66917e+07
-iteration: 5 objective: 4741.9
-iteration: 6 objective: 0.000238674
-iteration: 7 objective: 7.8815e-19
-iteration: 8 objective: 0
-inferred parameters: 8.40188 3.94383 7.83099
-
-solution error: 0
-
-Use Levenberg-Marquardt, approximate derivatives
-iteration: 0 objective: 2.14455e+10
-iteration: 1 objective: 1.96248e+10
-iteration: 2 objective: 1.39172e+10
-iteration: 3 objective: 1.57036e+09
-iteration: 4 objective: 2.66917e+07
-iteration: 5 objective: 4741.87
-iteration: 6 objective: 0.000238701
-iteration: 7 objective: 1.0571e-18
-iteration: 8 objective: 4.12469e-22
-inferred parameters: 8.40188 3.94383 7.83099
-
-solution error: 5.34754e-15
-
-Use Levenberg-Marquardt/quasi-newton hybrid
-iteration: 0 objective: 2.14455e+10
-iteration: 1 objective: 1.96248e+10
-iteration: 2 objective: 1.3917e+10
-iteration: 3 objective: 1.5572e+09
-iteration: 4 objective: 2.74139e+07
-iteration: 5 objective: 5135.98
-iteration: 6 objective: 0.000285539
-iteration: 7 objective: 1.15441e-18
-iteration: 8 objective: 3.38834e-23
-inferred parameters: 8.40188 3.94383 7.83099
-
-solution error: 1.77636e-15
-*/
diff --git a/ml/dlib/examples/linear_manifold_regularizer_ex.cpp b/ml/dlib/examples/linear_manifold_regularizer_ex.cpp
deleted file mode 100644
index 9c6f10f26..000000000
--- a/ml/dlib/examples/linear_manifold_regularizer_ex.cpp
+++ /dev/null
@@ -1,284 +0,0 @@
-// The contents of this file are in the public domain. See LICENSE_FOR_EXAMPLE_PROGRAMS.txt
-/*
-
- This is an example illustrating the use of the linear_manifold_regularizer
- and empirical_kernel_map from the dlib C++ Library.
-
- This example program assumes you are familiar with some general elements of
- the library. In particular, you should have at least read the svm_ex.cpp
- and matrix_ex.cpp examples. You should also have read the empirical_kernel_map_ex.cpp
- example program as the present example builds upon it.
-
-
-
- This program shows an example of what is called semi-supervised learning.
- That is, a small amount of labeled data is augmented with a large amount
- of unlabeled data. A learning algorithm is then run on all the data
- and the hope is that by including the unlabeled data we will end up with
- a better result.
-
-
- In this particular example we will generate 200,000 sample points of
- unlabeled data along with 2 samples of labeled data. The sample points
- will be drawn randomly from two concentric circles. One labeled data
- point will be drawn from each circle. The goal is to learn to
- correctly separate the two circles using only the 2 labeled points
- and the unlabeled data.
-
- To do this we will first run an approximate form of k nearest neighbors
- to determine which of the unlabeled samples are closest together. We will
- then make the manifold assumption, that is, we will assume that points close
- to each other should share the same classification label.
-
- Once we have determined which points are near neighbors we will use the
- empirical_kernel_map and linear_manifold_regularizer to transform all the
- data points into a new vector space where any linear rule will have similar
- output for points which we have decided are near neighbors.
-
- Finally, we will classify all the unlabeled data according to which of
- the two labeled points are nearest. Normally this would not work but by
- using the manifold assumption we will be able to successfully classify
- all the unlabeled data.
-
-
-
- For further information on this subject you should begin with the following
- paper as it discusses a very similar application of manifold regularization.
-
- Beyond the Point Cloud: from Transductive to Semi-supervised Learning
- by Vikas Sindhwani, Partha Niyogi, and Mikhail Belkin
-
-
-
-
- ******** SAMPLE PROGRAM OUTPUT ********
-
- Testing manifold regularization with an intrinsic_regularization_strength of 0.
- number of edges generated: 49998
- Running simple test...
- error: 0.37022
- error: 0.44036
- error: 0.376715
- error: 0.307545
- error: 0.463455
- error: 0.426065
- error: 0.416155
- error: 0.288295
- error: 0.400115
- error: 0.46347
-
- Testing manifold regularization with an intrinsic_regularization_strength of 10000.
- number of edges generated: 49998
- Running simple test...
- error: 0
- error: 0
- error: 0
- error: 0
- error: 0
- error: 0
- error: 0
- error: 0
- error: 0
- error: 0
-
-
-*/
-
-#include <dlib/manifold_regularization.h>
-#include <dlib/svm.h>
-#include <dlib/rand.h>
-#include <dlib/statistics.h>
-#include <iostream>
-#include <vector>
-#include <ctime>
-
-
-using namespace std;
-using namespace dlib;
-
-// ----------------------------------------------------------------------------------------
-
-// First let's make a typedef for the kind of samples we will be using.
-typedef matrix<double, 0, 1> sample_type;
-
-// We will be using the radial_basis_kernel in this example program.
-typedef radial_basis_kernel<sample_type> kernel_type;
-
-// ----------------------------------------------------------------------------------------
-
-void generate_circle (
- std::vector<sample_type>& samples,
- double radius,
- const long num
-);
-/*!
- requires
- - num > 0
- - radius > 0
- ensures
- - generates num points centered at (0,0) with the given radius. Adds these
- points into the given samples vector.
-!*/
-
-// ----------------------------------------------------------------------------------------
-
-void test_manifold_regularization (
- const double intrinsic_regularization_strength
-);
-/*!
- ensures
- - Runs an example test using the linear_manifold_regularizer with the given
- intrinsic_regularization_strength.
-!*/
-
-// ----------------------------------------------------------------------------------------
-
-int main()
-{
- // Run the test without any manifold regularization.
- test_manifold_regularization(0);
-
- // Run the test with manifold regularization. You can think of this number as
- // a measure of how much we trust the manifold assumption. So if you are really
- // confident that you can select neighboring points which should have the same
- // classification then make this number big.
- test_manifold_regularization(10000.0);
-}
-
-// ----------------------------------------------------------------------------------------
-
-void test_manifold_regularization (
- const double intrinsic_regularization_strength
-)
-{
- cout << "Testing manifold regularization with an intrinsic_regularization_strength of "
- << intrinsic_regularization_strength << ".\n";
-
- std::vector<sample_type> samples;
-
- // Declare an instance of the kernel we will be using.
- const kernel_type kern(0.1);
-
- const unsigned long num_points = 100000;
-
- // create a large dataset with two concentric circles. There will be 100000 points on each circle
- // for a total of 200000 samples.
- generate_circle(samples, 2, num_points); // circle of radius 2
- generate_circle(samples, 4, num_points); // circle of radius 4
-
- // Create a set of sample_pairs that tells us which samples are "close" and should thus
- // be classified similarly. These edges will be used to define the manifold regularizer.
- // To find these edges we use a simple function that samples point pairs randomly and
- // returns the top 5% with the shortest edges.
- std::vector<sample_pair> edges;
- find_percent_shortest_edges_randomly(samples, squared_euclidean_distance(), 0.05, 1000000, time(0), edges);
-
- cout << "number of edges generated: " << edges.size() << endl;
-
- empirical_kernel_map<kernel_type> ekm;
-
- // Since the circles are not linearly separable we will use an empirical kernel map to
- // map them into a space where they are separable. We create an empirical_kernel_map
- // using a random subset of our data samples as basis samples. Note, however, that even
- // though the circles are linearly separable in this new space given by the empirical_kernel_map
- // we still won't be able to correctly classify all the points given just the 2 labeled examples.
- // We will need to make use of the nearest neighbor information stored in edges. To do that
- // we will use the linear_manifold_regularizer.
- ekm.load(kern, randomly_subsample(samples, 50));
-
- // Project all the samples into the span of our 50 basis samples
- for (unsigned long i = 0; i < samples.size(); ++i)
- samples[i] = ekm.project(samples[i]);
-
-
- // Now create the manifold regularizer. The result is a transformation matrix that
- // embodies the manifold assumption discussed above.
- linear_manifold_regularizer<sample_type> lmr;
- // use_gaussian_weights is a function object that tells lmr how to weight each edge. In this
- // case we let the weight decay as edges get longer. So shorter edges are more important than
- // longer edges.
- lmr.build(samples, edges, use_gaussian_weights(0.1));
- const matrix<double> T = lmr.get_transformation_matrix(intrinsic_regularization_strength);
-
- // Apply the transformation generated by the linear_manifold_regularizer to
- // all our samples.
- for (unsigned long i = 0; i < samples.size(); ++i)
- samples[i] = T*samples[i];
-
-
- // For convenience, generate a projection_function and merge the transformation
- // matrix T into it. That is, we will have: proj(x) == T*ekm.project(x).
- projection_function<kernel_type> proj = ekm.get_projection_function();
- proj.weights = T*proj.weights;
-
- cout << "Running simple test..." << endl;
-
- // Pick 2 different labeled points. One on the inner circle and another on the outer.
- // For each of these test points we will see if using the single plane that separates
- // them is a good way to separate the concentric circles. We also do this a bunch
- // of times with different randomly chosen points so we can see how robust the result is.
- for (int itr = 0; itr < 10; ++itr)
- {
- std::vector<sample_type> test_points;
- // generate a random point from the radius 2 circle
- generate_circle(test_points, 2, 1);
- // generate a random point from the radius 4 circle
- generate_circle(test_points, 4, 1);
-
- // project the two test points into kernel space. Recall that this projection_function
- // has the manifold regularizer incorporated into it.
- const sample_type class1_point = proj(test_points[0]);
- const sample_type class2_point = proj(test_points[1]);
-
- double num_wrong = 0;
-
- // Now attempt to classify all the data samples according to which point
- // they are closest to. The output of this program shows that without manifold
- // regularization this test will fail but with it it will perfectly classify
- // all the points.
- for (unsigned long i = 0; i < samples.size(); ++i)
- {
- double distance_to_class1 = length(samples[i] - class1_point);
- double distance_to_class2 = length(samples[i] - class2_point);
-
- bool predicted_as_class_1 = (distance_to_class1 < distance_to_class2);
-
- bool really_is_class_1 = (i < num_points);
-
- // now count how many times we make a mistake
- if (predicted_as_class_1 != really_is_class_1)
- ++num_wrong;
- }
-
- cout << "error: "<< num_wrong/samples.size() << endl;
- }
-
- cout << endl;
-}
-
-// ----------------------------------------------------------------------------------------
-
-dlib::rand rnd;
-
-void generate_circle (
- std::vector<sample_type>& samples,
- double radius,
- const long num
-)
-{
- sample_type m(2,1);
-
- for (long i = 0; i < num; ++i)
- {
- double sign = 1;
- if (rnd.get_random_double() < 0.5)
- sign = -1;
- m(0) = 2*radius*rnd.get_random_double()-radius;
- m(1) = sign*sqrt(radius*radius - m(0)*m(0));
-
- samples.push_back(m);
- }
-}
-
-// ----------------------------------------------------------------------------------------
-
diff --git a/ml/dlib/examples/logger_custom_output_ex.cpp b/ml/dlib/examples/logger_custom_output_ex.cpp
deleted file mode 100644
index 6916e43de..000000000
--- a/ml/dlib/examples/logger_custom_output_ex.cpp
+++ /dev/null
@@ -1,73 +0,0 @@
-// The contents of this file are in the public domain. See LICENSE_FOR_EXAMPLE_PROGRAMS.txt
-
-/*
-
- This is an example showing how to control where the dlib::logger sends its messages.
- This is done by creating a "hook" class that is called whenever any of the loggers want
- to log a message. The hook class then outputs the messages using any method you like.
-
-
- Prior to reading this example, you should understand the basics of the dlib::logger.
- So you should have already read the logger_ex.cpp and logger_ex_2.cpp example programs.
-
-*/
-
-
-#include <dlib/logger.h>
-
-using namespace dlib;
-using namespace std;
-
-class my_hook
-{
-public:
- my_hook(
- )
- {
- fout.open("my_log_file.txt");
- }
-
- void log (
- const string& logger_name,
- const log_level& ll,
- const uint64 thread_id,
- const char* message_to_log
- )
- {
- // Log all messages from any logger to our log file.
- fout << ll << " ["<<thread_id<<"] " << logger_name << ": " << message_to_log << endl;
-
- // But only log messages that are of LINFO priority or higher to the console.
- if (ll >= LINFO)
- cout << ll << " ["<<thread_id<<"] " << logger_name << ": " << message_to_log << endl;
- }
-
-private:
- ofstream fout;
-};
-
-int main()
-{
- my_hook hook;
- // This tells all dlib loggers to send their logging events to the hook object. That
- // is, any time a logger generates a message it will call hook.log() with the message
- // contents. Additionally, hook.log() will also only be called from one thread at a
- // time so it is safe to use this kind of hook in a multi-threaded program with many
- // loggers in many threads.
- set_all_logging_output_hooks(hook);
- // It should also be noted that the hook object must not be destructed while the
- // loggers are still in use. So it is a good idea to declare the hook object
- // somewhere where it will live the entire lifetime of the program, as we do here.
-
-
- logger dlog("main");
- // Tell the dlog logger to emit a message for all logging events rather than its
- // default behavior of only logging LERROR or above.
- dlog.set_level(LALL);
-
- // All these message go to my_log_file.txt, but only the last two go to the console.
- dlog << LDEBUG << "This is a debugging message.";
- dlog << LINFO << "This is an informational message.";
- dlog << LERROR << "An error message!";
-}
-
diff --git a/ml/dlib/examples/logger_ex.cpp b/ml/dlib/examples/logger_ex.cpp
deleted file mode 100644
index 281e2ad16..000000000
--- a/ml/dlib/examples/logger_ex.cpp
+++ /dev/null
@@ -1,70 +0,0 @@
-// The contents of this file are in the public domain. See LICENSE_FOR_EXAMPLE_PROGRAMS.txt
-
-/*
-
- This is a simple example illustrating the use of the logger object from
- the dlib C++ Library.
-
-
- The output of this program looks like this:
-
- 0 INFO [0] example: This is an informational message.
- 0 DEBUG [0] example: The integer variable is set to 8
- 0 WARN [0] example: The variable is bigger than 4! Its value is 8
- 0 INFO [0] example: we are going to sleep for half a second.
- 503 INFO [0] example: we just woke up
- 503 INFO [0] example: program ending
-
-
- The first column shows the number of milliseconds since program start at the time
- the message was printed, then the logging level of the message, then the thread that
- printed the message, then the logger's name and finally the message itself.
-
-*/
-
-
-#include <dlib/logger.h>
-#include <dlib/misc_api.h>
-
-using namespace dlib;
-
-// Create a logger object somewhere. It is usually convenient to make it at the global scope
-// which is what I am doing here. The following statement creates a logger that is named example.
-logger dlog("example");
-
-int main()
-{
- // Every logger has a logging level (given by dlog.level()). Each log message is tagged with a
- // level and only levels equal to or higher than dlog.level() will be printed. By default all
- // loggers start with level() == LERROR. In this case I'm going to set the lowest level LALL
- // which means that dlog will print all logging messages it gets.
- dlog.set_level(LALL);
-
-
- // print our first message. It will go to cout because that is the default.
- dlog << LINFO << "This is an informational message.";
-
- // now print a debug message.
- int variable = 8;
- dlog << LDEBUG << "The integer variable is set to " << variable;
-
- // the logger can be used pretty much like any ostream object. But you have to give a logging
- // level first. But after that you can chain << operators like normal.
-
- if (variable > 4)
- dlog << LWARN << "The variable is bigger than 4! Its value is " << variable;
-
-
-
- dlog << LINFO << "we are going to sleep for half a second.";
- // sleep for half a second
- dlib::sleep(500);
- dlog << LINFO << "we just woke up";
-
-
-
- dlog << LINFO << "program ending";
-}
-
-
-
diff --git a/ml/dlib/examples/logger_ex_2.cpp b/ml/dlib/examples/logger_ex_2.cpp
deleted file mode 100644
index 99332bffc..000000000
--- a/ml/dlib/examples/logger_ex_2.cpp
+++ /dev/null
@@ -1,153 +0,0 @@
-// The contents of this file are in the public domain. See LICENSE_FOR_EXAMPLE_PROGRAMS.txt
-
-/*
-
- This is a somewhat complex example illustrating the use of the logger object
- from the dlib C++ Library. It will demonstrate using multiple loggers and threads.
-
-
- The output of this program looks like this:
- 0 INFO [0] example: This is an informational message.
- 0 WARN [0] example: The variable is bigger than 4! Its value is 8
- 0 INFO [0] example: make two threads
- 0 WARN [0] example.test_class: warning! someone called warning()!
- 0 INFO [0] example: we are going to sleep for half a second.
- 0 INFO [1] example.thread: entering our thread
- 0 WARN [1] example.test_class: warning! someone called warning()!
- 0 INFO [2] example.thread: entering our thread
- 0 WARN [2] example.test_class: warning! someone called warning()!
- 203 INFO [1] example.thread: exiting our thread
- 203 INFO [2] example.thread: exiting our thread
- 503 INFO [0] example: we just woke up
- 503 INFO [0] example: program ending
-
-
-*/
-
-
-#include <dlib/logger.h>
-#include <dlib/misc_api.h>
-#include <dlib/threads.h>
-
-using namespace dlib;
-
-/*
- Here we create three loggers. Note that it is the case that:
- - logp.is_child_of(logp) == true
- - logt.is_child_of(logp) == true
- - logc.is_child_of(logp) == true
-
- logp is the child of itself because all loggers are their own children :) But the other
- two are child loggers of logp because their names start with logp.name() + "." which means
- that whenever you set a property on a logger it will also set that same property on all of
- the logger's children.
-*/
-logger logp("example");
-logger logt("example.thread");
-logger logc("example.test_class");
-
-class test
-{
-public:
- test ()
- {
- // this message won't get logged because LINFO is too low
- logc << LINFO << "constructed a test object";
- }
-
- ~test ()
- {
- // this message won't get logged because LINFO is too low
- logc << LINFO << "destructed a test object";
- }
-
- void warning ()
- {
- logc << LWARN << "warning! someone called warning()!";
- }
-};
-
-void thread (void*)
-{
- logt << LINFO << "entering our thread";
-
-
- test mytest;
- mytest.warning();
-
- dlib::sleep(200);
-
- logt << LINFO << "exiting our thread";
-}
-
-
-void setup_loggers (
-)
-{
- // Create a logger that has the same name as our root logger logp. This isn't very useful in
- // this example program but if you had loggers defined in other files then you might not have
- // easy access to them when starting up your program and setting log levels. This mechanism
- // allows you to manipulate the properties of any logger so long as you know its name.
- logger temp_log("example");
-
- // For this example I don't want to log debug messages so I'm setting the logging level of
- // All our loggers to LINFO. Note that this statement sets all three of our loggers to this
- // logging level because they are all children of temp_log.
- temp_log.set_level(LINFO);
-
-
- // In addition I only want the example.test_class to print LWARN or higher messages so I'm going
- // to set that here too. Note that we set this value after calling temp_log.set_level(). If we
- // did it the other way around the set_level() call on temp_log would set logc_temp.level() and
- // logc.level() back to LINFO since temp_log is a parent of logc_temp.
- logger logc_temp("example.test_class");
- logc_temp.set_level(LWARN);
-
-
- // Finally, note that you can also configure your loggers from a text config file.
- // See the documentation for the configure_loggers_from_file() function for details.
-}
-
-int main()
-{
- setup_loggers();
-
- // print our first message. It will go to cout because that is the default.
- logp << LINFO << "This is an informational message.";
-
- int variable = 8;
-
- // Here is a debug message. It won't print though because its log level is too low (it is below LINFO).
- logp << LDEBUG << "The integer variable is set to " << variable;
-
-
- if (variable > 4)
- logp << LWARN << "The variable is bigger than 4! Its value is " << variable;
-
- logp << LINFO << "make two threads";
- create_new_thread(thread,0);
- create_new_thread(thread,0);
-
- test mytest;
- mytest.warning();
-
- logp << LINFO << "we are going to sleep for half a second.";
- // sleep for half a second
- dlib::sleep(500);
- logp << LINFO << "we just woke up";
-
-
-
- logp << LINFO << "program ending";
-
-
- // It is also worth pointing out that the logger messages are atomic. This means, for example, that
- // in the above log statements that involve a string literal and a variable, no other thread can
- // come in and print a log message in-between the literal string and the variable. This is good
- // because it means your messages don't get corrupted. However, this also means that you shouldn't
- // make any function calls inside a logging statement if those calls might try to log a message
- // themselves since the atomic nature of the logger would cause your application to deadlock.
-}
-
-
-
diff --git a/ml/dlib/examples/matrix_ex.cpp b/ml/dlib/examples/matrix_ex.cpp
deleted file mode 100644
index a56dbfbb2..000000000
--- a/ml/dlib/examples/matrix_ex.cpp
+++ /dev/null
@@ -1,276 +0,0 @@
-// The contents of this file are in the public domain. See LICENSE_FOR_EXAMPLE_PROGRAMS.txt
-
-/*
- This is an example illustrating the use of the matrix object
- from the dlib C++ Library.
-*/
-
-
-#include <iostream>
-#include <dlib/matrix.h>
-
-using namespace dlib;
-using namespace std;
-
-// ----------------------------------------------------------------------------------------
-
-int main()
-{
- // Let's begin this example by using the library to solve a simple
- // linear system.
- //
- // We will find the value of x such that y = M*x where
- //
- // 3.5
- // y = 1.2
- // 7.8
- //
- // and M is
- //
- // 54.2 7.4 12.1
- // M = 1 2 3
- // 5.9 0.05 1
-
-
- // First let's declare these 3 matrices.
- // This declares a matrix that contains doubles and has 3 rows and 1 column.
- // Moreover, it's size is a compile time constant since we put it inside the <>.
- matrix<double,3,1> y;
- // Make a 3 by 3 matrix of doubles for the M matrix. In this case, M is
- // sized at runtime and can therefore be resized later by calling M.set_size().
- matrix<double> M(3,3);
-
- // You may be wondering why someone would want to specify the size of a
- // matrix at compile time when you don't have to. The reason is two fold.
- // First, there is often a substantial performance improvement, especially
- // for small matrices, because it enables a number of optimizations that
- // otherwise would be impossible. Second, the dlib::matrix object checks
- // these compile time sizes to ensure that the matrices are being used
- // correctly. For example, if you attempt to compile the expression y*y you
- // will get a compiler error since that is not a legal matrix operation (the
- // matrix dimensions don't make sense as a matrix multiplication). So if
- // you know the size of a matrix at compile time then it is always a good
- // idea to let the compiler know about it.
-
-
-
-
- // Now we need to initialize the y and M matrices and we can do so like this:
- M = 54.2, 7.4, 12.1,
- 1, 2, 3,
- 5.9, 0.05, 1;
-
- y = 3.5,
- 1.2,
- 7.8;
-
-
- // The solution to y = M*x can be obtained by multiplying the inverse of M
- // with y. As an aside, you should *NEVER* use the auto keyword to capture
- // the output from a matrix expression. So don't do this: auto x = inv(M)*y;
- // To understand why, read the matrix_expressions_ex.cpp example program.
- matrix<double> x = inv(M)*y;
-
- cout << "x: \n" << x << endl;
-
- // We can check that it really worked by plugging x back into the original equation
- // and subtracting y to see if we get a column vector with values all very close
- // to zero (Which is what happens. Also, the values may not be exactly zero because
- // there may be some numerical error and round off).
- cout << "M*x - y: \n" << M*x - y << endl;
-
-
- // Also note that we can create run-time sized column or row vectors like so
- matrix<double,0,1> runtime_sized_column_vector;
- matrix<double,1,0> runtime_sized_row_vector;
- // and then they are sized by saying
- runtime_sized_column_vector.set_size(3);
-
- // Similarly, the x matrix can be resized by calling set_size(num rows, num columns). For example
- x.set_size(3,4); // x now has 3 rows and 4 columns.
-
-
-
- // The elements of a matrix are accessed using the () operator like so:
- cout << M(0,1) << endl;
- // The above expression prints out the value 7.4. That is, the value of
- // the element at row 0 and column 1.
-
- // If we have a matrix that is a row or column vector. That is, it contains either
- // a single row or a single column then we know that any access is always either
- // to row 0 or column 0 so we can omit that 0 and use the following syntax.
- cout << y(1) << endl;
- // The above expression prints out the value 1.2
-
-
- // Let's compute the sum of elements in the M matrix.
- double M_sum = 0;
- // loop over all the rows
- for (long r = 0; r < M.nr(); ++r)
- {
- // loop over all the columns
- for (long c = 0; c < M.nc(); ++c)
- {
- M_sum += M(r,c);
- }
- }
- cout << "sum of all elements in M is " << M_sum << endl;
-
- // The above code is just to show you how to loop over the elements of a matrix. An
- // easier way to find this sum is to do the following:
- cout << "sum of all elements in M is " << sum(M) << endl;
-
-
-
-
- // Note that you can always print a matrix to an output stream by saying:
- cout << M << endl;
- // which will print:
- // 54.2 7.4 12.1
- // 1 2 3
- // 5.9 0.05 1
-
- // However, if you want to print using comma separators instead of spaces you can say:
- cout << csv << M << endl;
- // and you will instead get this as output:
- // 54.2, 7.4, 12.1
- // 1, 2, 3
- // 5.9, 0.05, 1
-
- // Conversely, you can also read in a matrix that uses either space, tab, or comma
- // separated values by uncommenting the following:
- // cin >> M;
-
-
-
- // ----------------------------- Comparison with MATLAB ------------------------------
- // Here I list a set of Matlab commands and their equivalent expressions using the dlib
- // matrix. Note that there are a lot more functions defined for the dlib::matrix. See
- // the HTML documentation for a full listing.
-
- matrix<double> A, B, C, D, E;
- matrix<int> Aint;
- matrix<long> Blong;
-
- // MATLAB: A = eye(3)
- A = identity_matrix<double>(3);
-
- // MATLAB: B = ones(3,4)
- B = ones_matrix<double>(3,4);
-
- // MATLAB: B = rand(3,4)
- B = randm(3,4);
-
- // MATLAB: C = 1.4*A
- C = 1.4*A;
-
- // MATLAB: D = A.*C
- D = pointwise_multiply(A,C);
-
- // MATLAB: E = A * B
- E = A*B;
-
- // MATLAB: E = A + B
- E = A + C;
-
- // MATLAB: E = A + 5
- E = A + 5;
-
- // MATLAB: E = E'
- E = trans(E); // Note that if you want a conjugate transpose then you need to say conj(trans(E))
-
- // MATLAB: E = B' * B
- E = trans(B)*B;
-
- double var;
- // MATLAB: var = A(1,2)
- var = A(0,1); // dlib::matrix is 0 indexed rather than starting at 1 like Matlab.
-
- // MATLAB: C = round(C)
- C = round(C);
-
- // MATLAB: C = floor(C)
- C = floor(C);
-
- // MATLAB: C = ceil(C)
- C = ceil(C);
-
- // MATLAB: C = diag(B)
- C = diag(B);
-
- // MATLAB: B = cast(A, "int32")
- Aint = matrix_cast<int>(A);
-
- // MATLAB: A = B(1,:)
- A = rowm(B,0);
-
- // MATLAB: A = B([1:2],:)
- A = rowm(B,range(0,1));
-
- // MATLAB: A = B(:,1)
- A = colm(B,0);
-
- // MATLAB: A = [1:5]
- Blong = range(1,5);
-
- // MATLAB: A = [1:2:5]
- Blong = range(1,2,5);
-
- // MATLAB: A = B([1:3], [1:2])
- A = subm(B, range(0,2), range(0,1));
- // or equivalently
- A = subm(B, rectangle(0,0,1,2));
-
-
- // MATLAB: A = B([1:3], [1:2:4])
- A = subm(B, range(0,2), range(0,2,3));
-
- // MATLAB: B(:,:) = 5
- B = 5;
- // or equivalently
- set_all_elements(B,5);
-
-
- // MATLAB: B([1:2],[1,2]) = 7
- set_subm(B,range(0,1), range(0,1)) = 7;
-
- // MATLAB: B([1:3],[2:3]) = A
- set_subm(B,range(0,2), range(1,2)) = A;
-
- // MATLAB: B(:,1) = 4
- set_colm(B,0) = 4;
-
- // MATLAB: B(:,[1:2]) = 4
- set_colm(B,range(0,1)) = 4;
-
- // MATLAB: B(:,1) = B(:,2)
- set_colm(B,0) = colm(B,1);
-
- // MATLAB: B(1,:) = 4
- set_rowm(B,0) = 4;
-
- // MATLAB: B(1,:) = B(2,:)
- set_rowm(B,0) = rowm(B,1);
-
- // MATLAB: var = det(E' * E)
- var = det(trans(E)*E);
-
- // MATLAB: C = pinv(E)
- C = pinv(E);
-
- // MATLAB: C = inv(E)
- C = inv(E);
-
- // MATLAB: [A,B,C] = svd(E)
- svd(E,A,B,C);
-
- // MATLAB: A = chol(E,'lower')
- A = chol(E);
-
- // MATLAB: var = min(min(A))
- var = min(A);
-}
-
-// ----------------------------------------------------------------------------------------
-
-
diff --git a/ml/dlib/examples/matrix_expressions_ex.cpp b/ml/dlib/examples/matrix_expressions_ex.cpp
deleted file mode 100644
index b52370907..000000000
--- a/ml/dlib/examples/matrix_expressions_ex.cpp
+++ /dev/null
@@ -1,406 +0,0 @@
-// The contents of this file are in the public domain. See LICENSE_FOR_EXAMPLE_PROGRAMS.txt
-
-/*
- This example contains a detailed discussion of the template expression
- technique used to implement the matrix tools in the dlib C++ library.
-
- It also gives examples showing how a user can create their own custom
- matrix expressions.
-
- Note that you should be familiar with the dlib::matrix before reading
- this example. So if you haven't done so already you should read the
- matrix_ex.cpp example program.
-*/
-
-
-#include <iostream>
-#include <dlib/matrix.h>
-
-using namespace dlib;
-using namespace std;
-
-// ----------------------------------------------------------------------------------------
-
-void custom_matrix_expressions_example();
-
-// ----------------------------------------------------------------------------------------
-
-int main()
-{
-
- // Declare some variables used below
- matrix<double,3,1> y;
- matrix<double,3,3> M;
- matrix<double> x;
-
- // set all elements to 1
- y = 1;
- M = 1;
-
-
- // ------------------------- Template Expressions -----------------------------
- // Now I will discuss the "template expressions" technique and how it is
- // used in the matrix object. First consider the following expression:
- x = y + y;
-
- /*
- Normally this expression results in machine code that looks, at a high
- level, like the following:
- temp = y + y;
- x = temp
-
- Temp is a temporary matrix returned by the overloaded + operator.
- temp then contains the result of adding y to itself. The assignment
- operator copies the value of temp into x and temp is then destroyed while
- the blissful C++ user never sees any of this.
-
- This is, however, totally inefficient. In the process described above
- you have to pay for the cost of constructing a temporary matrix object
- and allocating its memory. Then you pay the additional cost of copying
- it over to x. It also gets worse when you have more complex expressions
- such as x = round(y + y + y + M*y) which would involve the creation and copying
- of 5 temporary matrices.
-
- All these inefficiencies are removed by using the template expressions
- technique. The basic idea is as follows, instead of having operators and
- functions return temporary matrix objects you return a special object that
- represents the expression you wish to perform.
-
- So consider the expression x = y + y again. With dlib::matrix what happens
- is the expression y+y returns a matrix_exp object instead of a temporary matrix.
- The construction of a matrix_exp does not allocate any memory or perform any
- computations. The matrix_exp however has an interface that looks just like a
- dlib::matrix object and when you ask it for the value of one of its elements
- it computes that value on the spot. Only in the assignment operator does
- someone ask the matrix_exp for these values so this avoids the use of any
- temporary matrices. Thus the statement x = y + y is equivalent to the following
- code:
- // loop over all elements in y matrix
- for (long r = 0; r < y.nr(); ++r)
- for (long c = 0; c < y.nc(); ++c)
- x(r,c) = y(r,c) + y(r,c);
-
-
- This technique works for expressions of arbitrary complexity. So if you typed
- x = round(y + y + y + M*y) it would involve no temporary matrices being created
- at all. Each operator takes and returns only matrix_exp objects. Thus, no
- computations are performed until the assignment operator requests the values
- from the matrix_exp it receives as input. This also means that statements such as:
- auto x = round(y + y + y + M*y)
- will not work properly because x would be a matrix expression that references
- parts of the expression round(y + y + y + M*y) but those expression parts will
- immediately go out of scope so x will contain references to non-existing sub
- matrix expressions. This is very bad, so you should never use auto to store
- the result of a matrix expression. Always store the output in a matrix object
- like so:
- matrix<double> x = round(y + y + y + M*y)
-
-
-
-
- In terms of implementation, there is a slight complication in all of this. It
- is for statements that involve the multiplication of a complex matrix_exp such
- as the following:
- */
- x = M*(M+M+M+M+M+M+M);
- /*
- According to the discussion above, this statement would compute the value of
- M*(M+M+M+M+M+M+M) totally without any temporary matrix objects. This sounds
- good but we should take a closer look. Consider that the + operator is
- invoked 6 times. This means we have something like this:
-
- x = M * (matrix_exp representing M+M+M+M+M+M+M);
-
- M is being multiplied with a quite complex matrix_exp. Now recall that when
- you ask a matrix_exp what the value of any of its elements are it computes
- their values *right then*.
-
- If you think on what is involved in performing a matrix multiply you will
- realize that each element of a matrix is accessed M.nr() times. In the
- case of our above expression the cost of accessing an element of the
- matrix_exp on the right hand side is the cost of doing 6 addition operations.
-
- Thus, it would be faster to assign M+M+M+M+M+M+M to a temporary matrix and then
- multiply that by M. This is exactly what the dlib::matrix does under the covers.
- This is because it is able to spot expressions where the introduction of a
- temporary is needed to speed up the computation and it will automatically do this
- for you.
-
-
-
-
- Another complication that is dealt with automatically is aliasing. All matrix
- expressions are said to "alias" their contents. For example, consider
- the following expressions:
- M + M
- M * M
-
- We say that the expressions (M + M) and (M * M) alias M. Additionally, we say that
- the expression (M * M) destructively aliases M.
-
- To understand why we say (M * M) destructively aliases M consider what would happen
- if we attempted to evaluate it without first assigning (M * M) to a temporary matrix.
- That is, if we attempted to perform the following:
- for (long r = 0; r < M.nr(); ++r)
- for (long c = 0; c < M.nc(); ++c)
- M(r,c) = rowm(M,r)*colm(M,c);
-
- It is clear that the result would be corrupted and M wouldn't end up with the right
- values in it. So in this case we must perform the following:
- temp = M*M;
- M = temp;
-
- This sort of interaction is what defines destructive aliasing. Whenever we are
- assigning a matrix expression to a destination that is destructively aliased by
- the expression we need to introduce a temporary. The dlib::matrix is capable of
- recognizing the two forms of aliasing and introduces temporary matrices only when
- necessary.
- */
-
-
-
- // Next we discuss how to create custom matrix expressions. In what follows we
- // will define three different matrix expressions and show their use.
- custom_matrix_expressions_example();
-}
-
-// ----------------------------------------------------------------------------------------
-// ----------------------------------------------------------------------------------------
-// ----------------------------------------------------------------------------------------
-
-template <typename M>
-struct example_op_trans
-{
- /*!
- This object defines a matrix expression that represents a transposed matrix.
- As discussed above, constructing this object doesn't compute anything. It just
- holds a reference to a matrix and presents an interface which defines
- matrix transposition.
- !*/
-
- // Here we simply hold a reference to the matrix we are supposed to be the transpose of.
- example_op_trans( const M& m_) : m(m_){}
- const M& m;
-
- // The cost field is used by matrix multiplication code to decide if a temporary needs to
- // be introduced. It represents the computational cost of evaluating an element of the
- // matrix expression. In this case we say that the cost of obtaining an element of the
- // transposed matrix is the same as obtaining an element of the original matrix (since
- // transpose doesn't really compute anything).
- const static long cost = M::cost;
-
- // Here we define the matrix expression's compile-time known dimensions. Since this
- // is a transpose we define them to be the reverse of M's dimensions.
- const static long NR = M::NC;
- const static long NC = M::NR;
-
- // Define the type of element in this matrix expression. Also define the
- // memory manager type used and the layout. Usually we use the same types as the
- // input matrix.
- typedef typename M::type type;
- typedef typename M::mem_manager_type mem_manager_type;
- typedef typename M::layout_type layout_type;
-
- // This is where the action is. This function is what defines the value of an element of
- // this matrix expression. Here we are saying that m(c,r) == trans(m)(r,c) which is just
- // the definition of transposition. Note also that we must define the return type from this
- // function as a typedef. This typedef lets us either return our argument by value or by
- // reference. In this case we use the same type as the underlying m matrix. Later in this
- // example program you will see two other options.
- typedef typename M::const_ret_type const_ret_type;
- const_ret_type apply (long r, long c) const { return m(c,r); }
-
- // Define the run-time defined dimensions of this matrix.
- long nr () const { return m.nc(); }
- long nc () const { return m.nr(); }
-
- // Recall the discussion of aliasing. Each matrix expression needs to define what
- // kind of aliasing it introduces so that we know when to introduce temporaries. The
- // aliases() function indicates that the matrix transpose expression aliases item if
- // and only if the m matrix aliases item.
- template <typename U> bool aliases ( const matrix_exp<U>& item) const { return m.aliases(item); }
- // This next function indicates that the matrix transpose expression also destructively
- // aliases anything m aliases. I.e. transpose has destructive aliasing.
- template <typename U> bool destructively_aliases ( const matrix_exp<U>& item) const { return m.aliases(item); }
-
-};
-
-
-// Here we define a simple function that creates and returns transpose expressions. Note that the
-// matrix_op<> template is a matrix_exp object and exists solely to reduce the amount of boilerplate
-// you have to write to create a matrix expression.
-template < typename M >
-const matrix_op<example_op_trans<M> > example_trans (
- const matrix_exp<M>& m
-)
-{
- typedef example_op_trans<M> op;
- // m.ref() returns a reference to the object of type M contained in the matrix expression m.
- return matrix_op<op>(op(m.ref()));
-}
-
-// ----------------------------------------------------------------------------------------
-
-template <typename T>
-struct example_op_vector_to_matrix
-{
- /*!
- This object defines a matrix expression that holds a reference to a std::vector<T>
- and makes it look like a column vector. Thus it enables you to use a std::vector
- as if it was a dlib::matrix.
-
- !*/
- example_op_vector_to_matrix( const std::vector<T>& vect_) : vect(vect_){}
-
- const std::vector<T>& vect;
-
- // This expression wraps direct memory accesses so we use the lowest possible cost.
- const static long cost = 1;
-
- const static long NR = 0; // We don't know the length of the vector until runtime. So we put 0 here.
- const static long NC = 1; // We do know that it only has one column (since it's a vector)
- typedef T type;
- // Since the std::vector doesn't use a dlib memory manager we list the default one here.
- typedef default_memory_manager mem_manager_type;
- // The layout type also doesn't really matter in this case. So we list row_major_layout
- // since it is a good default.
- typedef row_major_layout layout_type;
-
- // Note that we define const_ret_type to be a reference type. This way we can
- // return the contents of the std::vector by reference.
- typedef const T& const_ret_type;
- const_ret_type apply (long r, long ) const { return vect[r]; }
-
- long nr () const { return vect.size(); }
- long nc () const { return 1; }
-
- // This expression never aliases anything since it doesn't contain any matrix expression (it
- // contains only a std::vector which doesn't count since you can't assign a matrix expression
- // to a std::vector object).
- template <typename U> bool aliases ( const matrix_exp<U>& ) const { return false; }
- template <typename U> bool destructively_aliases ( const matrix_exp<U>& ) const { return false; }
-};
-
-template < typename T >
-const matrix_op<example_op_vector_to_matrix<T> > example_vector_to_matrix (
- const std::vector<T>& vector
-)
-{
- typedef example_op_vector_to_matrix<T> op;
- return matrix_op<op>(op(vector));
-}
-
-// ----------------------------------------------------------------------------------------
-
-template <typename M, typename T>
-struct example_op_add_scalar
-{
- /*!
- This object defines a matrix expression that represents a matrix with a single
- scalar value added to all its elements.
- !*/
-
- example_op_add_scalar( const M& m_, const T& val_) : m(m_), val(val_){}
-
- // A reference to the matrix
- const M& m;
- // A copy of the scalar value that should be added to each element of m
- const T val;
-
- // This time we add 1 to the cost since evaluating an element of this
- // expression means performing 1 addition operation.
- const static long cost = M::cost + 1;
- const static long NR = M::NR;
- const static long NC = M::NC;
- typedef typename M::type type;
- typedef typename M::mem_manager_type mem_manager_type;
- typedef typename M::layout_type layout_type;
-
- // Note that we declare const_ret_type to be a non-reference type. This is important
- // since apply() computes a new temporary value and thus we can't return a reference
- // to it.
- typedef type const_ret_type;
- const_ret_type apply (long r, long c) const { return m(r,c) + val; }
-
- long nr () const { return m.nr(); }
- long nc () const { return m.nc(); }
-
- // This expression aliases anything m aliases.
- template <typename U> bool aliases ( const matrix_exp<U>& item) const { return m.aliases(item); }
- // Unlike the transpose expression. This expression only destructively aliases something if m does.
- // So this expression has the regular non-destructive kind of aliasing.
- template <typename U> bool destructively_aliases ( const matrix_exp<U>& item) const { return m.destructively_aliases(item); }
-
-};
-
-template < typename M, typename T >
-const matrix_op<example_op_add_scalar<M,T> > add_scalar (
- const matrix_exp<M>& m,
- T val
-)
-{
- typedef example_op_add_scalar<M,T> op;
- return matrix_op<op>(op(m.ref(), val));
-}
-
-// ----------------------------------------------------------------------------------------
-
-void custom_matrix_expressions_example(
-)
-{
- matrix<double> x(2,3);
- x = 1, 1, 1,
- 2, 2, 2;
-
- cout << x << endl;
-
- // Finally, let's use the matrix expressions we defined above.
-
- // prints the transpose of x
- cout << example_trans(x) << endl;
-
- // prints this:
- // 11 11 11
- // 12 12 12
- cout << add_scalar(x, 10) << endl;
-
-
- // matrix expressions can be nested, even the user defined ones.
- // the following statement prints this:
- // 11 12
- // 11 12
- // 11 12
- cout << example_trans(add_scalar(x, 10)) << endl;
-
- // Since we setup the alias detection correctly we can even do this:
- x = example_trans(add_scalar(x, 10));
- cout << "new x:\n" << x << endl;
-
- cout << "Do some testing with the example_vector_to_matrix() function: " << endl;
- std::vector<float> vect;
- vect.push_back(1);
- vect.push_back(3);
- vect.push_back(5);
-
- // Now let's treat our std::vector like a matrix and print some things.
- cout << example_vector_to_matrix(vect) << endl;
- cout << add_scalar(example_vector_to_matrix(vect), 10) << endl;
-
-
-
- /*
- As an aside, note that dlib contains functions equivalent to the ones we
- defined above. They are:
- - dlib::trans()
- - dlib::mat() (converts things into matrices)
- - operator+ (e.g. you can say my_mat + 1)
-
-
- Also, if you are going to be creating your own matrix expression you should also
- look through the matrix code in the dlib/matrix folder. There you will find
- many other examples of matrix expressions.
- */
-}
-
-// ----------------------------------------------------------------------------------------
-
diff --git a/ml/dlib/examples/max_cost_assignment_ex.cpp b/ml/dlib/examples/max_cost_assignment_ex.cpp
deleted file mode 100755
index f6985a9e3..000000000
--- a/ml/dlib/examples/max_cost_assignment_ex.cpp
+++ /dev/null
@@ -1,47 +0,0 @@
-// The contents of this file are in the public domain. See LICENSE_FOR_EXAMPLE_PROGRAMS.txt
-/*
-
- This simple example shows how to call dlib's optimal linear assignment problem solver.
- It is an implementation of the famous Hungarian algorithm and is quite fast, operating in
- O(N^3) time.
-
-*/
-
-#include <dlib/optimization/max_cost_assignment.h>
-#include <iostream>
-
-using namespace std;
-using namespace dlib;
-
-int main ()
-{
- // Let's imagine you need to assign N people to N jobs. Additionally, each person will make
- // your company a certain amount of money at each job, but each person has different skills
- // so they are better at some jobs and worse at others. You would like to find the best way
- // to assign people to these jobs. In particular, you would like to maximize the amount of
- // money the group makes as a whole. This is an example of an assignment problem and is
- // what is solved by the max_cost_assignment() routine.
- //
- // So in this example, let's imagine we have 3 people and 3 jobs. We represent the amount of
- // money each person will produce at each job with a cost matrix. Each row corresponds to a
- // person and each column corresponds to a job. So for example, below we are saying that
- // person 0 will make $1 at job 0, $2 at job 1, and $6 at job 2.
- matrix<int> cost(3,3);
- cost = 1, 2, 6,
- 5, 3, 6,
- 4, 5, 0;
-
- // To find out the best assignment of people to jobs we just need to call this function.
- std::vector<long> assignment = max_cost_assignment(cost);
-
- // This prints optimal assignments: [2, 0, 1] which indicates that we should assign
- // the person from the first row of the cost matrix to job 2, the middle row person to
- // job 0, and the bottom row person to job 1.
- for (unsigned int i = 0; i < assignment.size(); i++)
- cout << assignment[i] << std::endl;
-
- // This prints optimal cost: 16.0
- // which is correct since our optimal assignment is 6+5+5.
- cout << "optimal cost: " << assignment_cost(cost, assignment) << endl;
-}
-
diff --git a/ml/dlib/examples/member_function_pointer_ex.cpp b/ml/dlib/examples/member_function_pointer_ex.cpp
deleted file mode 100644
index 26724d3a3..000000000
--- a/ml/dlib/examples/member_function_pointer_ex.cpp
+++ /dev/null
@@ -1,78 +0,0 @@
-// The contents of this file are in the public domain. See LICENSE_FOR_EXAMPLE_PROGRAMS.txt
-
-/*
- This is an example illustrating the use of the member_function_pointer object
- from the dlib C++ Library.
-
-*/
-
-
-#include <iostream>
-#include <dlib/member_function_pointer.h>
-
-using namespace dlib;
-using namespace std;
-
-// ----------------------------------------------------------------------------------------
-
-class example_object
-{
-public:
-
- void do_something (
- )
- {
- cout << "hello world" << endl;
- }
-
- void print_this_number (
- int num
- )
- {
- cout << "number you gave me = " << num << endl;
- }
-
-};
-
-// ----------------------------------------------------------------------------------------
-
-int main()
-{
- // create a pointer that can point to member functions that take no arguments
- member_function_pointer<> mfp1;
-
- // create a pointer that can point to member functions that take a single int argument
- member_function_pointer<int> mfp2;
-
- example_object obj;
-
- // now we set the mfp1 pointer to point to the member function do_something()
- // on the obj object.
- mfp1.set(obj, &example_object::do_something);
-
-
- // now we set the mfp1 pointer to point to the member function print_this_number()
- // on the obj object.
- mfp2.set(obj, &example_object::print_this_number);
-
-
- // Now we can call the function this pointer points to. This calls the function
- // obj.do_something() via our member function pointer.
- mfp1();
-
- // Now we can call the function this pointer points to. This calls the function
- // obj.print_this_number(5) via our member function pointer.
- mfp2(5);
-
-
- // The above example shows a very simple use of the member_function_pointer.
- // A more interesting use of the member_function_pointer is in the implementation
- // of callbacks or event handlers. For example, when you register an event
- // handler for a dlib::button click it uses a member_function_pointer
- // internally to save and later call your event handler.
-}
-
-// ----------------------------------------------------------------------------------------
-
-
-
diff --git a/ml/dlib/examples/mlp_ex.cpp b/ml/dlib/examples/mlp_ex.cpp
deleted file mode 100644
index 372753c81..000000000
--- a/ml/dlib/examples/mlp_ex.cpp
+++ /dev/null
@@ -1,86 +0,0 @@
-// The contents of this file are in the public domain. See LICENSE_FOR_EXAMPLE_PROGRAMS.txt
-/*
-
- This is an example illustrating the use of the multilayer perceptron
- from the dlib C++ Library.
-
- This example creates a simple set of data to train on and shows
- you how to train a mlp object on that data.
-
-
- The data used in this example will be 2 dimensional data and will
- come from a distribution where points with a distance less than 10
- from the origin are labeled 1 and all other points are labeled
- as 0.
-
-*/
-
-
-#include <iostream>
-#include <dlib/mlp.h>
-
-using namespace std;
-using namespace dlib;
-
-
-int main()
-{
- // The mlp takes column vectors as input and gives column vectors as output. The dlib::matrix
- // object is used to represent the column vectors. So the first thing we do here is declare
- // a convenient typedef for the matrix object we will be using.
-
- // This typedef declares a matrix with 2 rows and 1 column. It will be the
- // object that contains each of our 2 dimensional samples. (Note that if you wanted
- // more than 2 features in this vector you can simply change the 2 to something else)
- typedef matrix<double, 2, 1> sample_type;
-
-
- // make an instance of a sample matrix so we can use it below
- sample_type sample;
-
- // Create a multi-layer perceptron network. This network has 2 nodes on the input layer
- // (which means it takes column vectors of length 2 as input) and 5 nodes in the first
- // hidden layer. Note that the other 4 variables in the mlp's constructor are left at
- // their default values.
- mlp::kernel_1a_c net(2,5);
-
- // Now let's put some data into our sample and train on it. We do this
- // by looping over 41*41 points and labeling them according to their
- // distance from the origin.
- for (int i = 0; i < 1000; ++i)
- {
- for (int r = -20; r <= 20; ++r)
- {
- for (int c = -20; c <= 20; ++c)
- {
- sample(0) = r;
- sample(1) = c;
-
- // if this point is less than 10 from the origin
- if (sqrt((double)r*r + c*c) <= 10)
- net.train(sample,1);
- else
- net.train(sample,0);
- }
- }
- }
-
- // Now we have trained our mlp. Let's see how well it did.
- // Note that if you run this program multiple times you will get different results. This
- // is because the mlp network is randomly initialized.
-
- // each of these statements prints out the output of the network given a particular sample.
-
- sample(0) = 3.123;
- sample(1) = 4;
- cout << "This sample should be close to 1 and it is classified as a " << net(sample) << endl;
-
- sample(0) = 13.123;
- sample(1) = 9.3545;
- cout << "This sample should be close to 0 and it is classified as a " << net(sample) << endl;
-
- sample(0) = 13.123;
- sample(1) = 0;
- cout << "This sample should be close to 0 and it is classified as a " << net(sample) << endl;
-}
-
diff --git a/ml/dlib/examples/mmod_cars_test_image.jpg b/ml/dlib/examples/mmod_cars_test_image.jpg
deleted file mode 100644
index cfffffe66..000000000
--- a/ml/dlib/examples/mmod_cars_test_image.jpg
+++ /dev/null
Binary files differ
diff --git a/ml/dlib/examples/mmod_cars_test_image2.jpg b/ml/dlib/examples/mmod_cars_test_image2.jpg
deleted file mode 100644
index 16aa30eb7..000000000
--- a/ml/dlib/examples/mmod_cars_test_image2.jpg
+++ /dev/null
Binary files differ
diff --git a/ml/dlib/examples/model_selection_ex.cpp b/ml/dlib/examples/model_selection_ex.cpp
deleted file mode 100644
index cfe2bf620..000000000
--- a/ml/dlib/examples/model_selection_ex.cpp
+++ /dev/null
@@ -1,148 +0,0 @@
-// The contents of this file are in the public domain. See LICENSE_FOR_EXAMPLE_PROGRAMS.txt
-/*
-
- This is an example that shows how you can perform model selection with the
- dlib C++ Library.
-
- It will create a simple dataset and show you how to use cross validation and
- global optimization to determine good parameters for the purpose of training
- an svm to classify the data.
-
- The data used in this example will be 2 dimensional data and will come from a
- distribution where points with a distance less than 10 from the origin are
- labeled +1 and all other points are labeled as -1.
-
-
- As an side, you should probably read the svm_ex.cpp and matrix_ex.cpp example
- programs before you read this one.
-*/
-
-
-#include <iostream>
-#include <dlib/svm.h>
-#include <dlib/global_optimization.h>
-
-using namespace std;
-using namespace dlib;
-
-
-int main() try
-{
- // The svm functions use column vectors to contain a lot of the data on which they
- // operate. So the first thing we do here is declare a convenient typedef.
-
- // This typedef declares a matrix with 2 rows and 1 column. It will be the
- // object that contains each of our 2 dimensional samples.
- typedef matrix<double, 2, 1> sample_type;
-
-
-
- // Now we make objects to contain our samples and their respective labels.
- std::vector<sample_type> samples;
- std::vector<double> labels;
-
- // Now let's put some data into our samples and labels objects. We do this
- // by looping over a bunch of points and labeling them according to their
- // distance from the origin.
- for (double r = -20; r <= 20; r += 0.8)
- {
- for (double c = -20; c <= 20; c += 0.8)
- {
- sample_type samp;
- samp(0) = r;
- samp(1) = c;
- samples.push_back(samp);
-
- // if this point is less than 10 from the origin
- if (sqrt(r*r + c*c) <= 10)
- labels.push_back(+1);
- else
- labels.push_back(-1);
- }
- }
-
- cout << "Generated " << samples.size() << " points" << endl;
-
-
- // Here we normalize all the samples by subtracting their mean and dividing by their
- // standard deviation. This is generally a good idea since it often heads off
- // numerical stability problems and also prevents one large feature from smothering
- // others. Doing this doesn't matter much in this example so I'm just doing this here
- // so you can see an easy way to accomplish this with the library.
- vector_normalizer<sample_type> normalizer;
- // let the normalizer learn the mean and standard deviation of the samples
- normalizer.train(samples);
- // now normalize each sample
- for (unsigned long i = 0; i < samples.size(); ++i)
- samples[i] = normalizer(samples[i]);
-
-
- // Now that we have some data we want to train on it. We are going to train a
- // binary SVM with the RBF kernel to classify the data. However, there are
- // three parameters to the training. These are the SVM C parameters for each
- // class and the RBF kernel's gamma parameter. Our choice for these
- // parameters will influence how good the resulting decision function is. To
- // test how good a particular choice of these parameters is we can use the
- // cross_validate_trainer() function to perform n-fold cross validation on our
- // training data. However, there is a problem with the way we have sampled
- // our distribution above. The problem is that there is a definite ordering
- // to the samples. That is, the first half of the samples look like they are
- // from a different distribution than the second half. This would screw up
- // the cross validation process, but we can fix it by randomizing the order of
- // the samples with the following function call.
- randomize_samples(samples, labels);
-
-
- // And now we get to the important bit. Here we define a function,
- // cross_validation_score(), that will do the cross-validation we
- // mentioned and return a number indicating how good a particular setting
- // of gamma, c1, and c2 is.
- auto cross_validation_score = [&](const double gamma, const double c1, const double c2)
- {
- // Make a RBF SVM trainer and tell it what the parameters are supposed to be.
- typedef radial_basis_kernel<sample_type> kernel_type;
- svm_c_trainer<kernel_type> trainer;
- trainer.set_kernel(kernel_type(gamma));
- trainer.set_c_class1(c1);
- trainer.set_c_class2(c2);
-
- // Finally, perform 10-fold cross validation and then print and return the results.
- matrix<double> result = cross_validate_trainer(trainer, samples, labels, 10);
- cout << "gamma: " << setw(11) << gamma << " c1: " << setw(11) << c1 << " c2: " << setw(11) << c2 << " cross validation accuracy: " << result;
-
- // Now return a number indicating how good the parameters are. Bigger is
- // better in this example. Here I'm returning the harmonic mean between the
- // accuracies of each class. However, you could do something else. For
- // example, you might care a lot more about correctly predicting the +1 class,
- // so you could penalize results that didn't obtain a high accuracy on that
- // class. You might do this by using something like a weighted version of the
- // F1-score (see http://en.wikipedia.org/wiki/F1_score).
- return 2*prod(result)/sum(result);
- };
-
-
- // And finally, we call this global optimizer that will search for the best parameters.
- // It will call cross_validation_score() 50 times with different settings and return
- // the best parameter setting it finds. find_max_global() uses a global optimization
- // method based on a combination of non-parametric global function modeling and
- // quadratic trust region modeling to efficiently find a global maximizer. It usually
- // does a good job with a relatively small number of calls to cross_validation_score().
- // In this example, you should observe that it finds settings that give perfect binary
- // classification of the data.
- auto result = find_max_global(cross_validation_score,
- {1e-5, 1e-5, 1e-5}, // lower bound constraints on gamma, c1, and c2, respectively
- {100, 1e6, 1e6}, // upper bound constraints on gamma, c1, and c2, respectively
- max_function_calls(50));
-
- double best_gamma = result.x(0);
- double best_c1 = result.x(1);
- double best_c2 = result.x(2);
-
- cout << " best cross-validation score: " << result.y << endl;
- cout << " best gamma: " << best_gamma << " best c1: " << best_c1 << " best c2: "<< best_c2 << endl;
-}
-catch (exception& e)
-{
- cout << e.what() << endl;
-}
-
diff --git a/ml/dlib/examples/mpc_ex.cpp b/ml/dlib/examples/mpc_ex.cpp
deleted file mode 100644
index 8df5173d7..000000000
--- a/ml/dlib/examples/mpc_ex.cpp
+++ /dev/null
@@ -1,156 +0,0 @@
-// The contents of this file are in the public domain. See LICENSE_FOR_EXAMPLE_PROGRAMS.txt
-/*
-
- This is an example illustrating the use of the linear model predictive
- control tool from the dlib C++ Library. To explain what it does, suppose
- you have some process you want to control and the process dynamics are
- described by the linear equation:
- x_{i+1} = A*x_i + B*u_i + C
- That is, the next state the system goes into is a linear function of its
- current state (x_i) and the current control (u_i) plus some constant bias or
- disturbance.
-
- A model predictive controller can find the control (u) you should apply to
- drive the state (x) to some reference value, which is what we show in this
- example. In particular, we will simulate a simple vehicle moving around in
- a planet's gravity. We will use MPC to get the vehicle to fly to and then
- hover at a certain point in the air.
-
-*/
-
-
-#include <dlib/gui_widgets.h>
-#include <dlib/control.h>
-#include <dlib/image_transforms.h>
-
-
-using namespace std;
-using namespace dlib;
-
-// ----------------------------------------------------------------------------
-
-int main()
-{
- const int STATES = 4;
- const int CONTROLS = 2;
-
- // The first thing we do is setup our vehicle dynamics model (A*x + B*u + C).
- // Our state space (the x) will have 4 dimensions, the 2D vehicle position
- // and also the 2D velocity. The control space (u) will be just 2 variables
- // which encode the amount of force we apply to the vehicle along each axis.
- // Therefore, the A matrix defines a simple constant velocity model.
- matrix<double,STATES,STATES> A;
- A = 1, 0, 1, 0, // next_pos = pos + velocity
- 0, 1, 0, 1, // next_pos = pos + velocity
- 0, 0, 1, 0, // next_velocity = velocity
- 0, 0, 0, 1; // next_velocity = velocity
-
- // Here we say that the control variables effect only the velocity. That is,
- // the control applies an acceleration to the vehicle.
- matrix<double,STATES,CONTROLS> B;
- B = 0, 0,
- 0, 0,
- 1, 0,
- 0, 1;
-
- // Let's also say there is a small constant acceleration in one direction.
- // This is the force of gravity in our model.
- matrix<double,STATES,1> C;
- C = 0,
- 0,
- 0,
- 0.1;
-
-
- const int HORIZON = 30;
- // Now we need to setup some MPC specific parameters. To understand them,
- // let's first talk about how MPC works. When the MPC tool finds the "best"
- // control to apply it does it by simulating the process for HORIZON time
- // steps and selecting the control that leads to the best performance over
- // the next HORIZON steps.
- //
- // To be precise, each time you ask it for a control, it solves the
- // following quadratic program:
- //
- // min sum_i trans(x_i-target_i)*Q*(x_i-target_i) + trans(u_i)*R*u_i
- // x_i,u_i
- //
- // such that: x_0 == current_state
- // x_{i+1} == A*x_i + B*u_i + C
- // lower <= u_i <= upper
- // 0 <= i < HORIZON
- //
- // and reports u_0 as the control you should take given that you are currently
- // in current_state. Q and R are user supplied matrices that define how we
- // penalize variations away from the target state as well as how much we want
- // to avoid generating large control signals. We also allow you to specify
- // upper and lower bound constraints on the controls. The next few lines
- // define these parameters for our simple example.
-
- matrix<double,STATES,1> Q;
- // Setup Q so that the MPC only cares about matching the target position and
- // ignores the velocity.
- Q = 1, 1, 0, 0;
-
- matrix<double,CONTROLS,1> R, lower, upper;
- R = 1, 1;
- lower = -0.5, -0.5;
- upper = 0.5, 0.5;
-
- // Finally, create the MPC controller.
- mpc<STATES,CONTROLS,HORIZON> controller(A,B,C,Q,R,lower,upper);
-
-
- // Let's tell the controller to send our vehicle to a random location. It
- // will try to find the controls that makes the vehicle just hover at this
- // target position.
- dlib::rand rnd;
- matrix<double,STATES,1> target;
- target = rnd.get_random_double()*400,rnd.get_random_double()*400,0,0;
- controller.set_target(target);
-
-
- // Now let's start simulating our vehicle. Our vehicle moves around inside
- // a 400x400 unit sized world.
- matrix<rgb_pixel> world(400,400);
- image_window win;
- matrix<double,STATES,1> current_state;
- // And we start it at the center of the world with zero velocity.
- current_state = 200,200,0,0;
-
- int iter = 0;
- while(!win.is_closed())
- {
- // Find the best control action given our current state.
- matrix<double,CONTROLS,1> action = controller(current_state);
- cout << "best control: " << trans(action);
-
- // Now draw our vehicle on the world. We will draw the vehicle as a
- // black circle and its target position as a green circle.
- assign_all_pixels(world, rgb_pixel(255,255,255));
- const dpoint pos = point(current_state(0),current_state(1));
- const dpoint goal = point(target(0),target(1));
- draw_solid_circle(world, goal, 9, rgb_pixel(100,255,100));
- draw_solid_circle(world, pos, 7, 0);
- // We will also draw the control as a line showing which direction the
- // vehicle's thruster is firing.
- draw_line(world, pos, pos-50*action, rgb_pixel(255,0,0));
- win.set_image(world);
-
- // Take a step in the simulation
- current_state = A*current_state + B*action + C;
- dlib::sleep(100);
-
- // Every 100 iterations change the target to some other random location.
- ++iter;
- if (iter > 100)
- {
- iter = 0;
- target = rnd.get_random_double()*400,rnd.get_random_double()*400,0,0;
- controller.set_target(target);
- }
- }
-}
-
-// ----------------------------------------------------------------------------
-
diff --git a/ml/dlib/examples/multiclass_classification_ex.cpp b/ml/dlib/examples/multiclass_classification_ex.cpp
deleted file mode 100644
index 782511ca3..000000000
--- a/ml/dlib/examples/multiclass_classification_ex.cpp
+++ /dev/null
@@ -1,248 +0,0 @@
-// The contents of this file are in the public domain. See LICENSE_FOR_EXAMPLE_PROGRAMS.txt
-/*
- This is an example illustrating the use of the multiclass classification tools
- from the dlib C++ Library. Specifically, this example will make points from
- three classes and show you how to train a multiclass classifier to recognize
- these three classes.
-
- The classes are as follows:
- - class 1: points very close to the origin
- - class 2: points on the circle of radius 10 around the origin
- - class 3: points that are on a circle of radius 4 but not around the origin at all
-*/
-
-#include <dlib/svm_threaded.h>
-
-#include <iostream>
-#include <vector>
-
-#include <dlib/rand.h>
-
-using namespace std;
-using namespace dlib;
-
-// Our data will be 2-dimensional data. So declare an appropriate type to contain these points.
-typedef matrix<double,2,1> sample_type;
-
-// ----------------------------------------------------------------------------------------
-
-void generate_data (
- std::vector<sample_type>& samples,
- std::vector<double>& labels
-);
-/*!
- ensures
- - make some 3 class data as described above.
- - Create 60 points from class 1
- - Create 70 points from class 2
- - Create 80 points from class 3
-!*/
-
-// ----------------------------------------------------------------------------------------
-
-int main()
-{
- try
- {
- std::vector<sample_type> samples;
- std::vector<double> labels;
-
- // First, get our labeled set of training data
- generate_data(samples, labels);
-
- cout << "samples.size(): "<< samples.size() << endl;
-
- // The main object in this example program is the one_vs_one_trainer. It is essentially
- // a container class for regular binary classifier trainer objects. In particular, it
- // uses the any_trainer object to store any kind of trainer object that implements a
- // .train(samples,labels) function which returns some kind of learned decision function.
- // It uses these binary classifiers to construct a voting multiclass classifier. If
- // there are N classes then it trains N*(N-1)/2 binary classifiers, one for each pair of
- // labels, which then vote on the label of a sample.
- //
- // In this example program we will work with a one_vs_one_trainer object which stores any
- // kind of trainer that uses our sample_type samples.
- typedef one_vs_one_trainer<any_trainer<sample_type> > ovo_trainer;
-
-
- // Finally, make the one_vs_one_trainer.
- ovo_trainer trainer;
-
-
- // Next, we will make two different binary classification trainer objects. One
- // which uses kernel ridge regression and RBF kernels and another which uses a
- // support vector machine and polynomial kernels. The particular details don't matter.
- // The point of this part of the example is that you can use any kind of trainer object
- // with the one_vs_one_trainer.
- typedef polynomial_kernel<sample_type> poly_kernel;
- typedef radial_basis_kernel<sample_type> rbf_kernel;
-
- // make the binary trainers and set some parameters
- krr_trainer<rbf_kernel> rbf_trainer;
- svm_nu_trainer<poly_kernel> poly_trainer;
- poly_trainer.set_kernel(poly_kernel(0.1, 1, 2));
- rbf_trainer.set_kernel(rbf_kernel(0.1));
-
-
- // Now tell the one_vs_one_trainer that, by default, it should use the rbf_trainer
- // to solve the individual binary classification subproblems.
- trainer.set_trainer(rbf_trainer);
- // We can also get more specific. Here we tell the one_vs_one_trainer to use the
- // poly_trainer to solve the class 1 vs class 2 subproblem. All the others will
- // still be solved with the rbf_trainer.
- trainer.set_trainer(poly_trainer, 1, 2);
-
- // Now let's do 5-fold cross-validation using the one_vs_one_trainer we just setup.
- // As an aside, always shuffle the order of the samples before doing cross validation.
- // For a discussion of why this is a good idea see the svm_ex.cpp example.
- randomize_samples(samples, labels);
- cout << "cross validation: \n" << cross_validate_multiclass_trainer(trainer, samples, labels, 5) << endl;
- // The output is shown below. It is the confusion matrix which describes the results. Each row
- // corresponds to a class of data and each column to a prediction. Reading from top to bottom,
- // the rows correspond to the class labels if the labels have been listed in sorted order. So the
- // top row corresponds to class 1, the middle row to class 2, and the bottom row to class 3. The
- // columns are organized similarly, with the left most column showing how many samples were predicted
- // as members of class 1.
- //
- // So in the results below we can see that, for the class 1 samples, 60 of them were correctly predicted
- // to be members of class 1 and 0 were incorrectly classified. Similarly, the other two classes of data
- // are perfectly classified.
- /*
- cross validation:
- 60 0 0
- 0 70 0
- 0 0 80
- */
-
- // Next, if you wanted to obtain the decision rule learned by a one_vs_one_trainer you
- // would store it into a one_vs_one_decision_function.
- one_vs_one_decision_function<ovo_trainer> df = trainer.train(samples, labels);
-
- cout << "predicted label: "<< df(samples[0]) << ", true label: "<< labels[0] << endl;
- cout << "predicted label: "<< df(samples[90]) << ", true label: "<< labels[90] << endl;
- // The output is:
- /*
- predicted label: 2, true label: 2
- predicted label: 1, true label: 1
- */
-
-
- // If you want to save a one_vs_one_decision_function to disk, you can do
- // so. However, you must declare what kind of decision functions it contains.
- one_vs_one_decision_function<ovo_trainer,
- decision_function<poly_kernel>, // This is the output of the poly_trainer
- decision_function<rbf_kernel> // This is the output of the rbf_trainer
- > df2, df3;
-
-
- // Put df into df2 and then save df2 to disk. Note that we could have also said
- // df2 = trainer.train(samples, labels); But doing it this way avoids retraining.
- df2 = df;
- serialize("df.dat") << df2;
-
- // load the function back in from disk and store it in df3.
- deserialize("df.dat") >> df3;
-
-
- // Test df3 to see that this worked.
- cout << endl;
- cout << "predicted label: "<< df3(samples[0]) << ", true label: "<< labels[0] << endl;
- cout << "predicted label: "<< df3(samples[90]) << ", true label: "<< labels[90] << endl;
- // Test df3 on the samples and labels and print the confusion matrix.
- cout << "test deserialized function: \n" << test_multiclass_decision_function(df3, samples, labels) << endl;
-
-
-
-
-
- // Finally, if you want to get the binary classifiers from inside a multiclass decision
- // function you can do it by calling get_binary_decision_functions() like so:
- one_vs_one_decision_function<ovo_trainer>::binary_function_table functs;
- functs = df.get_binary_decision_functions();
- cout << "number of binary decision functions in df: " << functs.size() << endl;
- // The functs object is a std::map which maps pairs of labels to binary decision
- // functions. So we can access the individual decision functions like so:
- decision_function<poly_kernel> df_1_2 = any_cast<decision_function<poly_kernel> >(functs[make_unordered_pair(1,2)]);
- decision_function<rbf_kernel> df_1_3 = any_cast<decision_function<rbf_kernel> >(functs[make_unordered_pair(1,3)]);
- // df_1_2 contains the binary decision function that votes for class 1 vs. 2.
- // Similarly, df_1_3 contains the classifier that votes for 1 vs. 3.
-
- // Note that the multiclass decision function doesn't know what kind of binary
- // decision functions it contains. So we have to use any_cast to explicitly cast
- // them back into the concrete type. If you make a mistake and try to any_cast a
- // binary decision function into the wrong type of function any_cast will throw a
- // bad_any_cast exception.
- }
- catch (std::exception& e)
- {
- cout << "exception thrown!" << endl;
- cout << e.what() << endl;
- }
-}
-
-// ----------------------------------------------------------------------------------------
-
-void generate_data (
- std::vector<sample_type>& samples,
- std::vector<double>& labels
-)
-{
- const long num = 50;
-
- sample_type m;
-
- dlib::rand rnd;
-
-
- // make some samples near the origin
- double radius = 0.5;
- for (long i = 0; i < num+10; ++i)
- {
- double sign = 1;
- if (rnd.get_random_double() < 0.5)
- sign = -1;
- m(0) = 2*radius*rnd.get_random_double()-radius;
- m(1) = sign*sqrt(radius*radius - m(0)*m(0));
-
- // add this sample to our set of training samples
- samples.push_back(m);
- labels.push_back(1);
- }
-
- // make some samples in a circle around the origin but far away
- radius = 10.0;
- for (long i = 0; i < num+20; ++i)
- {
- double sign = 1;
- if (rnd.get_random_double() < 0.5)
- sign = -1;
- m(0) = 2*radius*rnd.get_random_double()-radius;
- m(1) = sign*sqrt(radius*radius - m(0)*m(0));
-
- // add this sample to our set of training samples
- samples.push_back(m);
- labels.push_back(2);
- }
-
- // make some samples in a circle around the point (25,25)
- radius = 4.0;
- for (long i = 0; i < num+30; ++i)
- {
- double sign = 1;
- if (rnd.get_random_double() < 0.5)
- sign = -1;
- m(0) = 2*radius*rnd.get_random_double()-radius;
- m(1) = sign*sqrt(radius*radius - m(0)*m(0));
-
- // translate this point away from the origin
- m(0) += 25;
- m(1) += 25;
-
- // add this sample to our set of training samples
- samples.push_back(m);
- labels.push_back(3);
- }
-}
-
-// ----------------------------------------------------------------------------------------
-
diff --git a/ml/dlib/examples/multithreaded_object_ex.cpp b/ml/dlib/examples/multithreaded_object_ex.cpp
deleted file mode 100644
index fed32a91c..000000000
--- a/ml/dlib/examples/multithreaded_object_ex.cpp
+++ /dev/null
@@ -1,138 +0,0 @@
-// The contents of this file are in the public domain. See LICENSE_FOR_EXAMPLE_PROGRAMS.txt
-/*
-
- This is an example illustrating the use of the multithreaded_object.
-
- This is a very simple example. It creates 3 threads that
- just print messages to the screen.
-
-
-
- Example program output:
- 0 INFO [1] mto: thread1(): hurray threads!
- 0 INFO [2] mto: thread2(): hurray threads!
- 0 INFO [3] mto: thread2(): hurray threads!
- 700 INFO [1] mto: thread1(): hurray threads!
- 800 INFO [2] mto: thread2(): hurray threads!
- 801 INFO [3] mto: thread2(): hurray threads!
- 1400 INFO [1] mto: thread1(): hurray threads!
- 1604 INFO [2] mto: thread2(): hurray threads!
- 1605 INFO [3] mto: thread2(): hurray threads!
- 2100 INFO [1] mto: thread1(): hurray threads!
- 2409 INFO [2] mto: thread2(): hurray threads!
- 2409 INFO [3] mto: thread2(): hurray threads!
- 2801 INFO [1] mto: thread1(): hurray threads!
- 3001 INFO [0] mto: paused threads
- 6001 INFO [0] mto: starting threads back up from paused state
- 6001 INFO [2] mto: thread2(): hurray threads!
- 6001 INFO [1] mto: thread1(): hurray threads!
- 6001 INFO [3] mto: thread2(): hurray threads!
- 6705 INFO [1] mto: thread1(): hurray threads!
- 6805 INFO [2] mto: thread2(): hurray threads!
- 6805 INFO [3] mto: thread2(): hurray threads!
- 7405 INFO [1] mto: thread1(): hurray threads!
- 7609 INFO [2] mto: thread2(): hurray threads!
- 7609 INFO [3] mto: thread2(): hurray threads!
- 8105 INFO [1] mto: thread1(): hurray threads!
- 8413 INFO [2] mto: thread2(): hurray threads!
- 8413 INFO [3] mto: thread2(): hurray threads!
- 8805 INFO [1] mto: thread1(): hurray threads!
-
- The first column is the number of milliseconds since program start, the second
- column is the logging level, the third column is the thread id, and the rest
- is the log message.
-*/
-
-
-#include <iostream>
-#include <dlib/threads.h>
-#include <dlib/misc_api.h> // for dlib::sleep
-#include <dlib/logger.h>
-
-using namespace std;
-using namespace dlib;
-
-logger dlog("mto");
-
-class my_object : public multithreaded_object
-{
-public:
- my_object()
- {
- // register which functions we want to run as threads. We want one thread running
- // thread1() and two threads to run thread2(). So we will have a total of 3 threads
- // running.
- register_thread(*this,&my_object::thread1);
- register_thread(*this,&my_object::thread2);
- register_thread(*this,&my_object::thread2);
-
- // start all our registered threads going by calling the start() function
- start();
- }
-
- ~my_object()
- {
- // Tell the thread() function to stop. This will cause should_stop() to
- // return true so the thread knows what to do.
- stop();
-
- // Wait for the threads to stop before letting this object destruct itself.
- // Also note, you are *required* to wait for the threads to end before
- // letting this object destruct itself.
- wait();
- }
-
-private:
-
- void thread1()
- {
- // This is a thread. It will loop until it is told that it should terminate.
- while (should_stop() == false)
- {
- dlog << LINFO << "thread1(): hurray threads!";
- dlib::sleep(700);
- }
- }
-
- void thread2()
- {
- // This is a thread. It will loop until it is told that it should terminate.
- while (should_stop() == false)
- {
- dlog << LINFO << "thread2(): hurray threads!";
- dlib::sleep(800);
- }
- }
-
-};
-
-int main()
-{
- // tell the logger to output all messages
- dlog.set_level(LALL);
-
- // Create an instance of our multi-threaded object.
- my_object t;
-
- dlib::sleep(3000);
-
- // Tell the multi-threaded object to pause its threads. This causes the
- // threads to block on their next calls to should_stop().
- t.pause();
- dlog << LINFO << "paused threads";
-
- dlib::sleep(3000);
- dlog << LINFO << "starting threads back up from paused state";
-
- // Tell the threads to unpause themselves. This causes should_stop() to unblock
- // and to let the threads continue.
- t.start();
-
- dlib::sleep(3000);
-
- // Let the program end. When t is destructed it will gracefully terminate your
- // threads because we have set the destructor up to do so.
-}
-
-
-
diff --git a/ml/dlib/examples/object_detector_advanced_ex.cpp b/ml/dlib/examples/object_detector_advanced_ex.cpp
deleted file mode 100644
index 718994e27..000000000
--- a/ml/dlib/examples/object_detector_advanced_ex.cpp
+++ /dev/null
@@ -1,302 +0,0 @@
-// The contents of this file are in the public domain. See LICENSE_FOR_EXAMPLE_PROGRAMS.txt
-/*
-
- This is an example illustrating the process for defining custom
- bag-of-visual-word style feature extractors for use with the
- structural_object_detection_trainer.
-
- NOTICE: This example assumes you are familiar with the contents of the
- object_detector_ex.cpp example program. Also, if the objects you want to
- detect are somewhat rigid in appearance (e.g. faces, pedestrians, etc.)
- then you should try the methods shown in the fhog_object_detector_ex.cpp
- example program before trying to use the bag-of-visual-word tools shown in
- this example.
-*/
-
-
-#include <dlib/svm_threaded.h>
-#include <dlib/gui_widgets.h>
-#include <dlib/array.h>
-#include <dlib/array2d.h>
-#include <dlib/image_keypoint.h>
-#include <dlib/image_processing.h>
-
-#include <iostream>
-#include <fstream>
-
-
-using namespace std;
-using namespace dlib;
-
-// ----------------------------------------------------------------------------------------
-
-template <
- typename image_array_type
- >
-void make_simple_test_data (
- image_array_type& images,
- std::vector<std::vector<rectangle> >& object_locations
-)
-/*!
- ensures
- - #images.size() == 3
- - #object_locations.size() == 3
- - Creates some simple images to test the object detection routines. In particular,
- this function creates images with white 70x70 squares in them. It also stores
- the locations of these squares in object_locations.
- - for all valid i:
- - object_locations[i] == A list of all the white rectangles present in images[i].
-!*/
-{
- images.clear();
- object_locations.clear();
-
- images.resize(3);
- images[0].set_size(400,400);
- images[1].set_size(400,400);
- images[2].set_size(400,400);
-
- // set all the pixel values to black
- assign_all_pixels(images[0], 0);
- assign_all_pixels(images[1], 0);
- assign_all_pixels(images[2], 0);
-
- // Now make some squares and draw them onto our black images. All the
- // squares will be 70 pixels wide and tall.
-
- std::vector<rectangle> temp;
- temp.push_back(centered_rect(point(100,100), 70,70));
- fill_rect(images[0],temp.back(),255); // Paint the square white
- temp.push_back(centered_rect(point(200,300), 70,70));
- fill_rect(images[0],temp.back(),255); // Paint the square white
- object_locations.push_back(temp);
-
- temp.clear();
- temp.push_back(centered_rect(point(140,200), 70,70));
- fill_rect(images[1],temp.back(),255); // Paint the square white
- temp.push_back(centered_rect(point(303,200), 70,70));
- fill_rect(images[1],temp.back(),255); // Paint the square white
- object_locations.push_back(temp);
-
- temp.clear();
- temp.push_back(centered_rect(point(123,121), 70,70));
- fill_rect(images[2],temp.back(),255); // Paint the square white
- object_locations.push_back(temp);
-}
-
-// ----------------------------------------------------------------------------------------
-
-class very_simple_feature_extractor : noncopyable
-{
- /*!
- WHAT THIS OBJECT REPRESENTS
- This object is a feature extractor which goes to every pixel in an image and
- produces a 32 dimensional feature vector. This vector is an indicator vector
- which records the pattern of pixel values in a 4-connected region. So it should
- be able to distinguish basic things like whether or not a location falls on the
- corner of a white box, on an edge, in the middle, etc.
-
-
- Note that this object also implements the interface defined in dlib/image_keypoint/hashed_feature_image_abstract.h.
- This means all the member functions in this object are supposed to behave as
- described in the hashed_feature_image specification. So when you define your own
- feature extractor objects you should probably refer yourself to that documentation
- in addition to reading this example program.
- !*/
-
-
-public:
-
- template <
- typename image_type
- >
- inline void load (
- const image_type& img
- )
- {
- feat_image.set_size(img.nr(), img.nc());
- assign_all_pixels(feat_image,0);
- for (long r = 1; r+1 < img.nr(); ++r)
- {
- for (long c = 1; c+1 < img.nc(); ++c)
- {
- unsigned char f = 0;
- if (img[r][c]) f |= 0x1;
- if (img[r][c+1]) f |= 0x2;
- if (img[r][c-1]) f |= 0x4;
- if (img[r+1][c]) f |= 0x8;
- if (img[r-1][c]) f |= 0x10;
-
- // Store the code value for the pattern of pixel values in the 4-connected
- // neighborhood around this row and column.
- feat_image[r][c] = f;
- }
- }
- }
-
- inline size_t size () const { return feat_image.size(); }
- inline long nr () const { return feat_image.nr(); }
- inline long nc () const { return feat_image.nc(); }
-
- inline long get_num_dimensions (
- ) const
- {
- // Return the dimensionality of the vectors produced by operator()
- return 32;
- }
-
- typedef std::vector<std::pair<unsigned int,double> > descriptor_type;
-
- inline const descriptor_type& operator() (
- long row,
- long col
- ) const
- /*!
- requires
- - 0 <= row < nr()
- - 0 <= col < nc()
- ensures
- - returns a sparse vector which describes the image at the given row and column.
- In particular, this is a vector that is 0 everywhere except for one element.
- !*/
- {
- feat.clear();
- const unsigned long only_nonzero_element_index = feat_image[row][col];
- feat.push_back(make_pair(only_nonzero_element_index,1.0));
- return feat;
- }
-
- // This block of functions is meant to provide a way to map between the row/col space taken by
- // this object's operator() function and the images supplied to load(). In this example it's trivial.
- // However, in general, you might create feature extractors which don't perform extraction at every
- // possible image location (e.g. the hog_image) and thus result in some more complex mapping.
- inline const rectangle get_block_rect ( long row, long col) const { return centered_rect(col,row,3,3); }
- inline const point image_to_feat_space ( const point& p) const { return p; }
- inline const rectangle image_to_feat_space ( const rectangle& rect) const { return rect; }
- inline const point feat_to_image_space ( const point& p) const { return p; }
- inline const rectangle feat_to_image_space ( const rectangle& rect) const { return rect; }
-
- inline friend void serialize ( const very_simple_feature_extractor& item, std::ostream& out) { serialize(item.feat_image, out); }
- inline friend void deserialize ( very_simple_feature_extractor& item, std::istream& in ) { deserialize(item.feat_image, in); }
-
- void copy_configuration ( const very_simple_feature_extractor& item){}
-
-private:
- array2d<unsigned char> feat_image;
-
- // This variable doesn't logically contribute to the state of this object. It is here
- // only to avoid returning a descriptor_type object by value inside the operator() method.
- mutable descriptor_type feat;
-};
-
-// ----------------------------------------------------------------------------------------
-
-int main()
-{
- try
- {
- // Get some data
- dlib::array<array2d<unsigned char> > images;
- std::vector<std::vector<rectangle> > object_locations;
- make_simple_test_data(images, object_locations);
-
-
- typedef scan_image_pyramid<pyramid_down<5>, very_simple_feature_extractor> image_scanner_type;
- image_scanner_type scanner;
- // Instead of using setup_grid_detection_templates() like in object_detector_ex.cpp, let's manually
- // setup the sliding window box. We use a window with the same shape as the white boxes we
- // are trying to detect.
- const rectangle object_box = compute_box_dimensions(1, // width/height ratio
- 70*70 // box area
- );
- scanner.add_detection_template(object_box, create_grid_detection_template(object_box,2,2));
-
- // Since our sliding window is already the right size to detect our objects we don't need
- // to use an image pyramid. So setting this to 1 turns off the image pyramid.
- scanner.set_max_pyramid_levels(1);
-
-
- // While the very_simple_feature_extractor doesn't have any parameters, when you go solve
- // real problems you might define a feature extractor which has some non-trivial parameters
- // that need to be setup before it can be used. So you need to be able to pass these parameters
- // to the scanner object somehow. You can do this using the copy_configuration() function as
- // shown below.
- very_simple_feature_extractor fe;
- /*
- setup the parameters in the fe object.
- ...
- */
- // The scanner will use very_simple_feature_extractor::copy_configuration() to copy the state
- // of fe into its internal feature extractor.
- scanner.copy_configuration(fe);
-
-
-
-
- // Now that we have defined the kind of sliding window classifier system we want and stored
- // the details into the scanner object we are ready to use the structural_object_detection_trainer
- // to learn the weight vector and threshold needed to produce a complete object detector.
- structural_object_detection_trainer<image_scanner_type> trainer(scanner);
- trainer.set_num_threads(4); // Set this to the number of processing cores on your machine.
-
-
- // The trainer will try and find the detector which minimizes the number of detection mistakes.
- // This function controls how it decides if a detection output is a mistake or not. The bigger
- // the input to this function the more strict it is in deciding if the detector is correctly
- // hitting the targets. Try reducing the value to 0.001 and observing the results. You should
- // see that the detections aren't exactly on top of the white squares anymore. See the documentation
- // for the structural_object_detection_trainer and structural_svm_object_detection_problem objects
- // for a more detailed discussion of this parameter.
- trainer.set_match_eps(0.95);
-
-
- object_detector<image_scanner_type> detector = trainer.train(images, object_locations);
-
- // We can easily test the new detector against our training data. This print
- // statement will indicate that it has perfect precision and recall on this simple
- // task. It will also print the average precision (AP).
- cout << "Test detector (precision,recall,AP): " << test_object_detection_function(detector, images, object_locations) << endl;
-
- // The cross validation should also indicate perfect precision and recall.
- cout << "3-fold cross validation (precision,recall,AP): "
- << cross_validate_object_detection_trainer(trainer, images, object_locations, 3) << endl;
-
-
- /*
- It is also worth pointing out that you don't have to use dlib::array2d objects to
- represent your images. In fact, you can use any object, even something like a struct
- of many images and other things as the "image". The only requirements on an image
- are that it should be possible to pass it to scanner.load(). So if you can say
- scanner.load(images[0]), for example, then you are good to go. See the documentation
- for scan_image_pyramid::load() for more details.
- */
-
-
- // Let's display the output of the detector along with our training images.
- image_window win;
- for (unsigned long i = 0; i < images.size(); ++i)
- {
- // Run the detector on images[i]
- const std::vector<rectangle> rects = detector(images[i]);
- cout << "Number of detections: "<< rects.size() << endl;
-
- // Put the image and detections into the window.
- win.clear_overlay();
- win.set_image(images[i]);
- win.add_overlay(rects, rgb_pixel(255,0,0));
-
- cout << "Hit enter to see the next image.";
- cin.get();
- }
-
- }
- catch (exception& e)
- {
- cout << "\nexception thrown!" << endl;
- cout << e.what() << endl;
- }
-}
-
-// ----------------------------------------------------------------------------------------
-
-
diff --git a/ml/dlib/examples/object_detector_ex.cpp b/ml/dlib/examples/object_detector_ex.cpp
deleted file mode 100644
index cda71eb5a..000000000
--- a/ml/dlib/examples/object_detector_ex.cpp
+++ /dev/null
@@ -1,263 +0,0 @@
-// The contents of this file are in the public domain. See LICENSE_FOR_EXAMPLE_PROGRAMS.txt
-/*
-
- This is an example illustrating the use of dlib's bag-of-visual-word based
- tools for detecting objects in images. In this example we will create three
- simple images, each containing some white squares. We will then use the
- sliding window classifier tools to learn to detect these squares.
-
- If the objects you want to detect are somewhat rigid in appearance (e.g.
- faces, pedestrians, etc.) then you should try the methods shown in the
- fhog_object_detector_ex.cpp example program before trying to use the
- bag-of-visual-word tools shown in this example.
-*/
-
-
-#include <dlib/svm_threaded.h>
-#include <dlib/gui_widgets.h>
-#include <dlib/array.h>
-#include <dlib/array2d.h>
-#include <dlib/image_keypoint.h>
-#include <dlib/image_processing.h>
-
-#include <iostream>
-#include <fstream>
-
-
-using namespace std;
-using namespace dlib;
-
-// ----------------------------------------------------------------------------------------
-
-template <
- typename image_array_type
- >
-void make_simple_test_data (
- image_array_type& images,
- std::vector<std::vector<rectangle> >& object_locations
-)
-/*!
- ensures
- - #images.size() == 3
- - #object_locations.size() == 3
- - Creates some simple images to test the object detection routines. In particular,
- this function creates images with white 70x70 squares in them. It also stores
- the locations of these squares in object_locations.
- - for all valid i:
- - object_locations[i] == A list of all the white rectangles present in images[i].
-!*/
-{
- images.clear();
- object_locations.clear();
-
- images.resize(3);
- images[0].set_size(400,400);
- images[1].set_size(400,400);
- images[2].set_size(400,400);
-
- // set all the pixel values to black
- assign_all_pixels(images[0], 0);
- assign_all_pixels(images[1], 0);
- assign_all_pixels(images[2], 0);
-
- // Now make some squares and draw them onto our black images. All the
- // squares will be 70 pixels wide and tall.
-
- std::vector<rectangle> temp;
- temp.push_back(centered_rect(point(100,100), 70,70));
- fill_rect(images[0],temp.back(),255); // Paint the square white
- temp.push_back(centered_rect(point(200,300), 70,70));
- fill_rect(images[0],temp.back(),255); // Paint the square white
- object_locations.push_back(temp);
-
- temp.clear();
- temp.push_back(centered_rect(point(140,200), 70,70));
- fill_rect(images[1],temp.back(),255); // Paint the square white
- temp.push_back(centered_rect(point(303,200), 70,70));
- fill_rect(images[1],temp.back(),255); // Paint the square white
- object_locations.push_back(temp);
-
- temp.clear();
- temp.push_back(centered_rect(point(123,121), 70,70));
- fill_rect(images[2],temp.back(),255); // Paint the square white
- object_locations.push_back(temp);
-
- // corrupt each image with random noise just to make this a little more
- // challenging
- dlib::rand rnd;
- for (unsigned long i = 0; i < images.size(); ++i)
- {
- for (long r = 0; r < images[i].nr(); ++r)
- {
- for (long c = 0; c < images[i].nc(); ++c)
- {
- images[i][r][c] = put_in_range(0,255,images[i][r][c] + 40*rnd.get_random_gaussian());
- }
- }
- }
-}
-
-// ----------------------------------------------------------------------------------------
-
-int main()
-{
- try
- {
- // The first thing we do is create the set of 3 images discussed above.
- dlib::array<array2d<unsigned char> > images;
- std::vector<std::vector<rectangle> > object_locations;
- make_simple_test_data(images, object_locations);
-
-
- /*
- This next block of code specifies the type of sliding window classifier we will
- be using to detect the white squares. The most important thing here is the
- scan_image_pyramid template. Instances of this template represent the core
- of a sliding window classifier. To go into more detail, the sliding window
- classifiers used by this object have three parts:
- 1. The underlying feature extraction. See the dlib documentation for a detailed
- discussion of how the hashed_feature_image and hog_image feature extractors
- work. However, to understand this example, all you need to know is that the
- feature extractor associates a vector with each location in an image. This
- vector is supposed to capture information which describes how parts of the
- image look. Importantly, it should do this in a way that is relevant to the
- problem you are trying to solve.
-
- 2. A detection template. This is a rectangle which defines the shape of a
- sliding window (i.e. the object_box), as well as a set of rectangular feature
- extraction regions inside it. This set of regions defines the spatial
- structure of the overall feature extraction within a sliding window. In
- particular, each location of a sliding window has a feature vector
- associated with it. This feature vector is defined as follows:
- - Let N denote the number of feature extraction zones.
- - Let M denote the dimensionality of the vectors output by Feature_extractor_type
- objects.
- - Let F(i) == the M dimensional vector which is the sum of all vectors
- given by our Feature_extractor_type object inside the ith feature extraction
- zone.
- - Then the feature vector for a sliding window is an M*N dimensional vector
- [F(1) F(2) F(3) ... F(N)] (i.e. it is a concatenation of the N vectors).
- This feature vector can be thought of as a collection of N "bags of features",
- each bag coming from a spatial location determined by one of the rectangular
- feature extraction zones.
-
- 3. A weight vector and a threshold value. The dot product between the weight
- vector and the feature vector for a sliding window location gives the score
- of the window. If this score is greater than the threshold value then the
- window location is output as a detection. You don't need to determine these
- parameters yourself. They are automatically populated by the
- structural_object_detection_trainer.
-
- The sliding window classifiers described above are applied to every level of an
- image pyramid. So you need to tell scan_image_pyramid what kind of pyramid you want
- to use. In this case we are using pyramid_down<2> which downsamples each pyramid
- layer by half (if you want to use a finer image pyramid then just change the
- template argument to a larger value. For example, using pyramid_down<5> would
- downsample each layer by a ratio of 5 to 4).
-
- Finally, some of the feature extraction zones are allowed to move freely within the
- object box. This means that when we are sliding the classifier over an image, some
- feature extraction zones are stationary (i.e. always in the same place relative to
- the object box) while others are allowed to move anywhere within the object box. In
- particular, the movable regions are placed at the locations that maximize the score
- of the classifier. Note further that each of the movable feature extraction zones
- must pass a threshold test for it to be included. That is, if the score that a
- movable zone would contribute to the overall score for a sliding window location is
- not positive then that zone is not included in the feature vector (i.e. its part of
- the feature vector is set to zero. This way the length of the feature vector stays
- constant). This movable region construction allows us to represent objects with
- parts that move around relative to the object box. For example, a human has hands
- but they aren't always in the same place relative to a person's bounding box.
- However, to keep this example program simple, we will only be using stationary
- feature extraction regions.
- */
- typedef hashed_feature_image<hog_image<3,3,1,4,hog_signed_gradient,hog_full_interpolation> > feature_extractor_type;
- typedef scan_image_pyramid<pyramid_down<2>, feature_extractor_type> image_scanner_type;
- image_scanner_type scanner;
-
- // The hashed_feature_image in the scanner needs to be supplied with a hash function capable
- // of hashing the outputs of the hog_image. Calling this function will set it up for us. The
- // 10 here indicates that it will hash HOG vectors into the range [0, pow(2,10)). Therefore,
- // the feature vectors output by the hashed_feature_image will have dimension pow(2,10).
- setup_hashed_features(scanner, images, 10);
- // We should also tell the scanner to use the uniform feature weighting scheme
- // since it works best on the data in this example. If you don't call this
- // function then it will use a slightly different weighting scheme which can give
- // improved results on many normal image types.
- use_uniform_feature_weights(scanner);
-
- // We also need to setup the detection templates the scanner will use. It is important that
- // we add detection templates which are capable of matching all the output boxes we want to learn.
- // For example, if object_locations contained a rectangle with a height to width ratio of 10 but
- // we only added square detection templates then it would be impossible to detect this non-square
- // rectangle. The setup_grid_detection_templates_verbose() routine will take care of this for us by
- // looking at the contents of object_locations and automatically picking an appropriate set. Also,
- // the final arguments indicate that we want our detection templates to have 4 feature extraction
- // regions laid out in a 2x2 regular grid inside each sliding window.
- setup_grid_detection_templates_verbose(scanner, object_locations, 2, 2);
-
-
- // Now that we have defined the kind of sliding window classifier system we want and stored
- // the details into the scanner object we are ready to use the structural_object_detection_trainer
- // to learn the weight vector and threshold needed to produce a complete object detector.
- structural_object_detection_trainer<image_scanner_type> trainer(scanner);
- trainer.set_num_threads(4); // Set this to the number of processing cores on your machine.
-
-
- // There are a variety of other useful parameters to the structural_object_detection_trainer.
- // Examples of the ones you are most likely to use follow (see dlib documentation for what they do):
- //trainer.set_match_eps(0.80);
- //trainer.set_c(1.0);
- //trainer.set_loss_per_missed_target(1);
- //trainer.set_loss_per_false_alarm(1);
-
-
- // Do the actual training and save the results into the detector object.
- object_detector<image_scanner_type> detector = trainer.train(images, object_locations);
-
- // We can easily test the new detector against our training data. This print statement will indicate that it
- // has perfect precision and recall on this simple task. It will also print the average precision (AP).
- cout << "Test detector (precision,recall,AP): " << test_object_detection_function(detector, images, object_locations) << endl;
-
- // The cross validation should also indicate perfect precision and recall.
- cout << "3-fold cross validation (precision,recall,AP): "
- << cross_validate_object_detection_trainer(trainer, images, object_locations, 3) << endl;
-
-
-
-
- // Let's display the output of the detector along with our training images.
- image_window win;
- for (unsigned long i = 0; i < images.size(); ++i)
- {
- // Run the detector on images[i]
- const std::vector<rectangle> rects = detector(images[i]);
- cout << "Number of detections: "<< rects.size() << endl;
-
- // Put the image and detections into the window.
- win.clear_overlay();
- win.set_image(images[i]);
- win.add_overlay(rects, rgb_pixel(255,0,0));
-
- cout << "Hit enter to see the next image.";
- cin.get();
- }
-
-
-
-
- // Finally, note that the detector can be serialized to disk just like other dlib objects.
- serialize("object_detector.dat") << detector;
-
- // Recall from disk.
- deserialize("object_detector.dat") >> detector;
- }
- catch (exception& e)
- {
- cout << "\nexception thrown!" << endl;
- cout << e.what() << endl;
- }
-}
-
-// ----------------------------------------------------------------------------------------
-
diff --git a/ml/dlib/examples/one_class_classifiers_ex.cpp b/ml/dlib/examples/one_class_classifiers_ex.cpp
deleted file mode 100644
index 3394ee76f..000000000
--- a/ml/dlib/examples/one_class_classifiers_ex.cpp
+++ /dev/null
@@ -1,245 +0,0 @@
-// The contents of this file are in the public domain. See LICENSE_FOR_EXAMPLE_PROGRAMS.txt
-/*
- This is an example illustrating the use of the tools in dlib for doing distribution
- estimation or detecting anomalies using one-class support vector machines.
-
- Unlike regular classifiers, these tools take unlabeled points and try to learn what
- parts of the feature space normally contain data samples and which do not. Typically
- you use these tools when you are interested in finding outliers or otherwise
- identifying "unusual" data samples.
-
- In this example, we will sample points from the sinc() function to generate our set of
- "typical looking" points. Then we will train some one-class classifiers and use them
- to predict if new points are unusual or not. In this case, unusual means a point is
- not from the sinc() curve.
-*/
-
-#include <iostream>
-#include <vector>
-#include <dlib/svm.h>
-#include <dlib/gui_widgets.h>
-#include <dlib/array2d.h>
-#include <dlib/image_transforms.h>
-
-using namespace std;
-using namespace dlib;
-
-// Here is the sinc function we will be trying to learn with the one-class SVMs
-double sinc(double x)
-{
- if (x == 0)
- return 2;
- return 2*sin(x)/x;
-}
-
-int main()
-{
- // We will use column vectors to store our points. Here we make a convenient typedef
- // for the kind of vector we will use.
- typedef matrix<double,0,1> sample_type;
-
- // Then we select the kernel we want to use. For our present problem the radial basis
- // kernel is quite effective.
- typedef radial_basis_kernel<sample_type> kernel_type;
-
- // Now make the object responsible for training one-class SVMs.
- svm_one_class_trainer<kernel_type> trainer;
- // Here we set the width of the radial basis kernel to 4.0. Larger values make the
- // width smaller and give the radial basis kernel more resolution. If you play with
- // the value and observe the program output you will get a more intuitive feel for what
- // that means.
- trainer.set_kernel(kernel_type(4.0));
-
- // Now sample some 2D points. The points will be located on the curve defined by the
- // sinc() function.
- std::vector<sample_type> samples;
- sample_type m(2);
- for (double x = -15; x <= 8; x += 0.3)
- {
- m(0) = x;
- m(1) = sinc(x);
- samples.push_back(m);
- }
-
- // Now train a one-class SVM. The result is a function, df(), that outputs large
- // values for points from the sinc() curve and smaller values for points that are
- // anomalous (i.e. not on the sinc() curve in our case).
- decision_function<kernel_type> df = trainer.train(samples);
-
- // So for example, let's look at the output from some points on the sinc() curve.
- cout << "Points that are on the sinc function:\n";
- m(0) = -1.5; m(1) = sinc(m(0)); cout << " " << df(m) << endl;
- m(0) = -1.5; m(1) = sinc(m(0)); cout << " " << df(m) << endl;
- m(0) = -0; m(1) = sinc(m(0)); cout << " " << df(m) << endl;
- m(0) = -0.5; m(1) = sinc(m(0)); cout << " " << df(m) << endl;
- m(0) = -4.1; m(1) = sinc(m(0)); cout << " " << df(m) << endl;
- m(0) = -1.5; m(1) = sinc(m(0)); cout << " " << df(m) << endl;
- m(0) = -0.5; m(1) = sinc(m(0)); cout << " " << df(m) << endl;
-
- cout << endl;
- // Now look at some outputs for points not on the sinc() curve. You will see that
- // these values are all notably smaller.
- cout << "Points that are NOT on the sinc function:\n";
- m(0) = -1.5; m(1) = sinc(m(0))+4; cout << " " << df(m) << endl;
- m(0) = -1.5; m(1) = sinc(m(0))+3; cout << " " << df(m) << endl;
- m(0) = -0; m(1) = -sinc(m(0)); cout << " " << df(m) << endl;
- m(0) = -0.5; m(1) = -sinc(m(0)); cout << " " << df(m) << endl;
- m(0) = -4.1; m(1) = sinc(m(0))+2; cout << " " << df(m) << endl;
- m(0) = -1.5; m(1) = sinc(m(0))+0.9; cout << " " << df(m) << endl;
- m(0) = -0.5; m(1) = sinc(m(0))+1; cout << " " << df(m) << endl;
-
- // The output is as follows:
- /*
- Points that are on the sinc function:
- 0.000389691
- 0.000389691
- -0.000239037
- -0.000179978
- -0.000178491
- 0.000389691
- -0.000179978
-
- Points that are NOT on the sinc function:
- -0.269389
- -0.269389
- -0.269389
- -0.269389
- -0.269389
- -0.239954
- -0.264318
- */
-
- // So we can see that in this example the one-class SVM correctly indicates that
- // the non-sinc points are definitely not points from the sinc() curve.
-
-
- // It should be noted that the svm_one_class_trainer becomes very slow when you have
- // more than 10 or 20 thousand training points. However, dlib comes with very fast SVM
- // tools which you can use instead at the cost of a little more setup. In particular,
- // it is possible to use one of dlib's very fast linear SVM solvers to train a one
- // class SVM. This is what we do below. We will train on 115,000 points and it only
- // takes a few seconds with this tool!
- //
- // The first step is constructing a feature space that is appropriate for use with a
- // linear SVM. In general, this is quite problem dependent. However, if you have
- // under about a hundred dimensions in your vectors then it can often be quite
- // effective to use the empirical_kernel_map as we do below (see the
- // empirical_kernel_map documentation and example program for an extended discussion of
- // what it does).
- //
- // But putting the empirical_kernel_map aside, the most important step in turning a
- // linear SVM into a one-class SVM is the following. We append a -1 value onto the end
- // of each feature vector and then tell the trainer to force the weight for this
- // feature to 1. This means that if the linear SVM assigned all other weights a value
- // of 0 then the output from a learned decision function would always be -1. The
- // second step is that we ask the SVM to label each training sample with +1. This
- // causes the SVM to set the other feature weights such that the training samples have
- // positive outputs from the learned decision function. But the starting bias for all
- // the points in the whole feature space is -1. The result is that points outside our
- // training set will not be affected, so their outputs from the decision function will
- // remain close to -1.
-
- empirical_kernel_map<kernel_type> ekm;
- ekm.load(trainer.get_kernel(),samples);
-
- samples.clear();
- std::vector<double> labels;
- // make a vector with just 1 element in it equal to -1.
- sample_type bias(1);
- bias = -1;
- sample_type augmented;
- // This time sample 115,000 points from the sinc() function.
- for (double x = -15; x <= 8; x += 0.0002)
- {
- m(0) = x;
- m(1) = sinc(x);
- // Apply the empirical_kernel_map transformation and then append the -1 value
- augmented = join_cols(ekm.project(m), bias);
- samples.push_back(augmented);
- labels.push_back(+1);
- }
- cout << "samples.size(): "<< samples.size() << endl;
-
- // The svm_c_linear_dcd_trainer is a very fast SVM solver which only works with the
- // linear_kernel. It has the nice feature of supporting this "force_last_weight_to_1"
- // mode we discussed above.
- svm_c_linear_dcd_trainer<linear_kernel<sample_type> > linear_trainer;
- linear_trainer.force_last_weight_to_1(true);
-
- // Train the SVM
- decision_function<linear_kernel<sample_type> > df2 = linear_trainer.train(samples, labels);
-
- // Here we test it as before, again we note that points from the sinc() curve have
- // large outputs from the decision function. Note also that we must remember to
- // transform the points in exactly the same manner used to construct the training set
- // before giving them to df2() or the code will not work.
- cout << "Points that are on the sinc function:\n";
- m(0) = -1.5; m(1) = sinc(m(0)); cout << " " << df2(join_cols(ekm.project(m),bias)) << endl;
- m(0) = -1.5; m(1) = sinc(m(0)); cout << " " << df2(join_cols(ekm.project(m),bias)) << endl;
- m(0) = -0; m(1) = sinc(m(0)); cout << " " << df2(join_cols(ekm.project(m),bias)) << endl;
- m(0) = -0.5; m(1) = sinc(m(0)); cout << " " << df2(join_cols(ekm.project(m),bias)) << endl;
- m(0) = -4.1; m(1) = sinc(m(0)); cout << " " << df2(join_cols(ekm.project(m),bias)) << endl;
- m(0) = -1.5; m(1) = sinc(m(0)); cout << " " << df2(join_cols(ekm.project(m),bias)) << endl;
- m(0) = -0.5; m(1) = sinc(m(0)); cout << " " << df2(join_cols(ekm.project(m),bias)) << endl;
-
- cout << endl;
- // Again, we see here that points not on the sinc() function have small values.
- cout << "Points that are NOT on the sinc function:\n";
- m(0) = -1.5; m(1) = sinc(m(0))+4; cout << " " << df2(join_cols(ekm.project(m),bias)) << endl;
- m(0) = -1.5; m(1) = sinc(m(0))+3; cout << " " << df2(join_cols(ekm.project(m),bias)) << endl;
- m(0) = -0; m(1) = -sinc(m(0)); cout << " " << df2(join_cols(ekm.project(m),bias)) << endl;
- m(0) = -0.5; m(1) = -sinc(m(0)); cout << " " << df2(join_cols(ekm.project(m),bias)) << endl;
- m(0) = -4.1; m(1) = sinc(m(0))+2; cout << " " << df2(join_cols(ekm.project(m),bias)) << endl;
- m(0) = -1.5; m(1) = sinc(m(0))+0.9; cout << " " << df2(join_cols(ekm.project(m),bias)) << endl;
- m(0) = -0.5; m(1) = sinc(m(0))+1; cout << " " << df2(join_cols(ekm.project(m),bias)) << endl;
-
-
- // The output is as follows:
- /*
- Points that are on the sinc function:
- 1.00454
- 1.00454
- 1.00022
- 1.00007
- 1.00371
- 1.00454
- 1.00007
-
- Points that are NOT on the sinc function:
- -1
- -1
- -1
- -1
- -0.999998
- -0.781231
- -0.96242
- */
-
-
- // Finally, to help you visualize what is happening here we are going to plot the
- // response of the one-class classifiers on the screen. The code below creates two
- // heatmap images which show the response. In these images you can clearly see where
- // the algorithms have identified the sinc() curve. The hotter the pixel looks, the
- // larger the value coming out of the decision function and therefore the more "normal"
- // it is according to the classifier.
- const long size = 500;
- array2d<double> img1(size,size);
- array2d<double> img2(size,size);
- for (long r = 0; r < img1.nr(); ++r)
- {
- for (long c = 0; c < img1.nc(); ++c)
- {
- double x = 30.0*c/size - 19;
- double y = 8.0*r/size - 4;
- m(0) = x;
- m(1) = y;
- img1[r][c] = df(m);
- img2[r][c] = df2(join_cols(ekm.project(m),bias));
- }
- }
- image_window win1(heatmap(img1), "svm_one_class_trainer");
- image_window win2(heatmap(img2), "svm_c_linear_dcd_trainer");
- win1.wait_until_closed();
-}
-
-
diff --git a/ml/dlib/examples/optimization_ex.cpp b/ml/dlib/examples/optimization_ex.cpp
deleted file mode 100644
index 2d35fa814..000000000
--- a/ml/dlib/examples/optimization_ex.cpp
+++ /dev/null
@@ -1,319 +0,0 @@
-// The contents of this file are in the public domain. See LICENSE_FOR_EXAMPLE_PROGRAMS.txt
-/*
-
- This is an example illustrating the use the general purpose non-linear
- optimization routines from the dlib C++ Library.
-
- The library provides implementations of many popular algorithms such as L-BFGS
- and BOBYQA. These algorithms allow you to find the minimum or maximum of a
- function of many input variables. This example walks though a few of the ways
- you might put these routines to use.
-
-*/
-
-
-#include <dlib/optimization.h>
-#include <dlib/global_optimization.h>
-#include <iostream>
-
-
-using namespace std;
-using namespace dlib;
-
-// ----------------------------------------------------------------------------------------
-
-// In dlib, most of the general purpose solvers optimize functions that take a
-// column vector as input and return a double. So here we make a typedef for a
-// variable length column vector of doubles. This is the type we will use to
-// represent the input to our objective functions which we will be minimizing.
-typedef matrix<double,0,1> column_vector;
-
-// ----------------------------------------------------------------------------------------
-// Below we create a few functions. When you get down into main() you will see that
-// we can use the optimization algorithms to find the minimums of these functions.
-// ----------------------------------------------------------------------------------------
-
-double rosen (const column_vector& m)
-/*
- This function computes what is known as Rosenbrock's function. It is
- a function of two input variables and has a global minimum at (1,1).
- So when we use this function to test out the optimization algorithms
- we will see that the minimum found is indeed at the point (1,1).
-*/
-{
- const double x = m(0);
- const double y = m(1);
-
- // compute Rosenbrock's function and return the result
- return 100.0*pow(y - x*x,2) + pow(1 - x,2);
-}
-
-// This is a helper function used while optimizing the rosen() function.
-const column_vector rosen_derivative (const column_vector& m)
-/*!
- ensures
- - returns the gradient vector for the rosen function
-!*/
-{
- const double x = m(0);
- const double y = m(1);
-
- // make us a column vector of length 2
- column_vector res(2);
-
- // now compute the gradient vector
- res(0) = -400*x*(y-x*x) - 2*(1-x); // derivative of rosen() with respect to x
- res(1) = 200*(y-x*x); // derivative of rosen() with respect to y
- return res;
-}
-
-// This function computes the Hessian matrix for the rosen() fuction. This is
-// the matrix of second derivatives.
-matrix<double> rosen_hessian (const column_vector& m)
-{
- const double x = m(0);
- const double y = m(1);
-
- matrix<double> res(2,2);
-
- // now compute the second derivatives
- res(0,0) = 1200*x*x - 400*y + 2; // second derivative with respect to x
- res(1,0) = res(0,1) = -400*x; // derivative with respect to x and y
- res(1,1) = 200; // second derivative with respect to y
- return res;
-}
-
-// ----------------------------------------------------------------------------------------
-
-class rosen_model
-{
- /*!
- This object is a "function model" which can be used with the
- find_min_trust_region() routine.
- !*/
-
-public:
- typedef ::column_vector column_vector;
- typedef matrix<double> general_matrix;
-
- double operator() (
- const column_vector& x
- ) const { return rosen(x); }
-
- void get_derivative_and_hessian (
- const column_vector& x,
- column_vector& der,
- general_matrix& hess
- ) const
- {
- der = rosen_derivative(x);
- hess = rosen_hessian(x);
- }
-};
-
-// ----------------------------------------------------------------------------------------
-
-int main() try
-{
- // Set the starting point to (4,8). This is the point the optimization algorithm
- // will start out from and it will move it closer and closer to the function's
- // minimum point. So generally you want to try and compute a good guess that is
- // somewhat near the actual optimum value.
- column_vector starting_point = {4, 8};
-
- // The first example below finds the minimum of the rosen() function and uses the
- // analytical derivative computed by rosen_derivative(). Since it is very easy to
- // make a mistake while coding a function like rosen_derivative() it is a good idea
- // to compare your derivative function against a numerical approximation and see if
- // the results are similar. If they are very different then you probably made a
- // mistake. So the first thing we do is compare the results at a test point:
- cout << "Difference between analytic derivative and numerical approximation of derivative: "
- << length(derivative(rosen)(starting_point) - rosen_derivative(starting_point)) << endl;
-
-
- cout << "Find the minimum of the rosen function()" << endl;
- // Now we use the find_min() function to find the minimum point. The first argument
- // to this routine is the search strategy we want to use. The second argument is the
- // stopping strategy. Below I'm using the objective_delta_stop_strategy which just
- // says that the search should stop when the change in the function being optimized
- // is small enough.
-
- // The other arguments to find_min() are the function to be minimized, its derivative,
- // then the starting point, and the last is an acceptable minimum value of the rosen()
- // function. That is, if the algorithm finds any inputs to rosen() that gives an output
- // value <= -1 then it will stop immediately. Usually you supply a number smaller than
- // the actual global minimum. So since the smallest output of the rosen function is 0
- // we just put -1 here which effectively causes this last argument to be disregarded.
-
- find_min(bfgs_search_strategy(), // Use BFGS search algorithm
- objective_delta_stop_strategy(1e-7), // Stop when the change in rosen() is less than 1e-7
- rosen, rosen_derivative, starting_point, -1);
- // Once the function ends the starting_point vector will contain the optimum point
- // of (1,1).
- cout << "rosen solution:\n" << starting_point << endl;
-
-
- // Now let's try doing it again with a different starting point and the version
- // of find_min() that doesn't require you to supply a derivative function.
- // This version will compute a numerical approximation of the derivative since
- // we didn't supply one to it.
- starting_point = {-94, 5.2};
- find_min_using_approximate_derivatives(bfgs_search_strategy(),
- objective_delta_stop_strategy(1e-7),
- rosen, starting_point, -1);
- // Again the correct minimum point is found and stored in starting_point
- cout << "rosen solution:\n" << starting_point << endl;
-
-
- // Here we repeat the same thing as above but this time using the L-BFGS
- // algorithm. L-BFGS is very similar to the BFGS algorithm, however, BFGS
- // uses O(N^2) memory where N is the size of the starting_point vector.
- // The L-BFGS algorithm however uses only O(N) memory. So if you have a
- // function of a huge number of variables the L-BFGS algorithm is probably
- // a better choice.
- starting_point = {0.8, 1.3};
- find_min(lbfgs_search_strategy(10), // The 10 here is basically a measure of how much memory L-BFGS will use.
- objective_delta_stop_strategy(1e-7).be_verbose(), // Adding be_verbose() causes a message to be
- // printed for each iteration of optimization.
- rosen, rosen_derivative, starting_point, -1);
-
- cout << endl << "rosen solution: \n" << starting_point << endl;
-
- starting_point = {-94, 5.2};
- find_min_using_approximate_derivatives(lbfgs_search_strategy(10),
- objective_delta_stop_strategy(1e-7),
- rosen, starting_point, -1);
- cout << "rosen solution: \n"<< starting_point << endl;
-
-
-
-
- // dlib also supports solving functions subject to bounds constraints on
- // the variables. So for example, if you wanted to find the minimizer
- // of the rosen function where both input variables were in the range
- // 0.1 to 0.8 you would do it like this:
- starting_point = {0.1, 0.1}; // Start with a valid point inside the constraint box.
- find_min_box_constrained(lbfgs_search_strategy(10),
- objective_delta_stop_strategy(1e-9),
- rosen, rosen_derivative, starting_point, 0.1, 0.8);
- // Here we put the same [0.1 0.8] range constraint on each variable, however, you
- // can put different bounds on each variable by passing in column vectors of
- // constraints for the last two arguments rather than scalars.
-
- cout << endl << "constrained rosen solution: \n" << starting_point << endl;
-
- // You can also use an approximate derivative like so:
- starting_point = {0.1, 0.1};
- find_min_box_constrained(bfgs_search_strategy(),
- objective_delta_stop_strategy(1e-9),
- rosen, derivative(rosen), starting_point, 0.1, 0.8);
- cout << endl << "constrained rosen solution: \n" << starting_point << endl;
-
-
-
-
- // In many cases, it is useful if we also provide second derivative information
- // to the optimizers. Two examples of how we can do that are shown below.
- starting_point = {0.8, 1.3};
- find_min(newton_search_strategy(rosen_hessian),
- objective_delta_stop_strategy(1e-7),
- rosen,
- rosen_derivative,
- starting_point,
- -1);
- cout << "rosen solution: \n"<< starting_point << endl;
-
- // We can also use find_min_trust_region(), which is also a method which uses
- // second derivatives. For some kinds of non-convex function it may be more
- // reliable than using a newton_search_strategy with find_min().
- starting_point = {0.8, 1.3};
- find_min_trust_region(objective_delta_stop_strategy(1e-7),
- rosen_model(),
- starting_point,
- 10 // initial trust region radius
- );
- cout << "rosen solution: \n"<< starting_point << endl;
-
-
-
-
-
- // Next, let's try the BOBYQA algorithm. This is a technique specially
- // designed to minimize a function in the absence of derivative information.
- // Generally speaking, it is the method of choice if derivatives are not available
- // and the function you are optimizing is smooth and has only one local optima. As
- // an example, consider the be_like_target function defined below:
- column_vector target = {3, 5, 1, 7};
- auto be_like_target = [&](const column_vector& x) {
- return mean(squared(x-target));
- };
- starting_point = {-4,5,99,3};
- find_min_bobyqa(be_like_target,
- starting_point,
- 9, // number of interpolation points
- uniform_matrix<double>(4,1, -1e100), // lower bound constraint
- uniform_matrix<double>(4,1, 1e100), // upper bound constraint
- 10, // initial trust region radius
- 1e-6, // stopping trust region radius
- 100 // max number of objective function evaluations
- );
- cout << "be_like_target solution:\n" << starting_point << endl;
-
-
-
-
-
- // Finally, let's try the find_min_global() routine. Like find_min_bobyqa(),
- // this technique is specially designed to minimize a function in the absence
- // of derivative information. However, it is also designed to handle
- // functions with many local optima. Where BOBYQA would get stuck at the
- // nearest local optima, find_min_global() won't. find_min_global() uses a
- // global optimization method based on a combination of non-parametric global
- // function modeling and BOBYQA style quadratic trust region modeling to
- // efficiently find a global minimizer. It usually does a good job with a
- // relatively small number of calls to the function being optimized.
- //
- // You also don't have to give it a starting point or set any parameters,
- // other than defining bounds constraints. This makes it the method of
- // choice for derivative free optimization in the presence of multiple local
- // optima. Its API also allows you to define functions that take a
- // column_vector as shown above or to explicitly use named doubles as
- // arguments, which we do here.
- auto complex_holder_table = [](double x0, double x1)
- {
- // This function is a version of the well known Holder table test
- // function, which is a function containing a bunch of local optima.
- // Here we make it even more difficult by adding more local optima
- // and also a bunch of discontinuities.
-
- // add discontinuities
- double sign = 1;
- for (double j = -4; j < 9; j += 0.5)
- {
- if (j < x0 && x0 < j+0.5)
- x0 += sign*0.25;
- sign *= -1;
- }
- // Holder table function tilted towards 10,10 and with additional
- // high frequency terms to add more local optima.
- return -( std::abs(sin(x0)*cos(x1)*exp(std::abs(1-std::sqrt(x0*x0+x1*x1)/pi))) -(x0+x1)/10 - sin(x0*10)*cos(x1*10));
- };
-
- // To optimize this difficult function all we need to do is call
- // find_min_global()
- auto result = find_min_global(complex_holder_table,
- {-10,-10}, // lower bounds
- {10,10}, // upper bounds
- max_function_calls(300));
-
- cout.precision(9);
- // These cout statements will show that find_min_global() found the
- // globally optimal solution to 9 digits of precision:
- cout << "complex holder table function solution y (should be -21.9210397): " << result.y << endl;
- cout << "complex holder table function solution x:\n" << result.x << endl;
-}
-catch (std::exception& e)
-{
- cout << e.what() << endl;
-}
-
diff --git a/ml/dlib/examples/parallel_for_ex.cpp b/ml/dlib/examples/parallel_for_ex.cpp
deleted file mode 100644
index 70fccab20..000000000
--- a/ml/dlib/examples/parallel_for_ex.cpp
+++ /dev/null
@@ -1,158 +0,0 @@
-// The contents of this file are in the public domain. See LICENSE_FOR_EXAMPLE_PROGRAMS.txt
-/*
-
- This is an example illustrating the use of the parallel for loop tools from the dlib
- C++ Library.
-
- Normally, a for loop executes the body of the loop in a serial manner. This means
- that, for example, if it takes 1 second to execute the body of the loop and the body
- needs to execute 10 times then it will take 10 seconds to execute the entire loop.
- However, on modern multi-core computers we have the opportunity to speed this up by
- executing multiple steps of a for loop in parallel. This example program will walk you
- though a few examples showing how to do just that.
-*/
-
-
-#include <dlib/threads.h>
-#include <dlib/misc_api.h> // for dlib::sleep
-#include <vector>
-#include <iostream>
-
-using namespace dlib;
-using namespace std;
-
-// ----------------------------------------------------------------------------------------
-
-void print(const std::vector<int>& vect)
-{
- for (unsigned long i = 0; i < vect.size(); ++i)
- {
- cout << vect[i] << endl;
- }
- cout << "\n**************************************\n";
-}
-
-// ----------------------------------------------------------------------------------------
-
-void example_using_regular_non_parallel_loops();
-void example_using_lambda_functions();
-
-// ----------------------------------------------------------------------------------------
-
-int main()
-{
- // We have 2 examples, each contained in a separate function. Both examples perform
- // exactly the same computation, however, the second does so using parallel for loops.
- // The first example is here to show you what we are doing in terms of classical
- // non-parallel for loops. The other example will illustrate how to parallelize the
- // for loops in C++11.
-
- example_using_regular_non_parallel_loops();
- example_using_lambda_functions();
-}
-
-// ----------------------------------------------------------------------------------------
-
-void example_using_regular_non_parallel_loops()
-{
- cout << "\nExample using regular non-parallel for loops\n" << endl;
-
- std::vector<int> vect;
-
- // put 10 elements into vect which are all equal to -1
- vect.assign(10, -1);
-
- // Now set each element equal to its index value. We put a sleep call in here so that
- // when we run the same thing with a parallel for loop later on you will be able to
- // observe the speedup.
- for (unsigned long i = 0; i < vect.size(); ++i)
- {
- vect[i] = i;
- dlib::sleep(1000); // sleep for 1 second
- }
- print(vect);
-
-
-
- // Assign only part of the elements in vect.
- vect.assign(10, -1);
- for (unsigned long i = 1; i < 5; ++i)
- {
- vect[i] = i;
- dlib::sleep(1000);
- }
- print(vect);
-
-
-
- // Sum all element sin vect.
- int sum = 0;
- vect.assign(10, 2);
- for (unsigned long i = 0; i < vect.size(); ++i)
- {
- dlib::sleep(1000);
- sum += vect[i];
- }
-
- cout << "sum: "<< sum << endl;
-}
-
-// ----------------------------------------------------------------------------------------
-
-void example_using_lambda_functions()
-{
- cout << "\nExample using parallel for loops\n" << endl;
-
- std::vector<int> vect;
-
- vect.assign(10, -1);
- parallel_for(0, vect.size(), [&](long i){
- // The i variable is the loop counter as in a normal for loop. So we simply need
- // to place the body of the for loop right here and we get the same behavior. The
- // range for the for loop is determined by the 1nd and 2rd arguments to
- // parallel_for(). This way of calling parallel_for() will use a number of threads
- // that is appropriate for your hardware. See the parallel_for() documentation for
- // other options.
- vect[i] = i;
- dlib::sleep(1000);
- });
- print(vect);
-
-
- // Assign only part of the elements in vect.
- vect.assign(10, -1);
- parallel_for(1, 5, [&](long i){
- vect[i] = i;
- dlib::sleep(1000);
- });
- print(vect);
-
-
- // Note that things become a little more complex if the loop bodies are not totally
- // independent. In the first two cases each iteration of the loop touched different
- // memory locations, so we didn't need to use any kind of thread synchronization.
- // However, in the summing loop we need to add some synchronization to protect the sum
- // variable. This is easily accomplished by creating a mutex and locking it before
- // adding to sum. More generally, you must ensure that the bodies of your parallel for
- // loops are thread safe using whatever means is appropriate for your code. Since a
- // parallel for loop is implemented using threads, all the usual techniques for
- // ensuring thread safety can be used.
- int sum = 0;
- dlib::mutex m;
- vect.assign(10, 2);
- parallel_for(0, vect.size(), [&](long i){
- // The sleep statements still execute in parallel.
- dlib::sleep(1000);
-
- // Lock the m mutex. The auto_mutex will automatically unlock at the closing }.
- // This will ensure only one thread can execute the sum += vect[i] statement at
- // a time.
- auto_mutex lock(m);
- sum += vect[i];
- });
-
- cout << "sum: "<< sum << endl;
-}
-
-// ----------------------------------------------------------------------------------------
-
diff --git a/ml/dlib/examples/pipe_ex.cpp b/ml/dlib/examples/pipe_ex.cpp
deleted file mode 100644
index 9298dba1b..000000000
--- a/ml/dlib/examples/pipe_ex.cpp
+++ /dev/null
@@ -1,172 +0,0 @@
-// The contents of this file are in the public domain. See LICENSE_FOR_EXAMPLE_PROGRAMS.txt
-
-
-/*
- This is an example illustrating the use of the threading API and pipe object
- from the dlib C++ Library.
-
- In this example we will create three threads that will read "jobs" off the end of
- a pipe object and process them. It shows you how you can use the pipe object
- to communicate between threads.
-
-
- Example program output:
- 0 INFO [0] pipe_example: Add job 0 to pipe
- 0 INFO [0] pipe_example: Add job 1 to pipe
- 0 INFO [0] pipe_example: Add job 2 to pipe
- 0 INFO [0] pipe_example: Add job 3 to pipe
- 0 INFO [0] pipe_example: Add job 4 to pipe
- 0 INFO [0] pipe_example: Add job 5 to pipe
- 0 INFO [1] pipe_example: got job 0
- 0 INFO [0] pipe_example: Add job 6 to pipe
- 0 INFO [2] pipe_example: got job 1
- 0 INFO [0] pipe_example: Add job 7 to pipe
- 0 INFO [3] pipe_example: got job 2
- 103 INFO [0] pipe_example: Add job 8 to pipe
- 103 INFO [1] pipe_example: got job 3
- 103 INFO [0] pipe_example: Add job 9 to pipe
- 103 INFO [2] pipe_example: got job 4
- 103 INFO [0] pipe_example: Add job 10 to pipe
- 103 INFO [3] pipe_example: got job 5
- 207 INFO [0] pipe_example: Add job 11 to pipe
- 207 INFO [1] pipe_example: got job 6
- 207 INFO [0] pipe_example: Add job 12 to pipe
- 207 INFO [2] pipe_example: got job 7
- 207 INFO [0] pipe_example: Add job 13 to pipe
- 207 INFO [3] pipe_example: got job 8
- 311 INFO [1] pipe_example: got job 9
- 311 INFO [2] pipe_example: got job 10
- 311 INFO [3] pipe_example: got job 11
- 311 INFO [0] pipe_example: Add job 14 to pipe
- 311 INFO [0] pipe_example: main ending
- 311 INFO [0] pipe_example: destructing pipe object: wait for job_pipe to be empty
- 415 INFO [1] pipe_example: got job 12
- 415 INFO [2] pipe_example: got job 13
- 415 INFO [3] pipe_example: got job 14
- 415 INFO [0] pipe_example: destructing pipe object: job_pipe is empty
- 519 INFO [1] pipe_example: thread ending
- 519 INFO [2] pipe_example: thread ending
- 519 INFO [3] pipe_example: thread ending
- 519 INFO [0] pipe_example: destructing pipe object: all threads have ended
-
-
- The first column is the number of milliseconds since program start, the second
- column is the logging level, the third column is the thread id, and the rest
- is the log message.
-*/
-
-
-#include <dlib/threads.h>
-#include <dlib/misc_api.h> // for dlib::sleep
-#include <dlib/pipe.h>
-#include <dlib/logger.h>
-
-using namespace dlib;
-
-struct job
-{
- /*
- This object represents the jobs we are going to send out to our threads.
- */
- int id;
-};
-
-dlib::logger dlog("pipe_example");
-
-// ----------------------------------------------------------------------------------------
-
-class pipe_example : private multithreaded_object
-{
-public:
- pipe_example(
- ) :
- job_pipe(4) // This 4 here is the size of our job_pipe. The significance is that
- // if you try to enqueue more than 4 jobs onto the pipe then enqueue() will
- // block until there is room.
- {
- // register 3 threads
- register_thread(*this,&pipe_example::thread);
- register_thread(*this,&pipe_example::thread);
- register_thread(*this,&pipe_example::thread);
-
- // start the 3 threads we registered above
- start();
- }
-
- ~pipe_example (
- )
- {
- dlog << LINFO << "destructing pipe object: wait for job_pipe to be empty";
- // wait for all the jobs to be processed
- job_pipe.wait_until_empty();
-
- dlog << LINFO << "destructing pipe object: job_pipe is empty";
-
- // now disable the job_pipe. doing this will cause all calls to
- // job_pipe.dequeue() to return false so our threads will terminate
- job_pipe.disable();
-
- // now block until all the threads have terminated
- wait();
- dlog << LINFO << "destructing pipe object: all threads have ended";
- }
-
- // Here we declare our pipe object. It will contain our job objects.
- // There are only two requirements on the type of objects you can use in a
- // pipe, first they must have a default constructor and second they must
- // be swappable by a global swap().
- dlib::pipe<job> job_pipe;
-
-private:
- void thread ()
- {
- job j;
- // Here we loop on jobs from the job_pipe.
- while (job_pipe.dequeue(j))
- {
- // process our job j in some way.
- dlog << LINFO << "got job " << j.id;
-
- // sleep for 0.1 seconds
- dlib::sleep(100);
- }
- dlog << LINFO << "thread ending";
- }
-
-};
-
-// ----------------------------------------------------------------------------------------
-
-int main()
-{
- // Set the dlog object so that it logs everything.
- dlog.set_level(LALL);
-
- pipe_example pe;
-
- for (int i = 0; i < 15; ++i)
- {
- dlog << LINFO << "Add job " << i << " to pipe";
- job j;
- j.id = i;
-
-
- // Add this job to the pipe. One of our three threads will get it and process it.
- // It should also be pointed out that the enqueue() function uses the global
- // swap function to move jobs into the pipe. This means that it modifies the
- // jobs we are passing in to it. This allows you to implement a fast swap
- // operator for your jobs. For example, std::vector objects have a global
- // swap and it can execute in constant time by just swapping pointers inside
- // std::vector. This means that the dlib::pipe is effectively a zero-copy
- // message passing system if you setup global swap for your jobs.
- pe.job_pipe.enqueue(j);
- }
-
- dlog << LINFO << "main ending";
-
- // the main function won't really terminate here. It will call the destructor for pe
- // which will block until all the jobs have been processed.
-}
-
-// ----------------------------------------------------------------------------------------
-
diff --git a/ml/dlib/examples/pipe_ex_2.cpp b/ml/dlib/examples/pipe_ex_2.cpp
deleted file mode 100644
index 53998dbe8..000000000
--- a/ml/dlib/examples/pipe_ex_2.cpp
+++ /dev/null
@@ -1,160 +0,0 @@
-// The contents of this file are in the public domain. See LICENSE_FOR_EXAMPLE_PROGRAMS.txt
-
-
-/*
- This is an example showing how to use the type_safe_union and pipe object from
- from the dlib C++ Library to send messages between threads.
-
- In this example we will create a class with a single thread in it. This thread
- will receive messages from a pipe object and simply print them to the screen.
- The interesting thing about this example is that it shows how to use a pipe and
- type_safe_union to create a message channel between threads that can send many
- different types of objects in a type safe manner.
-
-
-
- Program output:
- got a float: 4.567
- got a string: string message
- got an int: 7
- got a string: yet another string message
-*/
-
-
-#include <dlib/threads.h>
-#include <dlib/pipe.h>
-#include <dlib/type_safe_union.h>
-#include <iostream>
-
-using namespace dlib;
-using namespace std;
-
-// ----------------------------------------------------------------------------------------
-
-typedef type_safe_union<int, float, std::string> tsu_type;
-/* This is a typedef for the type_safe_union we will be using in this example.
- This type_safe_union object is a type-safe analogue of a union declared as follows:
- union our_union_type
- {
- int a;
- float b;
- std::string c;
- };
-
- Note that the above union isn't actually valid C++ code because it contains a
- non-POD type. That is, you can't put a std::string or any non-trivial
- C++ class in a union. The type_safe_union, however, enables you to store non-POD
- types such as the std::string.
-
-*/
-
-// ----------------------------------------------------------------------------------------
-
-class pipe_example : private threaded_object
-{
-public:
- pipe_example(
- ) :
- message_pipe(4) // This 4 here is the size of our message_pipe. The significance is that
- // if you try to enqueue more than 4 messages onto the pipe then enqueue() will
- // block until there is room.
- {
- // start the thread
- start();
- }
-
- ~pipe_example (
- )
- {
- // wait for all the messages to be processed
- message_pipe.wait_until_empty();
-
- // Now disable the message_pipe. Doing this will cause all calls to
- // message_pipe.dequeue() to return false so our thread will terminate
- message_pipe.disable();
-
- // now block until our thread has terminated
- wait();
- }
-
- // Here we declare our pipe object. It will contain our messages.
- dlib::pipe<tsu_type> message_pipe;
-
-private:
-
- // When we call apply_to_contents() below these are the
- // functions which get called.
- void operator() (int val)
- {
- cout << "got an int: " << val << endl;
- }
-
- void operator() (float val)
- {
- cout << "got a float: " << val << endl;
- }
-
- void operator() (std::string val)
- {
- cout << "got a string: " << val << endl;
- }
-
- void thread ()
- {
- tsu_type msg;
-
- // Here we loop on messages from the message_pipe.
- while (message_pipe.dequeue(msg))
- {
- // Here we call the apply_to_contents() function on our type_safe_union.
- // It takes a function object and applies that function object
- // to the contents of the union. In our case we have setup
- // the pipe_example class as our function object and so below we
- // tell the msg object to take whatever it contains and
- // call (*this)(contained_object); So what happens here is
- // one of the three above functions gets called with the message
- // we just got.
- msg.apply_to_contents(*this);
- }
- }
-
- // Finally, note that since we declared the operator() member functions
- // private we need to declare the type_safe_union as a friend of this
- // class so that it will be able to call them.
- friend class type_safe_union<int, float, std::string>;
-
-};
-
-// ----------------------------------------------------------------------------------------
-
-int main()
-{
- pipe_example pe;
-
- // Make one of our type_safe_union objects
- tsu_type msg;
-
- // Treat our msg as a float and assign it 4.567
- msg.get<float>() = 4.567f;
- // Now put the message into the pipe
- pe.message_pipe.enqueue(msg);
-
- // Put a string into the pipe
- msg.get<std::string>() = "string message";
- pe.message_pipe.enqueue(msg);
-
- // And now an int
- msg.get<int>() = 7;
- pe.message_pipe.enqueue(msg);
-
- // And another string
- msg.get<std::string>() = "yet another string message";
- pe.message_pipe.enqueue(msg);
-
-
- // the main function won't really terminate here. It will call the destructor for pe
- // which will block until all the messages have been processed.
-}
-
-// ----------------------------------------------------------------------------------------
-
diff --git a/ml/dlib/examples/quantum_computing_ex.cpp b/ml/dlib/examples/quantum_computing_ex.cpp
deleted file mode 100644
index fcc7c845f..000000000
--- a/ml/dlib/examples/quantum_computing_ex.cpp
+++ /dev/null
@@ -1,337 +0,0 @@
-// The contents of this file are in the public domain. See LICENSE_FOR_EXAMPLE_PROGRAMS.txt
-/*
- This is an example illustrating the use of the quantum computing
- simulation classes from the dlib C++ Library.
-
- This example assumes you are familiar with quantum computing and
- Grover's search algorithm and Shor's 9 bit error correcting code
- in particular. The example shows how to simulate both of these
- algorithms.
-
-
- The code to simulate Grover's algorithm is primarily here to show
- you how to make custom quantum gate objects. The Shor ECC example
- is simpler and uses just the default gates that come with the
- library.
-
-*/
-
-
-#include <iostream>
-#include <complex>
-#include <ctime>
-#include <dlib/quantum_computing.h>
-#include <dlib/string.h>
-
-
-using namespace std;
-using namespace dlib;
-
-// ----------------------------------------------------------------------------------------
-// ----------------------------------------------------------------------------------------
-// ----------------------------------------------------------------------------------------
-
-// This declares a random number generator that we will be using below
-dlib::rand rnd;
-
-// ----------------------------------------------------------------------------------------
-
-void shor_encode (
- quantum_register& reg
-)
-/*!
- requires
- - reg.num_bits() == 1
- ensures
- - #reg.num_bits() == 9
- - #reg == the Shor error coding of the input register
-!*/
-{
- DLIB_CASSERT(reg.num_bits() == 1,"");
-
- quantum_register zeros;
- zeros.set_num_bits(8);
- reg.append(zeros);
-
- using namespace dlib::quantum_gates;
- const gate<1> h = hadamard();
- const gate<1> i = noop();
-
- // Note that the expression (h,i) represents the tensor product of the 1 qubit
- // h gate with the 1 qubit i gate and larger versions of this expression
- // represent even bigger tensor products. So as you see below, we make gates
- // big enough to apply to our quantum register by listing out all the gates we
- // want to go into the tensor product and then we just apply the resulting gate
- // to the quantum register.
-
- // Now apply the gates that constitute Shor's encoding to the input register.
- (cnot<3,0>(),i,i,i,i,i).apply_gate_to(reg);
- (cnot<6,0>(),i,i).apply_gate_to(reg);
- (h,i,i,h,i,i,h,i,i).apply_gate_to(reg);
- (cnot<1,0>(),i,cnot<1,0>(),i,cnot<1,0>(),i).apply_gate_to(reg);
- (cnot<2,0>(),cnot<2,0>(),cnot<2,0>()).apply_gate_to(reg);
-}
-
-// ----------------------------------------------------------------------------------------
-
-void shor_decode (
- quantum_register& reg
-)
-/*!
- requires
- - reg.num_bits() == 9
- ensures
- - #reg.num_bits() == 1
- - #reg == the decoded qubit that was in the given input register
-!*/
-{
- DLIB_CASSERT(reg.num_bits() == 9,"");
-
- using namespace dlib::quantum_gates;
- const gate<1> h = hadamard();
- const gate<1> i = noop();
-
- // Now apply the gates that constitute Shor's decoding to the input register
-
- (cnot<2,0>(),cnot<2,0>(),cnot<2,0>()).apply_gate_to(reg);
- (cnot<1,0>(),i,cnot<1,0>(),i,cnot<1,0>(),i).apply_gate_to(reg);
-
- (toffoli<0,1,2>(),toffoli<0,1,2>(),toffoli<0,1,2>()).apply_gate_to(reg);
-
- (h,i,i,h,i,i,h,i,i).apply_gate_to(reg);
-
- (cnot<6,0>(),i,i).apply_gate_to(reg);
- (cnot<3,0>(),i,i,i,i,i).apply_gate_to(reg);
- (toffoli<0,3,6>(),i,i).apply_gate_to(reg);
-
- // Now that we have decoded the value we don't need the extra 8 bits any more so
- // remove them from the register.
- for (int i = 0; i < 8; ++i)
- reg.measure_and_remove_bit(0,rnd);
-}
-
-// ----------------------------------------------------------------------------------------
-// ----------------------------------------------------------------------------------------
-// ----------------------------------------------------------------------------------------
-
-// This is the function we will use in Grover's search algorithm. In this
-// case the value we are searching for is 257.
-bool is_key (unsigned long n)
-{
- return n == 257;
-}
-
-// ----------------------------------------------------------------------------------------
-
-template <int bits>
-class uf_gate;
-
-namespace dlib {
-template <int bits>
-struct gate_traits<uf_gate<bits> >
-{
- static const long num_bits = bits;
- static const long dims = dlib::qc_helpers::exp_2_n<num_bits>::value;
-};}
-
-template <int bits>
-class uf_gate : public gate_exp<uf_gate<bits> >
-{
- /*!
- This gate represents the black box function in Grover's search algorithm.
- That is, it is the gate defined as follows:
- Uf|x>|y> = |x>|y XOR is_key(x)>
-
- See the documentation for the gate_exp object for the details regarding
- the compute_state_element() and operator() functions defined below.
- !*/
-public:
- uf_gate() : gate_exp<uf_gate>(*this) {}
-
- static const long num_bits = gate_traits<uf_gate>::num_bits;
- static const long dims = gate_traits<uf_gate>::dims;
-
- const qc_scalar_type operator() (long r, long c) const
- {
- unsigned long output = c;
- // if the input control bit is set
- if (is_key(output>>1))
- {
- output = output^0x1;
- }
-
- if ((unsigned long)r == output)
- return 1;
- else
- return 0;
- }
-
- template <typename exp>
- qc_scalar_type compute_state_element (
- const matrix_exp<exp>& reg,
- long row_idx
- ) const
- {
- unsigned long output = row_idx;
- // if the input control bit is set
- if (is_key(output>>1))
- {
- output = output^0x1;
- }
-
- return reg(output);
- }
-};
-
-// ----------------------------------------------------------------------------------------
-
-template <int bits>
-class w_gate;
-
-namespace dlib {
-template <int bits>
-struct gate_traits<w_gate<bits> >
-{
- static const long num_bits = bits;
- static const long dims = dlib::qc_helpers::exp_2_n<num_bits>::value;
-}; }
-
-template <int bits>
-class w_gate : public gate_exp<w_gate<bits> >
-{
- /*!
- This is the W gate from the Grover algorithm
- !*/
-public:
-
- w_gate() : gate_exp<w_gate>(*this) {}
-
- static const long num_bits = gate_traits<w_gate>::num_bits;
- static const long dims = gate_traits<w_gate>::dims;
-
- const qc_scalar_type operator() (long r, long c) const
- {
- qc_scalar_type res = 2.0/dims;
- if (r != c)
- return res;
- else
- return res - 1.0;
- }
-
- template <typename exp>
- qc_scalar_type compute_state_element (
- const matrix_exp<exp>& reg,
- long row_idx
- ) const
- {
- qc_scalar_type temp = sum(reg)*2.0/dims;
- // compute this value: temp = temp - reg(row_idx)*2.0/dims + reg(row_idx)*(2.0/dims - 1.0)
- temp = temp - reg(row_idx);
-
- return temp;
- }
-};
-
-// ----------------------------------------------------------------------------------------
-// ----------------------------------------------------------------------------------------
-// ----------------------------------------------------------------------------------------
-
-int main()
-{
- // seed the random number generator
- rnd.set_seed(cast_to_string(time(0)));
-
- // Pick out some of the gates we will be using below
- using namespace dlib::quantum_gates;
- const gate<1> h = quantum_gates::hadamard();
- const gate<1> z = quantum_gates::z();
- const gate<1> x = quantum_gates::x();
- const gate<1> i = quantum_gates::noop();
-
- quantum_register reg;
-
- // We will be doing the 12 qubit version of Grover's search algorithm.
- const int bits=12;
- reg.set_num_bits(bits);
-
-
- // set the quantum register to its initial state
- (i,i, i,i,i,i,i, i,i,i,i,x).apply_gate_to(reg);
-
- // Print out the starting bits
- cout << "starting bits: ";
- for (int i = reg.num_bits()-1; i >= 0; --i)
- cout << reg.probability_of_bit(i);
- cout << endl;
-
-
- // Now apply the Hadamard gate to all the input bits
- (h,h, h,h,h,h,h, h,h,h,h,h).apply_gate_to(reg);
-
- // Here we do the grover iteration
- for (int j = 0; j < 35; ++j)
- {
- (uf_gate<bits>()).apply_gate_to(reg);
- (w_gate<bits-1>(),i).apply_gate_to(reg);
-
-
- cout << j << " probability: bit 1 = " << reg.probability_of_bit(1) << ", bit 9 = " << reg.probability_of_bit(9) << endl;
- }
-
- cout << endl;
-
- // Print out the final probability of measuring a 1 for each of the bits
- for (int i = reg.num_bits()-1; i >= 1; --i)
- cout << "probability for bit " << i << " = " << reg.probability_of_bit(i) << endl;
- cout << endl;
-
- cout << "The value we want grover's search to find is 257 which means we should measure a bit pattern of 00100000001" << endl;
- cout << "Measured bits: ";
- // finally, measure all the bits and print out what they are.
- for (int i = reg.num_bits()-1; i >= 1; --i)
- cout << reg.measure_bit(i,rnd);
- cout << endl;
-
-
-
-
-
- // Now let's test out the Shor 9 bit encoding
- cout << "\n\n\n\nNow let's try playing around with Shor's 9bit error correcting code" << endl;
-
- // Reset the quantum register to contain a single bit
- reg.set_num_bits(1);
- // Set the state of this single qubit to some random mixture of the two computational bases
- reg.state_vector()(0) = qc_scalar_type(rnd.get_random_double(),rnd.get_random_double());
- reg.state_vector()(1) = qc_scalar_type(rnd.get_random_double(),rnd.get_random_double());
- // Make sure the state of the quantum register is a unit vector
- reg.state_vector() /= sqrt(sum(norm(reg.state_vector())));
-
- cout << "state: " << trans(reg.state_vector());
-
- shor_encode(reg);
- cout << "x bit corruption on bit 8" << endl;
- (x,i,i,i,i,i,i,i,i).apply_gate_to(reg); // mess up the high order bit
- shor_decode(reg); // try to decode the register
-
- cout << "state: " << trans(reg.state_vector());
-
- shor_encode(reg);
- cout << "x bit corruption on bit 1" << endl;
- (i,i,i,i,i,i,i,x,i).apply_gate_to(reg);
- shor_decode(reg);
-
- cout << "state: " << trans(reg.state_vector());
-
- shor_encode(reg);
- cout << "z bit corruption on bit 8" << endl;
- (z,i,i,i,i,i,i,i,i).apply_gate_to(reg);
- shor_decode(reg);
-
- cout << "state: " << trans(reg.state_vector());
-
- cout << "\nThe state of the input qubit survived all the corruptions in tact so the code works." << endl;
-
-}
-
-
diff --git a/ml/dlib/examples/queue_ex.cpp b/ml/dlib/examples/queue_ex.cpp
deleted file mode 100644
index c79bf25eb..000000000
--- a/ml/dlib/examples/queue_ex.cpp
+++ /dev/null
@@ -1,78 +0,0 @@
-// The contents of this file are in the public domain. See LICENSE_FOR_EXAMPLE_PROGRAMS.txt
-/*
-
- This is an example illustrating the use of the queue component (and
- to some degree the general idea behind most of the other container
- classes) from the dlib C++ Library.
-
- It loads a queue with 20 random numbers. Then it uses the enumerable
- interface to print them all to the screen. Then it sorts the numbers and
- prints them to the screen.
-*/
-
-
-
-
-#include <dlib/queue.h>
-#include <iostream>
-#include <iomanip>
-#include <ctime>
-#include <cstdlib>
-
-
-// I'm picking the version of the queue that is kernel_2a extended by
-// the queue sorting extension. This is just a normal queue but with the
-// added member function sort() which sorts the queue.
-typedef dlib::queue<int>::sort_1b_c queue_of_int;
-
-
-using namespace std;
-using namespace dlib;
-
-
-int main()
-{
- queue_of_int q;
-
- // initialize rand()
- srand(time(0));
-
- for (int i = 0; i < 20; ++i)
- {
- int a = rand()&0xFF;
-
- // note that adding a to the queue "consumes" the value of a because
- // all container classes move values around by swapping them rather
- // than copying them. So a is swapped into the queue which results
- // in a having an initial value for its type (for int types that value
- // is just some undefined value. )
- q.enqueue(a);
-
- }
-
-
- cout << "The contents of the queue are:\n";
- while (q.move_next())
- cout << q.element() << " ";
-
- cout << "\n\nNow we sort the queue and its contents are:\n";
- q.sort(); // note that we don't have to call q.reset() to put the enumerator
- // back at the start of the queue because calling sort() does
- // that automatically for us. (In general, modifying a container
- // will reset the enumerator).
- while (q.move_next())
- cout << q.element() << " ";
-
-
- cout << "\n\nNow we remove the numbers from the queue:\n";
- while (q.size() > 0)
- {
- int a;
- q.dequeue(a);
- cout << a << " ";
- }
-
-
- cout << endl;
-}
-
diff --git a/ml/dlib/examples/random_cropper_ex.cpp b/ml/dlib/examples/random_cropper_ex.cpp
deleted file mode 100644
index 6b020058d..000000000
--- a/ml/dlib/examples/random_cropper_ex.cpp
+++ /dev/null
@@ -1,99 +0,0 @@
-// The contents of this file are in the public domain. See LICENSE_FOR_EXAMPLE_PROGRAMS.txt
-/*
- When you are training a convolutional neural network using the loss_mmod loss
- layer, you need to generate a bunch of identically sized training images. The
- random_cropper is a convenient tool to help you crop out a bunch of
- identically sized images from a training dataset.
-
- This example shows you what it does exactly and talks about some of its options.
-*/
-
-
-#include <iostream>
-#include <dlib/data_io.h>
-#include <dlib/gui_widgets.h>
-#include <dlib/image_transforms.h>
-
-using namespace std;
-using namespace dlib;
-
-// ----------------------------------------------------------------------------------------
-
-int main(int argc, char** argv) try
-{
- if (argc != 2)
- {
- cout << "Give an image dataset XML file to run this program." << endl;
- cout << "For example, if you are running from the examples folder then run this program by typing" << endl;
- cout << " ./random_cropper_ex faces/training.xml" << endl;
- cout << endl;
- return 0;
- }
-
- // First lets load a dataset
- std::vector<matrix<rgb_pixel>> images;
- std::vector<std::vector<mmod_rect>> boxes;
- load_image_dataset(images, boxes, argv[1]);
-
- // Here we make our random_cropper. It has a number of options.
- random_cropper cropper;
- // We can tell it how big we want the cropped images to be.
- cropper.set_chip_dims(400,400);
- // Also, when doing cropping, it will map the object annotations from the
- // dataset to the cropped image as well as perform random scale jittering.
- // You can tell it how much scale jittering you would like by saying "please
- // make the objects in the crops have a min and max size of such and such".
- // You do that by calling these two functions. Here we are saying we want the
- // objects in our crops to be no more than 0.8*400 pixels in height and width.
- cropper.set_max_object_size(0.8);
- // And also that they shouldn't be too small. Specifically, each object's smallest
- // dimension (i.e. height or width) should be at least 60 pixels and at least one of
- // the dimensions must be at least 80 pixels. So the smallest objects the cropper will
- // output will be either 80x60 or 60x80.
- cropper.set_min_object_size(80,60);
- // The cropper can also randomly mirror and rotate crops, which we ask it to
- // perform as well.
- cropper.set_randomly_flip(true);
- cropper.set_max_rotation_degrees(50);
- // This fraction of crops are from random parts of images, rather than being centered
- // on some object.
- cropper.set_background_crops_fraction(0.2);
-
- // Now ask the cropper to generate a bunch of crops. The output is stored in
- // crops and crop_boxes.
- std::vector<matrix<rgb_pixel>> crops;
- std::vector<std::vector<mmod_rect>> crop_boxes;
- // Make 1000 crops.
- cropper(1000, images, boxes, crops, crop_boxes);
-
- // Finally, lets look at the results
- image_window win;
- for (size_t i = 0; i < crops.size(); ++i)
- {
- win.clear_overlay();
- win.set_image(crops[i]);
- for (auto b : crop_boxes[i])
- {
- // Note that mmod_rect has an ignore field. If an object was labeled
- // ignore in boxes then it will still be labeled as ignore in
- // crop_boxes. Moreover, objects that are not well contained within
- // the crop are also set to ignore.
- if (b.ignore)
- win.add_overlay(b.rect, rgb_pixel(255,255,0)); // draw ignored boxes as orange
- else
- win.add_overlay(b.rect, rgb_pixel(255,0,0)); // draw other boxes as red
- }
- cout << "Hit enter to view the next random crop.";
- cin.get();
- }
-
-}
-catch(std::exception& e)
-{
- cout << e.what() << endl;
-}
-
-
-
-
-
diff --git a/ml/dlib/examples/rank_features_ex.cpp b/ml/dlib/examples/rank_features_ex.cpp
deleted file mode 100644
index 548db4be7..000000000
--- a/ml/dlib/examples/rank_features_ex.cpp
+++ /dev/null
@@ -1,152 +0,0 @@
-// The contents of this file are in the public domain. See LICENSE_FOR_EXAMPLE_PROGRAMS.txt
-/*
-
- This is an example illustrating the use of the rank_features() function
- from the dlib C++ Library.
-
- This example creates a simple set of data and then shows
- you how to use the rank_features() function to find a good
- set of features (where "good" means the feature set will probably
- work well with a classification algorithm).
-
- The data used in this example will be 4 dimensional data and will
- come from a distribution where points with a distance less than 10
- from the origin are labeled +1 and all other points are labeled
- as -1. Note that this data is conceptually 2 dimensional but we
- will add two extra features for the purpose of showing what
- the rank_features() function does.
-*/
-
-
-#include <iostream>
-#include <dlib/svm.h>
-#include <dlib/rand.h>
-#include <vector>
-
-using namespace std;
-using namespace dlib;
-
-
-int main()
-{
-
- // This first typedef declares a matrix with 4 rows and 1 column. It will be the
- // object that contains each of our 4 dimensional samples.
- typedef matrix<double, 4, 1> sample_type;
-
-
-
- // Now let's make some vector objects that can hold our samples
- std::vector<sample_type> samples;
- std::vector<double> labels;
-
- dlib::rand rnd;
-
- for (int x = -30; x <= 30; ++x)
- {
- for (int y = -30; y <= 30; ++y)
- {
- sample_type samp;
-
- // the first two features are just the (x,y) position of our points and so
- // we expect them to be good features since our two classes here are points
- // close to the origin and points far away from the origin.
- samp(0) = x;
- samp(1) = y;
-
- // This is a worthless feature since it is just random noise. It should
- // be indicated as worthless by the rank_features() function below.
- samp(2) = rnd.get_random_double();
-
- // This is a version of the y feature that is corrupted by random noise. It
- // should be ranked as less useful than features 0, and 1, but more useful
- // than the above feature.
- samp(3) = y*0.2 + (rnd.get_random_double()-0.5)*10;
-
- // add this sample into our vector of samples.
- samples.push_back(samp);
-
- // if this point is less than 15 from the origin then label it as a +1 class point.
- // otherwise it is a -1 class point
- if (sqrt((double)x*x + y*y) <= 15)
- labels.push_back(+1);
- else
- labels.push_back(-1);
- }
- }
-
-
- // Here we normalize all the samples by subtracting their mean and dividing by their standard deviation.
- // This is generally a good idea since it often heads off numerical stability problems and also
- // prevents one large feature from smothering others.
- const sample_type m(mean(mat(samples))); // compute a mean vector
- const sample_type sd(reciprocal(stddev(mat(samples)))); // compute a standard deviation vector
- // now normalize each sample
- for (unsigned long i = 0; i < samples.size(); ++i)
- samples[i] = pointwise_multiply(samples[i] - m, sd);
-
- // This is another thing that is often good to do from a numerical stability point of view.
- // However, in our case it doesn't really matter. It's just here to show you how to do it.
- randomize_samples(samples,labels);
-
-
-
- // This is a typedef for the type of kernel we are going to use in this example.
- // In this case I have selected the radial basis kernel that can operate on our
- // 4D sample_type objects. In general, I would suggest using the same kernel for
- // classification and feature ranking.
- typedef radial_basis_kernel<sample_type> kernel_type;
-
- // The radial_basis_kernel has a parameter called gamma that we need to set. Generally,
- // you should try the same gamma that you are using for training. But if you don't
- // have a particular gamma in mind then you can use the following function to
- // find a reasonable default gamma for your data. Another reasonable way to pick a gamma
- // is often to use 1.0/compute_mean_squared_distance(randomly_subsample(samples, 2000)).
- // It computes the mean squared distance between 2000 randomly selected samples and often
- // works quite well.
- const double gamma = verbose_find_gamma_with_big_centroid_gap(samples, labels);
-
- // Next we declare an instance of the kcentroid object. It is used by rank_features()
- // two represent the centroids of the two classes. The kcentroid has 3 parameters
- // you need to set. The first argument to the constructor is the kernel we wish to
- // use. The second is a parameter that determines the numerical accuracy with which
- // the object will perform part of the ranking algorithm. Generally, smaller values
- // give better results but cause the algorithm to attempt to use more dictionary vectors
- // (and thus run slower and use more memory). The third argument, however, is the
- // maximum number of dictionary vectors a kcentroid is allowed to use. So you can use
- // it to put an upper limit on the runtime complexity.
- kcentroid<kernel_type> kc(kernel_type(gamma), 0.001, 25);
-
- // And finally we get to the feature ranking. Here we call rank_features() with the kcentroid we just made,
- // the samples and labels we made above, and the number of features we want it to rank.
- cout << rank_features(kc, samples, labels) << endl;
-
- // The output is:
- /*
- 0 0.749265
- 1 1
- 3 0.933378
- 2 0.825179
- */
-
- // The first column is a list of the features in order of decreasing goodness. So the rank_features() function
- // is telling us that the samples[i](0) and samples[i](1) (i.e. the x and y) features are the best two. Then
- // after that the next best feature is the samples[i](3) (i.e. the y corrupted by noise) and finally the worst
- // feature is the one that is just random noise. So in this case rank_features did exactly what we would
- // intuitively expect.
-
-
- // The second column of the matrix is a number that indicates how much the features up to that point
- // contribute to the separation of the two classes. So bigger numbers are better since they
- // indicate a larger separation. The max value is always 1. In the case below we see that the bad
- // features actually make the class separation go down.
-
- // So to break it down a little more.
- // 0 0.749265 <-- class separation of feature 0 all by itself
- // 1 1 <-- class separation of feature 0 and 1
- // 3 0.933378 <-- class separation of feature 0, 1, and 3
- // 2 0.825179 <-- class separation of feature 0, 1, 3, and 2
-
-
-}
-
diff --git a/ml/dlib/examples/running_stats_ex.cpp b/ml/dlib/examples/running_stats_ex.cpp
deleted file mode 100644
index d94faf35b..000000000
--- a/ml/dlib/examples/running_stats_ex.cpp
+++ /dev/null
@@ -1,58 +0,0 @@
-// The contents of this file are in the public domain. See LICENSE_FOR_EXAMPLE_PROGRAMS.txt
-/*
- This is an example illustrating the use of the running_stats object from the dlib C++
- Library. It is a simple tool for computing basic statistics on a stream of numbers.
- In this example, we sample 100 points from the sinc function and then then compute the
- unbiased sample mean, variance, skewness, and excess kurtosis.
-
-*/
-#include <iostream>
-#include <vector>
-#include <dlib/statistics.h>
-
-using namespace std;
-using namespace dlib;
-
-// Here we define the sinc function so that we may generate sample data. We compute the mean,
-// variance, skewness, and excess kurtosis of this sample data.
-
-double sinc(double x)
-{
- if (x == 0)
- return 1;
- return sin(x)/x;
-}
-
-int main()
-{
- running_stats<double> rs;
-
- double tp1 = 0;
- double tp2 = 0;
-
- // We first generate the data and add it sequentially to our running_stats object. We
- // then print every fifth data point.
- for (int x = 1; x <= 100; x++)
- {
- tp1 = x/100.0;
- tp2 = sinc(pi*x/100.0);
- rs.add(tp2);
-
- if(x % 5 == 0)
- {
- cout << " x = " << tp1 << " sinc(x) = " << tp2 << endl;
- }
- }
-
- // Finally, we compute and print the mean, variance, skewness, and excess kurtosis of
- // our data.
-
- cout << endl;
- cout << "Mean: " << rs.mean() << endl;
- cout << "Variance: " << rs.variance() << endl;
- cout << "Skewness: " << rs.skewness() << endl;
- cout << "Excess Kurtosis " << rs.ex_kurtosis() << endl;
-
- return 0;
-}
-
diff --git a/ml/dlib/examples/rvm_ex.cpp b/ml/dlib/examples/rvm_ex.cpp
deleted file mode 100644
index d1d5935e7..000000000
--- a/ml/dlib/examples/rvm_ex.cpp
+++ /dev/null
@@ -1,217 +0,0 @@
-// The contents of this file are in the public domain. See LICENSE_FOR_EXAMPLE_PROGRAMS.txt
-/*
-
- This is an example illustrating the use of the relevance vector machine
- utilities from the dlib C++ Library.
-
- This example creates a simple set of data to train on and then shows
- you how to use the cross validation and rvm training functions
- to find a good decision function that can classify examples in our
- data set.
-
-
- The data used in this example will be 2 dimensional data and will
- come from a distribution where points with a distance less than 10
- from the origin are labeled +1 and all other points are labeled
- as -1.
-
-*/
-
-
-#include <iostream>
-#include <dlib/svm.h>
-
-using namespace std;
-using namespace dlib;
-
-
-int main()
-{
- // The rvm functions use column vectors to contain a lot of the data on which they
- // operate. So the first thing we do here is declare a convenient typedef.
-
- // This typedef declares a matrix with 2 rows and 1 column. It will be the
- // object that contains each of our 2 dimensional samples. (Note that if you wanted
- // more than 2 features in this vector you can simply change the 2 to something else.
- // Or if you don't know how many features you want until runtime then you can put a 0
- // here and use the matrix.set_size() member function)
- typedef matrix<double, 2, 1> sample_type;
-
- // This is a typedef for the type of kernel we are going to use in this example.
- // In this case I have selected the radial basis kernel that can operate on our
- // 2D sample_type objects
- typedef radial_basis_kernel<sample_type> kernel_type;
-
-
- // Now we make objects to contain our samples and their respective labels.
- std::vector<sample_type> samples;
- std::vector<double> labels;
-
- // Now let's put some data into our samples and labels objects. We do this
- // by looping over a bunch of points and labeling them according to their
- // distance from the origin.
- for (int r = -20; r <= 20; ++r)
- {
- for (int c = -20; c <= 20; ++c)
- {
- sample_type samp;
- samp(0) = r;
- samp(1) = c;
- samples.push_back(samp);
-
- // if this point is less than 10 from the origin
- if (sqrt((double)r*r + c*c) <= 10)
- labels.push_back(+1);
- else
- labels.push_back(-1);
-
- }
- }
-
-
- // Here we normalize all the samples by subtracting their mean and dividing by their standard deviation.
- // This is generally a good idea since it often heads off numerical stability problems and also
- // prevents one large feature from smothering others. Doing this doesn't matter much in this example
- // so I'm just doing this here so you can see an easy way to accomplish this with
- // the library.
- vector_normalizer<sample_type> normalizer;
- // let the normalizer learn the mean and standard deviation of the samples
- normalizer.train(samples);
- // now normalize each sample
- for (unsigned long i = 0; i < samples.size(); ++i)
- samples[i] = normalizer(samples[i]);
-
-
-
-
- // Now that we have some data we want to train on it. However, there is a parameter to the
- // training. This is the gamma parameter of the RBF kernel. Our choice for this parameter will
- // influence how good the resulting decision function is. To test how good a particular choice of
- // kernel parameters is we can use the cross_validate_trainer() function to perform n-fold cross
- // validation on our training data. However, there is a problem with the way we have sampled
- // our distribution. The problem is that there is a definite ordering to the samples.
- // That is, the first half of the samples look like they are from a different distribution
- // than the second half. This would screw up the cross validation process but we can
- // fix it by randomizing the order of the samples with the following function call.
- randomize_samples(samples, labels);
-
-
- // here we make an instance of the rvm_trainer object that uses our kernel type.
- rvm_trainer<kernel_type> trainer;
-
- // One thing you can do to reduce the RVM training time is to make its
- // stopping epsilon bigger. However, this might make the outputs less
- // reliable. But sometimes it works out well. 0.001 is the default.
- trainer.set_epsilon(0.001);
- // You can also set an explicit limit on the number of iterations used by the numeric
- // solver. The default is 2000.
- trainer.set_max_iterations(2000);
-
- // Now we loop over some different gamma values to see how good they are. Note
- // that this is a very simple way to try out a few possible parameter choices. You
- // should look at the model_selection_ex.cpp program for examples of more sophisticated
- // strategies for determining good parameter choices.
- cout << "doing cross validation" << endl;
- for (double gamma = 0.000001; gamma <= 1; gamma *= 5)
- {
- // tell the trainer the parameters we want to use
- trainer.set_kernel(kernel_type(gamma));
-
- cout << "gamma: " << gamma;
- // Print out the cross validation accuracy for 3-fold cross validation using the current gamma.
- // cross_validate_trainer() returns a row vector. The first element of the vector is the fraction
- // of +1 training examples correctly classified and the second number is the fraction of -1 training
- // examples correctly classified.
- cout << " cross validation accuracy: " << cross_validate_trainer(trainer, samples, labels, 3);
- }
-
-
- // From looking at the output of the above loop it turns out that a good value for
- // gamma for this problem is 0.08. So that is what we will use.
-
- // Now we train on the full set of data and obtain the resulting decision function. We use the
- // value of 0.08 for gamma. The decision function will return values >= 0 for samples it predicts
- // are in the +1 class and numbers < 0 for samples it predicts to be in the -1 class.
- trainer.set_kernel(kernel_type(0.08));
- typedef decision_function<kernel_type> dec_funct_type;
- typedef normalized_function<dec_funct_type> funct_type;
-
-
- // Here we are making an instance of the normalized_function object. This object provides a convenient
- // way to store the vector normalization information along with the decision function we are
- // going to learn.
- funct_type learned_function;
- learned_function.normalizer = normalizer; // save normalization information
- learned_function.function = trainer.train(samples, labels); // perform the actual RVM training and save the results
-
- // Print out the number of relevance vectors in the resulting decision function.
- cout << "\nnumber of relevance vectors in our learned_function is "
- << learned_function.function.basis_vectors.size() << endl;
-
- // Now let's try this decision_function on some samples we haven't seen before
- sample_type sample;
-
- sample(0) = 3.123;
- sample(1) = 2;
- cout << "This is a +1 class example, the classifier output is " << learned_function(sample) << endl;
-
- sample(0) = 3.123;
- sample(1) = 9.3545;
- cout << "This is a +1 class example, the classifier output is " << learned_function(sample) << endl;
-
- sample(0) = 13.123;
- sample(1) = 9.3545;
- cout << "This is a -1 class example, the classifier output is " << learned_function(sample) << endl;
-
- sample(0) = 13.123;
- sample(1) = 0;
- cout << "This is a -1 class example, the classifier output is " << learned_function(sample) << endl;
-
-
- // We can also train a decision function that reports a well conditioned probability
- // instead of just a number > 0 for the +1 class and < 0 for the -1 class. An example
- // of doing that follows:
- typedef probabilistic_decision_function<kernel_type> probabilistic_funct_type;
- typedef normalized_function<probabilistic_funct_type> pfunct_type;
-
- pfunct_type learned_pfunct;
- learned_pfunct.normalizer = normalizer;
- learned_pfunct.function = train_probabilistic_decision_function(trainer, samples, labels, 3);
- // Now we have a function that returns the probability that a given sample is of the +1 class.
-
- // print out the number of relevance vectors in the resulting decision function.
- // (it should be the same as in the one above)
- cout << "\nnumber of relevance vectors in our learned_pfunct is "
- << learned_pfunct.function.decision_funct.basis_vectors.size() << endl;
-
- sample(0) = 3.123;
- sample(1) = 2;
- cout << "This +1 class example should have high probability. Its probability is: "
- << learned_pfunct(sample) << endl;
-
- sample(0) = 3.123;
- sample(1) = 9.3545;
- cout << "This +1 class example should have high probability. Its probability is: "
- << learned_pfunct(sample) << endl;
-
- sample(0) = 13.123;
- sample(1) = 9.3545;
- cout << "This -1 class example should have low probability. Its probability is: "
- << learned_pfunct(sample) << endl;
-
- sample(0) = 13.123;
- sample(1) = 0;
- cout << "This -1 class example should have low probability. Its probability is: "
- << learned_pfunct(sample) << endl;
-
-
-
- // Another thing that is worth knowing is that just about everything in dlib is serializable.
- // So for example, you can save the learned_pfunct object to disk and recall it later like so:
- serialize("saved_function.dat") << learned_pfunct;
-
- // Now let's open that file back up and load the function object it contains.
- deserialize("saved_function.dat") >> learned_pfunct;
-
-}
-
diff --git a/ml/dlib/examples/rvm_regression_ex.cpp b/ml/dlib/examples/rvm_regression_ex.cpp
deleted file mode 100644
index d65cb5203..000000000
--- a/ml/dlib/examples/rvm_regression_ex.cpp
+++ /dev/null
@@ -1,101 +0,0 @@
-// The contents of this file are in the public domain. See LICENSE_FOR_EXAMPLE_PROGRAMS.txt
-/*
- This is an example illustrating the use of the RVM regression object
- from the dlib C++ Library.
-
- This example will train on data from the sinc function.
-
-*/
-
-#include <iostream>
-#include <vector>
-
-#include <dlib/svm.h>
-
-using namespace std;
-using namespace dlib;
-
-// Here is the sinc function we will be trying to learn with rvm regression
-double sinc(double x)
-{
- if (x == 0)
- return 1;
- return sin(x)/x;
-}
-
-int main()
-{
- // Here we declare that our samples will be 1 dimensional column vectors.
- typedef matrix<double,1,1> sample_type;
-
- // Now sample some points from the sinc() function
- sample_type m;
- std::vector<sample_type> samples;
- std::vector<double> labels;
- for (double x = -10; x <= 4; x += 1)
- {
- m(0) = x;
- samples.push_back(m);
- labels.push_back(sinc(x));
- }
-
- // Now we are making a typedef for the kind of kernel we want to use. I picked the
- // radial basis kernel because it only has one parameter and generally gives good
- // results without much fiddling.
- typedef radial_basis_kernel<sample_type> kernel_type;
-
- // Here we declare an instance of the rvm_regression_trainer object. This is the
- // object that we will later use to do the training.
- rvm_regression_trainer<kernel_type> trainer;
-
- // Here we set the kernel we want to use for training. The radial_basis_kernel
- // has a parameter called gamma that we need to determine. As a rule of thumb, a good
- // gamma to try is 1.0/(mean squared distance between your sample points). So
- // below we are using a similar value. Note also that using an inappropriately large
- // gamma will cause the RVM training algorithm to run extremely slowly. What
- // "large" means is relative to how spread out your data is. So it is important
- // to use a rule like this as a starting point for determining the gamma value
- // if you want to use the RVM. It is also probably a good idea to normalize your
- // samples as shown in the rvm_ex.cpp example program.
- const double gamma = 2.0/compute_mean_squared_distance(samples);
- cout << "using gamma of " << gamma << endl;
- trainer.set_kernel(kernel_type(gamma));
-
- // One thing you can do to reduce the RVM training time is to make its
- // stopping epsilon bigger. However, this might make the outputs less
- // reliable. But sometimes it works out well. 0.001 is the default.
- trainer.set_epsilon(0.001);
-
- // now train a function based on our sample points
- decision_function<kernel_type> test = trainer.train(samples, labels);
-
- // now we output the value of the sinc function for a few test points as well as the
- // value predicted by our regression.
- m(0) = 2.5; cout << sinc(m(0)) << " " << test(m) << endl;
- m(0) = 0.1; cout << sinc(m(0)) << " " << test(m) << endl;
- m(0) = -4; cout << sinc(m(0)) << " " << test(m) << endl;
- m(0) = 5.0; cout << sinc(m(0)) << " " << test(m) << endl;
-
- // The output is as follows:
- //using gamma of 0.05
- //0.239389 0.240989
- //0.998334 0.999538
- //-0.189201 -0.188453
- //-0.191785 -0.226516
-
-
- // The first column is the true value of the sinc function and the second
- // column is the output from the rvm estimate.
-
-
-
- // Another thing that is worth knowing is that just about everything in dlib is serializable.
- // So for example, you can save the test object to disk and recall it later like so:
- serialize("saved_function.dat") << test;
-
- // Now let's open that file back up and load the function object it contains.
- deserialize("saved_function.dat") >> test;
-
-}
-
-
diff --git a/ml/dlib/examples/sequence_labeler_ex.cpp b/ml/dlib/examples/sequence_labeler_ex.cpp
deleted file mode 100644
index bdb666a7e..000000000
--- a/ml/dlib/examples/sequence_labeler_ex.cpp
+++ /dev/null
@@ -1,392 +0,0 @@
-// The contents of this file are in the public domain. See LICENSE_FOR_EXAMPLE_PROGRAMS.txt
-/*
-
- This is an example illustrating the use of the machine learning
- tools for sequence labeling in the dlib C++ Library.
-
- The general problem addressed by these tools is the following.
- Suppose you have a set of sequences of some kind and you want to
- learn to predict a label for each element of a sequence. So for
- example, you might have a set of English sentences where each
- word is labeled with its part of speech and you want to learn a
- model which can predict the part of speech for each word in a new
- sentence.
-
- Central to these tools is the sequence_labeler object. It is the
- object which represents the label prediction model. In particular,
- the model used by this object is the following. Given an input
- sequence x, predict an output label sequence y such that:
- y == argmax_y dot(weight_vector, PSI(x,y))
- where PSI() is supplied by the user and defines the form of the
- model. In this example program we will define it such that we
- obtain a simple Hidden Markov Model. However, it's possible to
- define much more sophisticated models. You should take a look
- at the following papers for a few examples:
- - Hidden Markov Support Vector Machines by
- Y. Altun, I. Tsochantaridis, T. Hofmann
- - Shallow Parsing with Conditional Random Fields by
- Fei Sha and Fernando Pereira
-
-
-
- In the remainder of this example program we will show how to
- define your own PSI(), as well as how to learn the "weight_vector"
- parameter. Once you have these two items you will be able to
- use the sequence_labeler to predict the labels of new sequences.
-*/
-
-
-#include <iostream>
-#include <dlib/svm_threaded.h>
-#include <dlib/rand.h>
-
-using namespace std;
-using namespace dlib;
-
-
-/*
- In this example we will be working with a Hidden Markov Model where
- the hidden nodes and observation nodes both take on 3 different states.
- The task will be to take a sequence of observations and predict the state
- of the corresponding hidden nodes.
-*/
-
-const unsigned long num_label_states = 3;
-const unsigned long num_sample_states = 3;
-
-// ----------------------------------------------------------------------------------------
-
-class feature_extractor
-{
- /*
- This object is where you define your PSI(). To ensure that the argmax_y
- remains a tractable problem, the PSI(x,y) vector is actually a sum of vectors,
- each derived from the entire input sequence x but only part of the label
- sequence y. This allows the argmax_y to be efficiently solved using the
- well known Viterbi algorithm.
- */
-
-public:
- // This defines the type used to represent the observed sequence. You can use
- // any type here so long as it has a .size() which returns the number of things
- // in the sequence.
- typedef std::vector<unsigned long> sequence_type;
-
- unsigned long num_features() const
- /*!
- ensures
- - returns the dimensionality of the PSI() feature vector.
- !*/
- {
- // Recall that we are defining a HMM. So in this case the PSI() vector
- // should have the same dimensionality as the number of parameters in the HMM.
- return num_label_states*num_label_states + num_label_states*num_sample_states;
- }
-
- unsigned long order() const
- /*!
- ensures
- - This object represents a Markov model on the output labels.
- This parameter defines the order of the model. That is, this
- value controls how many previous label values get to be taken
- into consideration when performing feature extraction for a
- particular element of the input sequence. Note that the runtime
- of the algorithm is exponential in the order. So don't make order
- very large.
- !*/
- {
- // In this case we are using a HMM model that only looks at the
- // previous label.
- return 1;
- }
-
- unsigned long num_labels() const
- /*!
- ensures
- - returns the number of possible output labels.
- !*/
- {
- return num_label_states;
- }
-
- template <typename feature_setter, typename EXP>
- void get_features (
- feature_setter& set_feature,
- const sequence_type& x,
- const matrix_exp<EXP>& y,
- unsigned long position
- ) const
- /*!
- requires
- - EXP::type == unsigned long
- (i.e. y contains unsigned longs)
- - position < x.size()
- - y.size() == min(position, order) + 1
- - is_vector(y) == true
- - max(y) < num_labels()
- - set_feature is a function object which allows expressions of the form:
- - set_features((unsigned long)feature_index, (double)feature_value);
- - set_features((unsigned long)feature_index);
- ensures
- - for all valid i:
- - interprets y(i) as the label corresponding to x[position-i]
- - This function computes the part of PSI() corresponding to the x[position]
- element of the input sequence. Moreover, this part of PSI() is returned as
- a sparse vector by invoking set_feature(). For example, to set the feature
- with an index of 55 to the value of 1 this method would call:
- set_feature(55);
- Or equivalently:
- set_feature(55,1);
- Therefore, the first argument to set_feature is the index of the feature
- to be set while the second argument is the value the feature should take.
- Additionally, note that calling set_feature() multiple times with the same
- feature index does NOT overwrite the old value, it adds to the previous
- value. For example, if you call set_feature(55) 3 times then it will
- result in feature 55 having a value of 3.
- - This function only calls set_feature() with feature_index values < num_features()
- !*/
- {
- // Again, the features below only define a simple HMM. But in general, you can
- // use a wide variety of sophisticated feature extraction methods here.
-
- // Pull out an indicator feature for the type of transition between the
- // previous label and the current label.
- if (y.size() > 1)
- set_feature(y(1)*num_label_states + y(0));
-
- // Pull out an indicator feature for the type of observed node given
- // the current label.
- set_feature(num_label_states*num_label_states +
- y(0)*num_sample_states + x[position]);
- }
-};
-
-// We need to define serialize() and deserialize() for our feature extractor if we want
-// to be able to serialize and deserialize our learned models. In this case the
-// implementation is empty since our feature_extractor doesn't have any state. But you
-// might define more complex feature extractors which have state that needs to be saved.
-void serialize(const feature_extractor&, std::ostream&) {}
-void deserialize(feature_extractor&, std::istream&) {}
-
-// ----------------------------------------------------------------------------------------
-
-void make_dataset (
- const matrix<double>& transition_probabilities,
- const matrix<double>& emission_probabilities,
- std::vector<std::vector<unsigned long> >& samples,
- std::vector<std::vector<unsigned long> >& labels,
- unsigned long dataset_size
-);
-/*!
- requires
- - transition_probabilities.nr() == transition_probabilities.nc()
- - transition_probabilities.nr() == emission_probabilities.nr()
- - The rows of transition_probabilities and emission_probabilities must sum to 1.
- (i.e. sum_cols(transition_probabilities) and sum_cols(emission_probabilities)
- must evaluate to vectors of all 1s.)
- ensures
- - This function randomly samples a bunch of sequences from the HMM defined by
- transition_probabilities and emission_probabilities.
- - The HMM is defined by:
- - The probability of transitioning from hidden state H1 to H2
- is given by transition_probabilities(H1,H2).
- - The probability of a hidden state H producing an observed state
- O is given by emission_probabilities(H,O).
- - #samples.size() == #labels.size() == dataset_size
- - for all valid i:
- - #labels[i] is a randomly sampled sequence of hidden states from the
- given HMM. #samples[i] is its corresponding randomly sampled sequence
- of observed states.
-!*/
-
-// ----------------------------------------------------------------------------------------
-
-int main()
-{
- // We need a dataset to test the machine learning algorithms. So we are going to
- // define a HMM based on the following two matrices and then randomly sample a
- // set of data from it. Then we will see if the machine learning method can
- // recover the HMM model from the training data.
-
-
- matrix<double> transition_probabilities(num_label_states, num_label_states);
- transition_probabilities = 0.05, 0.90, 0.05,
- 0.05, 0.05, 0.90,
- 0.90, 0.05, 0.05;
-
- matrix<double> emission_probabilities(num_label_states,num_sample_states);
- emission_probabilities = 0.5, 0.5, 0.0,
- 0.0, 0.5, 0.5,
- 0.5, 0.0, 0.5;
-
- std::vector<std::vector<unsigned long> > samples;
- std::vector<std::vector<unsigned long> > labels;
- // sample 1000 labeled sequences from the HMM.
- make_dataset(transition_probabilities,emission_probabilities,
- samples, labels, 1000);
-
- // print out some of the randomly sampled sequences
- for (int i = 0; i < 10; ++i)
- {
- cout << "hidden states: " << trans(mat(labels[i]));
- cout << "observed states: " << trans(mat(samples[i]));
- cout << "******************************" << endl;
- }
-
- // Next we use the structural_sequence_labeling_trainer to learn our
- // prediction model based on just the samples and labels.
- structural_sequence_labeling_trainer<feature_extractor> trainer;
- // This is the common SVM C parameter. Larger values encourage the
- // trainer to attempt to fit the data exactly but might overfit.
- // In general, you determine this parameter by cross-validation.
- trainer.set_c(4);
- // This trainer can use multiple CPU cores to speed up the training.
- // So set this to the number of available CPU cores.
- trainer.set_num_threads(4);
-
-
- // Learn to do sequence labeling from the dataset
- sequence_labeler<feature_extractor> labeler = trainer.train(samples, labels);
-
- // Test the learned labeler on one of the training samples. In this
- // case it will give the correct sequence of labels.
- std::vector<unsigned long> predicted_labels = labeler(samples[0]);
- cout << "true hidden states: "<< trans(mat(labels[0]));
- cout << "predicted hidden states: "<< trans(mat(predicted_labels));
-
-
-
- // We can also do cross-validation. The confusion_matrix is defined as:
- // - confusion_matrix(T,P) == the number of times a sequence element with label T
- // was predicted to have a label of P.
- // So if all predictions are perfect then only diagonal elements of this matrix will
- // be non-zero.
- matrix<double> confusion_matrix;
- confusion_matrix = cross_validate_sequence_labeler(trainer, samples, labels, 4);
- cout << "\ncross-validation: " << endl;
- cout << confusion_matrix;
- cout << "label accuracy: "<< sum(diag(confusion_matrix))/sum(confusion_matrix) << endl;
-
- // In this case, the label accuracy is about 88%. At this point, we want to know if
- // the machine learning method was able to recover the HMM model from the data. So
- // to test this, we can load the true HMM model into another sequence_labeler and
- // test it out on the data and compare the results.
-
- matrix<double,0,1> true_hmm_model_weights = log(join_cols(reshape_to_column_vector(transition_probabilities),
- reshape_to_column_vector(emission_probabilities)));
- // With this model, labeler_true will predict the most probable set of labels
- // given an input sequence. That is, it will predict using the equation:
- // y == argmax_y dot(true_hmm_model_weights, PSI(x,y))
- sequence_labeler<feature_extractor> labeler_true(true_hmm_model_weights);
-
- confusion_matrix = test_sequence_labeler(labeler_true, samples, labels);
- cout << "\nTrue HMM model: " << endl;
- cout << confusion_matrix;
- cout << "label accuracy: "<< sum(diag(confusion_matrix))/sum(confusion_matrix) << endl;
-
- // Happily, we observe that the true model also obtains a label accuracy of 88%.
-
-
-
-
-
-
- // Finally, the labeler can be serialized to disk just like most dlib objects.
- serialize("labeler.dat") << labeler;
-
- // recall from disk
- deserialize("labeler.dat") >> labeler;
-}
-
-// ----------------------------------------------------------------------------------------
-// ----------------------------------------------------------------------------------------
-// Code for creating a bunch of random samples from our HMM.
-// ----------------------------------------------------------------------------------------
-// ----------------------------------------------------------------------------------------
-
-void sample_hmm (
- dlib::rand& rnd,
- const matrix<double>& transition_probabilities,
- const matrix<double>& emission_probabilities,
- unsigned long previous_label,
- unsigned long& next_label,
- unsigned long& next_sample
-)
-/*!
- requires
- - previous_label < transition_probabilities.nr()
- - transition_probabilities.nr() == transition_probabilities.nc()
- - transition_probabilities.nr() == emission_probabilities.nr()
- - The rows of transition_probabilities and emission_probabilities must sum to 1.
- (i.e. sum_cols(transition_probabilities) and sum_cols(emission_probabilities)
- must evaluate to vectors of all 1s.)
- ensures
- - This function randomly samples the HMM defined by transition_probabilities
- and emission_probabilities assuming that the previous hidden state
- was previous_label.
- - The HMM is defined by:
- - P(next_label |previous_label) == transition_probabilities(previous_label, next_label)
- - P(next_sample|next_label) == emission_probabilities (next_label, next_sample)
- - #next_label == the sampled value of the hidden state
- - #next_sample == the sampled value of the observed state
-!*/
-{
- // sample next_label
- double p = rnd.get_random_double();
- for (long c = 0; p >= 0 && c < transition_probabilities.nc(); ++c)
- {
- next_label = c;
- p -= transition_probabilities(previous_label, c);
- }
-
- // now sample next_sample
- p = rnd.get_random_double();
- for (long c = 0; p >= 0 && c < emission_probabilities.nc(); ++c)
- {
- next_sample = c;
- p -= emission_probabilities(next_label, c);
- }
-}
-
-// ----------------------------------------------------------------------------------------
-
-void make_dataset (
- const matrix<double>& transition_probabilities,
- const matrix<double>& emission_probabilities,
- std::vector<std::vector<unsigned long> >& samples,
- std::vector<std::vector<unsigned long> >& labels,
- unsigned long dataset_size
-)
-{
- samples.clear();
- labels.clear();
-
- dlib::rand rnd;
-
- // now randomly sample some labeled sequences from our Hidden Markov Model
- for (unsigned long iter = 0; iter < dataset_size; ++iter)
- {
- const unsigned long sequence_size = rnd.get_random_32bit_number()%20+3;
- std::vector<unsigned long> sample(sequence_size);
- std::vector<unsigned long> label(sequence_size);
-
- unsigned long previous_label = rnd.get_random_32bit_number()%num_label_states;
- for (unsigned long i = 0; i < sample.size(); ++i)
- {
- unsigned long next_label = 0, next_sample = 0;
- sample_hmm(rnd, transition_probabilities, emission_probabilities,
- previous_label, next_label, next_sample);
-
- label[i] = next_label;
- sample[i] = next_sample;
-
- previous_label = next_label;
- }
-
- samples.push_back(sample);
- labels.push_back(label);
- }
-}
-
-// ----------------------------------------------------------------------------------------
-
diff --git a/ml/dlib/examples/sequence_segmenter_ex.cpp b/ml/dlib/examples/sequence_segmenter_ex.cpp
deleted file mode 100644
index 3b0eb8cde..000000000
--- a/ml/dlib/examples/sequence_segmenter_ex.cpp
+++ /dev/null
@@ -1,238 +0,0 @@
-// The contents of this file are in the public domain. See LICENSE_FOR_EXAMPLE_PROGRAMS.txt
-/*
-
- This example shows how to use dlib to learn to do sequence segmentation. In a sequence
- segmentation task we are given a sequence of objects (e.g. words in a sentence) and we
- are supposed to detect certain subsequences (e.g. the names of people). Therefore, in
- the code below we create some very simple training sequences and use them to learn a
- sequence segmentation model. In particular, our sequences will be sentences
- represented as arrays of words and our task will be to learn to identify person names.
- Once we have our segmentation model we can use it to find names in new sentences, as we
- will show.
-
-*/
-
-
-#include <iostream>
-#include <cctype>
-#include <dlib/svm_threaded.h>
-#include <dlib/string.h>
-
-using namespace std;
-using namespace dlib;
-
-
-// ----------------------------------------------------------------------------------------
-
-class feature_extractor
-{
- /*
- The sequence segmentation models we work with in this example are chain structured
- conditional random field style models. Therefore, central to a sequence
- segmentation model is a feature extractor object. This object defines all the
- properties of the model such as how many features it will use, and more importantly,
- how they are calculated.
- */
-
-public:
- // This should be the type used to represent an input sequence. It can be
- // anything so long as it has a .size() which returns the length of the sequence.
- typedef std::vector<std::string> sequence_type;
-
- // The next four lines define high-level properties of the feature extraction model.
- // See the documentation for the sequence_labeler object for an extended discussion of
- // how they are used (note that the main body of the documentation is at the top of the
- // file documenting the sequence_labeler).
- const static bool use_BIO_model = true;
- const static bool use_high_order_features = true;
- const static bool allow_negative_weights = true;
- unsigned long window_size() const { return 3; }
-
- // This function defines the dimensionality of the vectors output by the get_features()
- // function defined below.
- unsigned long num_features() const { return 1; }
-
- template <typename feature_setter>
- void get_features (
- feature_setter& set_feature,
- const sequence_type& sentence,
- unsigned long position
- ) const
- /*!
- requires
- - position < sentence.size()
- - set_feature is a function object which allows expressions of the form:
- - set_features((unsigned long)feature_index, (double)feature_value);
- - set_features((unsigned long)feature_index);
- ensures
- - This function computes a feature vector which should capture the properties
- of sentence[position] that are informative relative to the sequence
- segmentation task you are trying to perform.
- - The output feature vector is returned as a sparse vector by invoking set_feature().
- For example, to set the feature with an index of 55 to the value of 1
- this method would call:
- set_feature(55);
- Or equivalently:
- set_feature(55,1);
- Therefore, the first argument to set_feature is the index of the feature
- to be set while the second argument is the value the feature should take.
- Additionally, note that calling set_feature() multiple times with the
- same feature index does NOT overwrite the old value, it adds to the
- previous value. For example, if you call set_feature(55) 3 times then it
- will result in feature 55 having a value of 3.
- - This function only calls set_feature() with feature_index values < num_features()
- !*/
- {
- // The model in this example program is very simple. Our features only look at the
- // capitalization pattern of the words. So we have a single feature which checks
- // if the first letter is capitalized or not.
- if (isupper(sentence[position][0]))
- set_feature(0);
- }
-};
-
-// We need to define serialize() and deserialize() for our feature extractor if we want
-// to be able to serialize and deserialize our learned models. In this case the
-// implementation is empty since our feature_extractor doesn't have any state. But you
-// might define more complex feature extractors which have state that needs to be saved.
-void serialize(const feature_extractor&, std::ostream&) {}
-void deserialize(feature_extractor&, std::istream&) {}
-
-// ----------------------------------------------------------------------------------------
-
-void make_training_examples (
- std::vector<std::vector<std::string> >& samples,
- std::vector<std::vector<std::pair<unsigned long, unsigned long> > >& segments
-)
-/*!
- ensures
- - This function fills samples with example sentences and segments with the
- locations of person names that should be segmented out.
- - #samples.size() == #segments.size()
-!*/
-{
- std::vector<std::pair<unsigned long, unsigned long> > names;
-
-
- // Here we make our first training example. split() turns the string into an array of
- // 10 words and then we store that into samples.
- samples.push_back(split("The other day I saw a man named Jim Smith"));
- // We want to detect person names. So we note that the name is located within the
- // range [8, 10). Note that we use half open ranges to identify segments. So in this
- // case, the segment identifies the string "Jim Smith".
- names.push_back(make_pair(8, 10));
- segments.push_back(names); names.clear();
-
- // Now we add a few more example sentences
-
- samples.push_back(split("Davis King is the main author of the dlib Library"));
- names.push_back(make_pair(0, 2));
- segments.push_back(names); names.clear();
-
-
- samples.push_back(split("Bob Jones is a name and so is George Clinton"));
- names.push_back(make_pair(0, 2));
- names.push_back(make_pair(8, 10));
- segments.push_back(names); names.clear();
-
-
- samples.push_back(split("My dog is named Bob Barker"));
- names.push_back(make_pair(4, 6));
- segments.push_back(names); names.clear();
-
-
- samples.push_back(split("ABC is an acronym but John James Smith is a name"));
- names.push_back(make_pair(5, 8));
- segments.push_back(names); names.clear();
-
-
- samples.push_back(split("No names in this sentence at all"));
- segments.push_back(names); names.clear();
-}
-
-// ----------------------------------------------------------------------------------------
-
-void print_segment (
- const std::vector<std::string>& sentence,
- const std::pair<unsigned long,unsigned long>& segment
-)
-{
- // Recall that a segment is a half open range starting with .first and ending just
- // before .second.
- for (unsigned long i = segment.first; i < segment.second; ++i)
- cout << sentence[i] << " ";
- cout << endl;
-}
-
-// ----------------------------------------------------------------------------------------
-
-int main()
-{
- // Finally we make it into the main program body. So the first thing we do is get our
- // training data.
- std::vector<std::vector<std::string> > samples;
- std::vector<std::vector<std::pair<unsigned long, unsigned long> > > segments;
- make_training_examples(samples, segments);
-
-
- // Next we use the structural_sequence_segmentation_trainer to learn our segmentation
- // model based on just the samples and segments. But first we setup some of its
- // parameters.
- structural_sequence_segmentation_trainer<feature_extractor> trainer;
- // This is the common SVM C parameter. Larger values encourage the trainer to attempt
- // to fit the data exactly but might overfit. In general, you determine this parameter
- // by cross-validation.
- trainer.set_c(10);
- // This trainer can use multiple CPU cores to speed up the training. So set this to
- // the number of available CPU cores.
- trainer.set_num_threads(4);
-
-
- // Learn to do sequence segmentation from the dataset
- sequence_segmenter<feature_extractor> segmenter = trainer.train(samples, segments);
-
-
- // Let's print out all the segments our segmenter detects.
- for (unsigned long i = 0; i < samples.size(); ++i)
- {
- // get all the detected segments in samples[i]
- std::vector<std::pair<unsigned long,unsigned long> > seg = segmenter(samples[i]);
- // Print each of them
- for (unsigned long j = 0; j < seg.size(); ++j)
- {
- print_segment(samples[i], seg[j]);
- }
- }
-
-
- // Now let's test it on a new sentence and see what it detects.
- std::vector<std::string> sentence(split("There once was a man from Nantucket whose name rhymed with Bob Bucket"));
- std::vector<std::pair<unsigned long,unsigned long> > seg = segmenter(sentence);
- for (unsigned long j = 0; j < seg.size(); ++j)
- {
- print_segment(sentence, seg[j]);
- }
-
-
-
- // We can also test the accuracy of the segmenter on a dataset. This statement simply
- // tests on the training data. In this case we will see that it predicts everything
- // correctly.
- cout << "\nprecision, recall, f1-score: " << test_sequence_segmenter(segmenter, samples, segments);
- // Similarly, we can do 5-fold cross-validation and print the results. Just as before,
- // we see everything is predicted correctly.
- cout << "precision, recall, f1-score: " << cross_validate_sequence_segmenter(trainer, samples, segments, 5);
-
-
-
-
-
- // Finally, the segmenter can be serialized to disk just like most dlib objects.
- serialize("segmenter.dat") << segmenter;
-
- // recall from disk
- deserialize("segmenter.dat") >> segmenter;
-}
-
-// ----------------------------------------------------------------------------------------
-
diff --git a/ml/dlib/examples/server_http_ex.cpp b/ml/dlib/examples/server_http_ex.cpp
deleted file mode 100644
index 99914c14b..000000000
--- a/ml/dlib/examples/server_http_ex.cpp
+++ /dev/null
@@ -1,108 +0,0 @@
-// The contents of this file are in the public domain. See LICENSE_FOR_EXAMPLE_PROGRAMS.txt
-/*
-
- This example illustrates the use of the HTTP extension to the server object
- from the dlib C++ Library.
- It creates a server that always responds with a simple HTML form.
-
- To view the page this program displays you should go to http://localhost:5000
-
-*/
-
-#include <iostream>
-#include <sstream>
-#include <string>
-#include <dlib/server.h>
-
-using namespace dlib;
-using namespace std;
-
-class web_server : public server_http
-{
- const std::string on_request (
- const incoming_things& incoming,
- outgoing_things& outgoing
- )
- {
- ostringstream sout;
- // We are going to send back a page that contains an HTML form with two text input fields.
- // One field called name. The HTML form uses the post method but could also use the get
- // method (just change method='post' to method='get').
- sout << " <html> <body> "
- << "<form action='/form_handler' method='post'> "
- << "User Name: <input name='user' type='text'><br> "
- << "User password: <input name='pass' type='text'> <input type='submit'> "
- << " </form>";
-
- // Write out some of the inputs to this request so that they show up on the
- // resulting web page.
- sout << "<br> path = " << incoming.path << endl;
- sout << "<br> request_type = " << incoming.request_type << endl;
- sout << "<br> content_type = " << incoming.content_type << endl;
- sout << "<br> protocol = " << incoming.protocol << endl;
- sout << "<br> foreign_ip = " << incoming.foreign_ip << endl;
- sout << "<br> foreign_port = " << incoming.foreign_port << endl;
- sout << "<br> local_ip = " << incoming.local_ip << endl;
- sout << "<br> local_port = " << incoming.local_port << endl;
- sout << "<br> body = \"" << incoming.body << "\"" << endl;
-
-
- // If this request is the result of the user submitting the form then echo back
- // the submission.
- if (incoming.path == "/form_handler")
- {
- sout << "<h2> Stuff from the query string </h2>" << endl;
- sout << "<br> user = " << incoming.queries["user"] << endl;
- sout << "<br> pass = " << incoming.queries["pass"] << endl;
-
- // save these form submissions as cookies.
- outgoing.cookies["user"] = incoming.queries["user"];
- outgoing.cookies["pass"] = incoming.queries["pass"];
- }
-
-
- // Echo any cookies back to the client browser
- sout << "<h2>Cookies the web browser sent to the server</h2>";
- for ( key_value_map::const_iterator ci = incoming.cookies.begin(); ci != incoming.cookies.end(); ++ci )
- {
- sout << "<br/>" << ci->first << " = " << ci->second << endl;
- }
-
- sout << "<br/><br/>";
-
- sout << "<h2>HTTP Headers the web browser sent to the server</h2>";
- // Echo out all the HTTP headers we received from the client web browser
- for ( key_value_map_ci::const_iterator ci = incoming.headers.begin(); ci != incoming.headers.end(); ++ci )
- {
- sout << "<br/>" << ci->first << ": " << ci->second << endl;
- }
-
- sout << "</body> </html>";
-
- return sout.str();
- }
-
-};
-
-int main()
-{
- try
- {
- // create an instance of our web server
- web_server our_web_server;
-
- // make it listen on port 5000
- our_web_server.set_listening_port(5000);
- // Tell the server to begin accepting connections.
- our_web_server.start_async();
-
- cout << "Press enter to end this program" << endl;
- cin.get();
- }
- catch (exception& e)
- {
- cout << e.what() << endl;
- }
-}
-
-
diff --git a/ml/dlib/examples/server_iostream_ex.cpp b/ml/dlib/examples/server_iostream_ex.cpp
deleted file mode 100644
index 81fa30011..000000000
--- a/ml/dlib/examples/server_iostream_ex.cpp
+++ /dev/null
@@ -1,84 +0,0 @@
-// The contents of this file are in the public domain. See LICENSE_FOR_EXAMPLE_PROGRAMS.txt
-/*
-
- This is an example illustrating the use of the server_iostream object from
- the dlib C++ Library.
-
- This is a simple echo server. It listens on port 1234 for incoming
- connections and just echos back any text it receives, but in upper case. So
- basically it is the same as the sockets_ex.cpp example program except it
- uses iostreams.
-
- To test it out you can just open a command prompt and type:
- telnet localhost 1234
-
- Then you can type away.
-
-*/
-
-
-
-
-#include <dlib/server.h>
-#include <iostream>
-
-using namespace dlib;
-using namespace std;
-
-
-
-class serv : public server_iostream
-{
-
- void on_connect (
- std::istream& in,
- std::ostream& out,
- const std::string& foreign_ip,
- const std::string& local_ip,
- unsigned short foreign_port,
- unsigned short local_port,
- uint64 connection_id
- )
- {
- // The details of the connection are contained in the last few arguments to
- // on_connect(). For more information, see the documentation for the
- // server_iostream. However, the main arguments of interest are the two streams.
- // Here we also print the IP address of the remote machine.
- cout << "Got a connection from " << foreign_ip << endl;
-
- // Loop until we hit the end of the stream. This happens when the connection
- // terminates.
- while (in.peek() != EOF)
- {
- // get the next character from the client
- char ch = in.get();
-
- // now echo it back to them
- out << (char)toupper(ch);
- }
- }
-
-};
-
-
-int main()
-{
- try
- {
- serv our_server;
-
- // set up the server object we have made
- our_server.set_listening_port(1234);
- // Tell the server to begin accepting connections.
- our_server.start_async();
-
- cout << "Press enter to end this program" << endl;
- cin.get();
- }
- catch (exception& e)
- {
- cout << e.what() << endl;
- }
-}
-
-
diff --git a/ml/dlib/examples/sockets_ex.cpp b/ml/dlib/examples/sockets_ex.cpp
deleted file mode 100644
index 5fd9ebe07..000000000
--- a/ml/dlib/examples/sockets_ex.cpp
+++ /dev/null
@@ -1,63 +0,0 @@
-// The contents of this file are in the public domain. See LICENSE_FOR_EXAMPLE_PROGRAMS.txt
-/*
-
- This is an example illustrating the use of the sockets and
- server components from the dlib C++ Library.
-
- This is a simple echo server. It listens on port 1234 for incoming
- connections and just echos back any data it receives.
-
-*/
-
-
-
-
-#include <dlib/sockets.h>
-#include <dlib/server.h>
-#include <iostream>
-
-using namespace dlib;
-using namespace std;
-
-
-
-class serv : public server
-{
- void on_connect (
- connection& con
- )
- {
- char ch;
- while (con.read(&ch,1) > 0)
- {
- // we are just reading one char at a time and writing it back
- // to the connection. If there is some problem writing the char
- // then we quit the loop.
- if (con.write(&ch,1) != 1)
- break;
- }
- }
-
-};
-
-
-int main()
-{
- try
- {
- serv our_server;
-
- // set up the server object we have made
- our_server.set_listening_port(1234);
- // Tell the server to begin accepting connections.
- our_server.start_async();
-
- cout << "Press enter to end this program" << endl;
- cin.get();
- }
- catch (exception& e)
- {
- cout << e.what() << endl;
- }
-}
-
diff --git a/ml/dlib/examples/sockstreambuf_ex.cpp b/ml/dlib/examples/sockstreambuf_ex.cpp
deleted file mode 100644
index 93200baa5..000000000
--- a/ml/dlib/examples/sockstreambuf_ex.cpp
+++ /dev/null
@@ -1,92 +0,0 @@
-// The contents of this file are in the public domain. See LICENSE_FOR_EXAMPLE_PROGRAMS.txt
-/*
-
- This is an example illustrating the use of the sockets and sockstreambuf
- components from the dlib C++ Library. Note that there is also an
- iosockstream object in dlib that is often simpler to use, see
- iosockstream_ex.cpp for an example of its use.
-
- This program simply connects to www.google.com at port 80 and requests the
- main Google web page. It then prints what it gets back from Google to the
- screen.
-
-
- For those of you curious about HTTP check out the excellent introduction at
- http://www.jmarshall.com/easy/http/
-*/
-
-#include <iostream>
-#include <memory>
-
-#include <dlib/sockets.h>
-#include <dlib/sockstreambuf.h>
-
-using namespace std;
-using namespace dlib;
-
-int main()
-{
- try
- {
- // Connect to Google's web server which listens on port 80. If this
- // fails it will throw a dlib::socket_error exception. Note that we
- // are using a smart pointer here to contain the connection pointer
- // returned from connect. Doing this ensures that the connection
- // is deleted even if someone throws an exception somewhere in your code.
- std::unique_ptr<connection> con(connect("www.google.com",80));
-
-
- {
- // Create a stream buffer for our connection
- sockstreambuf buf(con);
- // Now stick that stream buffer into an iostream object
- iostream stream(&buf);
- // This command causes the iostream to flush its output buffers
- // whenever someone makes a read request.
- buf.flush_output_on_read();
-
- // Now we make the HTTP GET request for the main Google page.
- stream << "GET / HTTP/1.0\r\n\r\n";
-
- // Here we print each character we get back one at a time.
- int ch = stream.get();
- while (ch != EOF)
- {
- cout << (char)ch;
- ch = stream.get();
- }
-
- // At the end of this scope buf will be destructed and flush
- // anything it still contains to the connection. Thus putting
- // this } here makes it safe to destroy the connection later on.
- // If we just destroyed the connection before buf was destructed
- // then buf might try to flush its data to a closed connection
- // which would be an error.
- }
-
- // Here we call close_gracefully(). It takes a connection and performs
- // a proper TCP shutdown by sending a FIN packet to the other end of the
- // connection and waiting half a second for the other end to close the
- // connection as well. If half a second goes by without the other end
- // responding then the connection is forcefully shutdown and deleted.
- //
- // You usually want to perform a graceful shutdown of your TCP connections
- // because there might be some data you tried to send that is still buffered
- // in the operating system's output buffers. If you just killed the
- // connection it might not be sent to the other side (although maybe
- // you don't care, and in the case of this example it doesn't really matter.
- // But I'm only putting this here for the purpose of illustration :-).
- // In any case, this function is provided to allow you to perform a graceful
- // close if you so choose.
- //
- // Also note that the timeout can be changed by suppling an optional argument
- // to this function.
- close_gracefully(con);
- }
- catch (exception& e)
- {
- cout << e.what() << endl;
- }
-}
-
-
diff --git a/ml/dlib/examples/sqlite_ex.cpp b/ml/dlib/examples/sqlite_ex.cpp
deleted file mode 100644
index 4f1e30a2a..000000000
--- a/ml/dlib/examples/sqlite_ex.cpp
+++ /dev/null
@@ -1,137 +0,0 @@
-// The contents of this file are in the public domain. See LICENSE_FOR_EXAMPLE_PROGRAMS.txt
-
-/*
- This example gives a quick overview of dlib's C++ API for the popular SQLite library.
-*/
-
-
-#include <iostream>
-#include <dlib/sqlite.h>
-#include <dlib/matrix.h>
-
-using namespace dlib;
-using namespace std;
-
-// ----------------------------------------------------------------------------------------
-
-bool table_exists (
- database& db,
- const std::string& tablename
-)
-{
- // Sometimes you want to just run a query that returns one thing. In this case, we
- // want to see how many tables are in our database with the given tablename. The only
- // possible outcomes are 1 or 0 and we can do this by looking in the special
- // sqlite_master table that records such database metadata. For these kinds of "one
- // result" queries we can use the query_int() method which executes a SQL statement
- // against a database and returns the result as an int.
- return query_int(db, "select count(*) from sqlite_master where name = '"+tablename+"'")==1;
-}
-
-// ----------------------------------------------------------------------------------------
-
-int main() try
-{
- // Open the SQLite database in the stuff.db file (or create an empty database in
- // stuff.db if it doesn't exist).
- database db("stuff.db");
-
- // Create a people table that records a person's name, age, and their "data".
- if (!table_exists(db,"people"))
- db.exec("create table people (name, age, data)");
-
-
- // Now let's add some data to this table. We can do this by making a statement object
- // as shown. Here we use the special ? character to indicate bindable arguments and
- // below we will use st.bind() statements to populate those fields with values.
- statement st(db, "insert into people VALUES(?,?,?)");
-
- // The data for Davis
- string name = "Davis";
- int age = 32;
- matrix<double> m = randm(3,3); // some random "data" for Davis
-
- // You can bind any of the built in scalar types (e.g. int, float) or std::string and
- // they will go into the table as the appropriate SQL types (e.g. INT, TEXT). If you
- // try to bind any other object it will be saved as a binary blob if the type has an
- // appropriate void serialize(const T&, std::ostream&) function defined for it. The
- // matrix has such a serialize function (as do most dlib types) so the bind below saves
- // the matrix as a binary blob.
- st.bind(1, name);
- st.bind(2, age);
- st.bind(3, m);
- st.exec(); // execute the SQL statement. This does the insert.
-
-
- // We can reuse the statement to add more data to the database. In fact, if you have a
- // bunch of statements to execute it is fastest if you reuse them in this manner.
- name = "John";
- age = 82;
- m = randm(2,3);
- st.bind(1, name);
- st.bind(2, age);
- st.bind(3, m);
- st.exec();
-
-
-
- // Now lets print out all the rows in the people table.
- statement st2(db, "select * from people");
- st2.exec();
- // Loop over all the rows obtained by executing the statement with .exec().
- while(st2.move_next())
- {
- string name;
- int age;
- matrix<double> m;
- // Analogously to bind, we can grab the columns straight into C++ types. Here the
- // matrix is automatically deserialized by calling its deserialize() routine.
- st2.get_column(0, name);
- st2.get_column(1, age);
- st2.get_column(2, m);
- cout << name << " " << age << "\n" << m << endl << endl;
- }
-
-
-
- // Finally, if you want to make a bunch of atomic changes to a database then you should
- // do so inside a transaction. Here, either all the database modifications that occur
- // between the creation of my_trans and the invocation of my_trans.commit() will appear
- // in the database or none of them will. This way, if an exception or other error
- // happens halfway though your transaction you won't be left with your database in an
- // inconsistent state.
- //
- // Additionally, if you are going to do a large amount of inserts or updates then it is
- // much faster to group them into a transaction.
- transaction my_trans(db);
-
- name = "Dude";
- age = 49;
- m = randm(4,2);
- st.bind(1, name);
- st.bind(2, age);
- st.bind(3, m);
- st.exec();
-
- name = "Bob";
- age = 29;
- m = randm(2,2);
- st.bind(1, name);
- st.bind(2, age);
- st.bind(3, m);
- st.exec();
-
- // If you comment out this line then you will see that these inserts do not take place.
- // Specifically, what happens is that when my_trans is destructed it rolls back the
- // entire transaction unless commit() has been called.
- my_trans.commit();
-
-}
-catch (std::exception& e)
-{
- cout << e.what() << endl;
-}
-
-// ----------------------------------------------------------------------------------------
-
-
diff --git a/ml/dlib/examples/std_allocator_ex.cpp b/ml/dlib/examples/std_allocator_ex.cpp
deleted file mode 100644
index 0dc583fa0..000000000
--- a/ml/dlib/examples/std_allocator_ex.cpp
+++ /dev/null
@@ -1,57 +0,0 @@
-// The contents of this file are in the public domain. See LICENSE_FOR_EXAMPLE_PROGRAMS.txt
-/*
- This is an example illustrating the use of the dlib::std_allocator object.
-
- In this example we will create the necessary typedefs to give the
- dlib::std_allocator object to the standard string and vector objects
- in the STL. Thus we will create versions of std::string and std::vector
- that perform all their memory allocations and deallocations via one of
- the dlib memory manager objects.
-*/
-
-
-// include everything we need for this example
-#include <vector>
-#include <iostream>
-#include <string>
-#include <dlib/std_allocator.h>
-#include <dlib/memory_manager.h>
-#include <dlib/memory_manager_stateless.h>
-
-using namespace std;
-using namespace dlib;
-
-
-int main()
-{
- // Make a typedef for an allocator that uses the thread safe memory_manager_stateless object with a
- // global memory pool. This version of the memory_manager_stateless object keeps everything it allocates
- // in a global memory pool and doesn't release any memory until the program terminates.
- typedef std_allocator<char, memory_manager_stateless<char>::kernel_2_3a> alloc_char_with_global_memory_pool;
-
- // Now make a typedef for a C++ standard string that uses our new allocator type
- typedef std::basic_string<char, char_traits<char>, alloc_char_with_global_memory_pool > dstring;
-
-
- // typedef another allocator for dstring objects
- typedef std_allocator<dstring, memory_manager_stateless<char>::kernel_2_3a> alloc_dstring_with_global_memory_pool;
-
- // Now make a typedef for a C++ standard vector that uses our new allocator type and also contains the new dstring
- typedef std::vector<dstring, alloc_dstring_with_global_memory_pool > dvector;
-
- // Now we can use the string and vector we have as we normally would. So for example, I can make a
- // dvector and add 4 strings into it like so:
- dvector v;
- v.push_back("one");
- v.push_back("two");
- v.push_back("three");
- v.push_back("four");
-
- // And now we print out the contents of our vector
- for (unsigned long i = 0; i < v.size(); ++i)
- {
- cout << v[i] << endl;
- }
-
-}
-
diff --git a/ml/dlib/examples/surf_ex.cpp b/ml/dlib/examples/surf_ex.cpp
deleted file mode 100644
index 70fe19008..000000000
--- a/ml/dlib/examples/surf_ex.cpp
+++ /dev/null
@@ -1,82 +0,0 @@
-// The contents of this file are in the public domain. See LICENSE_FOR_EXAMPLE_PROGRAMS.txt
-/*
-
- This is a simple example illustrating the use of the get_surf_points() function. It
- pulls out SURF points from an input image and displays them on the screen as an overlay
- on the image.
-
- For a description of the SURF algorithm you should consult the following papers:
- This is the original paper which introduced the algorithm:
- SURF: Speeded Up Robust Features
- By Herbert Bay, Tinne Tuytelaars, and Luc Van Gool
-
- This paper provides a nice detailed overview of how the algorithm works:
- Notes on the OpenSURF Library by Christopher Evans
-
-*/
-
-
-
-#include <dlib/image_keypoint/draw_surf_points.h>
-#include <dlib/image_io.h>
-#include <dlib/image_keypoint.h>
-#include <fstream>
-
-
-using namespace std;
-using namespace dlib;
-
-// ----------------------------------------------------------------------------
-
-int main(int argc, char** argv)
-{
- try
- {
- // make sure the user entered an argument to this program
- if (argc != 2)
- {
- cout << "error, you have to enter a BMP file as an argument to this program" << endl;
- return 1;
- }
-
- // Here we declare an image object that can store rgb_pixels. Note that in dlib
- // there is no explicit image object, just a 2D array and various pixel types.
- array2d<rgb_pixel> img;
-
- // Now load the image file into our image. If something is wrong then load_image()
- // will throw an exception. Also, if you linked with libpng and libjpeg then
- // load_image() can load PNG and JPEG files in addition to BMP files.
- load_image(img, argv[1]);
-
- // Get SURF points from the image. Note that get_surf_points() has some optional
- // arguments that allow you to control the number of points you get back. Here we
- // simply take the default.
- std::vector<surf_point> sp = get_surf_points(img);
- cout << "number of SURF points found: "<< sp.size() << endl;
-
- if (sp.size() > 0)
- {
- // A surf_point object contains a lot of information describing each point.
- // The most important fields are shown below:
- cout << "center of first SURF point: "<< sp[0].p.center << endl;
- cout << "pyramid scale: " << sp[0].p.scale << endl;
- cout << "SURF descriptor: \n" << sp[0].des << endl;
- }
-
- // Create a window to display the input image and the SURF points. (Note that
- // you can zoom into the window by holding CTRL and scrolling the mouse wheel)
- image_window my_window(img);
- draw_surf_points(my_window, sp);
-
- // wait until the user closes the window before we let the program
- // terminate.
- my_window.wait_until_closed();
- }
- catch (exception& e)
- {
- cout << "exception thrown: " << e.what() << endl;
- }
-}
-
-// ----------------------------------------------------------------------------
-
diff --git a/ml/dlib/examples/svm_c_ex.cpp b/ml/dlib/examples/svm_c_ex.cpp
deleted file mode 100644
index b38d0e547..000000000
--- a/ml/dlib/examples/svm_c_ex.cpp
+++ /dev/null
@@ -1,266 +0,0 @@
-// The contents of this file are in the public domain. See LICENSE_FOR_EXAMPLE_PROGRAMS.txt
-/*
-
- This is an example illustrating the use of the support vector machine
- utilities from the dlib C++ Library. In particular, we show how to use the
- C parametrization of the SVM in this example.
-
- This example creates a simple set of data to train on and then shows
- you how to use the cross validation and svm training functions
- to find a good decision function that can classify examples in our
- data set.
-
-
- The data used in this example will be 2 dimensional data and will
- come from a distribution where points with a distance less than 10
- from the origin are labeled +1 and all other points are labeled
- as -1.
-
-*/
-
-
-#include <iostream>
-#include <dlib/svm.h>
-
-using namespace std;
-using namespace dlib;
-
-
-int main()
-{
- // The svm functions use column vectors to contain a lot of the data on
- // which they operate. So the first thing we do here is declare a convenient
- // typedef.
-
- // This typedef declares a matrix with 2 rows and 1 column. It will be the
- // object that contains each of our 2 dimensional samples. (Note that if
- // you wanted more than 2 features in this vector you can simply change the
- // 2 to something else. Or if you don't know how many features you want
- // until runtime then you can put a 0 here and use the matrix.set_size()
- // member function)
- typedef matrix<double, 2, 1> sample_type;
-
- // This is a typedef for the type of kernel we are going to use in this
- // example. In this case I have selected the radial basis kernel that can
- // operate on our 2D sample_type objects. You can use your own custom
- // kernels with these tools as well, see custom_trainer_ex.cpp for an
- // example.
- typedef radial_basis_kernel<sample_type> kernel_type;
-
-
- // Now we make objects to contain our samples and their respective labels.
- std::vector<sample_type> samples;
- std::vector<double> labels;
-
- // Now let's put some data into our samples and labels objects. We do this
- // by looping over a bunch of points and labeling them according to their
- // distance from the origin.
- for (int r = -20; r <= 20; ++r)
- {
- for (int c = -20; c <= 20; ++c)
- {
- sample_type samp;
- samp(0) = r;
- samp(1) = c;
- samples.push_back(samp);
-
- // if this point is less than 10 from the origin
- if (sqrt((double)r*r + c*c) <= 10)
- labels.push_back(+1);
- else
- labels.push_back(-1);
-
- }
- }
-
-
- // Here we normalize all the samples by subtracting their mean and dividing
- // by their standard deviation. This is generally a good idea since it
- // often heads off numerical stability problems and also prevents one large
- // feature from smothering others. Doing this doesn't matter much in this
- // example so I'm just doing this here so you can see an easy way to
- // accomplish it.
- vector_normalizer<sample_type> normalizer;
- // Let the normalizer learn the mean and standard deviation of the samples.
- normalizer.train(samples);
- // now normalize each sample
- for (unsigned long i = 0; i < samples.size(); ++i)
- samples[i] = normalizer(samples[i]);
-
-
- // Now that we have some data we want to train on it. However, there are
- // two parameters to the training. These are the C and gamma parameters.
- // Our choice for these parameters will influence how good the resulting
- // decision function is. To test how good a particular choice of these
- // parameters are we can use the cross_validate_trainer() function to perform
- // n-fold cross validation on our training data. However, there is a
- // problem with the way we have sampled our distribution above. The problem
- // is that there is a definite ordering to the samples. That is, the first
- // half of the samples look like they are from a different distribution than
- // the second half. This would screw up the cross validation process but we
- // can fix it by randomizing the order of the samples with the following
- // function call.
- randomize_samples(samples, labels);
-
-
- // here we make an instance of the svm_c_trainer object that uses our kernel
- // type.
- svm_c_trainer<kernel_type> trainer;
-
- // Now we loop over some different C and gamma values to see how good they
- // are. Note that this is a very simple way to try out a few possible
- // parameter choices. You should look at the model_selection_ex.cpp program
- // for examples of more sophisticated strategies for determining good
- // parameter choices.
- cout << "doing cross validation" << endl;
- for (double gamma = 0.00001; gamma <= 1; gamma *= 5)
- {
- for (double C = 1; C < 100000; C *= 5)
- {
- // tell the trainer the parameters we want to use
- trainer.set_kernel(kernel_type(gamma));
- trainer.set_c(C);
-
- cout << "gamma: " << gamma << " C: " << C;
- // Print out the cross validation accuracy for 3-fold cross validation using
- // the current gamma and C. cross_validate_trainer() returns a row vector.
- // The first element of the vector is the fraction of +1 training examples
- // correctly classified and the second number is the fraction of -1 training
- // examples correctly classified.
- cout << " cross validation accuracy: "
- << cross_validate_trainer(trainer, samples, labels, 3);
- }
- }
-
-
- // From looking at the output of the above loop it turns out that good
- // values for C and gamma for this problem are 5 and 0.15625 respectively.
- // So that is what we will use.
-
- // Now we train on the full set of data and obtain the resulting decision
- // function. The decision function will return values >= 0 for samples it
- // predicts are in the +1 class and numbers < 0 for samples it predicts to
- // be in the -1 class.
- trainer.set_kernel(kernel_type(0.15625));
- trainer.set_c(5);
- typedef decision_function<kernel_type> dec_funct_type;
- typedef normalized_function<dec_funct_type> funct_type;
-
- // Here we are making an instance of the normalized_function object. This
- // object provides a convenient way to store the vector normalization
- // information along with the decision function we are going to learn.
- funct_type learned_function;
- learned_function.normalizer = normalizer; // save normalization information
- learned_function.function = trainer.train(samples, labels); // perform the actual SVM training and save the results
-
- // print out the number of support vectors in the resulting decision function
- cout << "\nnumber of support vectors in our learned_function is "
- << learned_function.function.basis_vectors.size() << endl;
-
- // Now let's try this decision_function on some samples we haven't seen before.
- sample_type sample;
-
- sample(0) = 3.123;
- sample(1) = 2;
- cout << "This is a +1 class example, the classifier output is " << learned_function(sample) << endl;
-
- sample(0) = 3.123;
- sample(1) = 9.3545;
- cout << "This is a +1 class example, the classifier output is " << learned_function(sample) << endl;
-
- sample(0) = 13.123;
- sample(1) = 9.3545;
- cout << "This is a -1 class example, the classifier output is " << learned_function(sample) << endl;
-
- sample(0) = 13.123;
- sample(1) = 0;
- cout << "This is a -1 class example, the classifier output is " << learned_function(sample) << endl;
-
-
- // We can also train a decision function that reports a well conditioned
- // probability instead of just a number > 0 for the +1 class and < 0 for the
- // -1 class. An example of doing that follows:
- typedef probabilistic_decision_function<kernel_type> probabilistic_funct_type;
- typedef normalized_function<probabilistic_funct_type> pfunct_type;
-
- pfunct_type learned_pfunct;
- learned_pfunct.normalizer = normalizer;
- learned_pfunct.function = train_probabilistic_decision_function(trainer, samples, labels, 3);
- // Now we have a function that returns the probability that a given sample is of the +1 class.
-
- // print out the number of support vectors in the resulting decision function.
- // (it should be the same as in the one above)
- cout << "\nnumber of support vectors in our learned_pfunct is "
- << learned_pfunct.function.decision_funct.basis_vectors.size() << endl;
-
- sample(0) = 3.123;
- sample(1) = 2;
- cout << "This +1 class example should have high probability. Its probability is: "
- << learned_pfunct(sample) << endl;
-
- sample(0) = 3.123;
- sample(1) = 9.3545;
- cout << "This +1 class example should have high probability. Its probability is: "
- << learned_pfunct(sample) << endl;
-
- sample(0) = 13.123;
- sample(1) = 9.3545;
- cout << "This -1 class example should have low probability. Its probability is: "
- << learned_pfunct(sample) << endl;
-
- sample(0) = 13.123;
- sample(1) = 0;
- cout << "This -1 class example should have low probability. Its probability is: "
- << learned_pfunct(sample) << endl;
-
-
-
- // Another thing that is worth knowing is that just about everything in dlib
- // is serializable. So for example, you can save the learned_pfunct object
- // to disk and recall it later like so:
- serialize("saved_function.dat") << learned_pfunct;
-
- // Now let's open that file back up and load the function object it contains.
- deserialize("saved_function.dat") >> learned_pfunct;
-
- // Note that there is also an example program that comes with dlib called
- // the file_to_code_ex.cpp example. It is a simple program that takes a
- // file and outputs a piece of C++ code that is able to fully reproduce the
- // file's contents in the form of a std::string object. So you can use that
- // along with the std::istringstream to save learned decision functions
- // inside your actual C++ code files if you want.
-
-
-
-
- // Lastly, note that the decision functions we trained above involved well
- // over 200 basis vectors. Support vector machines in general tend to find
- // decision functions that involve a lot of basis vectors. This is
- // significant because the more basis vectors in a decision function, the
- // longer it takes to classify new examples. So dlib provides the ability
- // to find an approximation to the normal output of a trainer using fewer
- // basis vectors.
-
- // Here we determine the cross validation accuracy when we approximate the
- // output using only 10 basis vectors. To do this we use the reduced2()
- // function. It takes a trainer object and the number of basis vectors to
- // use and returns a new trainer object that applies the necessary post
- // processing during the creation of decision function objects.
- cout << "\ncross validation accuracy with only 10 support vectors: "
- << cross_validate_trainer(reduced2(trainer,10), samples, labels, 3);
-
- // Let's print out the original cross validation score too for comparison.
- cout << "cross validation accuracy with all the original support vectors: "
- << cross_validate_trainer(trainer, samples, labels, 3);
-
- // When you run this program you should see that, for this problem, you can
- // reduce the number of basis vectors down to 10 without hurting the cross
- // validation accuracy.
-
-
- // To get the reduced decision function out we would just do this:
- learned_function.function = reduced2(trainer,10).train(samples, labels);
- // And similarly for the probabilistic_decision_function:
- learned_pfunct.function = train_probabilistic_decision_function(reduced2(trainer,10), samples, labels, 3);
-}
-
diff --git a/ml/dlib/examples/svm_ex.cpp b/ml/dlib/examples/svm_ex.cpp
deleted file mode 100644
index 3d5d0bb84..000000000
--- a/ml/dlib/examples/svm_ex.cpp
+++ /dev/null
@@ -1,255 +0,0 @@
-// The contents of this file are in the public domain. See LICENSE_FOR_EXAMPLE_PROGRAMS.txt
-/*
-
- This is an example illustrating the use of the support vector machine
- utilities from the dlib C++ Library.
-
- This example creates a simple set of data to train on and then shows
- you how to use the cross validation and svm training functions
- to find a good decision function that can classify examples in our
- data set.
-
-
- The data used in this example will be 2 dimensional data and will
- come from a distribution where points with a distance less than 10
- from the origin are labeled +1 and all other points are labeled
- as -1.
-
-*/
-
-
-#include <iostream>
-#include <dlib/svm.h>
-
-using namespace std;
-using namespace dlib;
-
-
-int main()
-{
- // The svm functions use column vectors to contain a lot of the data on which they
- // operate. So the first thing we do here is declare a convenient typedef.
-
- // This typedef declares a matrix with 2 rows and 1 column. It will be the object that
- // contains each of our 2 dimensional samples. (Note that if you wanted more than 2
- // features in this vector you can simply change the 2 to something else. Or if you
- // don't know how many features you want until runtime then you can put a 0 here and
- // use the matrix.set_size() member function)
- typedef matrix<double, 2, 1> sample_type;
-
- // This is a typedef for the type of kernel we are going to use in this example. In
- // this case I have selected the radial basis kernel that can operate on our 2D
- // sample_type objects
- typedef radial_basis_kernel<sample_type> kernel_type;
-
-
- // Now we make objects to contain our samples and their respective labels.
- std::vector<sample_type> samples;
- std::vector<double> labels;
-
- // Now let's put some data into our samples and labels objects. We do this by looping
- // over a bunch of points and labeling them according to their distance from the
- // origin.
- for (int r = -20; r <= 20; ++r)
- {
- for (int c = -20; c <= 20; ++c)
- {
- sample_type samp;
- samp(0) = r;
- samp(1) = c;
- samples.push_back(samp);
-
- // if this point is less than 10 from the origin
- if (sqrt((double)r*r + c*c) <= 10)
- labels.push_back(+1);
- else
- labels.push_back(-1);
-
- }
- }
-
-
- // Here we normalize all the samples by subtracting their mean and dividing by their
- // standard deviation. This is generally a good idea since it often heads off
- // numerical stability problems and also prevents one large feature from smothering
- // others. Doing this doesn't matter much in this example so I'm just doing this here
- // so you can see an easy way to accomplish this with the library.
- vector_normalizer<sample_type> normalizer;
- // let the normalizer learn the mean and standard deviation of the samples
- normalizer.train(samples);
- // now normalize each sample
- for (unsigned long i = 0; i < samples.size(); ++i)
- samples[i] = normalizer(samples[i]);
-
-
- // Now that we have some data we want to train on it. However, there are two
- // parameters to the training. These are the nu and gamma parameters. Our choice for
- // these parameters will influence how good the resulting decision function is. To
- // test how good a particular choice of these parameters is we can use the
- // cross_validate_trainer() function to perform n-fold cross validation on our training
- // data. However, there is a problem with the way we have sampled our distribution
- // above. The problem is that there is a definite ordering to the samples. That is,
- // the first half of the samples look like they are from a different distribution than
- // the second half. This would screw up the cross validation process but we can fix it
- // by randomizing the order of the samples with the following function call.
- randomize_samples(samples, labels);
-
-
- // The nu parameter has a maximum value that is dependent on the ratio of the +1 to -1
- // labels in the training data. This function finds that value.
- const double max_nu = maximum_nu(labels);
-
- // here we make an instance of the svm_nu_trainer object that uses our kernel type.
- svm_nu_trainer<kernel_type> trainer;
-
- // Now we loop over some different nu and gamma values to see how good they are. Note
- // that this is a very simple way to try out a few possible parameter choices. You
- // should look at the model_selection_ex.cpp program for examples of more sophisticated
- // strategies for determining good parameter choices.
- cout << "doing cross validation" << endl;
- for (double gamma = 0.00001; gamma <= 1; gamma *= 5)
- {
- for (double nu = 0.00001; nu < max_nu; nu *= 5)
- {
- // tell the trainer the parameters we want to use
- trainer.set_kernel(kernel_type(gamma));
- trainer.set_nu(nu);
-
- cout << "gamma: " << gamma << " nu: " << nu;
- // Print out the cross validation accuracy for 3-fold cross validation using
- // the current gamma and nu. cross_validate_trainer() returns a row vector.
- // The first element of the vector is the fraction of +1 training examples
- // correctly classified and the second number is the fraction of -1 training
- // examples correctly classified.
- cout << " cross validation accuracy: " << cross_validate_trainer(trainer, samples, labels, 3);
- }
- }
-
-
- // From looking at the output of the above loop it turns out that a good value for nu
- // and gamma for this problem is 0.15625 for both. So that is what we will use.
-
- // Now we train on the full set of data and obtain the resulting decision function. We
- // use the value of 0.15625 for nu and gamma. The decision function will return values
- // >= 0 for samples it predicts are in the +1 class and numbers < 0 for samples it
- // predicts to be in the -1 class.
- trainer.set_kernel(kernel_type(0.15625));
- trainer.set_nu(0.15625);
- typedef decision_function<kernel_type> dec_funct_type;
- typedef normalized_function<dec_funct_type> funct_type;
-
- // Here we are making an instance of the normalized_function object. This object
- // provides a convenient way to store the vector normalization information along with
- // the decision function we are going to learn.
- funct_type learned_function;
- learned_function.normalizer = normalizer; // save normalization information
- learned_function.function = trainer.train(samples, labels); // perform the actual SVM training and save the results
-
- // print out the number of support vectors in the resulting decision function
- cout << "\nnumber of support vectors in our learned_function is "
- << learned_function.function.basis_vectors.size() << endl;
-
- // Now let's try this decision_function on some samples we haven't seen before.
- sample_type sample;
-
- sample(0) = 3.123;
- sample(1) = 2;
- cout << "This is a +1 class example, the classifier output is " << learned_function(sample) << endl;
-
- sample(0) = 3.123;
- sample(1) = 9.3545;
- cout << "This is a +1 class example, the classifier output is " << learned_function(sample) << endl;
-
- sample(0) = 13.123;
- sample(1) = 9.3545;
- cout << "This is a -1 class example, the classifier output is " << learned_function(sample) << endl;
-
- sample(0) = 13.123;
- sample(1) = 0;
- cout << "This is a -1 class example, the classifier output is " << learned_function(sample) << endl;
-
-
- // We can also train a decision function that reports a well conditioned probability
- // instead of just a number > 0 for the +1 class and < 0 for the -1 class. An example
- // of doing that follows:
- typedef probabilistic_decision_function<kernel_type> probabilistic_funct_type;
- typedef normalized_function<probabilistic_funct_type> pfunct_type;
-
- pfunct_type learned_pfunct;
- learned_pfunct.normalizer = normalizer;
- learned_pfunct.function = train_probabilistic_decision_function(trainer, samples, labels, 3);
- // Now we have a function that returns the probability that a given sample is of the +1 class.
-
- // print out the number of support vectors in the resulting decision function.
- // (it should be the same as in the one above)
- cout << "\nnumber of support vectors in our learned_pfunct is "
- << learned_pfunct.function.decision_funct.basis_vectors.size() << endl;
-
- sample(0) = 3.123;
- sample(1) = 2;
- cout << "This +1 class example should have high probability. Its probability is: "
- << learned_pfunct(sample) << endl;
-
- sample(0) = 3.123;
- sample(1) = 9.3545;
- cout << "This +1 class example should have high probability. Its probability is: "
- << learned_pfunct(sample) << endl;
-
- sample(0) = 13.123;
- sample(1) = 9.3545;
- cout << "This -1 class example should have low probability. Its probability is: "
- << learned_pfunct(sample) << endl;
-
- sample(0) = 13.123;
- sample(1) = 0;
- cout << "This -1 class example should have low probability. Its probability is: "
- << learned_pfunct(sample) << endl;
-
-
-
- // Another thing that is worth knowing is that just about everything in dlib is
- // serializable. So for example, you can save the learned_pfunct object to disk and
- // recall it later like so:
- serialize("saved_function.dat") << learned_pfunct;
-
- // Now let's open that file back up and load the function object it contains.
- deserialize("saved_function.dat") >> learned_pfunct;
-
- // Note that there is also an example program that comes with dlib called the
- // file_to_code_ex.cpp example. It is a simple program that takes a file and outputs a
- // piece of C++ code that is able to fully reproduce the file's contents in the form of
- // a std::string object. So you can use that along with the std::istringstream to save
- // learned decision functions inside your actual C++ code files if you want.
-
-
-
-
- // Lastly, note that the decision functions we trained above involved well over 200
- // basis vectors. Support vector machines in general tend to find decision functions
- // that involve a lot of basis vectors. This is significant because the more basis
- // vectors in a decision function, the longer it takes to classify new examples. So
- // dlib provides the ability to find an approximation to the normal output of a trainer
- // using fewer basis vectors.
-
- // Here we determine the cross validation accuracy when we approximate the output using
- // only 10 basis vectors. To do this we use the reduced2() function. It takes a
- // trainer object and the number of basis vectors to use and returns a new trainer
- // object that applies the necessary post processing during the creation of decision
- // function objects.
- cout << "\ncross validation accuracy with only 10 support vectors: "
- << cross_validate_trainer(reduced2(trainer,10), samples, labels, 3);
-
- // Let's print out the original cross validation score too for comparison.
- cout << "cross validation accuracy with all the original support vectors: "
- << cross_validate_trainer(trainer, samples, labels, 3);
-
- // When you run this program you should see that, for this problem, you can reduce the
- // number of basis vectors down to 10 without hurting the cross validation accuracy.
-
-
- // To get the reduced decision function out we would just do this:
- learned_function.function = reduced2(trainer,10).train(samples, labels);
- // And similarly for the probabilistic_decision_function:
- learned_pfunct.function = train_probabilistic_decision_function(reduced2(trainer,10), samples, labels, 3);
-}
-
diff --git a/ml/dlib/examples/svm_pegasos_ex.cpp b/ml/dlib/examples/svm_pegasos_ex.cpp
deleted file mode 100644
index e69b485fc..000000000
--- a/ml/dlib/examples/svm_pegasos_ex.cpp
+++ /dev/null
@@ -1,160 +0,0 @@
-// The contents of this file are in the public domain. See LICENSE_FOR_EXAMPLE_PROGRAMS.txt
-/*
-
- This is an example illustrating the use of the dlib C++ library's
- implementation of the pegasos algorithm for online training of support
- vector machines.
-
- This example creates a simple binary classification problem and shows
- you how to train a support vector machine on that data.
-
- The data used in this example will be 2 dimensional data and will
- come from a distribution where points with a distance less than 10
- from the origin are labeled +1 and all other points are labeled
- as -1.
-
-*/
-
-
-#include <iostream>
-#include <ctime>
-#include <vector>
-#include <dlib/svm.h>
-
-using namespace std;
-using namespace dlib;
-
-
-int main()
-{
- // The svm functions use column vectors to contain a lot of the data on which they
- // operate. So the first thing we do here is declare a convenient typedef.
-
- // This typedef declares a matrix with 2 rows and 1 column. It will be the
- // object that contains each of our 2 dimensional samples. (Note that if you wanted
- // more than 2 features in this vector you can simply change the 2 to something else.
- // Or if you don't know how many features you want until runtime then you can put a 0
- // here and use the matrix.set_size() member function)
- typedef matrix<double, 2, 1> sample_type;
-
-
- // This is a typedef for the type of kernel we are going to use in this example.
- // In this case I have selected the radial basis kernel that can operate on our
- // 2D sample_type objects
- typedef radial_basis_kernel<sample_type> kernel_type;
-
-
- // Here we create an instance of the pegasos svm trainer object we will be using.
- svm_pegasos<kernel_type> trainer;
- // Here we setup the parameters to this object. See the dlib documentation for a
- // description of what these parameters are.
- trainer.set_lambda(0.00001);
- trainer.set_kernel(kernel_type(0.005));
-
- // Set the maximum number of support vectors we want the trainer object to use
- // in representing the decision function it is going to learn. In general,
- // supplying a bigger number here will only ever give you a more accurate
- // answer. However, giving a smaller number will make the algorithm run
- // faster and decision rules that involve fewer support vectors also take
- // less time to evaluate.
- trainer.set_max_num_sv(10);
-
- std::vector<sample_type> samples;
- std::vector<double> labels;
-
- // make an instance of a sample matrix so we can use it below
- sample_type sample, center;
-
- center = 20, 20;
-
- // Now let's go into a loop and randomly generate 1000 samples.
- srand(time(0));
- for (int i = 0; i < 10000; ++i)
- {
- // Make a random sample vector.
- sample = randm(2,1)*40 - center;
-
- // Now if that random vector is less than 10 units from the origin then it is in
- // the +1 class.
- if (length(sample) <= 10)
- {
- // let the svm_pegasos learn about this sample
- trainer.train(sample,+1);
-
- // save this sample so we can use it with the batch training examples below
- samples.push_back(sample);
- labels.push_back(+1);
- }
- else
- {
- // let the svm_pegasos learn about this sample
- trainer.train(sample,-1);
-
- // save this sample so we can use it with the batch training examples below
- samples.push_back(sample);
- labels.push_back(-1);
- }
- }
-
- // Now we have trained our SVM. Let's see how well it did.
- // Each of these statements prints out the output of the SVM given a particular sample.
- // The SVM outputs a number > 0 if a sample is predicted to be in the +1 class and < 0
- // if a sample is predicted to be in the -1 class.
-
- sample(0) = 3.123;
- sample(1) = 4;
- cout << "This is a +1 example, its SVM output is: " << trainer(sample) << endl;
-
- sample(0) = 13.123;
- sample(1) = 9.3545;
- cout << "This is a -1 example, its SVM output is: " << trainer(sample) << endl;
-
- sample(0) = 13.123;
- sample(1) = 0;
- cout << "This is a -1 example, its SVM output is: " << trainer(sample) << endl;
-
-
-
-
-
- // The previous part of this example program showed you how to perform online training
- // with the pegasos algorithm. But it is often the case that you have a dataset and you
- // just want to perform batch learning on that dataset and get the resulting decision
- // function. To support this the dlib library provides functions for converting an online
- // training object like svm_pegasos into a batch training object.
-
- // First let's clear out anything in the trainer object.
- trainer.clear();
-
- // Now to begin with, you might want to compute the cross validation score of a trainer object
- // on your data. To do this you should use the batch_cached() function to convert the svm_pegasos object
- // into a batch training object. Note that the second argument to batch_cached() is the minimum
- // learning rate the trainer object must report for the batch_cached() function to consider training
- // complete. So smaller values of this parameter cause training to take longer but may result
- // in a more accurate solution.
- // Here we perform 4-fold cross validation and print the results
- cout << "cross validation: " << cross_validate_trainer(batch_cached(trainer,0.1), samples, labels, 4);
-
- // Here is an example of creating a decision function. Note that we have used the verbose_batch_cached()
- // function instead of batch_cached() as above. They do the same things except verbose_batch_cached() will
- // print status messages to standard output while training is under way.
- decision_function<kernel_type> df = verbose_batch_cached(trainer,0.1).train(samples, labels);
-
- // At this point we have obtained a decision function from the above batch mode training.
- // Now we can use it on some test samples exactly as we did above.
-
- sample(0) = 3.123;
- sample(1) = 4;
- cout << "This is a +1 example, its SVM output is: " << df(sample) << endl;
-
- sample(0) = 13.123;
- sample(1) = 9.3545;
- cout << "This is a -1 example, its SVM output is: " << df(sample) << endl;
-
- sample(0) = 13.123;
- sample(1) = 0;
- cout << "This is a -1 example, its SVM output is: " << df(sample) << endl;
-
-
-}
-
diff --git a/ml/dlib/examples/svm_rank_ex.cpp b/ml/dlib/examples/svm_rank_ex.cpp
deleted file mode 100644
index e39b90a1b..000000000
--- a/ml/dlib/examples/svm_rank_ex.cpp
+++ /dev/null
@@ -1,151 +0,0 @@
-// The contents of this file are in the public domain. See LICENSE_FOR_EXAMPLE_PROGRAMS.txt
-/*
-
- This is an example illustrating the use of the SVM-Rank tool from the dlib
- C++ Library. This is a tool useful for learning to rank objects. For
- example, you might use it to learn to rank web pages in response to a
- user's query. The idea being to rank the most relevant pages higher than
- non-relevant pages.
-
-
- In this example, we will create a simple test dataset and show how to learn
- a ranking function from it. The purpose of the function will be to give
- "relevant" objects higher scores than "non-relevant" objects. The idea is
- that you use this score to order the objects so that the most relevant
- objects come to the top of the ranked list.
-
-
-
- Note that we use dense vectors (i.e. dlib::matrix objects) in this example,
- however, the ranking tools can also use sparse vectors as well. See
- svm_sparse_ex.cpp for an example.
-*/
-
-#include <dlib/svm.h>
-#include <iostream>
-
-
-using namespace std;
-using namespace dlib;
-
-
-int main()
-{
- try
- {
- // Make a typedef for the kind of object we will be ranking. In this
- // example, we are ranking 2-dimensional vectors.
- typedef matrix<double,2,1> sample_type;
-
-
- // Now let's make some testing data. To make it really simple, let's
- // suppose that vectors with positive values in the first dimension
- // should rank higher than other vectors. So what we do is make
- // examples of relevant (i.e. high ranking) and non-relevant (i.e. low
- // ranking) vectors and store them into a ranking_pair object like so:
- ranking_pair<sample_type> data;
- sample_type samp;
-
- // Make one relevant example.
- samp = 1, 0;
- data.relevant.push_back(samp);
-
- // Now make a non-relevant example.
- samp = 0, 1;
- data.nonrelevant.push_back(samp);
-
-
- // Now that we have some data, we can use a machine learning method to
- // learn a function that will give high scores to the relevant vectors
- // and low scores to the non-relevant vectors.
-
- // The first thing we do is select the kernel we want to use. For the
- // svm_rank_trainer there are only two options. The linear_kernel and
- // sparse_linear_kernel. The later is used if you want to use sparse
- // vectors to represent your objects. Since we are using dense vectors
- // (i.e. dlib::matrix objects to represent the vectors) we use the
- // linear_kernel.
- typedef linear_kernel<sample_type> kernel_type;
-
- // Now make a trainer and tell it to learn a ranking function based on
- // our data.
- svm_rank_trainer<kernel_type> trainer;
- decision_function<kernel_type> rank = trainer.train(data);
-
- // Now if you call rank on a vector it will output a ranking score. In
- // particular, the ranking score for relevant vectors should be larger
- // than the score for non-relevant vectors.
- cout << "ranking score for a relevant vector: " << rank(data.relevant[0]) << endl;
- cout << "ranking score for a non-relevant vector: " << rank(data.nonrelevant[0]) << endl;
- // These output the following:
- /*
- ranking score for a relevant vector: 0.5
- ranking score for a non-relevant vector: -0.5
- */
-
-
- // If we want an overall measure of ranking accuracy we can compute the
- // ordering accuracy and mean average precision values by calling
- // test_ranking_function(). In this case, the ordering accuracy tells
- // us how often a non-relevant vector was ranked ahead of a relevant
- // vector. This function will return a 1 by 2 matrix containing these
- // measures. In this case, it returns 1 1 indicating that the rank
- // function outputs a perfect ranking.
- cout << "testing (ordering accuracy, mean average precision): " << test_ranking_function(rank, data) << endl;
-
- // We can also see the ranking weights:
- cout << "learned ranking weights: \n" << rank.basis_vectors(0) << endl;
- // In this case they are:
- // 0.5
- // -0.5
-
-
-
-
-
- // In the above example, our data contains just two sets of objects.
- // The relevant set and non-relevant set. The trainer is attempting to
- // find a ranking function that gives every relevant vector a higher
- // score than every non-relevant vector. Sometimes what you want to do
- // is a little more complex than this.
- //
- // For example, in the web page ranking example we have to rank pages
- // based on a user's query. In this case, each query will have its own
- // set of relevant and non-relevant documents. What might be relevant
- // to one query may well be non-relevant to another. So in this case
- // we don't have a single global set of relevant web pages and another
- // set of non-relevant web pages.
- //
- // To handle cases like this, we can simply give multiple ranking_pair
- // instances to the trainer. Therefore, each ranking_pair would
- // represent the relevant/non-relevant sets for a particular query. An
- // example is shown below (for simplicity, we reuse our data from above
- // to make 4 identical "queries").
-
- std::vector<ranking_pair<sample_type> > queries;
- queries.push_back(data);
- queries.push_back(data);
- queries.push_back(data);
- queries.push_back(data);
-
- // We train just as before.
- rank = trainer.train(queries);
-
-
- // Now that we have multiple ranking_pair instances, we can also use
- // cross_validate_ranking_trainer(). This performs cross-validation by
- // splitting the queries up into folds. That is, it lets the trainer
- // train on a subset of ranking_pair instances and tests on the rest.
- // It does this over 4 different splits and returns the overall ranking
- // accuracy based on the held out data. Just like test_ranking_function(),
- // it reports both the ordering accuracy and mean average precision.
- cout << "cross-validation (ordering accuracy, mean average precision): "
- << cross_validate_ranking_trainer(trainer, queries, 4) << endl;
-
- }
- catch (std::exception& e)
- {
- cout << e.what() << endl;
- }
-}
-
diff --git a/ml/dlib/examples/svm_sparse_ex.cpp b/ml/dlib/examples/svm_sparse_ex.cpp
deleted file mode 100644
index 5d68e4a2c..000000000
--- a/ml/dlib/examples/svm_sparse_ex.cpp
+++ /dev/null
@@ -1,120 +0,0 @@
-// The contents of this file are in the public domain. See LICENSE_FOR_EXAMPLE_PROGRAMS.txt
-/*
-
- This is an example showing how to use sparse feature vectors with
- the dlib C++ library's machine learning tools.
-
- This example creates a simple binary classification problem and shows
- you how to train a support vector machine on that data.
-
- The data used in this example will be 100 dimensional data and will
- come from a simple linearly separable distribution.
-*/
-
-
-#include <iostream>
-#include <ctime>
-#include <vector>
-#include <dlib/svm.h>
-
-using namespace std;
-using namespace dlib;
-
-
-int main()
-{
- // In this example program we will be dealing with feature vectors that are sparse (i.e. most
- // of the values in each vector are zero). So rather than using a dlib::matrix we can use
- // one of the containers from the STL to represent our sample vectors. In particular, we
- // can use the std::map to represent sparse vectors. (Note that you don't have to use std::map.
- // Any STL container of std::pair objects that is sorted can be used. So for example, you could
- // use a std::vector<std::pair<unsigned long,double> > here so long as you took care to sort every vector)
- typedef std::map<unsigned long,double> sample_type;
-
-
- // This is a typedef for the type of kernel we are going to use in this example.
- // Since our data is linearly separable I picked the linear kernel. Note that if you
- // are using a sparse vector representation like std::map then you have to use a kernel
- // meant to be used with that kind of data type.
- typedef sparse_linear_kernel<sample_type> kernel_type;
-
-
- // Here we create an instance of the pegasos svm trainer object we will be using.
- svm_pegasos<kernel_type> trainer;
- // Here we setup a parameter to this object. See the dlib documentation for a
- // description of what this parameter does.
- trainer.set_lambda(0.00001);
-
- // Let's also use the svm trainer specially optimized for the linear_kernel and
- // sparse_linear_kernel.
- svm_c_linear_trainer<kernel_type> linear_trainer;
- // This trainer solves the "C" formulation of the SVM. See the documentation for
- // details.
- linear_trainer.set_c(10);
-
- std::vector<sample_type> samples;
- std::vector<double> labels;
-
- // make an instance of a sample vector so we can use it below
- sample_type sample;
-
-
- // Now let's go into a loop and randomly generate 10000 samples.
- srand(time(0));
- double label = +1;
- for (int i = 0; i < 10000; ++i)
- {
- // flip this flag
- label *= -1;
-
- sample.clear();
-
- // now make a random sparse sample with at most 10 non-zero elements
- for (int j = 0; j < 10; ++j)
- {
- int idx = std::rand()%100;
- double value = static_cast<double>(std::rand())/RAND_MAX;
-
- sample[idx] = label*value;
- }
-
- // let the svm_pegasos learn about this sample.
- trainer.train(sample,label);
-
- // Also save the samples we are generating so we can let the svm_c_linear_trainer
- // learn from them below.
- samples.push_back(sample);
- labels.push_back(label);
- }
-
- // In addition to the rule we learned with the pegasos trainer, let's also use our
- // linear_trainer to learn a decision rule.
- decision_function<kernel_type> df = linear_trainer.train(samples, labels);
-
- // Now we have trained our SVMs. Let's test them out a bit.
- // Each of these statements prints the output of the SVMs given a particular sample.
- // Each SVM outputs a number > 0 if a sample is predicted to be in the +1 class and < 0
- // if a sample is predicted to be in the -1 class.
-
-
- sample.clear();
- sample[4] = 0.3;
- sample[10] = 0.9;
- cout << "This is a +1 example, its SVM output is: " << trainer(sample) << endl;
- cout << "df: " << df(sample) << endl;
-
- sample.clear();
- sample[83] = -0.3;
- sample[26] = -0.9;
- sample[58] = -0.7;
- cout << "This is a -1 example, its SVM output is: " << trainer(sample) << endl;
- cout << "df: " << df(sample) << endl;
-
- sample.clear();
- sample[0] = -0.2;
- sample[9] = -0.8;
- cout << "This is a -1 example, its SVM output is: " << trainer(sample) << endl;
- cout << "df: " << df(sample) << endl;
-
-}
-
diff --git a/ml/dlib/examples/svm_struct_ex.cpp b/ml/dlib/examples/svm_struct_ex.cpp
deleted file mode 100644
index f79ae4d14..000000000
--- a/ml/dlib/examples/svm_struct_ex.cpp
+++ /dev/null
@@ -1,414 +0,0 @@
-// The contents of this file are in the public domain. See LICENSE_FOR_EXAMPLE_PROGRAMS.txt
-/*
-
- This is an example illustrating the use of the structural SVM solver from the dlib C++
- Library. Therefore, this example teaches you the central ideas needed to setup a
- structural SVM model for your machine learning problems. To illustrate the process, we
- use dlib's structural SVM solver to learn the parameters of a simple multi-class
- classifier. We first discuss the multi-class classifier model and then walk through
- using the structural SVM tools to find the parameters of this classification model.
-
-*/
-
-
-#include <iostream>
-#include <dlib/svm_threaded.h>
-
-using namespace std;
-using namespace dlib;
-
-
-// Before we start, we define three typedefs we will use throughout this program. The
-// first is used to represent the parameter vector the structural SVM is learning, the
-// second is used to represent the "sample type". In this example program it is just a
-// vector but in general when using a structural SVM your sample type can be anything you
-// want (e.g. a string or an image). The last typedef is the type used to represent the
-// PSI vector which is part of the structural SVM model which we will explain in detail
-// later on. But the important thing to note here is that you can use either a dense
-// representation (i.e. a dlib::matrix object) or a sparse representation for the PSI
-// vector. See svm_sparse_ex.cpp for an introduction to sparse vectors in dlib. Here we
-// use the same type for each of these three things to keep the example program simple.
-typedef matrix<double,0,1> column_vector; // Must be a dlib::matrix type.
-typedef matrix<double,0,1> sample_type; // Can be anything you want.
-typedef matrix<double,0,1> feature_vector_type; // Must be dlib::matrix or some kind of sparse vector.
-
-// ----------------------------------------------------------------------------------------
-
-int predict_label (const column_vector& weights, const sample_type& sample);
-column_vector train_three_class_classifier (const std::vector<sample_type>& samples, const std::vector<int>& labels);
-
-// ----------------------------------------------------------------------------------------
-
-int main()
-{
- // In this example, we have three types of samples: class 0, 1, or 2. That is, each of
- // our sample vectors falls into one of three classes. To keep this example very
- // simple, each sample vector is zero everywhere except at one place. The non-zero
- // dimension of each vector determines the class of the vector. So for example, the
- // first element of samples has a class of 1 because samples[0](1) is the only non-zero
- // element of samples[0].
- sample_type samp(3);
- std::vector<sample_type> samples;
- samp = 0,2,0; samples.push_back(samp);
- samp = 1,0,0; samples.push_back(samp);
- samp = 0,4,0; samples.push_back(samp);
- samp = 0,0,3; samples.push_back(samp);
- // Since we want to use a machine learning method to learn a 3-class classifier we need
- // to record the labels of our samples. Here samples[i] has a class label of labels[i].
- std::vector<int> labels;
- labels.push_back(1);
- labels.push_back(0);
- labels.push_back(1);
- labels.push_back(2);
-
-
- // Now that we have some training data we can tell the structural SVM to learn the
- // parameters of our 3-class classifier model. The details of this will be explained
- // later. For now, just note that it finds the weights (i.e. a vector of real valued
- // parameters) such that predict_label(weights, sample) always returns the correct
- // label for a sample vector.
- column_vector weights = train_three_class_classifier(samples, labels);
-
- // Print the weights and then evaluate predict_label() on each of our training samples.
- // Note that the correct label is predicted for each sample.
- cout << weights << endl;
- for (unsigned long i = 0; i < samples.size(); ++i)
- cout << "predicted label for sample["<<i<<"]: " << predict_label(weights, samples[i]) << endl;
-}
-
-// ----------------------------------------------------------------------------------------
-
-int predict_label (
- const column_vector& weights,
- const sample_type& sample
-)
-/*!
- requires
- - weights.size() == 9
- - sample.size() == 3
- ensures
- - Given the 9-dimensional weight vector which defines a 3 class classifier, this
- function predicts the class of the given 3-dimensional sample vector.
- Therefore, the output of this function is either 0, 1, or 2 (i.e. one of the
- three possible labels).
-!*/
-{
- // Our 3-class classifier model can be thought of as containing 3 separate linear
- // classifiers. So to predict the class of a sample vector we evaluate each of these
- // three classifiers and then whatever classifier has the largest output "wins" and
- // predicts the label of the sample. This is the popular one-vs-all multi-class
- // classifier model.
- //
- // Keeping this in mind, the code below simply pulls the three separate weight vectors
- // out of weights and then evaluates each against sample. The individual classifier
- // scores are stored in scores and the highest scoring index is returned as the label.
- column_vector w0, w1, w2;
- w0 = rowm(weights, range(0,2));
- w1 = rowm(weights, range(3,5));
- w2 = rowm(weights, range(6,8));
-
- column_vector scores(3);
- scores = dot(w0, sample), dot(w1, sample), dot(w2, sample);
-
- return index_of_max(scores);
-}
-
-// ----------------------------------------------------------------------------------------
-// ----------------------------------------------------------------------------------------
-// ----------------------------------------------------------------------------------------
-
-class three_class_classifier_problem : public structural_svm_problem_threaded<column_vector, feature_vector_type>
-{
- /*!
- Now we arrive at the meat of this example program. To use dlib's structural SVM
- solver you need to define an object which tells the structural SVM solver what to
- do for your problem. In this example, this is done by defining the three_class_classifier_problem
- object which inherits from structural_svm_problem_threaded. Before we get into the
- details, we first discuss some background information on structural SVMs.
-
- A structural SVM is a supervised machine learning method for learning to predict
- complex outputs. This is contrasted with a binary classifier which makes only simple
- yes/no predictions. A structural SVM, on the other hand, can learn to predict
- complex outputs such as entire parse trees or DNA sequence alignments. To do this,
- it learns a function F(x,y) which measures how well a particular data sample x
- matches a label y, where a label is potentially a complex thing like a parse tree.
- However, to keep this example program simple we use only a 3 category label output.
-
- At test time, the best label for a new x is given by the y which maximizes F(x,y).
- To put this into the context of the current example, F(x,y) computes the score for
- a given sample and class label. The predicted class label is therefore whatever
- value of y which makes F(x,y) the biggest. This is exactly what predict_label()
- does. That is, it computes F(x,0), F(x,1), and F(x,2) and then reports which label
- has the biggest value.
-
- At a high level, a structural SVM can be thought of as searching the parameter space
- of F(x,y) for the set of parameters that make the following inequality true as often
- as possible:
- F(x_i,y_i) > max{over all incorrect labels of x_i} F(x_i, y_incorrect)
- That is, it seeks to find the parameter vector such that F(x,y) always gives the
- highest score to the correct output. To define the structural SVM optimization
- problem precisely, we first introduce some notation:
- - let PSI(x,y) == the joint feature vector for input x and a label y.
- - let F(x,y|w) == dot(w,PSI(x,y)).
- (we use the | notation to emphasize that F() has the parameter vector of
- weights called w)
- - let LOSS(idx,y) == the loss incurred for predicting that the idx-th training
- sample has a label of y. Note that LOSS() should always be >= 0 and should
- become exactly 0 when y is the correct label for the idx-th sample. Moreover,
- it should notionally indicate how bad it is to predict y for the idx'th sample.
- - let x_i == the i-th training sample.
- - let y_i == the correct label for the i-th training sample.
- - The number of data samples is N.
-
- Then the optimization problem solved by dlib's structural SVM solver is the following:
- Minimize: h(w) == 0.5*dot(w,w) + C*R(w)
-
- Where R(w) == sum from i=1 to N: 1/N * sample_risk(i,w)
- and sample_risk(i,w) == max over all Y: LOSS(i,Y) + F(x_i,Y|w) - F(x_i,y_i|w)
- and C > 0
-
- You can think of the sample_risk(i,w) as measuring the degree of error you would make
- when predicting the label of the i-th sample using parameters w. That is, it is zero
- only when the correct label would be predicted and grows larger the more "wrong" the
- predicted output becomes. Therefore, the objective function is minimizing a balance
- between making the weights small (typically this reduces overfitting) and fitting the
- training data. The degree to which you try to fit the data is controlled by the C
- parameter.
-
- For a more detailed introduction to structured support vector machines you should
- consult the following paper:
- Predicting Structured Objects with Support Vector Machines by
- Thorsten Joachims, Thomas Hofmann, Yisong Yue, and Chun-nam Yu
-
- !*/
-
-public:
-
- // Finally, we come back to the code. To use dlib's structural SVM solver you need to
- // provide the things discussed above. This is the number of training samples, the
- // dimensionality of PSI(), as well as methods for calculating the loss values and
- // PSI() vectors. You will also need to write code that can compute: max over all Y:
- // LOSS(i,Y) + F(x_i,Y|w). In particular, the three_class_classifier_problem class is
- // required to implement the following four virtual functions:
- // - get_num_dimensions()
- // - get_num_samples()
- // - get_truth_joint_feature_vector()
- // - separation_oracle()
-
-
- // But first, we declare a constructor so we can populate our three_class_classifier_problem
- // object with the data we need to define our machine learning problem. All we do here
- // is take in the training samples and their labels as well as a number indicating how
- // many threads the structural SVM solver will use. You can declare this constructor
- // any way you like since it is not used by any of the dlib tools.
- three_class_classifier_problem (
- const std::vector<sample_type>& samples_,
- const std::vector<int>& labels_,
- const unsigned long num_threads
- ) :
- structural_svm_problem_threaded<column_vector, feature_vector_type>(num_threads),
- samples(samples_),
- labels(labels_)
- {}
-
- feature_vector_type make_psi (
- const sample_type& x,
- const int label
- ) const
- /*!
- ensures
- - returns the vector PSI(x,label)
- !*/
- {
- // All we are doing here is taking x, which is a 3 dimensional sample vector in this
- // example program, and putting it into one of 3 places in a 9 dimensional PSI
- // vector, which we then return. So this function returns PSI(x,label). To see why
- // we setup PSI like this, recall how predict_label() works. It takes in a 9
- // dimensional weight vector and breaks the vector into 3 pieces. Each piece then
- // defines a different classifier and we use them in a one-vs-all manner to predict
- // the label. So now that we are in the structural SVM code we have to define the
- // PSI vector to correspond to this usage. That is, we need to setup PSI so that
- // argmax_y dot(weights,PSI(x,y)) == predict_label(weights,x). This is how we tell
- // the structural SVM solver what kind of problem we are trying to solve.
- //
- // It's worth emphasizing that the single biggest step in using a structural SVM is
- // deciding how you want to represent PSI(x,label). It is always a vector, but
- // deciding what to put into it to solve your problem is often not a trivial task.
- // Part of the difficulty is that you need an efficient method for finding the label
- // that makes dot(w,PSI(x,label)) the biggest. Sometimes this is easy, but often
- // finding the max scoring label turns into a difficult combinatorial optimization
- // problem. So you need to pick a PSI that doesn't make the label maximization step
- // intractable but also still well models your problem.
- //
- // Finally, note that make_psi() is a helper routine we define in this example. In
- // general, you are not required to implement it. That is, all you must implement
- // are the four virtual functions defined below.
-
-
- // So let's make an empty 9-dimensional PSI vector
- feature_vector_type psi(get_num_dimensions());
- psi = 0; // zero initialize it
-
- // Now put a copy of x into the right place in PSI according to its label. So for
- // example, if label is 1 then psi would be: [0 0 0 x(0) x(1) x(2) 0 0 0]
- if (label == 0)
- set_rowm(psi,range(0,2)) = x;
- else if (label == 1)
- set_rowm(psi,range(3,5)) = x;
- else // the label must be 2
- set_rowm(psi,range(6,8)) = x;
-
- return psi;
- }
-
- // We need to declare the dimensionality of the PSI vector (this is also the
- // dimensionality of the weight vector we are learning). Similarly, we need to declare
- // the number of training samples. We do this by defining the following virtual
- // functions.
- virtual long get_num_dimensions () const { return samples[0].size() * 3; }
- virtual long get_num_samples () const { return samples.size(); }
-
- // In get_truth_joint_feature_vector(), all you have to do is output the PSI() vector
- // for the idx-th training sample when it has its true label. So here it outputs
- // PSI(samples[idx], labels[idx]).
- virtual void get_truth_joint_feature_vector (
- long idx,
- feature_vector_type& psi
- ) const
- {
- psi = make_psi(samples[idx], labels[idx]);
- }
-
- // separation_oracle() is more interesting. dlib's structural SVM solver will call
- // separation_oracle() many times during the optimization. Each time it will give it
- // the current value of the parameter weights and separation_oracle() is supposed to
- // find the label that most violates the structural SVM objective function for the
- // idx-th sample. Then the separation oracle reports the corresponding PSI vector and
- // loss value. To state this more precisely, the separation_oracle() member function
- // has the following contract:
- // requires
- // - 0 <= idx < get_num_samples()
- // - current_solution.size() == get_num_dimensions()
- // ensures
- // - runs the separation oracle on the idx-th sample. We define this as follows:
- // - let X == the idx-th training sample.
- // - let PSI(X,y) == the joint feature vector for input X and an arbitrary label y.
- // - let F(X,y) == dot(current_solution,PSI(X,y)).
- // - let LOSS(idx,y) == the loss incurred for predicting that the idx-th sample
- // has a label of y. Note that LOSS() should always be >= 0 and should
- // become exactly 0 when y is the correct label for the idx-th sample.
- //
- // Then the separation oracle finds a Y such that:
- // Y = argmax over all y: LOSS(idx,y) + F(X,y)
- // (i.e. It finds the label which maximizes the above expression.)
- //
- // Finally, we can define the outputs of this function as:
- // - #loss == LOSS(idx,Y)
- // - #psi == PSI(X,Y)
- virtual void separation_oracle (
- const long idx,
- const column_vector& current_solution,
- scalar_type& loss,
- feature_vector_type& psi
- ) const
- {
- // Note that the solver will use multiple threads to make concurrent calls to
- // separation_oracle(), therefore, you must implement it in a thread safe manner
- // (or disable threading by inheriting from structural_svm_problem instead of
- // structural_svm_problem_threaded). However, if your separation oracle is not
- // very fast to execute you can get a very significant speed boost by using the
- // threaded solver. In general, all you need to do to make your separation oracle
- // thread safe is to make sure it does not modify any global variables or members
- // of three_class_classifier_problem. So it is usually easy to make thread safe.
-
- column_vector scores(3);
-
- // compute scores for each of the three classifiers
- scores = dot(rowm(current_solution, range(0,2)), samples[idx]),
- dot(rowm(current_solution, range(3,5)), samples[idx]),
- dot(rowm(current_solution, range(6,8)), samples[idx]);
-
- // Add in the loss-augmentation. Recall that we maximize LOSS(idx,y) + F(X,y) in
- // the separate oracle, not just F(X,y) as we normally would in predict_label().
- // Therefore, we must add in this extra amount to account for the loss-augmentation.
- // For our simple multi-class classifier, we incur a loss of 1 if we don't predict
- // the correct label and a loss of 0 if we get the right label.
- if (labels[idx] != 0)
- scores(0) += 1;
- if (labels[idx] != 1)
- scores(1) += 1;
- if (labels[idx] != 2)
- scores(2) += 1;
-
- // Now figure out which classifier has the largest loss-augmented score.
- const int max_scoring_label = index_of_max(scores);
- // And finally record the loss that was associated with that predicted label.
- // Again, the loss is 1 if the label is incorrect and 0 otherwise.
- if (max_scoring_label == labels[idx])
- loss = 0;
- else
- loss = 1;
-
- // Finally, compute the PSI vector corresponding to the label we just found and
- // store it into psi for output.
- psi = make_psi(samples[idx], max_scoring_label);
- }
-
-private:
-
- // Here we hold onto the training data by reference. You can hold it by value or by
- // any other method you like.
- const std::vector<sample_type>& samples;
- const std::vector<int>& labels;
-};
-
-// ----------------------------------------------------------------------------------------
-
-// This function puts it all together. In here we use the three_class_classifier_problem
-// along with dlib's oca cutting plane solver to find the optimal weights given our
-// training data.
-column_vector train_three_class_classifier (
- const std::vector<sample_type>& samples,
- const std::vector<int>& labels
-)
-{
- const unsigned long num_threads = 4;
- three_class_classifier_problem problem(samples, labels, num_threads);
-
- // Before we run the solver we set up some general parameters. First,
- // you can set the C parameter of the structural SVM by calling set_c().
- problem.set_c(1);
-
- // The epsilon parameter controls the stopping tolerance. The optimizer will run until
- // R(w) is within epsilon of its optimal value. If you don't set this then it defaults
- // to 0.001.
- problem.set_epsilon(0.0001);
-
- // Uncomment this and the optimizer will print its progress to standard out. You will
- // be able to see things like the current risk gap. The optimizer continues until the
- // risk gap is below epsilon.
- //problem.be_verbose();
-
- // The optimizer uses an internal cache to avoid unnecessary calls to your
- // separation_oracle() routine. This parameter controls the size of that cache.
- // Bigger values use more RAM and might make the optimizer run faster. You can also
- // disable it by setting it to 0 which is good to do when your separation_oracle is
- // very fast. If you don't call this function it defaults to a value of 5.
- //problem.set_max_cache_size(20);
-
-
- column_vector weights;
- // Finally, we create the solver and then run it.
- oca solver;
- solver(problem, weights);
-
- // Alternatively, if you wanted to require that the learned weights are all
- // non-negative then you can call the solver as follows and it will put a constraint on
- // the optimization problem which causes all elements of weights to be >= 0.
- //solver(problem, weights, problem.get_num_dimensions());
-
- return weights;
-}
-
-// ----------------------------------------------------------------------------------------
-
diff --git a/ml/dlib/examples/svr_ex.cpp b/ml/dlib/examples/svr_ex.cpp
deleted file mode 100644
index a18edf24d..000000000
--- a/ml/dlib/examples/svr_ex.cpp
+++ /dev/null
@@ -1,96 +0,0 @@
-// The contents of this file are in the public domain. See LICENSE_FOR_EXAMPLE_PROGRAMS.txt
-/*
- This is an example illustrating the use of the epsilon-insensitive support vector
- regression object from the dlib C++ Library.
-
- In this example we will draw some points from the sinc() function and do a
- non-linear regression on them.
-*/
-
-#include <iostream>
-#include <vector>
-
-#include <dlib/svm.h>
-
-using namespace std;
-using namespace dlib;
-
-// Here is the sinc function we will be trying to learn with the svr_trainer
-// object.
-double sinc(double x)
-{
- if (x == 0)
- return 1;
- return sin(x)/x;
-}
-
-int main()
-{
- // Here we declare that our samples will be 1 dimensional column vectors.
- typedef matrix<double,1,1> sample_type;
-
- // Now we are making a typedef for the kind of kernel we want to use. I picked the
- // radial basis kernel because it only has one parameter and generally gives good
- // results without much fiddling.
- typedef radial_basis_kernel<sample_type> kernel_type;
-
-
- std::vector<sample_type> samples;
- std::vector<double> targets;
-
- // The first thing we do is pick a few training points from the sinc() function.
- sample_type m;
- for (double x = -10; x <= 4; x += 1)
- {
- m(0) = x;
-
- samples.push_back(m);
- targets.push_back(sinc(x));
- }
-
- // Now setup a SVR trainer object. It has three parameters, the kernel and
- // two parameters specific to SVR.
- svr_trainer<kernel_type> trainer;
- trainer.set_kernel(kernel_type(0.1));
-
- // This parameter is the usual regularization parameter. It determines the trade-off
- // between trying to reduce the training error or allowing more errors but hopefully
- // improving the generalization of the resulting function. Larger values encourage exact
- // fitting while smaller values of C may encourage better generalization.
- trainer.set_c(10);
-
- // Epsilon-insensitive regression means we do regression but stop trying to fit a data
- // point once it is "close enough" to its target value. This parameter is the value that
- // controls what we mean by "close enough". In this case, I'm saying I'm happy if the
- // resulting regression function gets within 0.001 of the target value.
- trainer.set_epsilon_insensitivity(0.001);
-
- // Now do the training and save the results
- decision_function<kernel_type> df = trainer.train(samples, targets);
-
- // now we output the value of the sinc function for a few test points as well as the
- // value predicted by SVR.
- m(0) = 2.5; cout << sinc(m(0)) << " " << df(m) << endl;
- m(0) = 0.1; cout << sinc(m(0)) << " " << df(m) << endl;
- m(0) = -4; cout << sinc(m(0)) << " " << df(m) << endl;
- m(0) = 5.0; cout << sinc(m(0)) << " " << df(m) << endl;
-
- // The output is as follows:
- // 0.239389 0.23905
- // 0.998334 0.997331
- // -0.189201 -0.187636
- // -0.191785 -0.218924
-
- // The first column is the true value of the sinc function and the second
- // column is the output from the SVR estimate.
-
- // We can also do 5-fold cross-validation and find the mean squared error and R-squared
- // values. Note that we need to randomly shuffle the samples first. See the svm_ex.cpp
- // for a discussion of why this is important.
- randomize_samples(samples, targets);
- cout << "MSE and R-Squared: "<< cross_validate_regression_trainer(trainer, samples, targets, 5) << endl;
- // The output is:
- // MSE and R-Squared: 1.65984e-05 0.999901
-}
-
-
diff --git a/ml/dlib/examples/thread_function_ex.cpp b/ml/dlib/examples/thread_function_ex.cpp
deleted file mode 100644
index 91825ffe7..000000000
--- a/ml/dlib/examples/thread_function_ex.cpp
+++ /dev/null
@@ -1,71 +0,0 @@
-// The contents of this file are in the public domain. See LICENSE_FOR_EXAMPLE_PROGRAMS.txt
-/*
- This is a very simple example that illustrates the use of the
- thread_function object from the dlib C++ Library.
-
- The output of the programs should look like this:
-
- 45.6
- 9.999
- I have no args!
- val: 3
-*/
-
-
-#include <iostream>
-#include <dlib/threads.h>
-#include <dlib/ref.h>
-
-using namespace dlib;
-using namespace std;
-
-void thread_1(double a)
-{
- cout << a << endl;
-}
-
-void thread_2 ()
-{
- cout << "I have no args!" << endl;
-}
-
-void thread_increment(double& a)
-{
- a += 1;
-}
-
-int main()
-{
- // create a thread that will call thread_1(45.6)
- thread_function t1(thread_1,45.6);
- // wait for the t1 thread to end
- t1.wait();
-
-
- // create a thread that will call thread_1(9.999)
- thread_function t2(thread_1,9.999);
- // wait for the t2 thread to end
- t2.wait();
-
-
- // create a thread that will call thread_2()
- thread_function t3(thread_2);
-
-
- // Note that we can also use the ref() function to pass a variable
- // to a thread by reference. For example, the thread below adds
- // one to val.
- double val = 2;
- thread_function t4(thread_increment, dlib::ref(val));
- t4.wait(); // wait for t4 to finish before printing val.
- // Print val. It will now have a value of 3.
- cout << "val: " << val << endl;
-
-
-
- // At this point we will automatically wait for t3 to end because
- // the destructor for thread_function objects always wait for their
- // thread to terminate.
-}
-
-
diff --git a/ml/dlib/examples/thread_pool_ex.cpp b/ml/dlib/examples/thread_pool_ex.cpp
deleted file mode 100644
index e0a566ef6..000000000
--- a/ml/dlib/examples/thread_pool_ex.cpp
+++ /dev/null
@@ -1,183 +0,0 @@
-// The contents of this file are in the public domain. See LICENSE_FOR_EXAMPLE_PROGRAMS.txt
-/*
-
- This is an example illustrating the use of the thread_pool
- object from the dlib C++ Library.
-
-
- In this example we will crate a thread pool with 3 threads and then show a
- few different ways to send tasks to the pool.
-*/
-
-
-#include <dlib/threads.h>
-#include <dlib/misc_api.h> // for dlib::sleep
-#include <dlib/logger.h>
-#include <vector>
-
-using namespace dlib;
-
-// We will be using the dlib logger object to print messages in this example
-// because its output is timestamped and labeled with the thread that the log
-// message came from. This will make it easier to see what is going on in this
-// example. Here we make an instance of the logger. See the logger
-// documentation and examples for detailed information regarding its use.
-logger dlog("main");
-
-
-// Here we make an instance of the thread pool object. You could also use the
-// global dlib::default_thread_pool(), which automatically selects the number of
-// threads based on your hardware. But here let's make our own.
-thread_pool tp(3);
-
-// ----------------------------------------------------------------------------------------
-
-class test
-{
- /*
- The thread_pool accepts "tasks" from the user and schedules them for
- execution in one of its threads when one becomes available. Each task
- is just a request to call a function. So here we create a class called
- test with a few member functions, which we will have the thread pool call
- as tasks.
- */
-public:
-
- void mytask()
- {
- dlog << LINFO << "mytask start";
-
- dlib::future<int> var;
-
- var = 1;
-
- // Here we ask the thread pool to call this->subtask() and this->subtask2().
- // Note that calls to add_task() will return immediately if there is an
- // available thread. However, if there isn't a thread ready then
- // add_task() blocks until there is such a thread. Also, note that if
- // mytask() is executed within the thread pool then calls to add_task()
- // will execute the requested task within the calling thread in cases
- // where the thread pool is full. This means it is always safe to spawn
- // subtasks from within another task, which is what we are doing here.
- tp.add_task(*this,&test::subtask,var); // schedule call to this->subtask(var)
- tp.add_task(*this,&test::subtask2); // schedule call to this->subtask2()
-
- // Since var is a future, this line will wait for the test::subtask task to
- // finish before allowing us to access the contents of var. Then var will
- // return the integer it contains. In this case result will be assigned
- // the value 2 since var was incremented by subtask().
- int result = var;
- dlog << LINFO << "var = " << result;
-
- // Wait for all the tasks we have started to finish. Note that
- // wait_for_all_tasks() only waits for tasks which were started by the
- // calling thread. So you don't have to worry about other unrelated
- // parts of your application interfering. In this case it just waits
- // for subtask2() to finish.
- tp.wait_for_all_tasks();
-
- dlog << LINFO << "mytask end" ;
- }
-
- void subtask(int& a)
- {
- dlib::sleep(200);
- a = a + 1;
- dlog << LINFO << "subtask end ";
- }
-
- void subtask2()
- {
- dlib::sleep(300);
- dlog << LINFO << "subtask2 end ";
- }
-
-};
-
-// ----------------------------------------------------------------------------------------
-
-int main() try
-{
- // tell the logger to print out everything
- dlog.set_level(LALL);
-
-
- dlog << LINFO << "schedule a few tasks";
-
- test taskobj;
- // Schedule the thread pool to call taskobj.mytask(). Note that all forms of
- // add_task() pass in the task object by reference. This means you must make sure,
- // in this case, that taskobj isn't destructed until after the task has finished
- // executing.
- tp.add_task(taskobj, &test::mytask);
-
- // This behavior of add_task() enables it to guarantee that no memory allocations
- // occur after the thread_pool has been constructed, so long as the user doesn't
- // call any of the add_task_by_value() routines. The future object also doesn't
- // perform any memory allocations or contain any system resources such as mutex
- // objects. If you don't care about memory allocations then you will likely find
- // the add_task_by_value() interface more convenient to use, which is shown below.
-
-
-
- // If we call add_task_by_value() we pass task objects to a thread pool by value.
- // So in this case we don't have to worry about keeping our own instance of the
- // task. Here we create a lambda function and pass it right in and everything
- // works like it should.
- dlib::future<int> num = 3;
- tp.add_task_by_value([](int& val){val += 7;}, num); // adds 7 to num
- int result = num.get();
- dlog << LINFO << "result = " << result; // prints result = 10
-
-
- // dlib also contains dlib::async(), which is essentially identical to std::async()
- // except that it launches tasks to a dlib::thread_pool (using add_task_by_value)
- // rather than starting an unbounded number of threads. As an example, here we
- // make 10 different tasks, each assigns a different value into the elements of the
- // vector vect.
- std::vector<std::future<unsigned long>> vect(10);
- for (unsigned long i = 0; i < vect.size(); ++i)
- vect[i] = dlib::async(tp, [i]() { return i*i; });
- // Print the results
- for (unsigned long i = 0; i < vect.size(); ++i)
- dlog << LINFO << "vect["<<i<<"]: " << vect[i].get();
-
-
- // Finally, it's usually a good idea to wait for all your tasks to complete.
- // Moreover, if any of your tasks threw an exception then waiting for the tasks
- // will rethrow the exception in the calling context, allowing you to handle it in
- // your local thread. Also, if you don't wait for the tasks and there is an
- // exception and you allow the thread pool to be destructed your program will be
- // terminated. So don't ignore exceptions :)
- tp.wait_for_all_tasks();
-
-
- /* A possible run of this program might produce the following output (the first
- column is the time the log message occurred and the value in [] is the thread
- id for the thread that generated the log message):
-
- 0 INFO [0] main: schedule a few tasks
- 0 INFO [1] main: task start
- 0 INFO [0] main: result = 10
- 200 INFO [2] main: subtask end
- 200 INFO [1] main: var = 2
- 200 INFO [0] main: vect[0]: 0
- 200 INFO [0] main: vect[1]: 1
- 200 INFO [0] main: vect[2]: 4
- 200 INFO [0] main: vect[3]: 9
- 200 INFO [0] main: vect[4]: 16
- 200 INFO [0] main: vect[5]: 25
- 200 INFO [0] main: vect[6]: 36
- 200 INFO [0] main: vect[7]: 49
- 200 INFO [0] main: vect[8]: 64
- 200 INFO [0] main: vect[9]: 81
- 300 INFO [3] main: subtask2 end
- 300 INFO [1] main: task end
- */
-}
-catch(std::exception& e)
-{
- std::cout << e.what() << std::endl;
-}
-
-
diff --git a/ml/dlib/examples/threaded_object_ex.cpp b/ml/dlib/examples/threaded_object_ex.cpp
deleted file mode 100644
index 84fe10265..000000000
--- a/ml/dlib/examples/threaded_object_ex.cpp
+++ /dev/null
@@ -1,79 +0,0 @@
-// The contents of this file are in the public domain. See LICENSE_FOR_EXAMPLE_PROGRAMS.txt
-/*
-
- This is an example illustrating the use of the threaded_object
- from the dlib C++ Library.
-
-
- This is a very simple example. It creates a single thread that
- just prints messages to the screen.
-*/
-
-
-#include <iostream>
-#include <dlib/threads.h>
-#include <dlib/misc_api.h> // for dlib::sleep
-
-using namespace std;
-using namespace dlib;
-
-class my_object : public threaded_object
-{
-public:
- my_object()
- {
- // Start our thread going in the thread() function
- start();
- }
-
- ~my_object()
- {
- // Tell the thread() function to stop. This will cause should_stop() to
- // return true so the thread knows what to do.
- stop();
-
- // Wait for the thread to stop before letting this object destruct itself.
- // Also note, you are *required* to wait for the thread to end before
- // letting this object destruct itself.
- wait();
- }
-
-private:
-
- void thread()
- {
- // This is our thread. It will loop until it is told that it should terminate.
- while (should_stop() == false)
- {
- cout << "hurray threads!" << endl;
- dlib::sleep(500);
- }
- }
-};
-
-int main()
-{
- // Create an instance of our threaded object.
- my_object t;
-
- dlib::sleep(4000);
-
- // Tell the threaded object to pause its thread. This causes the
- // thread to block on its next call to should_stop().
- t.pause();
-
- dlib::sleep(3000);
- cout << "starting thread back up from paused state" << endl;
-
- // Tell the thread to unpause itself. This causes should_stop() to unblock
- // and to let the thread continue.
- t.start();
-
- dlib::sleep(4000);
-
- // Let the program end. When t is destructed it will gracefully terminate your
- // thread because we have set the destructor up to do so.
-}
-
-
-
diff --git a/ml/dlib/examples/threads_ex.cpp b/ml/dlib/examples/threads_ex.cpp
deleted file mode 100644
index f0f1e914f..000000000
--- a/ml/dlib/examples/threads_ex.cpp
+++ /dev/null
@@ -1,93 +0,0 @@
-// The contents of this file are in the public domain. See LICENSE_FOR_EXAMPLE_PROGRAMS.txt
-
-/*
-
- This is an example illustrating the use of the threading api from the dlib
- C++ Library.
-
-
- This is a very simple example. It makes some threads and just waits for
- them to terminate. It should be noted that this example shows how to use
- the lowest level of the dlib threading API. Often, other higher level tools
- are more appropriate. For examples of higher level tools see the
- documentation on the pipe, thread_pool, thread_function, or
- threaded_object.
-*/
-
-
-#include <iostream>
-#include <dlib/threads.h>
-#include <dlib/misc_api.h> // for dlib::sleep
-
-using namespace std;
-using namespace dlib;
-
-int thread_count = 10;
-dlib::mutex count_mutex; // This is a mutex we will use to guard the thread_count variable. Note that the mutex doesn't know
- // anything about the thread_count variable. Only our usage of a mutex determines what it guards.
- // In this case we are going to make sure this mutex is always locked before we touch the
- // thread_count variable.
-
-signaler count_signaler(count_mutex); // This is a signaler we will use to signal when
- // the thread_count variable is changed. Note that it is
- // associated with the count_mutex. This means that
- // when you call count_signaler.wait() it will automatically
- // unlock count_mutex for you.
-
-
-void test_thread (void*)
-{
- // just sleep for a second
- dlib::sleep(1000);
-
- // Now signal that this thread is ending. First we should get a lock on the
- // count_mutex so we can safely mess with thread_count. A convenient way to do this
- // is to use an auto_mutex object. Its constructor takes a mutex object and locks
- // it right away, it then unlocks the mutex when the auto_mutex object is destructed.
- // Note that this happens even if an exception is thrown. So it ensures that you
- // don't somehow quit your function without unlocking your mutex.
- auto_mutex locker(count_mutex);
- --thread_count;
- // Now we signal this change. This will cause one thread that is currently waiting
- // on a call to count_signaler.wait() to unblock.
- count_signaler.signal();
-
- // At the end of this function locker goes out of scope and gets destructed, thus
- // unlocking count_mutex for us.
-}
-
-int main()
-{
-
- cout << "Create some threads" << endl;
- for (int i = 0; i < thread_count; ++i)
- {
- // Create some threads. This 0 we are passing in here is the argument that gets
- // passed to the thread function (a void pointer) but we aren't using it in this
- // example program so i'm just using 0.
- create_new_thread(test_thread,0);
- }
- cout << "Done creating threads, now we wait for them to end" << endl;
-
-
- // Again we use an auto_mutex to get a lock. We don't have to do it this way
- // but it is convenient. Also note that we can name the auto_mutex object anything.
- auto_mutex some_random_unused_name(count_mutex);
-
- // Now we wait in a loop for thread_count to be 0. Note that it is important to do this in a
- // loop because it is possible to get spurious wakeups from calls to wait() on some
- // platforms. So this guards against that and it also makes the code easy to understand.
- while (thread_count > 0)
- count_signaler.wait(); // This puts this thread to sleep until we get a signal to look at the
- // thread_count variable. It also unlocks the count_mutex before it
- // goes to sleep and then relocks it when it wakes back up. Again,
- // note that it is possible for wait() to return even if no one signals you.
- // This is just weird junk you have to deal with on some platforms. So
- // don't try to be clever and write code that depends on the number of
- // times wait() returns because it won't always work.
-
-
- cout << "All threads done, ending program" << endl;
-}
-
-
diff --git a/ml/dlib/examples/timer_ex.cpp b/ml/dlib/examples/timer_ex.cpp
deleted file mode 100644
index e1d554926..000000000
--- a/ml/dlib/examples/timer_ex.cpp
+++ /dev/null
@@ -1,56 +0,0 @@
-// The contents of this file are in the public domain. See LICENSE_FOR_EXAMPLE_PROGRAMS.txt
-
-
-/*
- This is an example illustrating the use of the timer object from the dlib C++ Library.
-
- The timer is an object that calls some user specified member function at regular
- intervals from another thread.
-*/
-
-
-#include <dlib/timer.h>
-#include <dlib/misc_api.h> // for dlib::sleep
-#include <iostream>
-
-using namespace dlib;
-using namespace std;
-
-// ----------------------------------------------------------------------------------------
-
-class timer_example
-{
-public:
- void action_function()
- {
- // print out a message so we can see that this function is being triggered
- cout << "action_function() called" << endl;
- }
-};
-
-// ----------------------------------------------------------------------------------------
-
-int main()
-{
- timer_example e;
-
- // Here we construct our timer object. It needs two things. The second argument is
- // the member function it is going to call at regular intervals and the first argument
- // is the object instance it will call that member function on.
- timer<timer_example> t(e, &timer_example::action_function);
-
- // Set the timer object to trigger every second
- t.set_delay_time(1000);
-
- // Start the timer. It will start calling the action function 1 second from this call
- // to start.
- t.start();
-
- // Sleep for 10 seconds before letting the program end.
- dlib::sleep(10000);
-
- // The timer will destruct itself properly and stop calling the action_function.
-}
-
-// ----------------------------------------------------------------------------------------
-
diff --git a/ml/dlib/examples/train_object_detector.cpp b/ml/dlib/examples/train_object_detector.cpp
deleted file mode 100644
index 9bc0977c0..000000000
--- a/ml/dlib/examples/train_object_detector.cpp
+++ /dev/null
@@ -1,422 +0,0 @@
-// The contents of this file are in the public domain. See LICENSE_FOR_EXAMPLE_PROGRAMS.txt
-/*
-
- This is an example showing how you might use dlib to create a reasonably
- functional command line tool for object detection. This example assumes
- you are familiar with the contents of at least the following example
- programs:
- - fhog_object_detector_ex.cpp
- - compress_stream_ex.cpp
-
-
-
-
- This program is a command line tool for learning to detect objects in images.
- Therefore, to create an object detector it requires a set of annotated training
- images. To create this annotated data you will need to use the imglab tool
- included with dlib. It is located in the tools/imglab folder and can be compiled
- using the following commands.
- cd tools/imglab
- mkdir build
- cd build
- cmake ..
- cmake --build . --config Release
- Note that you may need to install CMake (www.cmake.org) for this to work.
-
- Next, let's assume you have a folder of images called /tmp/images. These images
- should contain examples of the objects you want to learn to detect. You will
- use the imglab tool to label these objects. Do this by typing the following
- ./imglab -c mydataset.xml /tmp/images
- This will create a file called mydataset.xml which simply lists the images in
- /tmp/images. To annotate them run
- ./imglab mydataset.xml
- A window will appear showing all the images. You can use the up and down arrow
- keys to cycle though the images and the mouse to label objects. In particular,
- holding the shift key, left clicking, and dragging the mouse will allow you to
- draw boxes around the objects you wish to detect. So next, label all the objects
- with boxes. Note that it is important to label all the objects since any object
- not labeled is implicitly assumed to be not an object we should detect. If there
- are objects you are not sure about you should draw a box around them, then double
- click the box and press i. This will cross out the box and mark it as "ignore".
- The training code in dlib will then simply ignore detections matching that box.
-
-
- Once you finish labeling objects go to the file menu, click save, and then close
- the program. This will save the object boxes back to mydataset.xml. You can verify
- this by opening the tool again with
- ./imglab mydataset.xml
- and observing that the boxes are present.
-
- Returning to the present example program, we can compile it using cmake just as we
- did with the imglab tool. Once compiled, we can issue the command
- ./train_object_detector -tv mydataset.xml
- which will train an object detection model based on our labeled data. The model
- will be saved to the file object_detector.svm. Once this has finished we can use
- the object detector to locate objects in new images with a command like
- ./train_object_detector some_image.png
- This command will display some_image.png in a window and any detected objects will
- be indicated by a red box.
-
- Finally, to make running this example easy dlib includes some training data in the
- examples/faces folder. Therefore, you can test this program out by running the
- following sequence of commands:
- ./train_object_detector -tv examples/faces/training.xml -u1 --flip
- ./train_object_detector --test examples/faces/testing.xml -u1
- ./train_object_detector examples/faces/*.jpg -u1
- That will make a face detector that performs perfectly on the test images listed in
- testing.xml and then it will show you the detections on all the images.
-*/
-
-
-#include <dlib/svm_threaded.h>
-#include <dlib/string.h>
-#include <dlib/gui_widgets.h>
-#include <dlib/image_processing.h>
-#include <dlib/data_io.h>
-#include <dlib/cmd_line_parser.h>
-
-
-#include <iostream>
-#include <fstream>
-
-
-using namespace std;
-using namespace dlib;
-
-// ----------------------------------------------------------------------------------------
-
-void pick_best_window_size (
- const std::vector<std::vector<rectangle> >& boxes,
- unsigned long& width,
- unsigned long& height,
- const unsigned long target_size
-)
-/*!
- ensures
- - Finds the average aspect ratio of the elements of boxes and outputs a width
- and height such that the aspect ratio is equal to the average and also the
- area is equal to target_size. That is, the following will be approximately true:
- - #width*#height == target_size
- - #width/#height == the average aspect ratio of the elements of boxes.
-!*/
-{
- // find the average width and height
- running_stats<double> avg_width, avg_height;
- for (unsigned long i = 0; i < boxes.size(); ++i)
- {
- for (unsigned long j = 0; j < boxes[i].size(); ++j)
- {
- avg_width.add(boxes[i][j].width());
- avg_height.add(boxes[i][j].height());
- }
- }
-
- // now adjust the box size so that it is about target_pixels pixels in size
- double size = avg_width.mean()*avg_height.mean();
- double scale = std::sqrt(target_size/size);
-
- width = (unsigned long)(avg_width.mean()*scale+0.5);
- height = (unsigned long)(avg_height.mean()*scale+0.5);
- // make sure the width and height never round to zero.
- if (width == 0)
- width = 1;
- if (height == 0)
- height = 1;
-}
-
-// ----------------------------------------------------------------------------------------
-
-bool contains_any_boxes (
- const std::vector<std::vector<rectangle> >& boxes
-)
-{
- for (unsigned long i = 0; i < boxes.size(); ++i)
- {
- if (boxes[i].size() != 0)
- return true;
- }
- return false;
-}
-
-// ----------------------------------------------------------------------------------------
-
-void throw_invalid_box_error_message (
- const std::string& dataset_filename,
- const std::vector<std::vector<rectangle> >& removed,
- const unsigned long target_size
-)
-{
- image_dataset_metadata::dataset data;
- load_image_dataset_metadata(data, dataset_filename);
-
- std::ostringstream sout;
- sout << "Error! An impossible set of object boxes was given for training. ";
- sout << "All the boxes need to have a similar aspect ratio and also not be ";
- sout << "smaller than about " << target_size << " pixels in area. ";
- sout << "The following images contain invalid boxes:\n";
- std::ostringstream sout2;
- for (unsigned long i = 0; i < removed.size(); ++i)
- {
- if (removed[i].size() != 0)
- {
- const std::string imgname = data.images[i].filename;
- sout2 << " " << imgname << "\n";
- }
- }
- throw error("\n"+wrap_string(sout.str()) + "\n" + sout2.str());
-}
-
-// ----------------------------------------------------------------------------------------
-
-int main(int argc, char** argv)
-{
- try
- {
- command_line_parser parser;
- parser.add_option("h","Display this help message.");
- parser.add_option("t","Train an object detector and save the detector to disk.");
- parser.add_option("cross-validate",
- "Perform cross-validation on an image dataset and print the results.");
- parser.add_option("test", "Test a trained detector on an image dataset and print the results.");
- parser.add_option("u", "Upsample each input image <arg> times. Each upsampling quadruples the number of pixels in the image (default: 0).", 1);
-
- parser.set_group_name("training/cross-validation sub-options");
- parser.add_option("v","Be verbose.");
- parser.add_option("folds","When doing cross-validation, do <arg> folds (default: 3).",1);
- parser.add_option("c","Set the SVM C parameter to <arg> (default: 1.0).",1);
- parser.add_option("threads", "Use <arg> threads for training (default: 4).",1);
- parser.add_option("eps", "Set training epsilon to <arg> (default: 0.01).", 1);
- parser.add_option("target-size", "Set size of the sliding window to about <arg> pixels in area (default: 80*80).", 1);
- parser.add_option("flip", "Add left/right flipped copies of the images into the training dataset. Useful when the objects "
- "you want to detect are left/right symmetric.");
-
-
- parser.parse(argc, argv);
-
- // Now we do a little command line validation. Each of the following functions
- // checks something and throws an exception if the test fails.
- const char* one_time_opts[] = {"h", "v", "t", "cross-validate", "c", "threads", "target-size",
- "folds", "test", "eps", "u", "flip"};
- parser.check_one_time_options(one_time_opts); // Can't give an option more than once
- // Make sure the arguments to these options are within valid ranges if they are supplied by the user.
- parser.check_option_arg_range("c", 1e-12, 1e12);
- parser.check_option_arg_range("eps", 1e-5, 1e4);
- parser.check_option_arg_range("threads", 1, 1000);
- parser.check_option_arg_range("folds", 2, 100);
- parser.check_option_arg_range("u", 0, 8);
- parser.check_option_arg_range("target-size", 4*4, 10000*10000);
- const char* incompatible[] = {"t", "cross-validate", "test"};
- parser.check_incompatible_options(incompatible);
- // You are only allowed to give these training_sub_ops if you also give either -t or --cross-validate.
- const char* training_ops[] = {"t", "cross-validate"};
- const char* training_sub_ops[] = {"v", "c", "threads", "target-size", "eps", "flip"};
- parser.check_sub_options(training_ops, training_sub_ops);
- parser.check_sub_option("cross-validate", "folds");
-
-
- if (parser.option("h"))
- {
- cout << "Usage: train_object_detector [options] <image dataset file|image file>\n";
- parser.print_options();
-
- return EXIT_SUCCESS;
- }
-
-
- typedef scan_fhog_pyramid<pyramid_down<6> > image_scanner_type;
- // Get the upsample option from the user but use 0 if it wasn't given.
- const unsigned long upsample_amount = get_option(parser, "u", 0);
-
- if (parser.option("t") || parser.option("cross-validate"))
- {
- if (parser.number_of_arguments() != 1)
- {
- cout << "You must give an image dataset metadata XML file produced by the imglab tool." << endl;
- cout << "\nTry the -h option for more information." << endl;
- return EXIT_FAILURE;
- }
-
- dlib::array<array2d<unsigned char> > images;
- std::vector<std::vector<rectangle> > object_locations, ignore;
-
- cout << "Loading image dataset from metadata file " << parser[0] << endl;
- ignore = load_image_dataset(images, object_locations, parser[0]);
- cout << "Number of images loaded: " << images.size() << endl;
-
- // Get the options from the user, but use default values if they are not
- // supplied.
- const int threads = get_option(parser, "threads", 4);
- const double C = get_option(parser, "c", 1.0);
- const double eps = get_option(parser, "eps", 0.01);
- unsigned int num_folds = get_option(parser, "folds", 3);
- const unsigned long target_size = get_option(parser, "target-size", 80*80);
- // You can't do more folds than there are images.
- if (num_folds > images.size())
- num_folds = images.size();
-
- // Upsample images if the user asked us to do that.
- for (unsigned long i = 0; i < upsample_amount; ++i)
- upsample_image_dataset<pyramid_down<2> >(images, object_locations, ignore);
-
-
- image_scanner_type scanner;
- unsigned long width, height;
- pick_best_window_size(object_locations, width, height, target_size);
- scanner.set_detection_window_size(width, height);
-
- structural_object_detection_trainer<image_scanner_type> trainer(scanner);
- trainer.set_num_threads(threads);
- if (parser.option("v"))
- trainer.be_verbose();
- trainer.set_c(C);
- trainer.set_epsilon(eps);
-
- // Now make sure all the boxes are obtainable by the scanner.
- std::vector<std::vector<rectangle> > removed;
- removed = remove_unobtainable_rectangles(trainer, images, object_locations);
- // if we weren't able to get all the boxes to match then throw an error
- if (contains_any_boxes(removed))
- {
- unsigned long scale = upsample_amount+1;
- scale = scale*scale;
- throw_invalid_box_error_message(parser[0], removed, target_size/scale);
- }
-
- if (parser.option("flip"))
- add_image_left_right_flips(images, object_locations, ignore);
-
- if (parser.option("t"))
- {
- // Do the actual training and save the results into the detector object.
- object_detector<image_scanner_type> detector = trainer.train(images, object_locations, ignore);
-
- cout << "Saving trained detector to object_detector.svm" << endl;
- serialize("object_detector.svm") << detector;
-
- cout << "Testing detector on training data..." << endl;
- cout << "Test detector (precision,recall,AP): " << test_object_detection_function(detector, images, object_locations, ignore) << endl;
- }
- else
- {
- // shuffle the order of the training images
- randomize_samples(images, object_locations);
-
- cout << num_folds << "-fold cross validation (precision,recall,AP): "
- << cross_validate_object_detection_trainer(trainer, images, object_locations, ignore, num_folds) << endl;
- }
-
- cout << "Parameters used: " << endl;
- cout << " threads: "<< threads << endl;
- cout << " C: "<< C << endl;
- cout << " eps: "<< eps << endl;
- cout << " target-size: "<< target_size << endl;
- cout << " detection window width: "<< width << endl;
- cout << " detection window height: "<< height << endl;
- cout << " upsample this many times : "<< upsample_amount << endl;
- if (parser.option("flip"))
- cout << " trained using left/right flips." << endl;
- if (parser.option("cross-validate"))
- cout << " num_folds: "<< num_folds << endl;
- cout << endl;
-
- return EXIT_SUCCESS;
- }
-
-
-
-
-
-
-
- // The rest of the code is devoted to testing an already trained object detector.
-
- if (parser.number_of_arguments() == 0)
- {
- cout << "You must give an image or an image dataset metadata XML file produced by the imglab tool." << endl;
- cout << "\nTry the -h option for more information." << endl;
- return EXIT_FAILURE;
- }
-
- // load a previously trained object detector and try it out on some data
- ifstream fin("object_detector.svm", ios::binary);
- if (!fin)
- {
- cout << "Can't find a trained object detector file object_detector.svm. " << endl;
- cout << "You need to train one using the -t option." << endl;
- cout << "\nTry the -h option for more information." << endl;
- return EXIT_FAILURE;
-
- }
- object_detector<image_scanner_type> detector;
- deserialize(detector, fin);
-
- dlib::array<array2d<unsigned char> > images;
- // Check if the command line argument is an XML file
- if (tolower(right_substr(parser[0],".")) == "xml")
- {
- std::vector<std::vector<rectangle> > object_locations, ignore;
- cout << "Loading image dataset from metadata file " << parser[0] << endl;
- ignore = load_image_dataset(images, object_locations, parser[0]);
- cout << "Number of images loaded: " << images.size() << endl;
-
- // Upsample images if the user asked us to do that.
- for (unsigned long i = 0; i < upsample_amount; ++i)
- upsample_image_dataset<pyramid_down<2> >(images, object_locations, ignore);
-
- if (parser.option("test"))
- {
- cout << "Testing detector on data..." << endl;
- cout << "Results (precision,recall,AP): " << test_object_detection_function(detector, images, object_locations, ignore) << endl;
- return EXIT_SUCCESS;
- }
- }
- else
- {
- // In this case, the user should have given some image files. So just
- // load them.
- images.resize(parser.number_of_arguments());
- for (unsigned long i = 0; i < images.size(); ++i)
- load_image(images[i], parser[i]);
-
- // Upsample images if the user asked us to do that.
- for (unsigned long i = 0; i < upsample_amount; ++i)
- {
- for (unsigned long j = 0; j < images.size(); ++j)
- pyramid_up(images[j]);
- }
- }
-
-
- // Test the detector on the images we loaded and display the results
- // in a window.
- image_window win;
- for (unsigned long i = 0; i < images.size(); ++i)
- {
- // Run the detector on images[i]
- const std::vector<rectangle> rects = detector(images[i]);
- cout << "Number of detections: "<< rects.size() << endl;
-
- // Put the image and detections into the window.
- win.clear_overlay();
- win.set_image(images[i]);
- win.add_overlay(rects, rgb_pixel(255,0,0));
-
- cout << "Hit enter to see the next image.";
- cin.get();
- }
-
-
- }
- catch (exception& e)
- {
- cout << "\nexception thrown!" << endl;
- cout << e.what() << endl;
- cout << "\nTry the -h option for more information." << endl;
- return EXIT_FAILURE;
- }
-
- return EXIT_SUCCESS;
-}
-
-// ----------------------------------------------------------------------------------------
-
diff --git a/ml/dlib/examples/train_shape_predictor_ex.cpp b/ml/dlib/examples/train_shape_predictor_ex.cpp
deleted file mode 100644
index 05eaf4b0e..000000000
--- a/ml/dlib/examples/train_shape_predictor_ex.cpp
+++ /dev/null
@@ -1,198 +0,0 @@
-// The contents of this file are in the public domain. See LICENSE_FOR_EXAMPLE_PROGRAMS.txt
-/*
-
- This example program shows how to use dlib's implementation of the paper:
- One Millisecond Face Alignment with an Ensemble of Regression Trees by
- Vahid Kazemi and Josephine Sullivan, CVPR 2014
-
- In particular, we will train a face landmarking model based on a small dataset
- and then evaluate it. If you want to visualize the output of the trained
- model on some images then you can run the face_landmark_detection_ex.cpp
- example program with sp.dat as the input model.
-
- It should also be noted that this kind of model, while often used for face
- landmarking, is quite general and can be used for a variety of shape
- prediction tasks. But here we demonstrate it only on a simple face
- landmarking task.
-*/
-
-
-#include <dlib/image_processing.h>
-#include <dlib/data_io.h>
-#include <iostream>
-
-using namespace dlib;
-using namespace std;
-
-// ----------------------------------------------------------------------------------------
-
-std::vector<std::vector<double> > get_interocular_distances (
- const std::vector<std::vector<full_object_detection> >& objects
-);
-/*!
- ensures
- - returns an object D such that:
- - D[i][j] == the distance, in pixels, between the eyes for the face represented
- by objects[i][j].
-!*/
-
-// ----------------------------------------------------------------------------------------
-
-int main(int argc, char** argv)
-{
- try
- {
- // In this example we are going to train a shape_predictor based on the
- // small faces dataset in the examples/faces directory. So the first
- // thing we do is load that dataset. This means you need to supply the
- // path to this faces folder as a command line argument so we will know
- // where it is.
- if (argc != 2)
- {
- cout << "Give the path to the examples/faces directory as the argument to this" << endl;
- cout << "program. For example, if you are in the examples folder then execute " << endl;
- cout << "this program by running: " << endl;
- cout << " ./train_shape_predictor_ex faces" << endl;
- cout << endl;
- return 0;
- }
- const std::string faces_directory = argv[1];
- // The faces directory contains a training dataset and a separate
- // testing dataset. The training data consists of 4 images, each
- // annotated with rectangles that bound each human face along with 68
- // face landmarks on each face. The idea is to use this training data
- // to learn to identify the position of landmarks on human faces in new
- // images.
- //
- // Once you have trained a shape_predictor it is always important to
- // test it on data it wasn't trained on. Therefore, we will also load
- // a separate testing set of 5 images. Once we have a shape_predictor
- // created from the training data we will see how well it works by
- // running it on the testing images.
- //
- // So here we create the variables that will hold our dataset.
- // images_train will hold the 4 training images and faces_train holds
- // the locations and poses of each face in the training images. So for
- // example, the image images_train[0] has the faces given by the
- // full_object_detections in faces_train[0].
- dlib::array<array2d<unsigned char> > images_train, images_test;
- std::vector<std::vector<full_object_detection> > faces_train, faces_test;
-
- // Now we load the data. These XML files list the images in each
- // dataset and also contain the positions of the face boxes and
- // landmarks (called parts in the XML file). Obviously you can use any
- // kind of input format you like so long as you store the data into
- // images_train and faces_train. But for convenience dlib comes with
- // tools for creating and loading XML image dataset files. Here you see
- // how to load the data. To create the XML files you can use the imglab
- // tool which can be found in the tools/imglab folder. It is a simple
- // graphical tool for labeling objects in images. To see how to use it
- // read the tools/imglab/README.txt file.
- load_image_dataset(images_train, faces_train, faces_directory+"/training_with_face_landmarks.xml");
- load_image_dataset(images_test, faces_test, faces_directory+"/testing_with_face_landmarks.xml");
-
- // Now make the object responsible for training the model.
- shape_predictor_trainer trainer;
- // This algorithm has a bunch of parameters you can mess with. The
- // documentation for the shape_predictor_trainer explains all of them.
- // You should also read Kazemi's paper which explains all the parameters
- // in great detail. However, here I'm just setting three of them
- // differently than their default values. I'm doing this because we
- // have a very small dataset. In particular, setting the oversampling
- // to a high amount (300) effectively boosts the training set size, so
- // that helps this example.
- trainer.set_oversampling_amount(300);
- // I'm also reducing the capacity of the model by explicitly increasing
- // the regularization (making nu smaller) and by using trees with
- // smaller depths.
- trainer.set_nu(0.05);
- trainer.set_tree_depth(2);
-
- // some parts of training process can be parallelized.
- // Trainer will use this count of threads when possible
- trainer.set_num_threads(2);
-
- // Tell the trainer to print status messages to the console so we can
- // see how long the training will take.
- trainer.be_verbose();
-
- // Now finally generate the shape model
- shape_predictor sp = trainer.train(images_train, faces_train);
-
-
- // Now that we have a model we can test it. This function measures the
- // average distance between a face landmark output by the
- // shape_predictor and where it should be according to the truth data.
- // Note that there is an optional 4th argument that lets us rescale the
- // distances. Here we are causing the output to scale each face's
- // distances by the interocular distance, as is customary when
- // evaluating face landmarking systems.
- cout << "mean training error: "<<
- test_shape_predictor(sp, images_train, faces_train, get_interocular_distances(faces_train)) << endl;
-
- // The real test is to see how well it does on data it wasn't trained
- // on. We trained it on a very small dataset so the accuracy is not
- // extremely high, but it's still doing quite good. Moreover, if you
- // train it on one of the large face landmarking datasets you will
- // obtain state-of-the-art results, as shown in the Kazemi paper.
- cout << "mean testing error: "<<
- test_shape_predictor(sp, images_test, faces_test, get_interocular_distances(faces_test)) << endl;
-
- // Finally, we save the model to disk so we can use it later.
- serialize("sp.dat") << sp;
- }
- catch (exception& e)
- {
- cout << "\nexception thrown!" << endl;
- cout << e.what() << endl;
- }
-}
-
-// ----------------------------------------------------------------------------------------
-
-double interocular_distance (
- const full_object_detection& det
-)
-{
- dlib::vector<double,2> l, r;
- double cnt = 0;
- // Find the center of the left eye by averaging the points around
- // the eye.
- for (unsigned long i = 36; i <= 41; ++i)
- {
- l += det.part(i);
- ++cnt;
- }
- l /= cnt;
-
- // Find the center of the right eye by averaging the points around
- // the eye.
- cnt = 0;
- for (unsigned long i = 42; i <= 47; ++i)
- {
- r += det.part(i);
- ++cnt;
- }
- r /= cnt;
-
- // Now return the distance between the centers of the eyes
- return length(l-r);
-}
-
-std::vector<std::vector<double> > get_interocular_distances (
- const std::vector<std::vector<full_object_detection> >& objects
-)
-{
- std::vector<std::vector<double> > temp(objects.size());
- for (unsigned long i = 0; i < objects.size(); ++i)
- {
- for (unsigned long j = 0; j < objects[i].size(); ++j)
- {
- temp[i].push_back(interocular_distance(objects[i][j]));
- }
- }
- return temp;
-}
-
-// ----------------------------------------------------------------------------------------
-
diff --git a/ml/dlib/examples/using_custom_kernels_ex.cpp b/ml/dlib/examples/using_custom_kernels_ex.cpp
deleted file mode 100644
index f0cac6905..000000000
--- a/ml/dlib/examples/using_custom_kernels_ex.cpp
+++ /dev/null
@@ -1,208 +0,0 @@
-// The contents of this file are in the public domain. See LICENSE_FOR_EXAMPLE_PROGRAMS.txt
-/*
-
- This is an example showing how to define custom kernel functions for use with
- the machine learning tools in the dlib C++ Library.
-
- This example assumes you are somewhat familiar with the machine learning
- tools in dlib. In particular, you should be familiar with the krr_trainer
- and the matrix object. So you may want to read the krr_classification_ex.cpp
- and matrix_ex.cpp example programs if you haven't already.
-*/
-
-
-#include <iostream>
-#include <dlib/svm.h>
-
-using namespace std;
-using namespace dlib;
-
-// ----------------------------------------------------------------------------------------
-
-/*
- Here we define our new kernel. It is the UKF kernel from
- Facilitating the applications of support vector machine by using a new kernel
- by Rui Zhang and Wenjian Wang.
-
-
-
- In the context of the dlib library a kernel function object is an object with
- an interface with the following properties:
- - a public typedef named sample_type
- - a public typedef named scalar_type which should be a float, double, or
- long double type.
- - an overloaded operator() that operates on two items of sample_type
- and returns a scalar_type.
- - a public typedef named mem_manager_type that is an implementation of
- dlib/memory_manager/memory_manager_kernel_abstract.h or
- dlib/memory_manager_global/memory_manager_global_kernel_abstract.h or
- dlib/memory_manager_stateless/memory_manager_stateless_kernel_abstract.h
- - an overloaded == operator that tells you if two kernels are
- identical or not.
-
- Below we define such a beast for the UKF kernel. In this case we are expecting the
- sample type (i.e. the T type) to be a dlib::matrix. However, note that you can design
- kernels which operate on any type you like so long as you meet the above requirements.
-*/
-
-template < typename T >
-struct ukf_kernel
-{
- typedef typename T::type scalar_type;
- typedef T sample_type;
- // If your sample type, the T, doesn't have a memory manager then
- // you can use dlib::default_memory_manager here.
- typedef typename T::mem_manager_type mem_manager_type;
-
- ukf_kernel(const scalar_type g) : sigma(g) {}
- ukf_kernel() : sigma(0.1) {}
-
- scalar_type sigma;
-
- scalar_type operator() (
- const sample_type& a,
- const sample_type& b
- ) const
- {
- // This is the formula for the UKF kernel from the above referenced paper.
- return 1/(length_squared(a-b) + sigma);
- }
-
- bool operator== (
- const ukf_kernel& k
- ) const
- {
- return sigma == k.sigma;
- }
-};
-
-// ----------------------------------------------------------------------------------------
-
-/*
- Here we define serialize() and deserialize() functions for our new kernel. Defining
- these functions is optional. However, if you don't define them you won't be able
- to save your learned decision_function objects to disk.
-*/
-
-template < typename T >
-void serialize ( const ukf_kernel<T>& item, std::ostream& out)
-{
- // save the state of the kernel to the output stream
- serialize(item.sigma, out);
-}
-
-template < typename T >
-void deserialize ( ukf_kernel<T>& item, std::istream& in )
-{
- deserialize(item.sigma, in);
-}
-
-// ----------------------------------------------------------------------------------------
-
-/*
- This next thing, the kernel_derivative specialization is optional. You only need
- to define it if you want to use the dlib::reduced2() or dlib::approximate_distance_function()
- routines. If so, then you need to supply code for computing the derivative of your kernel as
- shown below. Note also that you can only do this if your kernel operates on dlib::matrix
- objects which represent column vectors.
-*/
-
-namespace dlib
-{
- template < typename T >
- struct kernel_derivative<ukf_kernel<T> >
- {
- typedef typename T::type scalar_type;
- typedef T sample_type;
- typedef typename T::mem_manager_type mem_manager_type;
-
- kernel_derivative(const ukf_kernel<T>& k_) : k(k_){}
-
- sample_type operator() (const sample_type& x, const sample_type& y) const
- {
- // return the derivative of the ukf kernel with respect to the second argument (i.e. y)
- return 2*(x-y)*std::pow(k(x,y),2);
- }
-
- const ukf_kernel<T>& k;
- };
-}
-
-// ----------------------------------------------------------------------------------------
-
-int main()
-{
- // We are going to be working with 2 dimensional samples and trying to perform
- // binary classification on them using our new ukf_kernel.
- typedef matrix<double, 2, 1> sample_type;
-
- typedef ukf_kernel<sample_type> kernel_type;
-
-
- // Now let's generate some training data
- std::vector<sample_type> samples;
- std::vector<double> labels;
- for (double r = -20; r <= 20; r += 0.9)
- {
- for (double c = -20; c <= 20; c += 0.9)
- {
- sample_type samp;
- samp(0) = r;
- samp(1) = c;
- samples.push_back(samp);
-
- // if this point is less than 13 from the origin
- if (sqrt(r*r + c*c) <= 13)
- labels.push_back(+1);
- else
- labels.push_back(-1);
-
- }
- }
- cout << "samples generated: " << samples.size() << endl;
- cout << " number of +1 samples: " << sum(mat(labels) > 0) << endl;
- cout << " number of -1 samples: " << sum(mat(labels) < 0) << endl;
-
-
- // A valid kernel must always give rise to kernel matrices which are symmetric
- // and positive semidefinite (i.e. have nonnegative eigenvalues). This next
- // bit of code makes a kernel matrix and checks if it has these properties.
- const matrix<double> K = kernel_matrix(kernel_type(0.1), randomly_subsample(samples, 500));
- cout << "\nIs it symmetric? (this value should be 0): "<< min(abs(K - trans(K))) << endl;
- cout << "Smallest eigenvalue (should be >= 0): " << min(real_eigenvalues(K)) << endl;
-
-
- // here we make an instance of the krr_trainer object that uses our new kernel.
- krr_trainer<kernel_type> trainer;
- trainer.use_classification_loss_for_loo_cv();
-
-
- // Finally, let's test how good our new kernel is by doing some leave-one-out cross-validation.
- cout << "\ndoing leave-one-out cross-validation" << endl;
- for (double sigma = 0.01; sigma <= 100; sigma *= 3)
- {
- // tell the trainer the parameters we want to use
- trainer.set_kernel(kernel_type(sigma));
-
- std::vector<double> loo_values;
- trainer.train(samples, labels, loo_values);
-
- // Print sigma and the fraction of samples correctly classified during LOO cross-validation.
- const double classification_accuracy = mean_sign_agreement(labels, loo_values);
- cout << "sigma: " << sigma << " LOO accuracy: " << classification_accuracy << endl;
- }
-
-
-
-
- const kernel_type kern(10);
- // Since it is very easy to make a mistake while coding a derivative it is a good idea
- // to compare your derivative function against a numerical approximation and see if
- // the results are similar. If they are very different then you probably made a
- // mistake. So here we compare the results at a test point.
- cout << "\nThese vectors should match, if they don't then we coded the kernel_derivative wrong!" << endl;
- cout << "approximate derivative: \n" << derivative(kern)(samples[0],samples[100]) << endl;
- cout << "exact derivative: \n" << kernel_derivative<kernel_type>(kern)(samples[0],samples[100]) << endl;
-
-}
-
diff --git a/ml/dlib/examples/video_frames/frame_000100.jpg b/ml/dlib/examples/video_frames/frame_000100.jpg
deleted file mode 100644
index 938b04d51..000000000
--- a/ml/dlib/examples/video_frames/frame_000100.jpg
+++ /dev/null
Binary files differ
diff --git a/ml/dlib/examples/video_frames/frame_000101.jpg b/ml/dlib/examples/video_frames/frame_000101.jpg
deleted file mode 100644
index 13f149289..000000000
--- a/ml/dlib/examples/video_frames/frame_000101.jpg
+++ /dev/null
Binary files differ
diff --git a/ml/dlib/examples/video_frames/frame_000102.jpg b/ml/dlib/examples/video_frames/frame_000102.jpg
deleted file mode 100644
index d656b8ed2..000000000
--- a/ml/dlib/examples/video_frames/frame_000102.jpg
+++ /dev/null
Binary files differ
diff --git a/ml/dlib/examples/video_frames/frame_000103.jpg b/ml/dlib/examples/video_frames/frame_000103.jpg
deleted file mode 100644
index fc2990235..000000000
--- a/ml/dlib/examples/video_frames/frame_000103.jpg
+++ /dev/null
Binary files differ
diff --git a/ml/dlib/examples/video_frames/frame_000104.jpg b/ml/dlib/examples/video_frames/frame_000104.jpg
deleted file mode 100644
index 2e0c38a62..000000000
--- a/ml/dlib/examples/video_frames/frame_000104.jpg
+++ /dev/null
Binary files differ
diff --git a/ml/dlib/examples/video_frames/frame_000105.jpg b/ml/dlib/examples/video_frames/frame_000105.jpg
deleted file mode 100644
index e28b90890..000000000
--- a/ml/dlib/examples/video_frames/frame_000105.jpg
+++ /dev/null
Binary files differ
diff --git a/ml/dlib/examples/video_frames/frame_000106.jpg b/ml/dlib/examples/video_frames/frame_000106.jpg
deleted file mode 100644
index fa87399e5..000000000
--- a/ml/dlib/examples/video_frames/frame_000106.jpg
+++ /dev/null
Binary files differ
diff --git a/ml/dlib/examples/video_frames/frame_000107.jpg b/ml/dlib/examples/video_frames/frame_000107.jpg
deleted file mode 100644
index d7c1e966c..000000000
--- a/ml/dlib/examples/video_frames/frame_000107.jpg
+++ /dev/null
Binary files differ
diff --git a/ml/dlib/examples/video_frames/frame_000108.jpg b/ml/dlib/examples/video_frames/frame_000108.jpg
deleted file mode 100644
index 0203b161b..000000000
--- a/ml/dlib/examples/video_frames/frame_000108.jpg
+++ /dev/null
Binary files differ
diff --git a/ml/dlib/examples/video_frames/frame_000109.jpg b/ml/dlib/examples/video_frames/frame_000109.jpg
deleted file mode 100644
index e8d496d55..000000000
--- a/ml/dlib/examples/video_frames/frame_000109.jpg
+++ /dev/null
Binary files differ
diff --git a/ml/dlib/examples/video_frames/frame_000110.jpg b/ml/dlib/examples/video_frames/frame_000110.jpg
deleted file mode 100644
index 46da463f5..000000000
--- a/ml/dlib/examples/video_frames/frame_000110.jpg
+++ /dev/null
Binary files differ
diff --git a/ml/dlib/examples/video_frames/frame_000111.jpg b/ml/dlib/examples/video_frames/frame_000111.jpg
deleted file mode 100644
index 696ea3f66..000000000
--- a/ml/dlib/examples/video_frames/frame_000111.jpg
+++ /dev/null
Binary files differ
diff --git a/ml/dlib/examples/video_frames/frame_000112.jpg b/ml/dlib/examples/video_frames/frame_000112.jpg
deleted file mode 100644
index b2aaedf9b..000000000
--- a/ml/dlib/examples/video_frames/frame_000112.jpg
+++ /dev/null
Binary files differ
diff --git a/ml/dlib/examples/video_frames/frame_000113.jpg b/ml/dlib/examples/video_frames/frame_000113.jpg
deleted file mode 100644
index 9beb88a0b..000000000
--- a/ml/dlib/examples/video_frames/frame_000113.jpg
+++ /dev/null
Binary files differ
diff --git a/ml/dlib/examples/video_frames/frame_000114.jpg b/ml/dlib/examples/video_frames/frame_000114.jpg
deleted file mode 100644
index ae8de40e9..000000000
--- a/ml/dlib/examples/video_frames/frame_000114.jpg
+++ /dev/null
Binary files differ
diff --git a/ml/dlib/examples/video_frames/frame_000115.jpg b/ml/dlib/examples/video_frames/frame_000115.jpg
deleted file mode 100644
index 7682a690a..000000000
--- a/ml/dlib/examples/video_frames/frame_000115.jpg
+++ /dev/null
Binary files differ
diff --git a/ml/dlib/examples/video_frames/frame_000116.jpg b/ml/dlib/examples/video_frames/frame_000116.jpg
deleted file mode 100644
index 90b1109a7..000000000
--- a/ml/dlib/examples/video_frames/frame_000116.jpg
+++ /dev/null
Binary files differ
diff --git a/ml/dlib/examples/video_frames/frame_000117.jpg b/ml/dlib/examples/video_frames/frame_000117.jpg
deleted file mode 100644
index 388c914cc..000000000
--- a/ml/dlib/examples/video_frames/frame_000117.jpg
+++ /dev/null
Binary files differ
diff --git a/ml/dlib/examples/video_frames/frame_000118.jpg b/ml/dlib/examples/video_frames/frame_000118.jpg
deleted file mode 100644
index e77a1e558..000000000
--- a/ml/dlib/examples/video_frames/frame_000118.jpg
+++ /dev/null
Binary files differ
diff --git a/ml/dlib/examples/video_frames/frame_000119.jpg b/ml/dlib/examples/video_frames/frame_000119.jpg
deleted file mode 100644
index 7a19fe43e..000000000
--- a/ml/dlib/examples/video_frames/frame_000119.jpg
+++ /dev/null
Binary files differ
diff --git a/ml/dlib/examples/video_frames/frame_000120.jpg b/ml/dlib/examples/video_frames/frame_000120.jpg
deleted file mode 100644
index ab73738df..000000000
--- a/ml/dlib/examples/video_frames/frame_000120.jpg
+++ /dev/null
Binary files differ
diff --git a/ml/dlib/examples/video_frames/frame_000121.jpg b/ml/dlib/examples/video_frames/frame_000121.jpg
deleted file mode 100644
index 03c4705bb..000000000
--- a/ml/dlib/examples/video_frames/frame_000121.jpg
+++ /dev/null
Binary files differ
diff --git a/ml/dlib/examples/video_frames/frame_000122.jpg b/ml/dlib/examples/video_frames/frame_000122.jpg
deleted file mode 100644
index 13c17dc51..000000000
--- a/ml/dlib/examples/video_frames/frame_000122.jpg
+++ /dev/null
Binary files differ
diff --git a/ml/dlib/examples/video_frames/frame_000123.jpg b/ml/dlib/examples/video_frames/frame_000123.jpg
deleted file mode 100644
index 64ef5ea1b..000000000
--- a/ml/dlib/examples/video_frames/frame_000123.jpg
+++ /dev/null
Binary files differ
diff --git a/ml/dlib/examples/video_frames/frame_000124.jpg b/ml/dlib/examples/video_frames/frame_000124.jpg
deleted file mode 100644
index a9f1cb618..000000000
--- a/ml/dlib/examples/video_frames/frame_000124.jpg
+++ /dev/null
Binary files differ
diff --git a/ml/dlib/examples/video_frames/frame_000125.jpg b/ml/dlib/examples/video_frames/frame_000125.jpg
deleted file mode 100644
index 57fc8a246..000000000
--- a/ml/dlib/examples/video_frames/frame_000125.jpg
+++ /dev/null
Binary files differ
diff --git a/ml/dlib/examples/video_frames/frame_000126.jpg b/ml/dlib/examples/video_frames/frame_000126.jpg
deleted file mode 100644
index 435b104f2..000000000
--- a/ml/dlib/examples/video_frames/frame_000126.jpg
+++ /dev/null
Binary files differ
diff --git a/ml/dlib/examples/video_frames/frame_000127.jpg b/ml/dlib/examples/video_frames/frame_000127.jpg
deleted file mode 100644
index bb21d1a6b..000000000
--- a/ml/dlib/examples/video_frames/frame_000127.jpg
+++ /dev/null
Binary files differ
diff --git a/ml/dlib/examples/video_frames/frame_000128.jpg b/ml/dlib/examples/video_frames/frame_000128.jpg
deleted file mode 100644
index bcd47fd0b..000000000
--- a/ml/dlib/examples/video_frames/frame_000128.jpg
+++ /dev/null
Binary files differ
diff --git a/ml/dlib/examples/video_frames/frame_000129.jpg b/ml/dlib/examples/video_frames/frame_000129.jpg
deleted file mode 100644
index 871250dfb..000000000
--- a/ml/dlib/examples/video_frames/frame_000129.jpg
+++ /dev/null
Binary files differ
diff --git a/ml/dlib/examples/video_frames/frame_000130.jpg b/ml/dlib/examples/video_frames/frame_000130.jpg
deleted file mode 100644
index 84efad322..000000000
--- a/ml/dlib/examples/video_frames/frame_000130.jpg
+++ /dev/null
Binary files differ
diff --git a/ml/dlib/examples/video_frames/frame_000131.jpg b/ml/dlib/examples/video_frames/frame_000131.jpg
deleted file mode 100644
index 04def55d5..000000000
--- a/ml/dlib/examples/video_frames/frame_000131.jpg
+++ /dev/null
Binary files differ
diff --git a/ml/dlib/examples/video_frames/frame_000132.jpg b/ml/dlib/examples/video_frames/frame_000132.jpg
deleted file mode 100644
index ca2992c37..000000000
--- a/ml/dlib/examples/video_frames/frame_000132.jpg
+++ /dev/null
Binary files differ
diff --git a/ml/dlib/examples/video_frames/frame_000133.jpg b/ml/dlib/examples/video_frames/frame_000133.jpg
deleted file mode 100644
index 094d5c67a..000000000
--- a/ml/dlib/examples/video_frames/frame_000133.jpg
+++ /dev/null
Binary files differ
diff --git a/ml/dlib/examples/video_frames/frame_000134.jpg b/ml/dlib/examples/video_frames/frame_000134.jpg
deleted file mode 100644
index e8c33137f..000000000
--- a/ml/dlib/examples/video_frames/frame_000134.jpg
+++ /dev/null
Binary files differ
diff --git a/ml/dlib/examples/video_frames/frame_000135.jpg b/ml/dlib/examples/video_frames/frame_000135.jpg
deleted file mode 100644
index 6786acb90..000000000
--- a/ml/dlib/examples/video_frames/frame_000135.jpg
+++ /dev/null
Binary files differ
diff --git a/ml/dlib/examples/video_frames/frame_000136.jpg b/ml/dlib/examples/video_frames/frame_000136.jpg
deleted file mode 100644
index 431db0c23..000000000
--- a/ml/dlib/examples/video_frames/frame_000136.jpg
+++ /dev/null
Binary files differ
diff --git a/ml/dlib/examples/video_frames/frame_000137.jpg b/ml/dlib/examples/video_frames/frame_000137.jpg
deleted file mode 100644
index e945be613..000000000
--- a/ml/dlib/examples/video_frames/frame_000137.jpg
+++ /dev/null
Binary files differ
diff --git a/ml/dlib/examples/video_frames/frame_000138.jpg b/ml/dlib/examples/video_frames/frame_000138.jpg
deleted file mode 100644
index 41762cede..000000000
--- a/ml/dlib/examples/video_frames/frame_000138.jpg
+++ /dev/null
Binary files differ
diff --git a/ml/dlib/examples/video_frames/frame_000139.jpg b/ml/dlib/examples/video_frames/frame_000139.jpg
deleted file mode 100644
index 5f8ca40ed..000000000
--- a/ml/dlib/examples/video_frames/frame_000139.jpg
+++ /dev/null
Binary files differ
diff --git a/ml/dlib/examples/video_frames/frame_000140.jpg b/ml/dlib/examples/video_frames/frame_000140.jpg
deleted file mode 100644
index 912ab03ee..000000000
--- a/ml/dlib/examples/video_frames/frame_000140.jpg
+++ /dev/null
Binary files differ
diff --git a/ml/dlib/examples/video_frames/frame_000141.jpg b/ml/dlib/examples/video_frames/frame_000141.jpg
deleted file mode 100644
index 7a247a2f1..000000000
--- a/ml/dlib/examples/video_frames/frame_000141.jpg
+++ /dev/null
Binary files differ
diff --git a/ml/dlib/examples/video_frames/frame_000142.jpg b/ml/dlib/examples/video_frames/frame_000142.jpg
deleted file mode 100644
index a2c51b58a..000000000
--- a/ml/dlib/examples/video_frames/frame_000142.jpg
+++ /dev/null
Binary files differ
diff --git a/ml/dlib/examples/video_frames/frame_000143.jpg b/ml/dlib/examples/video_frames/frame_000143.jpg
deleted file mode 100644
index 11631fecc..000000000
--- a/ml/dlib/examples/video_frames/frame_000143.jpg
+++ /dev/null
Binary files differ
diff --git a/ml/dlib/examples/video_frames/frame_000144.jpg b/ml/dlib/examples/video_frames/frame_000144.jpg
deleted file mode 100644
index d0366c12a..000000000
--- a/ml/dlib/examples/video_frames/frame_000144.jpg
+++ /dev/null
Binary files differ
diff --git a/ml/dlib/examples/video_frames/frame_000145.jpg b/ml/dlib/examples/video_frames/frame_000145.jpg
deleted file mode 100644
index 853fac3e0..000000000
--- a/ml/dlib/examples/video_frames/frame_000145.jpg
+++ /dev/null
Binary files differ
diff --git a/ml/dlib/examples/video_frames/frame_000146.jpg b/ml/dlib/examples/video_frames/frame_000146.jpg
deleted file mode 100644
index fc9972df8..000000000
--- a/ml/dlib/examples/video_frames/frame_000146.jpg
+++ /dev/null
Binary files differ
diff --git a/ml/dlib/examples/video_frames/frame_000147.jpg b/ml/dlib/examples/video_frames/frame_000147.jpg
deleted file mode 100644
index 3937fae54..000000000
--- a/ml/dlib/examples/video_frames/frame_000147.jpg
+++ /dev/null
Binary files differ
diff --git a/ml/dlib/examples/video_frames/frame_000148.jpg b/ml/dlib/examples/video_frames/frame_000148.jpg
deleted file mode 100644
index ad0884583..000000000
--- a/ml/dlib/examples/video_frames/frame_000148.jpg
+++ /dev/null
Binary files differ
diff --git a/ml/dlib/examples/video_frames/frame_000149.jpg b/ml/dlib/examples/video_frames/frame_000149.jpg
deleted file mode 100644
index 2776e083f..000000000
--- a/ml/dlib/examples/video_frames/frame_000149.jpg
+++ /dev/null
Binary files differ
diff --git a/ml/dlib/examples/video_frames/frame_000150.jpg b/ml/dlib/examples/video_frames/frame_000150.jpg
deleted file mode 100644
index c6f80b942..000000000
--- a/ml/dlib/examples/video_frames/frame_000150.jpg
+++ /dev/null
Binary files differ
diff --git a/ml/dlib/examples/video_frames/frame_000151.jpg b/ml/dlib/examples/video_frames/frame_000151.jpg
deleted file mode 100644
index aa7bbe278..000000000
--- a/ml/dlib/examples/video_frames/frame_000151.jpg
+++ /dev/null
Binary files differ
diff --git a/ml/dlib/examples/video_frames/frame_000152.jpg b/ml/dlib/examples/video_frames/frame_000152.jpg
deleted file mode 100644
index ad1259b38..000000000
--- a/ml/dlib/examples/video_frames/frame_000152.jpg
+++ /dev/null
Binary files differ
diff --git a/ml/dlib/examples/video_frames/frame_000153.jpg b/ml/dlib/examples/video_frames/frame_000153.jpg
deleted file mode 100644
index 0b1b84f17..000000000
--- a/ml/dlib/examples/video_frames/frame_000153.jpg
+++ /dev/null
Binary files differ
diff --git a/ml/dlib/examples/video_frames/frame_000154.jpg b/ml/dlib/examples/video_frames/frame_000154.jpg
deleted file mode 100644
index 9be6d25f4..000000000
--- a/ml/dlib/examples/video_frames/frame_000154.jpg
+++ /dev/null
Binary files differ
diff --git a/ml/dlib/examples/video_frames/frame_000155.jpg b/ml/dlib/examples/video_frames/frame_000155.jpg
deleted file mode 100644
index 7a8913314..000000000
--- a/ml/dlib/examples/video_frames/frame_000155.jpg
+++ /dev/null
Binary files differ
diff --git a/ml/dlib/examples/video_frames/frame_000156.jpg b/ml/dlib/examples/video_frames/frame_000156.jpg
deleted file mode 100644
index 584d70470..000000000
--- a/ml/dlib/examples/video_frames/frame_000156.jpg
+++ /dev/null
Binary files differ
diff --git a/ml/dlib/examples/video_frames/frame_000157.jpg b/ml/dlib/examples/video_frames/frame_000157.jpg
deleted file mode 100644
index 057d8de54..000000000
--- a/ml/dlib/examples/video_frames/frame_000157.jpg
+++ /dev/null
Binary files differ
diff --git a/ml/dlib/examples/video_frames/frame_000158.jpg b/ml/dlib/examples/video_frames/frame_000158.jpg
deleted file mode 100644
index 755d9a4ea..000000000
--- a/ml/dlib/examples/video_frames/frame_000158.jpg
+++ /dev/null
Binary files differ
diff --git a/ml/dlib/examples/video_frames/frame_000159.jpg b/ml/dlib/examples/video_frames/frame_000159.jpg
deleted file mode 100644
index a19e4b673..000000000
--- a/ml/dlib/examples/video_frames/frame_000159.jpg
+++ /dev/null
Binary files differ
diff --git a/ml/dlib/examples/video_frames/frame_000160.jpg b/ml/dlib/examples/video_frames/frame_000160.jpg
deleted file mode 100644
index f577895bf..000000000
--- a/ml/dlib/examples/video_frames/frame_000160.jpg
+++ /dev/null
Binary files differ
diff --git a/ml/dlib/examples/video_frames/frame_000161.jpg b/ml/dlib/examples/video_frames/frame_000161.jpg
deleted file mode 100644
index fe407f34e..000000000
--- a/ml/dlib/examples/video_frames/frame_000161.jpg
+++ /dev/null
Binary files differ
diff --git a/ml/dlib/examples/video_frames/frame_000162.jpg b/ml/dlib/examples/video_frames/frame_000162.jpg
deleted file mode 100644
index fd611c5d3..000000000
--- a/ml/dlib/examples/video_frames/frame_000162.jpg
+++ /dev/null
Binary files differ
diff --git a/ml/dlib/examples/video_frames/frame_000163.jpg b/ml/dlib/examples/video_frames/frame_000163.jpg
deleted file mode 100644
index 054daa9e6..000000000
--- a/ml/dlib/examples/video_frames/frame_000163.jpg
+++ /dev/null
Binary files differ
diff --git a/ml/dlib/examples/video_frames/frame_000164.jpg b/ml/dlib/examples/video_frames/frame_000164.jpg
deleted file mode 100644
index b7891a4f9..000000000
--- a/ml/dlib/examples/video_frames/frame_000164.jpg
+++ /dev/null
Binary files differ
diff --git a/ml/dlib/examples/video_frames/frame_000165.jpg b/ml/dlib/examples/video_frames/frame_000165.jpg
deleted file mode 100644
index 273d02a96..000000000
--- a/ml/dlib/examples/video_frames/frame_000165.jpg
+++ /dev/null
Binary files differ
diff --git a/ml/dlib/examples/video_frames/frame_000166.jpg b/ml/dlib/examples/video_frames/frame_000166.jpg
deleted file mode 100644
index 53dc257ab..000000000
--- a/ml/dlib/examples/video_frames/frame_000166.jpg
+++ /dev/null
Binary files differ
diff --git a/ml/dlib/examples/video_frames/frame_000167.jpg b/ml/dlib/examples/video_frames/frame_000167.jpg
deleted file mode 100644
index b1e52c948..000000000
--- a/ml/dlib/examples/video_frames/frame_000167.jpg
+++ /dev/null
Binary files differ
diff --git a/ml/dlib/examples/video_frames/frame_000168.jpg b/ml/dlib/examples/video_frames/frame_000168.jpg
deleted file mode 100644
index 6650df13c..000000000
--- a/ml/dlib/examples/video_frames/frame_000168.jpg
+++ /dev/null
Binary files differ
diff --git a/ml/dlib/examples/video_frames/frame_000169.jpg b/ml/dlib/examples/video_frames/frame_000169.jpg
deleted file mode 100644
index 8811ac06d..000000000
--- a/ml/dlib/examples/video_frames/frame_000169.jpg
+++ /dev/null
Binary files differ
diff --git a/ml/dlib/examples/video_frames/frame_000170.jpg b/ml/dlib/examples/video_frames/frame_000170.jpg
deleted file mode 100644
index e5db6d862..000000000
--- a/ml/dlib/examples/video_frames/frame_000170.jpg
+++ /dev/null
Binary files differ
diff --git a/ml/dlib/examples/video_frames/frame_000171.jpg b/ml/dlib/examples/video_frames/frame_000171.jpg
deleted file mode 100644
index 01b781239..000000000
--- a/ml/dlib/examples/video_frames/frame_000171.jpg
+++ /dev/null
Binary files differ
diff --git a/ml/dlib/examples/video_frames/frame_000172.jpg b/ml/dlib/examples/video_frames/frame_000172.jpg
deleted file mode 100644
index dd423a43d..000000000
--- a/ml/dlib/examples/video_frames/frame_000172.jpg
+++ /dev/null
Binary files differ
diff --git a/ml/dlib/examples/video_frames/frame_000173.jpg b/ml/dlib/examples/video_frames/frame_000173.jpg
deleted file mode 100644
index e9921b5f0..000000000
--- a/ml/dlib/examples/video_frames/frame_000173.jpg
+++ /dev/null
Binary files differ
diff --git a/ml/dlib/examples/video_frames/frame_000174.jpg b/ml/dlib/examples/video_frames/frame_000174.jpg
deleted file mode 100644
index c334e3f5a..000000000
--- a/ml/dlib/examples/video_frames/frame_000174.jpg
+++ /dev/null
Binary files differ
diff --git a/ml/dlib/examples/video_frames/frame_000175.jpg b/ml/dlib/examples/video_frames/frame_000175.jpg
deleted file mode 100644
index b43abe8e5..000000000
--- a/ml/dlib/examples/video_frames/frame_000175.jpg
+++ /dev/null
Binary files differ
diff --git a/ml/dlib/examples/video_frames/frame_000176.jpg b/ml/dlib/examples/video_frames/frame_000176.jpg
deleted file mode 100644
index a816a898a..000000000
--- a/ml/dlib/examples/video_frames/frame_000176.jpg
+++ /dev/null
Binary files differ
diff --git a/ml/dlib/examples/video_frames/frame_000177.jpg b/ml/dlib/examples/video_frames/frame_000177.jpg
deleted file mode 100644
index f8542da32..000000000
--- a/ml/dlib/examples/video_frames/frame_000177.jpg
+++ /dev/null
Binary files differ
diff --git a/ml/dlib/examples/video_frames/frame_000178.jpg b/ml/dlib/examples/video_frames/frame_000178.jpg
deleted file mode 100644
index ab6c4d733..000000000
--- a/ml/dlib/examples/video_frames/frame_000178.jpg
+++ /dev/null
Binary files differ
diff --git a/ml/dlib/examples/video_frames/frame_000179.jpg b/ml/dlib/examples/video_frames/frame_000179.jpg
deleted file mode 100644
index c07be3add..000000000
--- a/ml/dlib/examples/video_frames/frame_000179.jpg
+++ /dev/null
Binary files differ
diff --git a/ml/dlib/examples/video_frames/frame_000180.jpg b/ml/dlib/examples/video_frames/frame_000180.jpg
deleted file mode 100644
index 9e6a503bc..000000000
--- a/ml/dlib/examples/video_frames/frame_000180.jpg
+++ /dev/null
Binary files differ
diff --git a/ml/dlib/examples/video_frames/frame_000181.jpg b/ml/dlib/examples/video_frames/frame_000181.jpg
deleted file mode 100644
index cc03f8cb7..000000000
--- a/ml/dlib/examples/video_frames/frame_000181.jpg
+++ /dev/null
Binary files differ
diff --git a/ml/dlib/examples/video_frames/frame_000182.jpg b/ml/dlib/examples/video_frames/frame_000182.jpg
deleted file mode 100644
index fe93728ce..000000000
--- a/ml/dlib/examples/video_frames/frame_000182.jpg
+++ /dev/null
Binary files differ
diff --git a/ml/dlib/examples/video_frames/frame_000183.jpg b/ml/dlib/examples/video_frames/frame_000183.jpg
deleted file mode 100644
index 96ba792f6..000000000
--- a/ml/dlib/examples/video_frames/frame_000183.jpg
+++ /dev/null
Binary files differ
diff --git a/ml/dlib/examples/video_frames/frame_000184.jpg b/ml/dlib/examples/video_frames/frame_000184.jpg
deleted file mode 100644
index b43db9ea6..000000000
--- a/ml/dlib/examples/video_frames/frame_000184.jpg
+++ /dev/null
Binary files differ
diff --git a/ml/dlib/examples/video_frames/frame_000185.jpg b/ml/dlib/examples/video_frames/frame_000185.jpg
deleted file mode 100644
index 0b31bb239..000000000
--- a/ml/dlib/examples/video_frames/frame_000185.jpg
+++ /dev/null
Binary files differ
diff --git a/ml/dlib/examples/video_frames/frame_000186.jpg b/ml/dlib/examples/video_frames/frame_000186.jpg
deleted file mode 100644
index 44156dd7d..000000000
--- a/ml/dlib/examples/video_frames/frame_000186.jpg
+++ /dev/null
Binary files differ
diff --git a/ml/dlib/examples/video_frames/frame_000187.jpg b/ml/dlib/examples/video_frames/frame_000187.jpg
deleted file mode 100644
index 2f972be39..000000000
--- a/ml/dlib/examples/video_frames/frame_000187.jpg
+++ /dev/null
Binary files differ
diff --git a/ml/dlib/examples/video_frames/frame_000188.jpg b/ml/dlib/examples/video_frames/frame_000188.jpg
deleted file mode 100644
index fc4c2fbed..000000000
--- a/ml/dlib/examples/video_frames/frame_000188.jpg
+++ /dev/null
Binary files differ
diff --git a/ml/dlib/examples/video_frames/frame_000189.jpg b/ml/dlib/examples/video_frames/frame_000189.jpg
deleted file mode 100644
index 1ef51a23f..000000000
--- a/ml/dlib/examples/video_frames/frame_000189.jpg
+++ /dev/null
Binary files differ
diff --git a/ml/dlib/examples/video_frames/frame_000190.jpg b/ml/dlib/examples/video_frames/frame_000190.jpg
deleted file mode 100644
index d5f65c1f0..000000000
--- a/ml/dlib/examples/video_frames/frame_000190.jpg
+++ /dev/null
Binary files differ
diff --git a/ml/dlib/examples/video_frames/frame_000191.jpg b/ml/dlib/examples/video_frames/frame_000191.jpg
deleted file mode 100644
index 00f7e8dc4..000000000
--- a/ml/dlib/examples/video_frames/frame_000191.jpg
+++ /dev/null
Binary files differ
diff --git a/ml/dlib/examples/video_frames/frame_000192.jpg b/ml/dlib/examples/video_frames/frame_000192.jpg
deleted file mode 100644
index 6a8de8bf9..000000000
--- a/ml/dlib/examples/video_frames/frame_000192.jpg
+++ /dev/null
Binary files differ
diff --git a/ml/dlib/examples/video_frames/frame_000193.jpg b/ml/dlib/examples/video_frames/frame_000193.jpg
deleted file mode 100644
index 7a8e5b49f..000000000
--- a/ml/dlib/examples/video_frames/frame_000193.jpg
+++ /dev/null
Binary files differ
diff --git a/ml/dlib/examples/video_frames/frame_000194.jpg b/ml/dlib/examples/video_frames/frame_000194.jpg
deleted file mode 100644
index d338701db..000000000
--- a/ml/dlib/examples/video_frames/frame_000194.jpg
+++ /dev/null
Binary files differ
diff --git a/ml/dlib/examples/video_frames/frame_000195.jpg b/ml/dlib/examples/video_frames/frame_000195.jpg
deleted file mode 100644
index 85b758f37..000000000
--- a/ml/dlib/examples/video_frames/frame_000195.jpg
+++ /dev/null
Binary files differ
diff --git a/ml/dlib/examples/video_frames/frame_000196.jpg b/ml/dlib/examples/video_frames/frame_000196.jpg
deleted file mode 100644
index 624fc1388..000000000
--- a/ml/dlib/examples/video_frames/frame_000196.jpg
+++ /dev/null
Binary files differ
diff --git a/ml/dlib/examples/video_frames/frame_000197.jpg b/ml/dlib/examples/video_frames/frame_000197.jpg
deleted file mode 100644
index 733cf4e3f..000000000
--- a/ml/dlib/examples/video_frames/frame_000197.jpg
+++ /dev/null
Binary files differ
diff --git a/ml/dlib/examples/video_frames/frame_000198.jpg b/ml/dlib/examples/video_frames/frame_000198.jpg
deleted file mode 100644
index fc42278f5..000000000
--- a/ml/dlib/examples/video_frames/frame_000198.jpg
+++ /dev/null
Binary files differ
diff --git a/ml/dlib/examples/video_frames/frame_000199.jpg b/ml/dlib/examples/video_frames/frame_000199.jpg
deleted file mode 100644
index 079c3211d..000000000
--- a/ml/dlib/examples/video_frames/frame_000199.jpg
+++ /dev/null
Binary files differ
diff --git a/ml/dlib/examples/video_frames/frame_000200.jpg b/ml/dlib/examples/video_frames/frame_000200.jpg
deleted file mode 100644
index 5eeb398ce..000000000
--- a/ml/dlib/examples/video_frames/frame_000200.jpg
+++ /dev/null
Binary files differ
diff --git a/ml/dlib/examples/video_frames/frame_000201.jpg b/ml/dlib/examples/video_frames/frame_000201.jpg
deleted file mode 100644
index 053858a8c..000000000
--- a/ml/dlib/examples/video_frames/frame_000201.jpg
+++ /dev/null
Binary files differ
diff --git a/ml/dlib/examples/video_frames/frame_000202.jpg b/ml/dlib/examples/video_frames/frame_000202.jpg
deleted file mode 100644
index 366c06d33..000000000
--- a/ml/dlib/examples/video_frames/frame_000202.jpg
+++ /dev/null
Binary files differ
diff --git a/ml/dlib/examples/video_frames/frame_000203.jpg b/ml/dlib/examples/video_frames/frame_000203.jpg
deleted file mode 100644
index f789ff5bf..000000000
--- a/ml/dlib/examples/video_frames/frame_000203.jpg
+++ /dev/null
Binary files differ
diff --git a/ml/dlib/examples/video_frames/frame_000204.jpg b/ml/dlib/examples/video_frames/frame_000204.jpg
deleted file mode 100644
index c0616ac17..000000000
--- a/ml/dlib/examples/video_frames/frame_000204.jpg
+++ /dev/null
Binary files differ
diff --git a/ml/dlib/examples/video_frames/frame_000205.jpg b/ml/dlib/examples/video_frames/frame_000205.jpg
deleted file mode 100644
index 4994bc6ba..000000000
--- a/ml/dlib/examples/video_frames/frame_000205.jpg
+++ /dev/null
Binary files differ
diff --git a/ml/dlib/examples/video_frames/frame_000206.jpg b/ml/dlib/examples/video_frames/frame_000206.jpg
deleted file mode 100644
index 8ca39e3da..000000000
--- a/ml/dlib/examples/video_frames/frame_000206.jpg
+++ /dev/null
Binary files differ
diff --git a/ml/dlib/examples/video_frames/frame_000207.jpg b/ml/dlib/examples/video_frames/frame_000207.jpg
deleted file mode 100644
index 1cc9f95aa..000000000
--- a/ml/dlib/examples/video_frames/frame_000207.jpg
+++ /dev/null
Binary files differ
diff --git a/ml/dlib/examples/video_frames/frame_000208.jpg b/ml/dlib/examples/video_frames/frame_000208.jpg
deleted file mode 100644
index 3d4e82cd4..000000000
--- a/ml/dlib/examples/video_frames/frame_000208.jpg
+++ /dev/null
Binary files differ
diff --git a/ml/dlib/examples/video_frames/frame_000209.jpg b/ml/dlib/examples/video_frames/frame_000209.jpg
deleted file mode 100644
index 2a9652506..000000000
--- a/ml/dlib/examples/video_frames/frame_000209.jpg
+++ /dev/null
Binary files differ
diff --git a/ml/dlib/examples/video_frames/frame_000210.jpg b/ml/dlib/examples/video_frames/frame_000210.jpg
deleted file mode 100644
index 4b1f034ad..000000000
--- a/ml/dlib/examples/video_frames/frame_000210.jpg
+++ /dev/null
Binary files differ
diff --git a/ml/dlib/examples/video_frames/frame_000211.jpg b/ml/dlib/examples/video_frames/frame_000211.jpg
deleted file mode 100644
index 67f6d13b3..000000000
--- a/ml/dlib/examples/video_frames/frame_000211.jpg
+++ /dev/null
Binary files differ
diff --git a/ml/dlib/examples/video_frames/frame_000212.jpg b/ml/dlib/examples/video_frames/frame_000212.jpg
deleted file mode 100644
index cae3ac6ed..000000000
--- a/ml/dlib/examples/video_frames/frame_000212.jpg
+++ /dev/null
Binary files differ
diff --git a/ml/dlib/examples/video_frames/frame_000213.jpg b/ml/dlib/examples/video_frames/frame_000213.jpg
deleted file mode 100644
index 21bb9ab4e..000000000
--- a/ml/dlib/examples/video_frames/frame_000213.jpg
+++ /dev/null
Binary files differ
diff --git a/ml/dlib/examples/video_frames/frame_000214.jpg b/ml/dlib/examples/video_frames/frame_000214.jpg
deleted file mode 100644
index 881cef7ef..000000000
--- a/ml/dlib/examples/video_frames/frame_000214.jpg
+++ /dev/null
Binary files differ
diff --git a/ml/dlib/examples/video_frames/frame_000215.jpg b/ml/dlib/examples/video_frames/frame_000215.jpg
deleted file mode 100644
index 9a7ff9e87..000000000
--- a/ml/dlib/examples/video_frames/frame_000215.jpg
+++ /dev/null
Binary files differ
diff --git a/ml/dlib/examples/video_frames/frame_000216.jpg b/ml/dlib/examples/video_frames/frame_000216.jpg
deleted file mode 100644
index a73357398..000000000
--- a/ml/dlib/examples/video_frames/frame_000216.jpg
+++ /dev/null
Binary files differ
diff --git a/ml/dlib/examples/video_frames/frame_000217.jpg b/ml/dlib/examples/video_frames/frame_000217.jpg
deleted file mode 100644
index f590c51c8..000000000
--- a/ml/dlib/examples/video_frames/frame_000217.jpg
+++ /dev/null
Binary files differ
diff --git a/ml/dlib/examples/video_frames/frame_000218.jpg b/ml/dlib/examples/video_frames/frame_000218.jpg
deleted file mode 100644
index 66c3c251d..000000000
--- a/ml/dlib/examples/video_frames/frame_000218.jpg
+++ /dev/null
Binary files differ
diff --git a/ml/dlib/examples/video_frames/frame_000219.jpg b/ml/dlib/examples/video_frames/frame_000219.jpg
deleted file mode 100644
index c637d61ac..000000000
--- a/ml/dlib/examples/video_frames/frame_000219.jpg
+++ /dev/null
Binary files differ
diff --git a/ml/dlib/examples/video_frames/frame_000220.jpg b/ml/dlib/examples/video_frames/frame_000220.jpg
deleted file mode 100644
index 3e4fc3d11..000000000
--- a/ml/dlib/examples/video_frames/frame_000220.jpg
+++ /dev/null
Binary files differ
diff --git a/ml/dlib/examples/video_frames/frame_000221.jpg b/ml/dlib/examples/video_frames/frame_000221.jpg
deleted file mode 100644
index 1e1736365..000000000
--- a/ml/dlib/examples/video_frames/frame_000221.jpg
+++ /dev/null
Binary files differ
diff --git a/ml/dlib/examples/video_frames/frame_000222.jpg b/ml/dlib/examples/video_frames/frame_000222.jpg
deleted file mode 100644
index ff77b3464..000000000
--- a/ml/dlib/examples/video_frames/frame_000222.jpg
+++ /dev/null
Binary files differ
diff --git a/ml/dlib/examples/video_frames/frame_000223.jpg b/ml/dlib/examples/video_frames/frame_000223.jpg
deleted file mode 100644
index 6c107288a..000000000
--- a/ml/dlib/examples/video_frames/frame_000223.jpg
+++ /dev/null
Binary files differ
diff --git a/ml/dlib/examples/video_frames/frame_000224.jpg b/ml/dlib/examples/video_frames/frame_000224.jpg
deleted file mode 100644
index 3c0a0e9b7..000000000
--- a/ml/dlib/examples/video_frames/frame_000224.jpg
+++ /dev/null
Binary files differ
diff --git a/ml/dlib/examples/video_frames/frame_000225.jpg b/ml/dlib/examples/video_frames/frame_000225.jpg
deleted file mode 100644
index 2c07fffbc..000000000
--- a/ml/dlib/examples/video_frames/frame_000225.jpg
+++ /dev/null
Binary files differ
diff --git a/ml/dlib/examples/video_frames/frame_000226.jpg b/ml/dlib/examples/video_frames/frame_000226.jpg
deleted file mode 100644
index 4695b5cd0..000000000
--- a/ml/dlib/examples/video_frames/frame_000226.jpg
+++ /dev/null
Binary files differ
diff --git a/ml/dlib/examples/video_frames/frame_000227.jpg b/ml/dlib/examples/video_frames/frame_000227.jpg
deleted file mode 100644
index 920faeea8..000000000
--- a/ml/dlib/examples/video_frames/frame_000227.jpg
+++ /dev/null
Binary files differ
diff --git a/ml/dlib/examples/video_frames/frame_000228.jpg b/ml/dlib/examples/video_frames/frame_000228.jpg
deleted file mode 100644
index 9d3de28f2..000000000
--- a/ml/dlib/examples/video_frames/frame_000228.jpg
+++ /dev/null
Binary files differ
diff --git a/ml/dlib/examples/video_frames/frame_000229.jpg b/ml/dlib/examples/video_frames/frame_000229.jpg
deleted file mode 100644
index e8c0444cf..000000000
--- a/ml/dlib/examples/video_frames/frame_000229.jpg
+++ /dev/null
Binary files differ
diff --git a/ml/dlib/examples/video_frames/frame_000230.jpg b/ml/dlib/examples/video_frames/frame_000230.jpg
deleted file mode 100644
index 1e65a4dbf..000000000
--- a/ml/dlib/examples/video_frames/frame_000230.jpg
+++ /dev/null
Binary files differ
diff --git a/ml/dlib/examples/video_frames/frame_000231.jpg b/ml/dlib/examples/video_frames/frame_000231.jpg
deleted file mode 100644
index 7a86ac53e..000000000
--- a/ml/dlib/examples/video_frames/frame_000231.jpg
+++ /dev/null
Binary files differ
diff --git a/ml/dlib/examples/video_frames/frame_000232.jpg b/ml/dlib/examples/video_frames/frame_000232.jpg
deleted file mode 100644
index 2f38dba48..000000000
--- a/ml/dlib/examples/video_frames/frame_000232.jpg
+++ /dev/null
Binary files differ
diff --git a/ml/dlib/examples/video_frames/frame_000233.jpg b/ml/dlib/examples/video_frames/frame_000233.jpg
deleted file mode 100644
index c72735c2c..000000000
--- a/ml/dlib/examples/video_frames/frame_000233.jpg
+++ /dev/null
Binary files differ
diff --git a/ml/dlib/examples/video_frames/frame_000234.jpg b/ml/dlib/examples/video_frames/frame_000234.jpg
deleted file mode 100644
index bec85f21d..000000000
--- a/ml/dlib/examples/video_frames/frame_000234.jpg
+++ /dev/null
Binary files differ
diff --git a/ml/dlib/examples/video_frames/frame_000235.jpg b/ml/dlib/examples/video_frames/frame_000235.jpg
deleted file mode 100644
index 425bf3f39..000000000
--- a/ml/dlib/examples/video_frames/frame_000235.jpg
+++ /dev/null
Binary files differ
diff --git a/ml/dlib/examples/video_frames/frame_000236.jpg b/ml/dlib/examples/video_frames/frame_000236.jpg
deleted file mode 100644
index 0ca67ddcb..000000000
--- a/ml/dlib/examples/video_frames/frame_000236.jpg
+++ /dev/null
Binary files differ
diff --git a/ml/dlib/examples/video_frames/frame_000237.jpg b/ml/dlib/examples/video_frames/frame_000237.jpg
deleted file mode 100644
index 8d6581b95..000000000
--- a/ml/dlib/examples/video_frames/frame_000237.jpg
+++ /dev/null
Binary files differ
diff --git a/ml/dlib/examples/video_frames/frame_000238.jpg b/ml/dlib/examples/video_frames/frame_000238.jpg
deleted file mode 100644
index 22cf36f75..000000000
--- a/ml/dlib/examples/video_frames/frame_000238.jpg
+++ /dev/null
Binary files differ
diff --git a/ml/dlib/examples/video_frames/frame_000239.jpg b/ml/dlib/examples/video_frames/frame_000239.jpg
deleted file mode 100644
index bb368be66..000000000
--- a/ml/dlib/examples/video_frames/frame_000239.jpg
+++ /dev/null
Binary files differ
diff --git a/ml/dlib/examples/video_frames/frame_000240.jpg b/ml/dlib/examples/video_frames/frame_000240.jpg
deleted file mode 100644
index 4073cdddc..000000000
--- a/ml/dlib/examples/video_frames/frame_000240.jpg
+++ /dev/null
Binary files differ
diff --git a/ml/dlib/examples/video_frames/frame_000241.jpg b/ml/dlib/examples/video_frames/frame_000241.jpg
deleted file mode 100644
index d3347b206..000000000
--- a/ml/dlib/examples/video_frames/frame_000241.jpg
+++ /dev/null
Binary files differ
diff --git a/ml/dlib/examples/video_frames/frame_000242.jpg b/ml/dlib/examples/video_frames/frame_000242.jpg
deleted file mode 100644
index 6df093f22..000000000
--- a/ml/dlib/examples/video_frames/frame_000242.jpg
+++ /dev/null
Binary files differ
diff --git a/ml/dlib/examples/video_frames/frame_000243.jpg b/ml/dlib/examples/video_frames/frame_000243.jpg
deleted file mode 100644
index c418887a2..000000000
--- a/ml/dlib/examples/video_frames/frame_000243.jpg
+++ /dev/null
Binary files differ
diff --git a/ml/dlib/examples/video_frames/frame_000244.jpg b/ml/dlib/examples/video_frames/frame_000244.jpg
deleted file mode 100644
index d60fd8ca5..000000000
--- a/ml/dlib/examples/video_frames/frame_000244.jpg
+++ /dev/null
Binary files differ
diff --git a/ml/dlib/examples/video_frames/frame_000245.jpg b/ml/dlib/examples/video_frames/frame_000245.jpg
deleted file mode 100644
index 8e5ff86f0..000000000
--- a/ml/dlib/examples/video_frames/frame_000245.jpg
+++ /dev/null
Binary files differ
diff --git a/ml/dlib/examples/video_frames/frame_000246.jpg b/ml/dlib/examples/video_frames/frame_000246.jpg
deleted file mode 100644
index 795ba1c54..000000000
--- a/ml/dlib/examples/video_frames/frame_000246.jpg
+++ /dev/null
Binary files differ
diff --git a/ml/dlib/examples/video_frames/frame_000247.jpg b/ml/dlib/examples/video_frames/frame_000247.jpg
deleted file mode 100644
index 5842e61c5..000000000
--- a/ml/dlib/examples/video_frames/frame_000247.jpg
+++ /dev/null
Binary files differ
diff --git a/ml/dlib/examples/video_frames/frame_000248.jpg b/ml/dlib/examples/video_frames/frame_000248.jpg
deleted file mode 100644
index 8d64586da..000000000
--- a/ml/dlib/examples/video_frames/frame_000248.jpg
+++ /dev/null
Binary files differ
diff --git a/ml/dlib/examples/video_frames/frame_000249.jpg b/ml/dlib/examples/video_frames/frame_000249.jpg
deleted file mode 100644
index 6a314e4bd..000000000
--- a/ml/dlib/examples/video_frames/frame_000249.jpg
+++ /dev/null
Binary files differ
diff --git a/ml/dlib/examples/video_frames/frame_000250.jpg b/ml/dlib/examples/video_frames/frame_000250.jpg
deleted file mode 100644
index d9ef51b2f..000000000
--- a/ml/dlib/examples/video_frames/frame_000250.jpg
+++ /dev/null
Binary files differ
diff --git a/ml/dlib/examples/video_frames/license.txt b/ml/dlib/examples/video_frames/license.txt
deleted file mode 100644
index d3b6ac69c..000000000
--- a/ml/dlib/examples/video_frames/license.txt
+++ /dev/null
@@ -1,6 +0,0 @@
-Please read terms of use for the content of this zip file at this websites:
-English: http://creativecommons.org/licenses/by-sa/3.0/de/deed.en
-German: http://creativecommons.org/licenses/by-sa/3.0/de/
-
-
-Note that this video is from the BoBoT dataset (see http://www.iai.uni-bonn.de/~kleind/tracking/) but has been compressed a lot, cropped, and converted to grayscale to make the dlib archive file as small as possible.
diff --git a/ml/dlib/examples/video_tracking_ex.cpp b/ml/dlib/examples/video_tracking_ex.cpp
deleted file mode 100644
index 464baaf91..000000000
--- a/ml/dlib/examples/video_tracking_ex.cpp
+++ /dev/null
@@ -1,72 +0,0 @@
-// The contents of this file are in the public domain. See LICENSE_FOR_EXAMPLE_PROGRAMS.txt
-/*
-
- This example shows how to use the correlation_tracker from the dlib C++ library. This
- object lets you track the position of an object as it moves from frame to frame in a
- video sequence. To use it, you give the correlation_tracker the bounding box of the
- object you want to track in the current video frame. Then it will identify the
- location of the object in subsequent frames.
-
- In this particular example, we are going to run on the video sequence that comes with
- dlib, which can be found in the examples/video_frames folder. This video shows a juice
- box sitting on a table and someone is waving the camera around. The task is to track the
- position of the juice box as the camera moves around.
-*/
-
-#include <dlib/image_processing.h>
-#include <dlib/gui_widgets.h>
-#include <dlib/image_io.h>
-#include <dlib/dir_nav.h>
-
-
-using namespace dlib;
-using namespace std;
-
-int main(int argc, char** argv) try
-{
- if (argc != 2)
- {
- cout << "Call this program like this: " << endl;
- cout << "./video_tracking_ex ../video_frames" << endl;
- return 1;
- }
-
- // Get the list of video frames.
- std::vector<file> files = get_files_in_directory_tree(argv[1], match_ending(".jpg"));
- std::sort(files.begin(), files.end());
- if (files.size() == 0)
- {
- cout << "No images found in " << argv[1] << endl;
- return 1;
- }
-
- // Load the first frame.
- array2d<unsigned char> img;
- load_image(img, files[0]);
- // Now create a tracker and start a track on the juice box. If you look at the first
- // frame you will see that the juice box is centered at pixel point(92,110) and 38
- // pixels wide and 86 pixels tall.
- correlation_tracker tracker;
- tracker.start_track(img, centered_rect(point(93,110), 38, 86));
-
- // Now run the tracker. All we have to do is call tracker.update() and it will keep
- // track of the juice box!
- image_window win;
- for (unsigned long i = 1; i < files.size(); ++i)
- {
- load_image(img, files[i]);
- tracker.update(img);
-
- win.set_image(img);
- win.clear_overlay();
- win.add_overlay(tracker.get_position());
-
- cout << "hit enter to process next frame" << endl;
- cin.get();
- }
-}
-catch (std::exception& e)
-{
- cout << e.what() << endl;
-}
-
diff --git a/ml/dlib/examples/webcam_face_pose_ex.cpp b/ml/dlib/examples/webcam_face_pose_ex.cpp
deleted file mode 100644
index e3b00d0f2..000000000
--- a/ml/dlib/examples/webcam_face_pose_ex.cpp
+++ /dev/null
@@ -1,100 +0,0 @@
-// The contents of this file are in the public domain. See LICENSE_FOR_EXAMPLE_PROGRAMS.txt
-/*
-
- This example program shows how to find frontal human faces in an image and
- estimate their pose. The pose takes the form of 68 landmarks. These are
- points on the face such as the corners of the mouth, along the eyebrows, on
- the eyes, and so forth.
-
-
- This example is essentially just a version of the face_landmark_detection_ex.cpp
- example modified to use OpenCV's VideoCapture object to read from a camera instead
- of files.
-
-
- Finally, note that the face detector is fastest when compiled with at least
- SSE2 instructions enabled. So if you are using a PC with an Intel or AMD
- chip then you should enable at least SSE2 instructions. If you are using
- cmake to compile this program you can enable them by using one of the
- following commands when you create the build project:
- cmake path_to_dlib_root/examples -DUSE_SSE2_INSTRUCTIONS=ON
- cmake path_to_dlib_root/examples -DUSE_SSE4_INSTRUCTIONS=ON
- cmake path_to_dlib_root/examples -DUSE_AVX_INSTRUCTIONS=ON
- This will set the appropriate compiler options for GCC, clang, Visual
- Studio, or the Intel compiler. If you are using another compiler then you
- need to consult your compiler's manual to determine how to enable these
- instructions. Note that AVX is the fastest but requires a CPU from at least
- 2011. SSE4 is the next fastest and is supported by most current machines.
-*/
-
-#include <dlib/opencv.h>
-#include <opencv2/highgui/highgui.hpp>
-#include <dlib/image_processing/frontal_face_detector.h>
-#include <dlib/image_processing/render_face_detections.h>
-#include <dlib/image_processing.h>
-#include <dlib/gui_widgets.h>
-
-using namespace dlib;
-using namespace std;
-
-int main()
-{
- try
- {
- cv::VideoCapture cap(0);
- if (!cap.isOpened())
- {
- cerr << "Unable to connect to camera" << endl;
- return 1;
- }
-
- image_window win;
-
- // Load face detection and pose estimation models.
- frontal_face_detector detector = get_frontal_face_detector();
- shape_predictor pose_model;
- deserialize("shape_predictor_68_face_landmarks.dat") >> pose_model;
-
- // Grab and process frames until the main window is closed by the user.
- while(!win.is_closed())
- {
- // Grab a frame
- cv::Mat temp;
- if (!cap.read(temp))
- {
- break;
- }
- // Turn OpenCV's Mat into something dlib can deal with. Note that this just
- // wraps the Mat object, it doesn't copy anything. So cimg is only valid as
- // long as temp is valid. Also don't do anything to temp that would cause it
- // to reallocate the memory which stores the image as that will make cimg
- // contain dangling pointers. This basically means you shouldn't modify temp
- // while using cimg.
- cv_image<bgr_pixel> cimg(temp);
-
- // Detect faces
- std::vector<rectangle> faces = detector(cimg);
- // Find the pose of each face.
- std::vector<full_object_detection> shapes;
- for (unsigned long i = 0; i < faces.size(); ++i)
- shapes.push_back(pose_model(cimg, faces[i]));
-
- // Display it all on the screen
- win.clear_overlay();
- win.set_image(cimg);
- win.add_overlay(render_face_detections(shapes));
- }
- }
- catch(serialization_error& e)
- {
- cout << "You need dlib's default face landmarking model file to run this example." << endl;
- cout << "You can get it from the following URL: " << endl;
- cout << " http://dlib.net/files/shape_predictor_68_face_landmarks.dat.bz2" << endl;
- cout << endl << e.what() << endl;
- }
- catch(exception& e)
- {
- cout << e.what() << endl;
- }
-}
-
diff --git a/ml/dlib/examples/xml_parser_ex.cpp b/ml/dlib/examples/xml_parser_ex.cpp
deleted file mode 100644
index 0d2139592..000000000
--- a/ml/dlib/examples/xml_parser_ex.cpp
+++ /dev/null
@@ -1,115 +0,0 @@
-// The contents of this file are in the public domain. See LICENSE_FOR_EXAMPLE_PROGRAMS.txt
-/*
-
- This is an example illustrating the use of the xml_parser component in
- the dlib C++ Library.
-
- This example simply reads in an xml file and prints the parsing events
- to the screen.
-*/
-
-
-
-
-#include <dlib/xml_parser.h>
-#include <iostream>
-#include <fstream>
-
-
-using namespace std;
-using namespace dlib;
-
-// ----------------------------------------------------------------------------------------
-
-class doc_handler : public document_handler
-{
- /*
- As the parser runs it generates events when it encounters tags and
- data in an XML file. To be able to receive these events all you have to
- do is make a class that inherits from dlib::document_handler and
- implements its virtual methods. Then you simply associate an
- instance of your class with the xml_parser.
-
- So this class is a simple example document handler that just prints
- all the events to the screen.
- */
-public:
-
- virtual void start_document (
- )
- {
- cout << "parsing begins" << endl;
- }
-
- virtual void end_document (
- )
- {
- cout << "Parsing done" << endl;
- }
-
- virtual void start_element (
- const unsigned long line_number,
- const std::string& name,
- const dlib::attribute_list& atts
- )
- {
- cout << "on line " << line_number << " we hit the <" << name << "> tag" << endl;
-
- // print all the tag's attributes
- atts.reset();
- while (atts.move_next())
- {
- cout << "\tattribute: " << atts.element().key() << " = " << atts.element().value() << endl;
- }
- }
-
- virtual void end_element (
- const unsigned long line_number,
- const std::string& name
- )
- {
- cout << "on line " << line_number << " we hit the closing tag </" << name << ">" << endl;
- }
-
- virtual void characters (
- const std::string& data
- )
- {
- cout << "Got some data between tags and it is:\n" << data << endl;
- }
-
- virtual void processing_instruction (
- const unsigned long line_number,
- const std::string& target,
- const std::string& data
- )
- {
- cout << "on line " << line_number << " we hit a processing instruction with a target of '"
- << target << "' and data '" << data << "'" << endl;
- }
-};
-
-// ----------------------------------------------------------------------------------------
-
-int main(int argc, char** argv)
-{
- try
- {
- // Check if the user entered an argument to this application.
- if (argc != 2)
- {
- cout << "Please enter an xml file to parse on the command line" << endl;
- return 1;
- }
-
- doc_handler dh;
- // Now run the parser and tell it to call our doc_handler for each of the parsing
- // events.
- parse_xml(argv[1], dh);
- }
- catch (std::exception& e)
- {
- cout << e.what() << endl;
- }
-}
-