diff options
author | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-05-05 12:08:03 +0000 |
---|---|---|
committer | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-05-05 12:08:18 +0000 |
commit | 5da14042f70711ea5cf66e034699730335462f66 (patch) | |
tree | 0f6354ccac934ed87a2d555f45be4c831cf92f4a /src/ml/dlib/examples/krls_filter_ex.cpp | |
parent | Releasing debian version 1.44.3-2. (diff) | |
download | netdata-5da14042f70711ea5cf66e034699730335462f66.tar.xz netdata-5da14042f70711ea5cf66e034699730335462f66.zip |
Merging upstream version 1.45.3+dfsg.
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'src/ml/dlib/examples/krls_filter_ex.cpp')
-rw-r--r-- | src/ml/dlib/examples/krls_filter_ex.cpp | 109 |
1 files changed, 109 insertions, 0 deletions
diff --git a/src/ml/dlib/examples/krls_filter_ex.cpp b/src/ml/dlib/examples/krls_filter_ex.cpp new file mode 100644 index 000000000..5bb74b183 --- /dev/null +++ b/src/ml/dlib/examples/krls_filter_ex.cpp @@ -0,0 +1,109 @@ +// 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. + +} + + |