Detecting normal EKG pulses » History » Version 1
Federico Vera, 2018-06-10 00:42
| 1 | 1 | Federico Vera | # Application Example |
|---|---|---|---|
| 2 | |||
| 3 | ## Detecting normal EKG pulses. |
||
| 4 | |||
| 5 | I will not enter into too much detail in this text in an attempt to _trick_ the |
||
| 6 | reader (you) into doing some research. But the basic idea is to train an MLP and |
||
| 7 | then use the results to try and deduce if a Pulse is normal or not (the same |
||
| 8 | approach can be used to detect specific pathologies). |
||
| 9 | |||
| 10 | This is **not** the usual approach which usually includes extracting features |
||
| 11 | like the a<sub>k</sub>s of the Fourier Transform, eigenvalues, and such. The |
||
| 12 | approach that will be described in this example is much simpler (albeit it has |
||
| 13 | a less accurate result... _or does it?_) |
||
| 14 | |||
| 15 | ## About the EKG |
||
| 16 | EKGs or ECGs (whichever you like) is basically a set of five (three, five or |
||
| 17 | six) different signals or _derivations_. Most of the bibliographic |
||
| 18 | information and cardiological knowledge is in the time domain, and |
||
| 19 | unfortunately most of the features usually extracted for NN training are |
||
| 20 | frequency based, which brings us to a little problem, no cardiologist wants to |
||
| 21 | apply something that he/she can't understand. |
||
| 22 | |||
| 23 | We can of course analyze an ECG in the time domain, and with a little tinkering |
||
| 24 | the results are actually quite encouraging. |
||
| 25 | |||
| 26 | ## Preprocessing |
||
| 27 | As you might know before throwing a signal at a NN and expecting great results |
||
| 28 | is usually coherent to to some filtering and transforming I'll keep the |
||
| 29 | filtering to a minimum, and mostly done in order to have nice function plots. |
||
| 30 | |||
| 31 | Let's start by getting a copy of [`mrft`] |
||
| 32 | and some EKG Data (for convenience there are some samples included in `mrft`), |
||
| 33 | in case you don't like them, you are free to search some, manufacture one, or |
||
| 34 | even use a synthesizer like [`Java ECG Generator`](http://www.mit.edu/~gari/CODE/ECGSYN/JAVA/APPLET2/ecgsyn/ecg-java/source.html). |
||
| 35 | |||
| 36 | ## Training |
||
| 37 | Open `mrft` select the menu `Examples`->`EKG (Synth)` this will populate the |
||
| 38 | tables the following way: |
||
| 39 | |||
| 40 | [[https://raw.githubusercontent.com/wiki/dktcoding/mrft/imgs/ekg/data.png|alt=Data]] |
||
| 41 | |||
| 42 | Go ahead and press `F5` (a training session should start and with some luck |
||
| 43 | converge to an _"acceptable"_ fit). |
||
| 44 | |||
| 45 | [[https://raw.githubusercontent.com/wiki/dktcoding/mrft/imgs/ekg/firstplot.png|alt=FirstPlot]] |
||
| 46 | |||
| 47 | There's something odd with the way this MLP is trained... do you see it? No? |
||
| 48 | |||
| 49 | (_Tip:_ in the lower plot both the training and validation errors stay very |
||
| 50 | close together! they should be diverging, or at the very least separate, remember over-fitting?) |
||
| 51 | This usually happens with synthetic data, since adjustment is **too perfect** |
||
| 52 | the training and validation datasets are basically one in the same. |
||
| 53 | |||
| 54 | ## Adding some noise |
||
| 55 | Noise is a bad thing that should be removed, why do we want to add it? well |
||
| 56 | the fact is that NN tend to work better with noisy data (not so noisy mind |
||
| 57 | you). |
||
| 58 | |||
| 59 | There are several ways to add noise, but for this we'll use a transformation, |
||
| 60 | so go to `Dataset -> Transform... -> Custom Function (All)`, something like |
||
| 61 | this should appear: |
||
| 62 | |||
| 63 | [[https://raw.githubusercontent.com/wiki/dktcoding/mrft/imgs/ekg/custransf.png|alt=FirstPlot]] |
||
| 64 | |||
| 65 | We'll leave the `x` value as it is, but in the `fx` text field write: |
||
| 66 | `gaussian2(fx, 0.1)` then click on apply, your data now must look |
||
| 67 | something like this: |
||
| 68 | |||
| 69 | [[https://raw.githubusercontent.com/wiki/dktcoding/mrft/imgs/ekg/secondplot.png|alt=SecondPlot]] |
||
| 70 | |||
| 71 | Try pressing `F5` now so it re trains... |
||
| 72 | |||
| 73 | Yes, I lied (not entirely) gaussian noise didn't change the validation error, |
||
| 74 | but I'll let you figure out why on your own (one clue: `Box–Muller`, the |
||
| 75 | rest is _simple_ math). For a bit more information about this see |
||
| 76 | `Adding noise` in [[Data manipulation]] |
||
| 77 | |||
| 78 | ## Selecting the right weights |
||
| 79 | As the NN trains itself the synaptic weights of the training epochs are saved |
||
| 80 | (not all of them), so now we must decide which of all the weights to use, |
||
| 81 | click on the error table (`Error Plots` panel), and when you start selecting |
||
| 82 | rows, you should see two things, one is that the red plot of the function plot |
||
| 83 | changes, and the second one is that a line (or guide) appears in the error |
||
| 84 | plot this indicates in the graph the moment of that particular weight. |
||
| 85 | |||
| 86 | [[https://raw.githubusercontent.com/wiki/dktcoding/mrft/imgs/ekg/guide.png|alt=Guide]] |
||
| 87 | |||
| 88 | Once you are satisfied with the results (i.e. choose the "best" weights |
||
| 89 | <sup id="a1">[1](#f1)</sup>) |
||
| 90 | |||
| 91 | ## Now what? |
||
| 92 | I don't actually have time to finish it today, but the gist is: we will use |
||
| 93 | that synaptic weight to predict values of an unknown EKG, and estimate how |
||
| 94 | similar is it with the training value (mse), with that, we'll choose the one |
||
| 95 | with the lowest mse (mean square error) is the one that we'll accept as |
||
| 96 | correct. |
||
| 97 | @TODO complete example |
||
| 98 | |||
| 99 | <b id="f1"><sup>1</sup></b> There are several criteria for choosing the "best" |
||
| 100 | as a rule of thumb pick the closest to the left with the lowest error, or the |
||
| 101 | point where the validation an training errors intersect. [↩](#a1) |