-
Notifications
You must be signed in to change notification settings - Fork 22
Training on another sleep database #9
Comments
I do not know the details of this dataset, but in principle, you can use whichever channels and channel combinations you want. I would not be surprised if it would also work with ECG (however be aware of the different sample frequency that needs to be interpolated). |
Thanks Simon. I was just wondering if the square brackets (a list) where syntaxically the correct way to retain several (available) channels like 'EEG(sec)' and 'EEG' (which presumably are extracted from a edf file header). |
I thought the scorer could be used with the two available EEG channels of the PSG (plus EOG & EMG, but data is shaped with a last dim of 3 in the SleepLoader), hence my question. (Resampling it to 100 Hz) Would it be possible to put the other available EEG channel in the 'EMG' field in the channel definition, for instance in this way : channels = { 'EEG' : 'EEG(SEC)', 'EMG' : 'EEG', 'EOG' : 'EOG(L)' } ? (in the SHHS, 'EEG(SEC)' and 'EEG' are C3/A2 and C4/A1). |
I don't quite understand what you mean? The network can be trained with any number of channels, and any configuration of channels, but you will need to adapt the script a bit to adjust the input layer of the network. Once a network is trained, the channels are fixed and you can't input any other channels or combinations. The already trained weights provided by this repository do necessarily require the existence of EEG/EMG and EOG. |
If you would allow me to rephrase Paul question. How to set the variable channels as in run_sample my best guess will
Update! |
Sorry for bringing confusion here. I am indeed reusing the script run_sample.py, where one EEG channel (among the two available), one EMG and one EOG channels are used. channels = {'EEG':['EEG(sec)','EEG'], 'EMG':'EMG', 'EOG':['EOG(L)','EOG(R)']} But doing this will not enable to recruit/use the two EEG channels (and the two EOG channels), it is only useful in the case where the name of a channel changes from one edf file to another. And in the SHHS database, this happens to be the case: the channel 'EEG(SEC)' is also named 'EEG2' depending on the files in the SHHS1 repository. In this case, channels = {'EEG':['EEG(sec)','EEG2'], 'EMG':'EMG', 'EOG':'EOG(L)'} ...did the job: selecting either EEG(SEC) or EEG2 depending on the edf file. Recruiting more channels than the 3 used maybe requires to modify varied scripts (models.py, SleepLoader.py, etc...). |
Pcode1 In run_sample, change channels to
Under def check_channels change the following
|
SImon, may I know the following for-loop is for what. Im unable to modify the following, because I do not know under what circumstances it will triger the for-loop. This syntax under def check_channels
|
I think this for-loop is precisely the one which picks up 'EEG(SEC)' or 'EEG2' (when the 'EEG' dict. item is declared as a list of strings like in: |
Yes you are right. The for-loop was for class list. But with my proposed workaround, we can omit this for loop, since we declared multiple EEG channels as a set |
Or, if you want to retain the possibility to select ('EEG(SEC)' OR 'EEG2') AND 'EEG' like with:
` |
Btw, the best model for the 50 males between 38 and 58 yrs drawn from the 200 cases of SHH1 only reaches:
`
` |
Seem not the best performance you have there. Are you using the pre-trained parameter?. |
Congratulations on getting it work! Regarding the accuracy: There are a multitude of things that can be held responsible here: Using a different architecture, different data set, not using all channels. Additionally, I found that each dataset has it's own hyperparameters that achieve optimal performance: Changing the learning rate, stronger/weaker regularization, using a different initialization, etc. Sometimes it turns out that just the random seed was at fault for not reaching a high performance. It's a gamble. Unfortunately neural networks are still notoriously difficult to debug. |
Please be aware, that as far as I remember (correct me if I'm wrong), this data set cuts off all EEG data at 120uV,which is a large part of slow oscillations and arousals etc. For this reason I also did not use it for my study. |
I was not aware that the dynamical range of the EEG channels was limited to 120µV. |
Using a balanced training, or not, made a difference... would it make sense to you the more I select similar individuals (gender, age, bmi, %rem, etc...) in this database, the harder it is to train on the selected cohort & to produce good scoring stats ? I was really expecting the opposite. |
The higher your variance in training data, the higher your generalization will be. If you select only very similar individiuals both for testing and training, you should get high accuracies. Be aware, that each scorer has a large bias (read this recent study). With a bit of bad luck the scorer of the data set you're using has a more extreme bias and generalization will not work very well, as we're basically learning to copy his scoring style. |
Yes Simon, thank you for this reference, the quality of the human scoring on which the automatic scorer is training maybe a main driver for this... but difficult to assess for the varied sleep databases (edfs, shhs, mass, etc) commonly used for machine learning ? Not being an expert in sleep research, I confess that in a first approximation, I would tend to look in the publications or in simulation how easily a given learning structure trains & reaches good training/testing accuracies on the varied sleep databases... but maybe this is more complex than that. |
The biggest problem in my opinion is, that there is no Gold standard and that current sleep staging is just a sub-optimal practice kept alive since the 60s. Probability scores calculated from several raters is the closest we can get to a gold standard, but that's extremely expensive. |
The EDFx sleep database is the one scored with the largest number (4 of them) of human experts ? |
No, see here for details: https://physionet.org/pn4/sleep-edfx/ If you find a database with 4 scorers per record, let me know. |
100% accuracy is certainly overfitting. With sleep data, if you get past 90% accuracy on your training set, you can be sure that you were overfitting. Also numbers on the training set are meaningless. A neural network of sufficient size will always be able to reach 100% accuracy on the training set, simply by "memorizing" the input. This is why you need to report on the validation or even test set. What's your reasoning for using bindsnet? Interesting approach. |
Even if the same accuracy / f1 value is obtained on testing data, the remaining ~30% (4000 30s frames) of the dataset ? (14 000 30sec frames). Overfitting also popped into my mind but these accuracies were reached very early (at 5-6000 frames) in the training (10 000 30sec frames): the SNN hasn't learnt anything from nearly half of the training dataset and was basically already (during the training phase) in a predictive mode (not learning anything). The 50 individuals drawn from the SHHS are very similar (age, BMI, no to mild apnea,...). With the AutoSleepScorer (with 2D convs and a larger sequence = 12 for the RNN) on the two EEG & EOG, I have never exceeded 86% of accuracy & 76% of F1 value, so reaching above 99% (rounded to 100) in less than 1 hour of CPU looked very suspicious to me, also knowing the nature of the dataset itself. |
If this is on hold out data I assume there is some error in your setup. |
Hi Simon,
I am starting to train the CNN/RNN on other sleep databases, and the 1st one is the SHHS database, but I have a doubt about the way to set the channels that are used (channels) and I did this:
Is it the correct way to retain the two available EEG channels 'EEG(sec)' and 'EEG' ? I ask because the script/training is running, so it has recognized/infered the EEG channel(s), but it missed the EOG channels.
Jeff
The text was updated successfully, but these errors were encountered: