{
  "id": 468684,
  "title": "UPDATED - WaveNet Starter Notebook - LB 0.52 - Raw EEG Features Only!",
  "url": "/competitions/hms-harmful-brain-activity-classification/discussion/468684",
  "author_name": "Chris Deotte",
  "post_date": "2024-01-17T15:12:14.215000",
  "votes": 142,
  "comment_count": 47,
  "views": 0,
  "content": "<p>I am excited to have built a successful model which only trains with raw EEG features <a href=\"https://www.kaggle.com/code/cdeotte/wavenet-starter-lb-0-70\" target=\"_blank\">here</a>. This model is WaveNet. WaveNet is a convolution neural network which uses dilations to spread out the convolutions and locate the presence of frequencies in waveforms. The research paper is <a href=\"https://arxiv.org/abs/1609.03499\" target=\"_blank\">here</a>. WaveNet is a powerful model which has contributed to many Kaggle competition winning solutions.</p>\n<h1>Example: How WaveNet Finds 5 Hz</h1>\n<p>When we apply a convolution with <code>kernel_size=3</code> and <code>dilation_rate=20</code> to a raw EEG waveform (that is sampled at 200Hz), then this convolution can detect 5Hz. </p>\n<pre><code>tf.keras.layers.\n</code></pre>\n<p>This is because wherever we apply this convolution, the 3 inspection points of the convolution have the same value when the EEG waveform has 5Hz present. This is show in the two example images below:</p>\n<p><img src=\"https://raw.githubusercontent.com/cdeotte/Kaggle_Images/main/Jan-2024/wave6.png\"><br>\n<img src=\"https://raw.githubusercontent.com/cdeotte/Kaggle_Images/main/Jan-2024/wave7.png\"></p>\n<h1>Butterworth Low-Pass Filter</h1>\n<p>In this competition, we (most likely) are only concerned with brain waves of 20Hz and below. Therefore the presence of brain frequencies above 20Hz will confuse WaveNet. We solve this by applying a butterworth low-pass filter. Below shows examples of using a Butterworth filter with cutoff frequencies 16, 8, 4, 2, 1 for illustration purposes.</p>\n<p><img src=\"https://raw.githubusercontent.com/cdeotte/Kaggle_Images/main/Jan-2024/butter.png\"></p>\n<h1>Example: How Spectrograms Find 5 Hz</h1>\n<p>A spectrogram is an image which represents a raw EEG waveform. Each row of a spectrogram image represents a specific frequency. Therefore to detect 5Hz with a spectrogram image, we simply need to take the mean across the row that represents 5Hz:</p>\n<p><img src=\"https://raw.githubusercontent.com/cdeotte/Kaggle_Images/main/Jan-2024/wave3.png\"></p>\n<h1>Starter Notebook</h1>\n<p>The TensorFlow WaveNet starter notebook is <a href=\"https://www.kaggle.com/code/cdeotte/wavenet-starter-lb-0-70\" target=\"_blank\">here</a>. And the PyTorch version (converted by <a href=\"https://www.kaggle.com/alejopaullier\" target=\"_blank\">@alejopaullier</a> ) is <a href=\"https://www.kaggle.com/competitions/hms-harmful-brain-activity-classification/discussion/477610\" target=\"_blank\">here</a></p>\n<h1>UPDATE</h1>\n<p>In version 5 and 6, we use 2 EEG features and achieve CV 0.91 LB 0.66. In version 7 and 8 we use 8 EEG features and achieve <strong>CV 0.81 LB 0.52</strong>, wow! 🥳. The motivation for version 7 and 8's features is the new Magic Formula described <a href=\"https://www.kaggle.com/competitions/hms-harmful-brain-activity-classification/discussion/469760\" target=\"_blank\">here</a>. The Magic Formula implies that we should process each montage chain separately and then combine the results. The new architecture for WaveNet follows this paradigm.<br>\n<img src=\"https://raw.githubusercontent.com/cdeotte/Kaggle_Images/main/Jan-2024/wave-model.png\"></p>\n<h1>Enjoy</h1>\n<p>Enjoy and happy modeling!</p>",
  "messages": [
    {
      "id": 2606338,
      "postDate": "2024-01-17T15:12:14.217Z",
      "content": "<p>I am excited to have built a successful model which only trains with raw EEG features <a href=\"https://www.kaggle.com/code/cdeotte/wavenet-starter-lb-0-70\" target=\"_blank\">here</a>. This model is WaveNet. WaveNet is a convolution neural network which uses dilations to spread out the convolutions and locate the presence of frequencies in waveforms. The research paper is <a href=\"https://arxiv.org/abs/1609.03499\" target=\"_blank\">here</a>. WaveNet is a powerful model which has contributed to many Kaggle competition winning solutions.</p>\n<h1>Example: How WaveNet Finds 5 Hz</h1>\n<p>When we apply a convolution with <code>kernel_size=3</code> and <code>dilation_rate=20</code> to a raw EEG waveform (that is sampled at 200Hz), then this convolution can detect 5Hz. </p>\n<pre><code>tf.keras.layers.\n</code></pre>\n<p>This is because wherever we apply this convolution, the 3 inspection points of the convolution have the same value when the EEG waveform has 5Hz present. This is show in the two example images below:</p>\n<p><img src=\"https://raw.githubusercontent.com/cdeotte/Kaggle_Images/main/Jan-2024/wave6.png\"><br>\n<img src=\"https://raw.githubusercontent.com/cdeotte/Kaggle_Images/main/Jan-2024/wave7.png\"></p>\n<h1>Butterworth Low-Pass Filter</h1>\n<p>In this competition, we (most likely) are only concerned with brain waves of 20Hz and below. Therefore the presence of brain frequencies above 20Hz will confuse WaveNet. We solve this by applying a butterworth low-pass filter. Below shows examples of using a Butterworth filter with cutoff frequencies 16, 8, 4, 2, 1 for illustration purposes.</p>\n<p><img src=\"https://raw.githubusercontent.com/cdeotte/Kaggle_Images/main/Jan-2024/butter.png\"></p>\n<h1>Example: How Spectrograms Find 5 Hz</h1>\n<p>A spectrogram is an image which represents a raw EEG waveform. Each row of a spectrogram image represents a specific frequency. Therefore to detect 5Hz with a spectrogram image, we simply need to take the mean across the row that represents 5Hz:</p>\n<p><img src=\"https://raw.githubusercontent.com/cdeotte/Kaggle_Images/main/Jan-2024/wave3.png\"></p>\n<h1>Starter Notebook</h1>\n<p>The TensorFlow WaveNet starter notebook is <a href=\"https://www.kaggle.com/code/cdeotte/wavenet-starter-lb-0-70\" target=\"_blank\">here</a>. And the PyTorch version (converted by <a href=\"https://www.kaggle.com/alejopaullier\" target=\"_blank\">@alejopaullier</a> ) is <a href=\"https://www.kaggle.com/competitions/hms-harmful-brain-activity-classification/discussion/477610\" target=\"_blank\">here</a></p>\n<h1>UPDATE</h1>\n<p>In version 5 and 6, we use 2 EEG features and achieve CV 0.91 LB 0.66. In version 7 and 8 we use 8 EEG features and achieve <strong>CV 0.81 LB 0.52</strong>, wow! 🥳. The motivation for version 7 and 8's features is the new Magic Formula described <a href=\"https://www.kaggle.com/competitions/hms-harmful-brain-activity-classification/discussion/469760\" target=\"_blank\">here</a>. The Magic Formula implies that we should process each montage chain separately and then combine the results. The new architecture for WaveNet follows this paradigm.<br>\n<img src=\"https://raw.githubusercontent.com/cdeotte/Kaggle_Images/main/Jan-2024/wave-model.png\"></p>\n<h1>Enjoy</h1>\n<p>Enjoy and happy modeling!</p>",
      "rawMarkdown": "I am excited to have built a successful model which only trains with raw EEG features [here][2]. This model is WaveNet. WaveNet is a convolution neural network which uses dilations to spread out the convolutions and locate the presence of frequencies in waveforms. The research paper is [here][1]. WaveNet is a powerful model which has contributed to many Kaggle competition winning solutions.\n\n# Example: How WaveNet Finds 5 Hz\nWhen we apply a convolution with `kernel_size=3` and `dilation_rate=20` to a raw EEG waveform (that is sampled at 200Hz), then this convolution can detect 5Hz. \n\n    tf.keras.layers.Conv1D(filters, kernel_size=3, dilation_rate=20)\n\nThis is because wherever we apply this convolution, the 3 inspection points of the convolution have the same value when the EEG waveform has 5Hz present. This is show in the two example images below:\n\n![](https://raw.githubusercontent.com/cdeotte/Kaggle_Images/main/Jan-2024/wave6.png)\n![](https://raw.githubusercontent.com/cdeotte/Kaggle_Images/main/Jan-2024/wave7.png)\n\n# Butterworth Low-Pass Filter\nIn this competition, we (most likely) are only concerned with brain waves of 20Hz and below. Therefore the presence of brain frequencies above 20Hz will confuse WaveNet. We solve this by applying a butterworth low-pass filter. Below shows examples of using a Butterworth filter with cutoff frequencies 16, 8, 4, 2, 1 for illustration purposes.\n\n![](https://raw.githubusercontent.com/cdeotte/Kaggle_Images/main/Jan-2024/butter.png)\n\n# Example: How Spectrograms Find 5 Hz\nA spectrogram is an image which represents a raw EEG waveform. Each row of a spectrogram image represents a specific frequency. Therefore to detect 5Hz with a spectrogram image, we simply need to take the mean across the row that represents 5Hz:\n\n![](https://raw.githubusercontent.com/cdeotte/Kaggle_Images/main/Jan-2024/wave3.png)\n\n# Starter Notebook\nThe TensorFlow WaveNet starter notebook is [here][2]. And the PyTorch version (converted by @alejopaullier ) is [here][4]\n\n# UPDATE\nIn version 5 and 6, we use 2 EEG features and achieve CV 0.91 LB 0.66. In version 7 and 8 we use 8 EEG features and achieve **CV 0.81 LB 0.52**, wow! 🥳. The motivation for version 7 and 8's features is the new Magic Formula described [here][3]. The Magic Formula implies that we should process each montage chain separately and then combine the results. The new architecture for WaveNet follows this paradigm.\n![](https://raw.githubusercontent.com/cdeotte/Kaggle_Images/main/Jan-2024/wave-model.png)\n\n# Enjoy\nEnjoy and happy modeling!\n\n[1]: https://arxiv.org/abs/1609.03499\n[2]: https://www.kaggle.com/code/cdeotte/wavenet-starter-lb-0-70\n[3]: https://www.kaggle.com/competitions/hms-harmful-brain-activity-classification/discussion/469760\n[4]: https://www.kaggle.com/competitions/hms-harmful-brain-activity-classification/discussion/477610",
      "votes": 141
    },
    {
      "id": 2616776,
      "postDate": "2024-01-23T20:19:42.880Z",
      "content": "<p><strong>UPDATE</strong> I added more features to WaveNet and updated the architecture. Version 7 and 8 now achieve CV 0.81 LB 0.52. Woohoo!</p>",
      "rawMarkdown": "**UPDATE** I added more features to WaveNet and updated the architecture. Version 7 and 8 now achieve CV 0.81 LB 0.52. Woohoo!",
      "votes": 8,
      "replies": [
        {
          "id": 2616977,
          "postDate": "2024-01-24T02:12:29.097Z",
          "content": "<p>Hi <a href=\"https://www.kaggle.com/cdeotte\" target=\"_blank\">@cdeotte</a>  one clarification required .I see dataloader outputs 10000,8 size but model input is 2000,8 ,why and how it is achieved, not able to figure out..</p>",
          "rawMarkdown": "Hi @cdeotte  one clarification required .I see dataloader outputs 10000,8 size but model input is 2000,8 ,why and how it is achieved, not able to figure out..",
          "votes": 1,
          "replies": [
            {
              "id": 2616983,
              "postDate": "2024-01-24T02:19:28.250Z",
              "content": "<p>The dataloader outputs a downsample, see code below</p>\n<pre><code> ():\n    \n    indexes = .indexes[index*.(index+)*.batch_size]\n    X, y = .__data_generation(indexes)\n     X[,.downsample,], y\n</code></pre>",
              "rawMarkdown": "The dataloader outputs a downsample, see code below\n\n    def __getitem__(self, index):\n        'Generate one batch of data'\n        indexes = self.indexes[index*self.batch_size:(index+1)*self.batch_size]\n        X, y = self.__data_generation(indexes)\n        return X[:,::self.downsample,:], y",
              "votes": 2
            }
          ]
        }
      ]
    },
    {
      "id": 2628498,
      "postDate": "2024-01-31T10:39:23.327Z",
      "content": "<p>Thank you for the Wavenet starter, just improved it from 0.52 to 0.51. Now I'll take a look if I can improve the efficientnet starter. Hopefully I can try an ensemble soon to pierce into the medal region.</p>",
      "rawMarkdown": "Thank you for the Wavenet starter, just improved it from 0.52 to 0.51. Now I'll take a look if I can improve the efficientnet starter. Hopefully I can try an ensemble soon to pierce into the medal region.",
      "votes": 3
    },
    {
      "id": 2611716,
      "postDate": "2024-01-20T23:05:37.543Z",
      "content": "<p>Is WaveNet limited to N frequencies, where N is the number of dilation rates?</p>\n<p>For example, in the WaveNet start notebook <a href=\"https://www.kaggle.com/code/cdeotte/wavenet-starter-lb-0-70\" target=\"_blank\">here</a>, there are 12 dilation rates in the first WaveBlock. I calculated the matched frequencies using <code>def dil2hz(dil_rate): return (200*0.5)/dil_rate</code>. This gives us 12 frequencies.</p>\n<p>Dilation rates: <code>[1, 2, 4, 8, 16, 32, 64, 128, 256, 512, 1024, 2048]</code><br>\nFrequencies: <code>[100.0, 50.0, 25.0, 12.5, 6.25, 3.125, 1.562, 0.781, 0.391, 0.195, 0.098, 0.049]</code></p>\n<p>Can WaveNet identify frequencies other than the 12 above. I am struggling to see how it can identify other frequencies?</p>",
      "rawMarkdown": "Is WaveNet limited to N frequencies, where N is the number of dilation rates?\n\nFor example, in the WaveNet start notebook [here](https://www.kaggle.com/code/cdeotte/wavenet-starter-lb-0-70), there are 12 dilation rates in the first WaveBlock. I calculated the matched frequencies using `def dil2hz(dil_rate): return (200*0.5)/dil_rate`. This gives us 12 frequencies.\n\nDilation rates: `[1, 2, 4, 8, 16, 32, 64, 128, 256, 512, 1024, 2048]`\nFrequencies: `[100.0, 50.0, 25.0, 12.5, 6.25, 3.125, 1.562, 0.781, 0.391, 0.195, 0.098, 0.049]`\n\nCan WaveNet identify frequencies other than the 12 above. I am struggling to see how it can identify other frequencies?",
      "votes": 3,
      "replies": [
        {
          "id": 2614175,
          "postDate": "2024-01-22T13:32:43.590Z",
          "content": "<p>Hi <a href=\"https://www.kaggle.com/brendanartley\" target=\"_blank\">@brendanartley</a> yes it can. Whenever we input a frequency into WaveNet, we will get \"feedback\" from the 12 different convolutions. Even though none of them by itself detects the frequency perfectly, the deep learning model will learn when it see pattern A in convolution 1, and pattern B in convolution 2, and pattern C in convolution 3, etc etc then the frequency is 4Hz or whatever.</p>\n<p>In other words, we can say the \"WaveNet has 12 eyeballs\" and although it doesn't see perfectly. It can deduce any frequency from what it sees with its \"12 eyeballs\". Obviously this is  simplistic explanation, but hopefully you get my point.</p>",
          "rawMarkdown": "Hi @brendanartley yes it can. Whenever we input a frequency into WaveNet, we will get \"feedback\" from the 12 different convolutions. Even though none of them by itself detects the frequency perfectly, the deep learning model will learn when it see pattern A in convolution 1, and pattern B in convolution 2, and pattern C in convolution 3, etc etc then the frequency is 4Hz or whatever.\n\nIn other words, we can say the \"WaveNet has 12 eyeballs\" and although it doesn't see perfectly. It can deduce any frequency from what it sees with its \"12 eyeballs\". Obviously this is  simplistic explanation, but hopefully you get my point.",
          "votes": 5
        }
      ]
    },
    {
      "id": 2607480,
      "postDate": "2024-01-18T08:58:27.007Z",
      "content": "<p><a href=\"https://www.kaggle.com/cdeotte\" target=\"_blank\">@cdeotte</a> Thank you for sharing your thoughts. If we are only interested in frequency &lt;= 20Hz, the sampling rate 200Hz seems much higher than we need. Do you think downsampling, say, to 40Hz is a good way to reduce the data size?</p>",
      "rawMarkdown": "@cdeotte Thank you for sharing your thoughts. If we are only interested in frequency <= 20Hz, the sampling rate 200Hz seems much higher than we need. Do you think downsampling, say, to 40Hz is a good way to reduce the data size?",
      "votes": 3,
      "replies": [
        {
          "id": 2607867,
          "postDate": "2024-01-18T13:38:23.560Z",
          "content": "<p>That's a great idea. We can do <code>data = data[:,::5,:]</code> and reduce data from <code>(batch, 10_000, features)</code> =&gt; <code>(batch, 2_000, features)</code> which is sampling 200Hz =&gt; 40Hz. This will help RNN and Transformers work better (because they don't like sequences of length 10_000.</p>\n<p>We can also try this with WaveNet (i.e. CNN), but CNN can handle longer sequences better than RNN and Transformers.</p>",
          "rawMarkdown": "That's a great idea. We can do `data = data[:,::5,:]` and reduce data from `(batch, 10_000, features)` => `(batch, 2_000, features)` which is sampling 200Hz => 40Hz. This will help RNN and Transformers work better (because they don't like sequences of length 10_000.\n\nWe can also try this with WaveNet (i.e. CNN), but CNN can handle longer sequences better than RNN and Transformers.",
          "votes": 2
        },
        {
          "id": 2608635,
          "postDate": "2024-01-19T01:21:01.473Z",
          "content": "<p>You may wanna filter out the 60Hz (sometimes 50Hz) power line noise with a symmetrical notch filter before downsampling.</p>",
          "rawMarkdown": "You may wanna filter out the 60Hz (sometimes 50Hz) power line noise with a symmetrical notch filter before downsampling.",
          "votes": 4
        },
        {
          "id": 2620300,
          "postDate": "2024-01-26T03:48:56.570Z",
          "content": "<p>Related to <a href=\"https://www.kaggle.com/tolgadincer\" target=\"_blank\">@tolgadincer</a> 's comment, to reduce noise when downsampling to 40 Hz (for a Nyquist frequency of 20 Hz), it woud be good to first do a digital low-pass filter on the 200 Hz data and then apply the <code>data = data[:,::5,:]</code> downsampling. I did a little googling and didn't find what I felt was a good page about it, but the second answer on this <a href=\"https://dsp.stackexchange.com/questions/73161/how-to-apply-an-anti-aliasing-filter-before-downsampling\" target=\"_blank\">Signal Processing Stack Exchange</a> is short and useful:<br>\n\"If you're using scipy.signal and processing signals offline, then you can just use <a href=\"https://docs.scipy.org/doc/scipy/reference/generated/scipy.signal.decimate.html\" target=\"_blank\"><code>decimate</code></a> which handles the filtering for you. It also does zero-phase filtering by default, which you probably want for an EEG signal to avoid shifting the shape of the waveforms? (I know that's desirable for EKG, not sure about EEG.)\" <br>\nNote that even just smoothing by applying a width-5 uniform window, e.g. with <a href=\"https://pandas.pydata.org/docs/reference/api/pandas.Series.rolling.html\" target=\"_blank\">pd.Series.rolling()</a>, is a simple form of lowpass filtering and should improve the downsampling result.</p>",
          "rawMarkdown": "Related to @tolgadincer 's comment, to reduce noise when downsampling to 40 Hz (for a Nyquist frequency of 20 Hz), it woud be good to first do a digital low-pass filter on the 200 Hz data and then apply the `data = data[:,::5,:]` downsampling. I did a little googling and didn't find what I felt was a good page about it, but the second answer on this [Signal Processing Stack Exchange](https://dsp.stackexchange.com/questions/73161/how-to-apply-an-anti-aliasing-filter-before-downsampling) is short and useful:\n\"If you're using scipy.signal and processing signals offline, then you can just use [`decimate`](https://docs.scipy.org/doc/scipy/reference/generated/scipy.signal.decimate.html) which handles the filtering for you. It also does zero-phase filtering by default, which you probably want for an EEG signal to avoid shifting the shape of the waveforms? (I know that's desirable for EKG, not sure about EEG.)\" \nNote that even just smoothing by applying a width-5 uniform window, e.g. with [pd.Series.rolling()](https://pandas.pydata.org/docs/reference/api/pandas.Series.rolling.html), is a simple form of lowpass filtering and should improve the downsampling result.",
          "votes": 5
        }
      ]
    },
    {
      "id": 2606473,
      "postDate": "2024-01-17T16:59:11.763Z",
      "content": "<p>Inb4 final solution is stacked ensemble of 10 seed 10 fold wavenet, efnet, resnet, swim, catboost, transformer, lgb, xgb</p>\n<p>😅 nice to see lots of things work</p>",
      "rawMarkdown": "Inb4 final solution is stacked ensemble of 10 seed 10 fold wavenet, efnet, resnet, swim, catboost, transformer, lgb, xgb\n\n😅 nice to see lots of things work",
      "votes": 3,
      "replies": [
        {
          "id": 2606504,
          "postDate": "2024-01-17T17:26:06.463Z",
          "content": "<p>Haha, yeah. I think mega ensembles will do good in this competition. Also a multimodal model that can take all the data (spectrogram and eeg waveform and stacked over GBT output) and have the benefits of CNN, RNN, self attention will make very strong \"single\" models.</p>",
          "rawMarkdown": "Haha, yeah. I think mega ensembles will do good in this competition. Also a multimodal model that can take all the data (spectrogram and eeg waveform and stacked over GBT output) and have the benefits of CNN, RNN, self attention will make very strong \"single\" models.",
          "votes": 4,
          "replies": [
            {
              "id": 2607285,
              "postDate": "2024-01-18T06:25:27.400Z",
              "content": "<p>Wow, thank you so much for your contribution in this competition, providing so much high-quality open source code for us to learn, especially when I saw that you may use multimodal models, which is a method I can hardly imagine and implement. Although I have not touched them, I am still excited to follow your footsteps to learn them 🥰.</p>",
              "rawMarkdown": "Wow, thank you so much for your contribution in this competition, providing so much high-quality open source code for us to learn, especially when I saw that you may use multimodal models, which is a method I can hardly imagine and implement. Although I have not touched them, I am still excited to follow your footsteps to learn them 🥰.",
              "votes": 1
            }
          ]
        }
      ]
    },
    {
      "id": 2606825,
      "postDate": "2024-01-17T21:42:02.040Z",
      "content": "<p>Great post, thank you! Just curious how you know \"we are only concerned with brain waves of 20Hz and below\"?</p>",
      "rawMarkdown": "Great post, thank you! Just curious how you know \"we are only concerned with brain waves of 20Hz and below\"?",
      "votes": 4,
      "replies": [
        {
          "id": 2606833,
          "postDate": "2024-01-17T21:54:31.657Z",
          "content": "<p>We don't know this for sure. But the current best public notebook uses Kaggle spectrograms. And Kaggle spectrograms only have information for 20Hz and below. I will run some experiments with higher frequencies to see if it helps.</p>",
          "rawMarkdown": "We don't know this for sure. But the current best public notebook uses Kaggle spectrograms. And Kaggle spectrograms only have information for 20Hz and below. I will run some experiments with higher frequencies to see if it helps.",
          "votes": 6,
          "replies": [
            {
              "id": 2606836,
              "postDate": "2024-01-17T21:58:57.823Z",
              "content": "<p>Cool insight, thanks!</p>",
              "rawMarkdown": "Cool insight, thanks!",
              "votes": 1
            },
            {
              "id": 2618192,
              "postDate": "2024-01-24T16:01:32.033Z",
              "content": "<p>Unless I am missing something the events are all &lt; 20Hz</p>",
              "rawMarkdown": "Unless I am missing something the events are all < 20Hz",
              "votes": 2
            }
          ]
        }
      ]
    },
    {
      "id": 2666150,
      "postDate": "2024-02-24T07:12:41.553Z",
      "content": "<p>HI <a href=\"https://www.kaggle.com/cdeotte\" target=\"_blank\">@cdeotte</a> ,</p>\n<p>Thank you as usual for the great notebook.<br>\nI have dabbled with WaveNet previously, but this is a new level of depth.<br>\nAs a sanity check, in your 5 Hz example, how would you fetch the outputs at the \"3 inspection points of the convolution\" to indeed confirm that the values are the same? Do we have to inspect the kernel outputs themselves?</p>",
      "rawMarkdown": "HI @cdeotte ,\n\nThank you as usual for the great notebook.\nI have dabbled with WaveNet previously, but this is a new level of depth.\nAs a sanity check, in your 5 Hz example, how would you fetch the outputs at the \"3 inspection points of the convolution\" to indeed confirm that the values are the same? Do we have to inspect the kernel outputs themselves?\n\n\n\n",
      "votes": 1,
      "replies": [
        {
          "id": 2667255,
          "postDate": "2024-02-25T02:48:00.283Z",
          "content": "<p>Hi, thanks. We do not need to do anything. When we use a convolution with <code>kernel_size = 3</code>, then the model uses 3 inspection points to compute a new value (that it passes to the next layer of our NN model). Without dilation, these 3 points will be consecutive time steps. With dilations, they are spaced as shown in the diagram. The model will do this and learn how to use these 3 points during training.</p>",
          "rawMarkdown": "Hi, thanks. We do not need to do anything. When we use a convolution with `kernel_size = 3`, then the model uses 3 inspection points to compute a new value (that it passes to the next layer of our NN model). Without dilation, these 3 points will be consecutive time steps. With dilations, they are spaced as shown in the diagram. The model will do this and learn how to use these 3 points during training.",
          "votes": 1,
          "replies": [
            {
              "id": 2667267,
              "postDate": "2024-02-25T03:01:15.313Z",
              "content": "<p>Thanks for this, think I had a brainfart over how 1DCNNs work</p>",
              "rawMarkdown": "Thanks for this, think I had a brainfart over how 1DCNNs work",
              "votes": 1
            }
          ]
        }
      ]
    },
    {
      "id": 2607687,
      "postDate": "2024-01-18T11:31:07.327Z",
      "content": "<p>Wow, by reading your discussions I believe there are limitless ways to be creative in this competition, one of the most interesting competitions I've seen in a while for sure. Thank you for sharing :)</p>\n<p><a href=\"https://www.kaggle.com/cdeotte\" target=\"_blank\">@cdeotte</a> you are on fire! Great work yet again!</p>",
      "rawMarkdown": "Wow, by reading your discussions I believe there are limitless ways to be creative in this competition, one of the most interesting competitions I've seen in a while for sure. Thank you for sharing :)\n\n@cdeotte you are on fire! Great work yet again!\n",
      "votes": 1,
      "replies": [
        {
          "id": 2607863,
          "postDate": "2024-01-18T13:36:52.977Z",
          "content": "<p>Yes I love competitions where there are many successful modeling options. This competition will allow for lots of creativity. I'm excited. Enjoy!</p>",
          "rawMarkdown": "Yes I love competitions where there are many successful modeling options. This competition will allow for lots of creativity. I'm excited. Enjoy!",
          "votes": 1
        }
      ]
    },
    {
      "id": 2606501,
      "postDate": "2024-01-17T17:22:18.003Z",
      "content": "<p><a href=\"https://www.kaggle.com/cdeotte\" target=\"_blank\">@cdeotte</a> you are on fire! Great work yet again!</p>",
      "rawMarkdown": "@cdeotte you are on fire! Great work yet again!",
      "votes": 1
    },
    {
      "id": 2606484,
      "postDate": "2024-01-17T17:12:04.523Z",
      "content": "<p>hi <a href=\"https://www.kaggle.com/cdeotte\" target=\"_blank\">@cdeotte</a> , Thank you for sharing. The discussion certainly makes a simpler way to start with the competition although I am sure there is more to it than meets the eye. Thanks!</p>",
      "rawMarkdown": "hi @cdeotte , Thank you for sharing. The discussion certainly makes a simpler way to start with the competition although I am sure there is more to it than meets the eye. Thanks!",
      "votes": 1
    },
    {
      "id": 2606392,
      "postDate": "2024-01-17T15:53:34.420Z",
      "content": "<p>Interesting post. Thanks for all the sharing you have done this competition. </p>\n<p>Why do you think this approach has a large CV/LB gap?</p>",
      "rawMarkdown": "Interesting post. Thanks for all the sharing you have done this competition. \n\nWhy do you think this approach has a large CV/LB gap?",
      "votes": 1,
      "replies": [
        {
          "id": 2606436,
          "postDate": "2024-01-17T16:18:04.030Z",
          "content": "<p>Here are the CV LB of my 4 starter notebooks:</p>\n<table>\n<thead>\n<tr>\n<th>Model</th>\n<th>Data</th>\n<th>CV</th>\n<th>LB</th>\n<th>Gap</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td>EfficientNet</td>\n<td>Spectrogram</td>\n<td>0.72</td>\n<td>0.56</td>\n<td>0.16</td>\n</tr>\n<tr>\n<td>WaveNet</td>\n<td>EEG Waveform</td>\n<td>0.91</td>\n<td>0.66</td>\n<td>0.25</td>\n</tr>\n<tr>\n<td>CatBoost</td>\n<td>Spectrogram</td>\n<td>0.67</td>\n<td>0.82</td>\n<td>0.15</td>\n</tr>\n<tr>\n<td>MLP</td>\n<td>EEG Spectrogram</td>\n<td>1.03</td>\n<td>0.77</td>\n<td>0.26</td>\n</tr>\n</tbody>\n</table>\n<p>Kaggle provides Spectrograms and EEGs. It appears that there is a larger CV LB gap when using EEG features. This may because the EEG features are more \"raw\". Maybe Kaggle standardized the Spectrograms in a way to make them generalize better. </p>",
          "rawMarkdown": "Here are the CV LB of my 4 starter notebooks:\n\n| Model | Data | CV | LB | Gap |\n| --- | --- |\n| EfficientNet | Spectrogram | 0.72 | 0.56 | 0.16 |\n| WaveNet | EEG Waveform | 0.91 | 0.66 | 0.25 |\n| CatBoost | Spectrogram | 0.67 | 0.82 | 0.15 |\n| MLP | EEG Spectrogram | 1.03 | 0.77 | 0.26 |\n\nKaggle provides Spectrograms and EEGs. It appears that there is a larger CV LB gap when using EEG features. This may because the EEG features are more \"raw\". Maybe Kaggle standardized the Spectrograms in a way to make them generalize better. \n",
          "votes": 5,
          "replies": [
            {
              "id": 2606991,
              "postDate": "2024-01-18T02:02:11.577Z",
              "content": "<p><a href=\"https://www.kaggle.com/cdeotte\" target=\"_blank\">@cdeotte</a> If I'm not mistaken, you had posted a discussion post and a notebook of your MLP. Did you delete it, or am I crazy?</p>",
              "rawMarkdown": "@cdeotte If I'm not mistaken, you had posted a discussion post and a notebook of your MLP. Did you delete it, or am I crazy?",
              "votes": 1
            },
            {
              "id": 2606995,
              "postDate": "2024-01-18T02:10:11.430Z",
              "content": "<p>Kaggle deleted it. In the post, I asked for people to view my notebook and upvote my dataset which I learned is against <a href=\"https://www.kaggle.com/community-guidelines\" target=\"_blank\">Community Guidelines</a>. I received a notification in my account and an email reminding me of the rules below:</p>\n<blockquote>\n  <p>Sharing self-promoting posts in other forums or in comments may result in the removal of that content and a warning may be issued to the author.</p>\n  <p>Requesting upvotes or suggesting that other users should view or “check out” your work is considered upvote begging and is not allowed. Comments or posts of this nature may be removed and a warning may be issued to the author.</p>\n</blockquote>",
              "rawMarkdown": "Kaggle deleted it. In the post, I asked for people to view my notebook and upvote my dataset which I learned is against [Community Guidelines][1]. I received a notification in my account and an email reminding me of the rules below:\n\n>Sharing self-promoting posts in other forums or in comments may result in the removal of that content and a warning may be issued to the author.\n\n>Requesting upvotes or suggesting that other users should view or “check out” your work is considered upvote begging and is not allowed. Comments or posts of this nature may be removed and a warning may be issued to the author.\n\n[1]: https://www.kaggle.com/community-guidelines",
              "votes": 3
            },
            {
              "id": 2612951,
              "postDate": "2024-01-21T18:12:18.643Z",
              "content": "<p>Hi <a href=\"https://www.kaggle.com/cdeotte\" target=\"_blank\">@cdeotte</a> . Is it possible that you can publish that notebook again ? It would be very much great if you do it. </p>",
              "rawMarkdown": "Hi @cdeotte . Is it possible that you can publish that notebook again ? It would be very much great if you do it. ",
              "votes": 1
            },
            {
              "id": 2612965,
              "postDate": "2024-01-21T18:20:03.083Z",
              "content": "<p>The notebook still exists, only the discussion post referring to it was deleted. My MLP starter is in version 1-3 of my notebook <a href=\"https://www.kaggle.com/code/cdeotte/how-to-make-spectrogram-from-eeg\" target=\"_blank\">here</a></p>",
              "rawMarkdown": "The notebook still exists, only the discussion post referring to it was deleted. My MLP starter is in version 1-3 of my notebook [here][1]\n\n[1]: https://www.kaggle.com/code/cdeotte/how-to-make-spectrogram-from-eeg",
              "votes": 2
            },
            {
              "id": 2613968,
              "postDate": "2024-01-22T11:23:26.220Z",
              "content": "<p>Thank you so much for this. </p>",
              "rawMarkdown": "Thank you so much for this. "
            }
          ]
        }
      ]
    },
    {
      "id": 2656264,
      "postDate": "2024-02-17T15:06:10.127Z",
      "content": "<p>Hi <a href=\"https://www.kaggle.com/cdeotte\" target=\"_blank\">@cdeotte</a>,</p>\n<p>I'm a beginner exploring your WaveNet implementation and have a question about dilated causal convolutions. While using conv1D, it seems the convolution process considers both past and future values around each point.</p>\n<p>However, the WaveNet paper specifies using dilated causal convolutions, where predictions at each point should only depend on dilated past points. I'm likely missing something in the implementation, and I'd love to hear your thinking about this.</p>\n<p>While we are using WaveNet for brain state classification (not next-point prediction), maybe dilated causal convolution doesn't need to be implemented because also the target is aggregated from multiple samples in preprocessing and it is same for each point in the wave. </p>\n<p>I am asking because through your code I want to understand model more clearly.</p>\n<p>Thank you for sharing your amazing resources!</p>",
      "rawMarkdown": "Hi @cdeotte,\n\nI'm a beginner exploring your WaveNet implementation and have a question about dilated causal convolutions. While using conv1D, it seems the convolution process considers both past and future values around each point.\n\nHowever, the WaveNet paper specifies using dilated causal convolutions, where predictions at each point should only depend on dilated past points. I'm likely missing something in the implementation, and I'd love to hear your thinking about this.\n\nWhile we are using WaveNet for brain state classification (not next-point prediction), maybe dilated causal convolution doesn't need to be implemented because also the target is aggregated from multiple samples in preprocessing and it is same for each point in the wave. \n\nI am asking because through your code I want to understand model more clearly.\n\nThank you for sharing your amazing resources!",
      "votes": 2,
      "replies": [
        {
          "id": 2656272,
          "postDate": "2024-02-17T15:13:22.717Z",
          "content": "<p>If we wanted to detect EEG events in real time (i.e. is there an EEG event happening now in the present moment), then yes we could only use causal convolutions and use past information. However in this competition, that is <strong>not</strong> what Kaggle is asking us to do.</p>\n<p>Kaggle is asking us to use both 5 minutes of <strong>before</strong> information and 5 minutes of <strong>after</strong> information to determine whether there is an EEG event in the middle 10 seconds. Since we have both past and future information, we will use it. Therefore in my WaveNet implementation, I use a convolution that uses both past and future information.</p>",
          "rawMarkdown": "If we wanted to detect EEG events in real time (i.e. is there an EEG event happening now in the present moment), then yes we could only use causal convolutions and use past information. However in this competition, that is **not** what Kaggle is asking us to do.\n\nKaggle is asking us to use both 5 minutes of **before** information and 5 minutes of **after** information to determine whether there is an EEG event in the middle 10 seconds. Since we have both past and future information, we will use it. Therefore in my WaveNet implementation, I use a convolution that uses both past and future information.",
          "votes": 7
        }
      ]
    },
    {
      "id": 2617602,
      "postDate": "2024-01-24T10:43:54.583Z",
      "content": "<p><a href=\"https://www.kaggle.com/cdeotte\" target=\"_blank\">@cdeotte</a>  sorry to bother you. Can you share the resource for wavenet where I can read more about it.</p>",
      "rawMarkdown": "@cdeotte  sorry to bother you. Can you share the resource for wavenet where I can read more about it.",
      "votes": 2,
      "replies": [
        {
          "id": 2619435,
          "postDate": "2024-01-25T12:49:46.550Z",
          "content": "<p>Here is the research paper <a href=\"https://arxiv.org/abs/1609.03499\" target=\"_blank\">here</a></p>",
          "rawMarkdown": "Here is the research paper [here][1]\n\n[1]: https://arxiv.org/abs/1609.03499",
          "votes": 3
        }
      ]
    },
    {
      "id": 2613309,
      "postDate": "2024-01-22T02:15:07.617Z",
      "content": "<p><a href=\"https://www.kaggle.com/cdeotte\" target=\"_blank\">@cdeotte</a> Really appreciate your work and I have some questions. The raw waveform is sampled at 200Hz and <code>dilation_rate</code> is set to <code>20</code>. I thus assume that 10 kernels will be chosen every second. Since every kernel correspond to one phase of a complete wave, I assume this thus corresponds to a <strong>10Hz</strong> wave rather than a <strong>5Hz</strong> wave. I must have misunderstood the illustration in the post😭</p>",
      "rawMarkdown": "@cdeotte Really appreciate your work and I have some questions. The raw waveform is sampled at 200Hz and `dilation_rate` is set to `20`. I thus assume that 10 kernels will be chosen every second. Since every kernel correspond to one phase of a complete wave, I assume this thus corresponds to a **10Hz** wave rather than a **5Hz** wave. I must have misunderstood the illustration in the post😭",
      "votes": 2,
      "replies": [
        {
          "id": 2614167,
          "postDate": "2024-01-22T13:29:01.033Z",
          "content": "<p>Hi. In my diagram, the <code>dilation=20</code> is the distance from the green mid point to the green end point. The diagram shows <code>kernel_size=3</code> which has 1 mid point and two end points. Thus the full length of the convolution is:</p>\n<pre><code> * (kernel_size-) =  * (-) = \n</code></pre>\n<p>So there are <code>5 = 200/40</code> complete kernels when place end to end in one second. So this <code>kernel size = 3</code> with <code>dilation = 20</code> will detect 5Hz. Note it will also detect 10Hz, 15Hz, 20Hz, etc, etc because all multiples of 5Hz will have the same phenomena as having same y value at inspection points.</p>",
          "rawMarkdown": "Hi. In my diagram, the `dilation=20` is the distance from the green mid point to the green end point. The diagram shows `kernel_size=3` which has 1 mid point and two end points. Thus the full length of the convolution is:\n\n    dilation * (kernel_size-1) = 20 * (3-1) = 40\n\nSo there are `5 = 200/40` complete kernels when place end to end in one second. So this `kernel size = 3` with `dilation = 20` will detect 5Hz. Note it will also detect 10Hz, 15Hz, 20Hz, etc, etc because all multiples of 5Hz will have the same phenomena as having same y value at inspection points.",
          "votes": 9
        }
      ]
    },
    {
      "id": 2610489,
      "postDate": "2024-01-20T06:49:25.303Z",
      "content": "<p>Thank you, Chris, for sharing your WaveNet Starter Notebook and its impressive results in leveraging raw EEG features. It's fascinating how you've utilized WaveNet's dilation property to effectively detect specific frequencies in EEG waveforms, and the addition of the Butterworth low-pass filter to refine the model's focus is a smart touch. Your approach offers valuable insights into the capabilities of convolutional neural networks in handling waveform data.</p>\n<p>I'm curious about the potential unexpected outcomes when applying this model in real-world scenarios. Have you encountered any funny or surprising interpretations by the model, especially given the complex and often unpredictable nature of EEG data? Sharing such anecdotes could not only provide a few laughs but also offer valuable lessons for the Kaggle community on the quirks and challenges of working with neural network models and EEG data.</p>\n<p>Best,<br>\nNishant</p>",
      "rawMarkdown": "Thank you, Chris, for sharing your WaveNet Starter Notebook and its impressive results in leveraging raw EEG features. It's fascinating how you've utilized WaveNet's dilation property to effectively detect specific frequencies in EEG waveforms, and the addition of the Butterworth low-pass filter to refine the model's focus is a smart touch. Your approach offers valuable insights into the capabilities of convolutional neural networks in handling waveform data.\n\nI'm curious about the potential unexpected outcomes when applying this model in real-world scenarios. Have you encountered any funny or surprising interpretations by the model, especially given the complex and often unpredictable nature of EEG data? Sharing such anecdotes could not only provide a few laughs but also offer valuable lessons for the Kaggle community on the quirks and challenges of working with neural network models and EEG data.\n\nBest,\nNishant",
      "votes": 2,
      "replies": [
        {
          "id": 2610522,
          "postDate": "2024-01-20T07:21:07.450Z",
          "content": "<p>When building models from raw waveforms (in this comp and past comps), i have found WaveNet to be powerful and successful.</p>",
          "rawMarkdown": "When building models from raw waveforms (in this comp and past comps), i have found WaveNet to be powerful and successful.",
          "votes": 2
        }
      ]
    },
    {
      "id": 2606457,
      "postDate": "2024-01-17T16:39:26.250Z",
      "content": "<p>Wow, by reading your discussions I believe there are limitless ways to be creative in this competition, one of the most interesting competitions I've seen in a while for sure. Thank you for sharing :) </p>",
      "rawMarkdown": "Wow, by reading your discussions I believe there are limitless ways to be creative in this competition, one of the most interesting competitions I've seen in a while for sure. Thank you for sharing :) ",
      "votes": 2,
      "replies": [
        {
          "id": 2606462,
          "postDate": "2024-01-17T16:43:31.317Z",
          "content": "<p>Yes and this is only the beginning. These models are still <strong>simple</strong>. The winning model will take both Spectrograms and EGG Waveforms as input and use sophisticated self attention to allow the model to attend to related parts between Spectrogram and EEG Waveform. </p>",
          "rawMarkdown": "Yes and this is only the beginning. These models are still **simple**. The winning model will take both Spectrograms and EGG Waveforms as input and use sophisticated self attention to allow the model to attend to related parts between Spectrogram and EEG Waveform. ",
          "votes": 4,
          "replies": [
            {
              "id": 2618155,
              "postDate": "2024-01-24T15:36:14.313Z",
              "content": "<p>This contest is so interesting!  maybe the machine learning will pick up subtleties in the raw data that the spectrogram doesn't show? </p>",
              "rawMarkdown": "This contest is so interesting!  maybe the machine learning will pick up subtleties in the raw data that the spectrogram doesn't show? ",
              "votes": 1
            }
          ]
        }
      ]
    },
    {
      "id": 2624942,
      "postDate": "2024-01-29T05:03:16.427Z",
      "rawMarkdown": "",
      "isDeleted": true,
      "replies": [
        {
          "id": 2624944,
          "postDate": "2024-01-29T05:07:35.883Z",
          "rawMarkdown": "",
          "isDeleted": true
        }
      ]
    },
    {
      "id": 2624937,
      "postDate": "2024-01-29T05:01:41.167Z",
      "rawMarkdown": "",
      "isDeleted": true
    },
    {
      "id": 2619361,
      "postDate": "2024-01-25T12:16:39.403Z",
      "rawMarkdown": "",
      "votes": 1,
      "isDeleted": true
    },
    {
      "id": 2606618,
      "postDate": "2024-01-17T18:51:31.273Z",
      "content": "<p><a href=\"https://www.kaggle.com/cdeotte\" target=\"_blank\">@cdeotte</a> Thanks for sharing wavnet</p>",
      "rawMarkdown": "@cdeotte Thanks for sharing wavnet",
      "votes": 2
    }
  ],
  "comments": [
    {
      "id": 2616776,
      "author_name": "Chris Deotte",
      "author_url": "",
      "post_date": "2024-01-23T20:19:42.880000",
      "content": "<p><strong>UPDATE</strong> I added more features to WaveNet and updated the architecture. Version 7 and 8 now achieve CV 0.81 LB 0.52. Woohoo!</p>",
      "votes": 8,
      "replies": [
        {
          "id": 2616977,
          "author_name": "Nirjhar Roy",
          "author_url": "",
          "post_date": "2024-01-24T02:12:29.097000",
          "content": "<p>Hi <a href=\"https://www.kaggle.com/cdeotte\" target=\"_blank\">@cdeotte</a>  one clarification required .I see dataloader outputs 10000,8 size but model input is 2000,8 ,why and how it is achieved, not able to figure out..</p>",
          "votes": 1,
          "replies": [
            {
              "id": 2616983,
              "author_name": "Chris Deotte",
              "author_url": "",
              "post_date": "2024-01-24T02:19:28.250000",
              "content": "<p>The dataloader outputs a downsample, see code below</p>\n<pre><code> ():\n    \n    indexes = .indexes[index*.(index+)*.batch_size]\n    X, y = .__data_generation(indexes)\n     X[,.downsample,], y\n</code></pre>",
              "votes": 2,
              "replies": []
            }
          ]
        }
      ]
    },
    {
      "id": 2628498,
      "author_name": "stefanoclss",
      "author_url": "",
      "post_date": "2024-01-31T10:39:23.327000",
      "content": "<p>Thank you for the Wavenet starter, just improved it from 0.52 to 0.51. Now I'll take a look if I can improve the efficientnet starter. Hopefully I can try an ensemble soon to pierce into the medal region.</p>",
      "votes": 3,
      "replies": []
    },
    {
      "id": 2611716,
      "author_name": "Bartley",
      "author_url": "",
      "post_date": "2024-01-20T23:05:37.543000",
      "content": "<p>Is WaveNet limited to N frequencies, where N is the number of dilation rates?</p>\n<p>For example, in the WaveNet start notebook <a href=\"https://www.kaggle.com/code/cdeotte/wavenet-starter-lb-0-70\" target=\"_blank\">here</a>, there are 12 dilation rates in the first WaveBlock. I calculated the matched frequencies using <code>def dil2hz(dil_rate): return (200*0.5)/dil_rate</code>. This gives us 12 frequencies.</p>\n<p>Dilation rates: <code>[1, 2, 4, 8, 16, 32, 64, 128, 256, 512, 1024, 2048]</code><br>\nFrequencies: <code>[100.0, 50.0, 25.0, 12.5, 6.25, 3.125, 1.562, 0.781, 0.391, 0.195, 0.098, 0.049]</code></p>\n<p>Can WaveNet identify frequencies other than the 12 above. I am struggling to see how it can identify other frequencies?</p>",
      "votes": 3,
      "replies": [
        {
          "id": 2614175,
          "author_name": "Chris Deotte",
          "author_url": "",
          "post_date": "2024-01-22T13:32:43.590000",
          "content": "<p>Hi <a href=\"https://www.kaggle.com/brendanartley\" target=\"_blank\">@brendanartley</a> yes it can. Whenever we input a frequency into WaveNet, we will get \"feedback\" from the 12 different convolutions. Even though none of them by itself detects the frequency perfectly, the deep learning model will learn when it see pattern A in convolution 1, and pattern B in convolution 2, and pattern C in convolution 3, etc etc then the frequency is 4Hz or whatever.</p>\n<p>In other words, we can say the \"WaveNet has 12 eyeballs\" and although it doesn't see perfectly. It can deduce any frequency from what it sees with its \"12 eyeballs\". Obviously this is  simplistic explanation, but hopefully you get my point.</p>",
          "votes": 5,
          "replies": []
        }
      ]
    },
    {
      "id": 2607480,
      "author_name": "Taichi Uemura",
      "author_url": "",
      "post_date": "2024-01-18T08:58:27.007000",
      "content": "<p><a href=\"https://www.kaggle.com/cdeotte\" target=\"_blank\">@cdeotte</a> Thank you for sharing your thoughts. If we are only interested in frequency &lt;= 20Hz, the sampling rate 200Hz seems much higher than we need. Do you think downsampling, say, to 40Hz is a good way to reduce the data size?</p>",
      "votes": 3,
      "replies": [
        {
          "id": 2607867,
          "author_name": "Chris Deotte",
          "author_url": "",
          "post_date": "2024-01-18T13:38:23.560000",
          "content": "<p>That's a great idea. We can do <code>data = data[:,::5,:]</code> and reduce data from <code>(batch, 10_000, features)</code> =&gt; <code>(batch, 2_000, features)</code> which is sampling 200Hz =&gt; 40Hz. This will help RNN and Transformers work better (because they don't like sequences of length 10_000.</p>\n<p>We can also try this with WaveNet (i.e. CNN), but CNN can handle longer sequences better than RNN and Transformers.</p>",
          "votes": 2,
          "replies": []
        },
        {
          "id": 2608635,
          "author_name": "Tolga",
          "author_url": "",
          "post_date": "2024-01-19T01:21:01.473000",
          "content": "<p>You may wanna filter out the 60Hz (sometimes 50Hz) power line noise with a symmetrical notch filter before downsampling.</p>",
          "votes": 4,
          "replies": []
        },
        {
          "id": 2620300,
          "author_name": "Daniel Dewey",
          "author_url": "",
          "post_date": "2024-01-26T03:48:56.570000",
          "content": "<p>Related to <a href=\"https://www.kaggle.com/tolgadincer\" target=\"_blank\">@tolgadincer</a> 's comment, to reduce noise when downsampling to 40 Hz (for a Nyquist frequency of 20 Hz), it woud be good to first do a digital low-pass filter on the 200 Hz data and then apply the <code>data = data[:,::5,:]</code> downsampling. I did a little googling and didn't find what I felt was a good page about it, but the second answer on this <a href=\"https://dsp.stackexchange.com/questions/73161/how-to-apply-an-anti-aliasing-filter-before-downsampling\" target=\"_blank\">Signal Processing Stack Exchange</a> is short and useful:<br>\n\"If you're using scipy.signal and processing signals offline, then you can just use <a href=\"https://docs.scipy.org/doc/scipy/reference/generated/scipy.signal.decimate.html\" target=\"_blank\"><code>decimate</code></a> which handles the filtering for you. It also does zero-phase filtering by default, which you probably want for an EEG signal to avoid shifting the shape of the waveforms? (I know that's desirable for EKG, not sure about EEG.)\" <br>\nNote that even just smoothing by applying a width-5 uniform window, e.g. with <a href=\"https://pandas.pydata.org/docs/reference/api/pandas.Series.rolling.html\" target=\"_blank\">pd.Series.rolling()</a>, is a simple form of lowpass filtering and should improve the downsampling result.</p>",
          "votes": 5,
          "replies": []
        }
      ]
    },
    {
      "id": 2606473,
      "author_name": "JM",
      "author_url": "",
      "post_date": "2024-01-17T16:59:11.763000",
      "content": "<p>Inb4 final solution is stacked ensemble of 10 seed 10 fold wavenet, efnet, resnet, swim, catboost, transformer, lgb, xgb</p>\n<p>😅 nice to see lots of things work</p>",
      "votes": 3,
      "replies": [
        {
          "id": 2606504,
          "author_name": "Chris Deotte",
          "author_url": "",
          "post_date": "2024-01-17T17:26:06.463000",
          "content": "<p>Haha, yeah. I think mega ensembles will do good in this competition. Also a multimodal model that can take all the data (spectrogram and eeg waveform and stacked over GBT output) and have the benefits of CNN, RNN, self attention will make very strong \"single\" models.</p>",
          "votes": 4,
          "replies": [
            {
              "id": 2607285,
              "author_name": "Orzlala",
              "author_url": "",
              "post_date": "2024-01-18T06:25:27.400000",
              "content": "<p>Wow, thank you so much for your contribution in this competition, providing so much high-quality open source code for us to learn, especially when I saw that you may use multimodal models, which is a method I can hardly imagine and implement. Although I have not touched them, I am still excited to follow your footsteps to learn them 🥰.</p>",
              "votes": 1,
              "replies": []
            }
          ]
        }
      ]
    },
    {
      "id": 2606825,
      "author_name": "mk0052",
      "author_url": "",
      "post_date": "2024-01-17T21:42:02.040000",
      "content": "<p>Great post, thank you! Just curious how you know \"we are only concerned with brain waves of 20Hz and below\"?</p>",
      "votes": 4,
      "replies": [
        {
          "id": 2606833,
          "author_name": "Chris Deotte",
          "author_url": "",
          "post_date": "2024-01-17T21:54:31.657000",
          "content": "<p>We don't know this for sure. But the current best public notebook uses Kaggle spectrograms. And Kaggle spectrograms only have information for 20Hz and below. I will run some experiments with higher frequencies to see if it helps.</p>",
          "votes": 6,
          "replies": [
            {
              "id": 2606836,
              "author_name": "mk0052",
              "author_url": "",
              "post_date": "2024-01-17T21:58:57.823000",
              "content": "<p>Cool insight, thanks!</p>",
              "votes": 1,
              "replies": []
            },
            {
              "id": 2618192,
              "author_name": "Edward Tuck",
              "author_url": "",
              "post_date": "2024-01-24T16:01:32.033000",
              "content": "<p>Unless I am missing something the events are all &lt; 20Hz</p>",
              "votes": 2,
              "replies": []
            }
          ]
        }
      ]
    },
    {
      "id": 2666150,
      "author_name": "Yijie Xu",
      "author_url": "",
      "post_date": "2024-02-24T07:12:41.553000",
      "content": "<p>HI <a href=\"https://www.kaggle.com/cdeotte\" target=\"_blank\">@cdeotte</a> ,</p>\n<p>Thank you as usual for the great notebook.<br>\nI have dabbled with WaveNet previously, but this is a new level of depth.<br>\nAs a sanity check, in your 5 Hz example, how would you fetch the outputs at the \"3 inspection points of the convolution\" to indeed confirm that the values are the same? Do we have to inspect the kernel outputs themselves?</p>",
      "votes": 1,
      "replies": [
        {
          "id": 2667255,
          "author_name": "Chris Deotte",
          "author_url": "",
          "post_date": "2024-02-25T02:48:00.283000",
          "content": "<p>Hi, thanks. We do not need to do anything. When we use a convolution with <code>kernel_size = 3</code>, then the model uses 3 inspection points to compute a new value (that it passes to the next layer of our NN model). Without dilation, these 3 points will be consecutive time steps. With dilations, they are spaced as shown in the diagram. The model will do this and learn how to use these 3 points during training.</p>",
          "votes": 1,
          "replies": [
            {
              "id": 2667267,
              "author_name": "Yijie Xu",
              "author_url": "",
              "post_date": "2024-02-25T03:01:15.313000",
              "content": "<p>Thanks for this, think I had a brainfart over how 1DCNNs work</p>",
              "votes": 1,
              "replies": []
            }
          ]
        }
      ]
    },
    {
      "id": 2607687,
      "author_name": "Tanishq dublish",
      "author_url": "",
      "post_date": "2024-01-18T11:31:07.327000",
      "content": "<p>Wow, by reading your discussions I believe there are limitless ways to be creative in this competition, one of the most interesting competitions I've seen in a while for sure. Thank you for sharing :)</p>\n<p><a href=\"https://www.kaggle.com/cdeotte\" target=\"_blank\">@cdeotte</a> you are on fire! Great work yet again!</p>",
      "votes": 1,
      "replies": [
        {
          "id": 2607863,
          "author_name": "Chris Deotte",
          "author_url": "",
          "post_date": "2024-01-18T13:36:52.977000",
          "content": "<p>Yes I love competitions where there are many successful modeling options. This competition will allow for lots of creativity. I'm excited. Enjoy!</p>",
          "votes": 1,
          "replies": []
        }
      ]
    },
    {
      "id": 2606501,
      "author_name": "Cody_Null",
      "author_url": "",
      "post_date": "2024-01-17T17:22:18.003000",
      "content": "<p><a href=\"https://www.kaggle.com/cdeotte\" target=\"_blank\">@cdeotte</a> you are on fire! Great work yet again!</p>",
      "votes": 1,
      "replies": []
    },
    {
      "id": 2606484,
      "author_name": "supplejade",
      "author_url": "",
      "post_date": "2024-01-17T17:12:04.523000",
      "content": "<p>hi <a href=\"https://www.kaggle.com/cdeotte\" target=\"_blank\">@cdeotte</a> , Thank you for sharing. The discussion certainly makes a simpler way to start with the competition although I am sure there is more to it than meets the eye. Thanks!</p>",
      "votes": 1,
      "replies": []
    },
    {
      "id": 2606392,
      "author_name": "Bartley",
      "author_url": "",
      "post_date": "2024-01-17T15:53:34.420000",
      "content": "<p>Interesting post. Thanks for all the sharing you have done this competition. </p>\n<p>Why do you think this approach has a large CV/LB gap?</p>",
      "votes": 1,
      "replies": [
        {
          "id": 2606436,
          "author_name": "Chris Deotte",
          "author_url": "",
          "post_date": "2024-01-17T16:18:04.030000",
          "content": "<p>Here are the CV LB of my 4 starter notebooks:</p>\n<table>\n<thead>\n<tr>\n<th>Model</th>\n<th>Data</th>\n<th>CV</th>\n<th>LB</th>\n<th>Gap</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td>EfficientNet</td>\n<td>Spectrogram</td>\n<td>0.72</td>\n<td>0.56</td>\n<td>0.16</td>\n</tr>\n<tr>\n<td>WaveNet</td>\n<td>EEG Waveform</td>\n<td>0.91</td>\n<td>0.66</td>\n<td>0.25</td>\n</tr>\n<tr>\n<td>CatBoost</td>\n<td>Spectrogram</td>\n<td>0.67</td>\n<td>0.82</td>\n<td>0.15</td>\n</tr>\n<tr>\n<td>MLP</td>\n<td>EEG Spectrogram</td>\n<td>1.03</td>\n<td>0.77</td>\n<td>0.26</td>\n</tr>\n</tbody>\n</table>\n<p>Kaggle provides Spectrograms and EEGs. It appears that there is a larger CV LB gap when using EEG features. This may because the EEG features are more \"raw\". Maybe Kaggle standardized the Spectrograms in a way to make them generalize better. </p>",
          "votes": 5,
          "replies": [
            {
              "id": 2606991,
              "author_name": "Yan Teixeira",
              "author_url": "",
              "post_date": "2024-01-18T02:02:11.577000",
              "content": "<p><a href=\"https://www.kaggle.com/cdeotte\" target=\"_blank\">@cdeotte</a> If I'm not mistaken, you had posted a discussion post and a notebook of your MLP. Did you delete it, or am I crazy?</p>",
              "votes": 1,
              "replies": []
            },
            {
              "id": 2606995,
              "author_name": "Chris Deotte",
              "author_url": "",
              "post_date": "2024-01-18T02:10:11.430000",
              "content": "<p>Kaggle deleted it. In the post, I asked for people to view my notebook and upvote my dataset which I learned is against <a href=\"https://www.kaggle.com/community-guidelines\" target=\"_blank\">Community Guidelines</a>. I received a notification in my account and an email reminding me of the rules below:</p>\n<blockquote>\n  <p>Sharing self-promoting posts in other forums or in comments may result in the removal of that content and a warning may be issued to the author.</p>\n  <p>Requesting upvotes or suggesting that other users should view or “check out” your work is considered upvote begging and is not allowed. Comments or posts of this nature may be removed and a warning may be issued to the author.</p>\n</blockquote>",
              "votes": 3,
              "replies": []
            },
            {
              "id": 2612951,
              "author_name": "JamshaidSohail",
              "author_url": "",
              "post_date": "2024-01-21T18:12:18.643000",
              "content": "<p>Hi <a href=\"https://www.kaggle.com/cdeotte\" target=\"_blank\">@cdeotte</a> . Is it possible that you can publish that notebook again ? It would be very much great if you do it. </p>",
              "votes": 1,
              "replies": []
            },
            {
              "id": 2612965,
              "author_name": "Chris Deotte",
              "author_url": "",
              "post_date": "2024-01-21T18:20:03.083000",
              "content": "<p>The notebook still exists, only the discussion post referring to it was deleted. My MLP starter is in version 1-3 of my notebook <a href=\"https://www.kaggle.com/code/cdeotte/how-to-make-spectrogram-from-eeg\" target=\"_blank\">here</a></p>",
              "votes": 2,
              "replies": []
            },
            {
              "id": 2613968,
              "author_name": "JamshaidSohail",
              "author_url": "",
              "post_date": "2024-01-22T11:23:26.220000",
              "content": "<p>Thank you so much for this. </p>",
              "votes": 0,
              "replies": []
            }
          ]
        }
      ]
    },
    {
      "id": 2656264,
      "author_name": "Matej Duvnjak",
      "author_url": "",
      "post_date": "2024-02-17T15:06:10.127000",
      "content": "<p>Hi <a href=\"https://www.kaggle.com/cdeotte\" target=\"_blank\">@cdeotte</a>,</p>\n<p>I'm a beginner exploring your WaveNet implementation and have a question about dilated causal convolutions. While using conv1D, it seems the convolution process considers both past and future values around each point.</p>\n<p>However, the WaveNet paper specifies using dilated causal convolutions, where predictions at each point should only depend on dilated past points. I'm likely missing something in the implementation, and I'd love to hear your thinking about this.</p>\n<p>While we are using WaveNet for brain state classification (not next-point prediction), maybe dilated causal convolution doesn't need to be implemented because also the target is aggregated from multiple samples in preprocessing and it is same for each point in the wave. </p>\n<p>I am asking because through your code I want to understand model more clearly.</p>\n<p>Thank you for sharing your amazing resources!</p>",
      "votes": 2,
      "replies": [
        {
          "id": 2656272,
          "author_name": "Chris Deotte",
          "author_url": "",
          "post_date": "2024-02-17T15:13:22.717000",
          "content": "<p>If we wanted to detect EEG events in real time (i.e. is there an EEG event happening now in the present moment), then yes we could only use causal convolutions and use past information. However in this competition, that is <strong>not</strong> what Kaggle is asking us to do.</p>\n<p>Kaggle is asking us to use both 5 minutes of <strong>before</strong> information and 5 minutes of <strong>after</strong> information to determine whether there is an EEG event in the middle 10 seconds. Since we have both past and future information, we will use it. Therefore in my WaveNet implementation, I use a convolution that uses both past and future information.</p>",
          "votes": 7,
          "replies": []
        }
      ]
    },
    {
      "id": 2617602,
      "author_name": "Shashank Shukla",
      "author_url": "",
      "post_date": "2024-01-24T10:43:54.583000",
      "content": "<p><a href=\"https://www.kaggle.com/cdeotte\" target=\"_blank\">@cdeotte</a>  sorry to bother you. Can you share the resource for wavenet where I can read more about it.</p>",
      "votes": 2,
      "replies": [
        {
          "id": 2619435,
          "author_name": "Chris Deotte",
          "author_url": "",
          "post_date": "2024-01-25T12:49:46.550000",
          "content": "<p>Here is the research paper <a href=\"https://arxiv.org/abs/1609.03499\" target=\"_blank\">here</a></p>",
          "votes": 3,
          "replies": []
        }
      ]
    },
    {
      "id": 2613309,
      "author_name": "Roy Wei",
      "author_url": "",
      "post_date": "2024-01-22T02:15:07.617000",
      "content": "<p><a href=\"https://www.kaggle.com/cdeotte\" target=\"_blank\">@cdeotte</a> Really appreciate your work and I have some questions. The raw waveform is sampled at 200Hz and <code>dilation_rate</code> is set to <code>20</code>. I thus assume that 10 kernels will be chosen every second. Since every kernel correspond to one phase of a complete wave, I assume this thus corresponds to a <strong>10Hz</strong> wave rather than a <strong>5Hz</strong> wave. I must have misunderstood the illustration in the post😭</p>",
      "votes": 2,
      "replies": [
        {
          "id": 2614167,
          "author_name": "Chris Deotte",
          "author_url": "",
          "post_date": "2024-01-22T13:29:01.033000",
          "content": "<p>Hi. In my diagram, the <code>dilation=20</code> is the distance from the green mid point to the green end point. The diagram shows <code>kernel_size=3</code> which has 1 mid point and two end points. Thus the full length of the convolution is:</p>\n<pre><code> * (kernel_size-) =  * (-) = \n</code></pre>\n<p>So there are <code>5 = 200/40</code> complete kernels when place end to end in one second. So this <code>kernel size = 3</code> with <code>dilation = 20</code> will detect 5Hz. Note it will also detect 10Hz, 15Hz, 20Hz, etc, etc because all multiples of 5Hz will have the same phenomena as having same y value at inspection points.</p>",
          "votes": 9,
          "replies": []
        }
      ]
    },
    {
      "id": 2610489,
      "author_name": "Nishant Singhal",
      "author_url": "",
      "post_date": "2024-01-20T06:49:25.303000",
      "content": "<p>Thank you, Chris, for sharing your WaveNet Starter Notebook and its impressive results in leveraging raw EEG features. It's fascinating how you've utilized WaveNet's dilation property to effectively detect specific frequencies in EEG waveforms, and the addition of the Butterworth low-pass filter to refine the model's focus is a smart touch. Your approach offers valuable insights into the capabilities of convolutional neural networks in handling waveform data.</p>\n<p>I'm curious about the potential unexpected outcomes when applying this model in real-world scenarios. Have you encountered any funny or surprising interpretations by the model, especially given the complex and often unpredictable nature of EEG data? Sharing such anecdotes could not only provide a few laughs but also offer valuable lessons for the Kaggle community on the quirks and challenges of working with neural network models and EEG data.</p>\n<p>Best,<br>\nNishant</p>",
      "votes": 2,
      "replies": [
        {
          "id": 2610522,
          "author_name": "Chris Deotte",
          "author_url": "",
          "post_date": "2024-01-20T07:21:07.450000",
          "content": "<p>When building models from raw waveforms (in this comp and past comps), i have found WaveNet to be powerful and successful.</p>",
          "votes": 2,
          "replies": []
        }
      ]
    },
    {
      "id": 2606457,
      "author_name": "Catharis",
      "author_url": "",
      "post_date": "2024-01-17T16:39:26.250000",
      "content": "<p>Wow, by reading your discussions I believe there are limitless ways to be creative in this competition, one of the most interesting competitions I've seen in a while for sure. Thank you for sharing :) </p>",
      "votes": 2,
      "replies": [
        {
          "id": 2606462,
          "author_name": "Chris Deotte",
          "author_url": "",
          "post_date": "2024-01-17T16:43:31.317000",
          "content": "<p>Yes and this is only the beginning. These models are still <strong>simple</strong>. The winning model will take both Spectrograms and EGG Waveforms as input and use sophisticated self attention to allow the model to attend to related parts between Spectrogram and EEG Waveform. </p>",
          "votes": 4,
          "replies": [
            {
              "id": 2618155,
              "author_name": "Edward Tuck",
              "author_url": "",
              "post_date": "2024-01-24T15:36:14.313000",
              "content": "<p>This contest is so interesting!  maybe the machine learning will pick up subtleties in the raw data that the spectrogram doesn't show? </p>",
              "votes": 1,
              "replies": []
            }
          ]
        }
      ]
    },
    {
      "id": 2624942,
      "author_name": "",
      "author_url": "",
      "post_date": "2024-01-29T05:03:16.427000",
      "content": "",
      "votes": 0,
      "replies": [
        {
          "id": 2624944,
          "author_name": "",
          "author_url": "",
          "post_date": "2024-01-29T05:07:35.883000",
          "content": "",
          "votes": 0,
          "replies": []
        }
      ]
    },
    {
      "id": 2624937,
      "author_name": "",
      "author_url": "",
      "post_date": "2024-01-29T05:01:41.167000",
      "content": "",
      "votes": 0,
      "replies": []
    },
    {
      "id": 2619361,
      "author_name": "",
      "author_url": "",
      "post_date": "2024-01-25T12:16:39.403000",
      "content": "",
      "votes": 1,
      "replies": []
    },
    {
      "id": 2606618,
      "author_name": "SeshuRaju 🧘‍♂️",
      "author_url": "",
      "post_date": "2024-01-17T18:51:31.273000",
      "content": "<p><a href=\"https://www.kaggle.com/cdeotte\" target=\"_blank\">@cdeotte</a> Thanks for sharing wavnet</p>",
      "votes": 2,
      "replies": []
    }
  ],
  "raw_markdown_by_id": {
    "2606338": "I am excited to have built a successful model which only trains with raw EEG features [here][2]. This model is WaveNet. WaveNet is a convolution neural network which uses dilations to spread out the convolutions and locate the presence of frequencies in waveforms. The research paper is [here][1]. WaveNet is a powerful model which has contributed to many Kaggle competition winning solutions.\n\n# Example: How WaveNet Finds 5 Hz\nWhen we apply a convolution with `kernel_size=3` and `dilation_rate=20` to a raw EEG waveform (that is sampled at 200Hz), then this convolution can detect 5Hz. \n\n    tf.keras.layers.Conv1D(filters, kernel_size=3, dilation_rate=20)\n\nThis is because wherever we apply this convolution, the 3 inspection points of the convolution have the same value when the EEG waveform has 5Hz present. This is show in the two example images below:\n\n![](https://raw.githubusercontent.com/cdeotte/Kaggle_Images/main/Jan-2024/wave6.png)\n![](https://raw.githubusercontent.com/cdeotte/Kaggle_Images/main/Jan-2024/wave7.png)\n\n# Butterworth Low-Pass Filter\nIn this competition, we (most likely) are only concerned with brain waves of 20Hz and below. Therefore the presence of brain frequencies above 20Hz will confuse WaveNet. We solve this by applying a butterworth low-pass filter. Below shows examples of using a Butterworth filter with cutoff frequencies 16, 8, 4, 2, 1 for illustration purposes.\n\n![](https://raw.githubusercontent.com/cdeotte/Kaggle_Images/main/Jan-2024/butter.png)\n\n# Example: How Spectrograms Find 5 Hz\nA spectrogram is an image which represents a raw EEG waveform. Each row of a spectrogram image represents a specific frequency. Therefore to detect 5Hz with a spectrogram image, we simply need to take the mean across the row that represents 5Hz:\n\n![](https://raw.githubusercontent.com/cdeotte/Kaggle_Images/main/Jan-2024/wave3.png)\n\n# Starter Notebook\nThe TensorFlow WaveNet starter notebook is [here][2]. And the PyTorch version (converted by @alejopaullier ) is [here][4]\n\n# UPDATE\nIn version 5 and 6, we use 2 EEG features and achieve CV 0.91 LB 0.66. In version 7 and 8 we use 8 EEG features and achieve **CV 0.81 LB 0.52**, wow! 🥳. The motivation for version 7 and 8's features is the new Magic Formula described [here][3]. The Magic Formula implies that we should process each montage chain separately and then combine the results. The new architecture for WaveNet follows this paradigm.\n![](https://raw.githubusercontent.com/cdeotte/Kaggle_Images/main/Jan-2024/wave-model.png)\n\n# Enjoy\nEnjoy and happy modeling!\n\n[1]: https://arxiv.org/abs/1609.03499\n[2]: https://www.kaggle.com/code/cdeotte/wavenet-starter-lb-0-70\n[3]: https://www.kaggle.com/competitions/hms-harmful-brain-activity-classification/discussion/469760\n[4]: https://www.kaggle.com/competitions/hms-harmful-brain-activity-classification/discussion/477610",
    "2616776": "**UPDATE** I added more features to WaveNet and updated the architecture. Version 7 and 8 now achieve CV 0.81 LB 0.52. Woohoo!",
    "2628498": "Thank you for the Wavenet starter, just improved it from 0.52 to 0.51. Now I'll take a look if I can improve the efficientnet starter. Hopefully I can try an ensemble soon to pierce into the medal region.",
    "2611716": "Is WaveNet limited to N frequencies, where N is the number of dilation rates?\n\nFor example, in the WaveNet start notebook [here](https://www.kaggle.com/code/cdeotte/wavenet-starter-lb-0-70), there are 12 dilation rates in the first WaveBlock. I calculated the matched frequencies using `def dil2hz(dil_rate): return (200*0.5)/dil_rate`. This gives us 12 frequencies.\n\nDilation rates: `[1, 2, 4, 8, 16, 32, 64, 128, 256, 512, 1024, 2048]`\nFrequencies: `[100.0, 50.0, 25.0, 12.5, 6.25, 3.125, 1.562, 0.781, 0.391, 0.195, 0.098, 0.049]`\n\nCan WaveNet identify frequencies other than the 12 above. I am struggling to see how it can identify other frequencies?",
    "2607480": "@cdeotte Thank you for sharing your thoughts. If we are only interested in frequency <= 20Hz, the sampling rate 200Hz seems much higher than we need. Do you think downsampling, say, to 40Hz is a good way to reduce the data size?",
    "2606473": "Inb4 final solution is stacked ensemble of 10 seed 10 fold wavenet, efnet, resnet, swim, catboost, transformer, lgb, xgb\n\n😅 nice to see lots of things work",
    "2606825": "Great post, thank you! Just curious how you know \"we are only concerned with brain waves of 20Hz and below\"?",
    "2666150": "HI @cdeotte ,\n\nThank you as usual for the great notebook.\nI have dabbled with WaveNet previously, but this is a new level of depth.\nAs a sanity check, in your 5 Hz example, how would you fetch the outputs at the \"3 inspection points of the convolution\" to indeed confirm that the values are the same? Do we have to inspect the kernel outputs themselves?\n\n\n\n",
    "2607687": "Wow, by reading your discussions I believe there are limitless ways to be creative in this competition, one of the most interesting competitions I've seen in a while for sure. Thank you for sharing :)\n\n@cdeotte you are on fire! Great work yet again!\n",
    "2606501": "@cdeotte you are on fire! Great work yet again!",
    "2606484": "hi @cdeotte , Thank you for sharing. The discussion certainly makes a simpler way to start with the competition although I am sure there is more to it than meets the eye. Thanks!",
    "2606392": "Interesting post. Thanks for all the sharing you have done this competition. \n\nWhy do you think this approach has a large CV/LB gap?",
    "2656264": "Hi @cdeotte,\n\nI'm a beginner exploring your WaveNet implementation and have a question about dilated causal convolutions. While using conv1D, it seems the convolution process considers both past and future values around each point.\n\nHowever, the WaveNet paper specifies using dilated causal convolutions, where predictions at each point should only depend on dilated past points. I'm likely missing something in the implementation, and I'd love to hear your thinking about this.\n\nWhile we are using WaveNet for brain state classification (not next-point prediction), maybe dilated causal convolution doesn't need to be implemented because also the target is aggregated from multiple samples in preprocessing and it is same for each point in the wave. \n\nI am asking because through your code I want to understand model more clearly.\n\nThank you for sharing your amazing resources!",
    "2617602": "@cdeotte  sorry to bother you. Can you share the resource for wavenet where I can read more about it.",
    "2613309": "@cdeotte Really appreciate your work and I have some questions. The raw waveform is sampled at 200Hz and `dilation_rate` is set to `20`. I thus assume that 10 kernels will be chosen every second. Since every kernel correspond to one phase of a complete wave, I assume this thus corresponds to a **10Hz** wave rather than a **5Hz** wave. I must have misunderstood the illustration in the post😭",
    "2610489": "Thank you, Chris, for sharing your WaveNet Starter Notebook and its impressive results in leveraging raw EEG features. It's fascinating how you've utilized WaveNet's dilation property to effectively detect specific frequencies in EEG waveforms, and the addition of the Butterworth low-pass filter to refine the model's focus is a smart touch. Your approach offers valuable insights into the capabilities of convolutional neural networks in handling waveform data.\n\nI'm curious about the potential unexpected outcomes when applying this model in real-world scenarios. Have you encountered any funny or surprising interpretations by the model, especially given the complex and often unpredictable nature of EEG data? Sharing such anecdotes could not only provide a few laughs but also offer valuable lessons for the Kaggle community on the quirks and challenges of working with neural network models and EEG data.\n\nBest,\nNishant",
    "2606457": "Wow, by reading your discussions I believe there are limitless ways to be creative in this competition, one of the most interesting competitions I've seen in a while for sure. Thank you for sharing :) ",
    "2624942": "",
    "2624937": "",
    "2619361": "",
    "2606618": "@cdeotte Thanks for sharing wavnet"
  }
}