{
  "id": 459761,
  "title": "27th solution",
  "url": "/competitions/child-mind-institute-detect-sleep-states/discussion/459761",
  "author_name": "tenten",
  "post_date": "2023-12-06T14:36:51.535000",
  "votes": 5,
  "comment_count": 0,
  "views": 0,
  "content": "<p>I implemented this solution based on <a href=\"https://www.kaggle.com/tubotubo\" target=\"_blank\">@tubotubo</a>'s source code. Thank you for sharing!</p>\n<h2>Input</h2>\n<ul>\n<li>anglez（normalized）</li>\n<li>enmo（normalized）</li>\n<li>hour_sin</li>\n<li>hour_cos</li>\n<li>minute_sin</li>\n<li>minute_cos</li>\n</ul>\n<h2>Model</h2>\n<ul>\n<li><p>Label</p>\n<ol>\n<li>awake<ul>\n<li>BCEWithLogitsLoss</li></ul></li>\n<li>onset, wakeup<ul>\n<li>BCEWithLogitsLoss</li></ul></li></ol>\n<ul>\n<li>loss = (awake loss) * (1 - 0.88) + (onset, wakeup loss) * 0.88</li></ul></li>\n<li><p>Data Augmentation</p>\n<ul>\n<li>GaussianNoise<ul>\n<li>min_amplitude: 0.01</li>\n<li>max_amplitude: 0.1</li></ul></li>\n<li><a href=\"https://www.kaggle.com/competitions/g2net-gravitational-wave-detection/discussion/275335\" target=\"_blank\">Zebra Mixup</a></li></ul></li>\n<li><p>encoder: UNet</p>\n<table>\n<thead>\n<tr>\n<th>feature extractor</th>\n<th>decoder</th>\n<th>downsample</th>\n<th>CV</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td>LSTM</td>\n<td>UNet1D</td>\n<td>2</td>\n<td>0.7611</td>\n</tr>\n<tr>\n<td>CNN</td>\n<td>UNet1D</td>\n<td>2</td>\n<td>0.7628</td>\n</tr>\n<tr>\n<td>Spectrogram</td>\n<td>UNet1D</td>\n<td>2</td>\n<td>0.7463</td>\n</tr>\n<tr>\n<td>CNN</td>\n<td>Transformer</td>\n<td>6</td>\n<td>0.7480</td>\n</tr>\n<tr>\n<td>Spectrogram</td>\n<td>Transformer</td>\n<td>6</td>\n<td>0.7725</td>\n</tr>\n<tr>\n<td>2CNN+ time feature embedding</td>\n<td>UNet1D</td>\n<td>2</td>\n<td>0.7705</td>\n</tr>\n</tbody>\n</table></li>\n<li><p>2CNN+time feature embedding</p>\n<ul>\n<li>anglez and enmo are input separately into CNN feature extractors</li>\n<li>In this model, month, hour, and minute are input as categorical variables.</li>\n<li>month, hour and minute are converted into embeddings and concatenated with the encoder output before being input to the decoder.</li></ul></li>\n</ul>\n<pre><code>month = self.month_embedding(month) \nhour = self.hour_embedding(hour) \nminute = self.minute_embedding(minute) \nx = x[:, :, :] \nx1 = self.feature_extractor1(x[:, :x.shape[]//, :])  \nx2 = self.feature_extractor2(x[:, x.shape[]//:, :])  \nx = torch.cat([x1, x2], dim=) \n\nx = self.encoder(x).squeeze()  \nx = torch.cat([x, month, hour, minute], dim=) \nlogits = self.decoder(x)  \n</code></pre>\n<h2>PostProcess</h2>\n<ul>\n<li>scipy.signal find peaks (after ensemble)<ul>\n<li>Chose the smallest possible value for height (0.003)</li>\n<li>distance optimized with optuna</li></ul></li>\n<li>overlap inference</li>\n</ul>\n<h2>Ensemble</h2>\n<ul>\n<li>4fold * 6model</li>\n<li>Ensemble with weighted output heatmaps</li>\n<li>Weights optimized with optuna<ul>\n<li>ensemble (mean) -&gt; cv: 0.795</li>\n<li>ensemble (weighted mean) -&gt; cv: 0.7981 (public: 0.753 private: 0.809)</li></ul></li>\n</ul>",
  "messages": [
    {
      "id": 2551188,
      "postDate": "2023-12-06T14:36:51.537Z",
      "content": "<p>I implemented this solution based on <a href=\"https://www.kaggle.com/tubotubo\" target=\"_blank\">@tubotubo</a>'s source code. Thank you for sharing!</p>\n<h2>Input</h2>\n<ul>\n<li>anglez（normalized）</li>\n<li>enmo（normalized）</li>\n<li>hour_sin</li>\n<li>hour_cos</li>\n<li>minute_sin</li>\n<li>minute_cos</li>\n</ul>\n<h2>Model</h2>\n<ul>\n<li><p>Label</p>\n<ol>\n<li>awake<ul>\n<li>BCEWithLogitsLoss</li></ul></li>\n<li>onset, wakeup<ul>\n<li>BCEWithLogitsLoss</li></ul></li></ol>\n<ul>\n<li>loss = (awake loss) * (1 - 0.88) + (onset, wakeup loss) * 0.88</li></ul></li>\n<li><p>Data Augmentation</p>\n<ul>\n<li>GaussianNoise<ul>\n<li>min_amplitude: 0.01</li>\n<li>max_amplitude: 0.1</li></ul></li>\n<li><a href=\"https://www.kaggle.com/competitions/g2net-gravitational-wave-detection/discussion/275335\" target=\"_blank\">Zebra Mixup</a></li></ul></li>\n<li><p>encoder: UNet</p>\n<table>\n<thead>\n<tr>\n<th>feature extractor</th>\n<th>decoder</th>\n<th>downsample</th>\n<th>CV</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td>LSTM</td>\n<td>UNet1D</td>\n<td>2</td>\n<td>0.7611</td>\n</tr>\n<tr>\n<td>CNN</td>\n<td>UNet1D</td>\n<td>2</td>\n<td>0.7628</td>\n</tr>\n<tr>\n<td>Spectrogram</td>\n<td>UNet1D</td>\n<td>2</td>\n<td>0.7463</td>\n</tr>\n<tr>\n<td>CNN</td>\n<td>Transformer</td>\n<td>6</td>\n<td>0.7480</td>\n</tr>\n<tr>\n<td>Spectrogram</td>\n<td>Transformer</td>\n<td>6</td>\n<td>0.7725</td>\n</tr>\n<tr>\n<td>2CNN+ time feature embedding</td>\n<td>UNet1D</td>\n<td>2</td>\n<td>0.7705</td>\n</tr>\n</tbody>\n</table></li>\n<li><p>2CNN+time feature embedding</p>\n<ul>\n<li>anglez and enmo are input separately into CNN feature extractors</li>\n<li>In this model, month, hour, and minute are input as categorical variables.</li>\n<li>month, hour and minute are converted into embeddings and concatenated with the encoder output before being input to the decoder.</li></ul></li>\n</ul>\n<pre><code>month = self.month_embedding(month) \nhour = self.hour_embedding(hour) \nminute = self.minute_embedding(minute) \nx = x[:, :, :] \nx1 = self.feature_extractor1(x[:, :x.shape[]//, :])  \nx2 = self.feature_extractor2(x[:, x.shape[]//:, :])  \nx = torch.cat([x1, x2], dim=) \n\nx = self.encoder(x).squeeze()  \nx = torch.cat([x, month, hour, minute], dim=) \nlogits = self.decoder(x)  \n</code></pre>\n<h2>PostProcess</h2>\n<ul>\n<li>scipy.signal find peaks (after ensemble)<ul>\n<li>Chose the smallest possible value for height (0.003)</li>\n<li>distance optimized with optuna</li></ul></li>\n<li>overlap inference</li>\n</ul>\n<h2>Ensemble</h2>\n<ul>\n<li>4fold * 6model</li>\n<li>Ensemble with weighted output heatmaps</li>\n<li>Weights optimized with optuna<ul>\n<li>ensemble (mean) -&gt; cv: 0.795</li>\n<li>ensemble (weighted mean) -&gt; cv: 0.7981 (public: 0.753 private: 0.809)</li></ul></li>\n</ul>",
      "rawMarkdown": "I implemented this solution based on @tubotubo's source code. Thank you for sharing!\n\n## Input\n- anglez（normalized）\n- enmo（normalized）\n- hour_sin\n- hour_cos\n- minute_sin\n- minute_cos\n\n## Model\n- Label\n    1. awake\n        - BCEWithLogitsLoss\n    2. onset, wakeup\n        - BCEWithLogitsLoss\n    - loss = (awake loss) * (1 - 0.88) + (onset, wakeup loss) * 0.88\n\n- Data Augmentation\n    - GaussianNoise\n        - min_amplitude: 0.01\n        - max_amplitude: 0.1\n    - [Zebra Mixup](https://www.kaggle.com/competitions/g2net-gravitational-wave-detection/discussion/275335)\n\n- encoder: UNet\n| feature extractor | decoder | downsample | CV |\n| --- | --- | --- | --- |\n| LSTM | UNet1D | 2 | 0.7611 |\n| CNN | UNet1D | 2 | 0.7628 |\n| Spectrogram | UNet1D | 2 | 0.7463 |\n| CNN | Transformer | 6 | 0.7480 |\n| Spectrogram | Transformer | 6 | 0.7725 |\n| 2CNN+ time feature embedding | UNet1D | 2 | 0.7705 |\n\n- 2CNN+time feature embedding\n  - anglez and enmo are input separately into CNN feature extractors\n  - In this model, month, hour, and minute are input as categorical variables.\n  - month, hour and minute are converted into embeddings and concatenated with the encoder output before being input to the decoder.\n\n```python\nmonth = self.month_embedding(month) # (batch_size, 4, n_timesteps)\nhour = self.hour_embedding(hour) # (batch_size, 8, n_timesteps)\nminute = self.minute_embedding(minute) # (batch_size, 16, n_timesteps)\nx = x[:, 3:, :] # (batch_size, n_channels, n_timesteps)\nx1 = self.feature_extractor1(x[:, :x.shape[1]//2, :])  # (batch_size, n_kernel, height, n_timesteps)\nx2 = self.feature_extractor2(x[:, x.shape[1]//2:, :])  # (batch_size, n_kernel, height, n_timesteps)\nx = torch.cat([x1, x2], dim=2) # (batch_size, n_kernel, height*2, n_timesteps)\n\nx = self.encoder(x).squeeze(1)  # (batch_size, height, n_timesteps)\nx = torch.cat([x, month, hour, minute], dim=1) # (batch_size, height+28, n_timesteps)\nlogits = self.decoder(x)  # (batch_size, n_timesteps, n_classes)\n```\n\n## PostProcess\n- scipy.signal find peaks (after ensemble)\n    - Chose the smallest possible value for height (0.003)\n    - distance optimized with optuna\n- overlap inference\n\n## Ensemble\n- 4fold * 6model\n- Ensemble with weighted output heatmaps\n- Weights optimized with optuna\n  - ensemble (mean) -> cv: 0.795\n  - ensemble (weighted mean) -> cv: 0.7981 (public: 0.753 private: 0.809)\n\n",
      "votes": 5
    }
  ],
  "comments": [],
  "raw_markdown_by_id": {
    "2551188": "I implemented this solution based on @tubotubo's source code. Thank you for sharing!\n\n## Input\n- anglez（normalized）\n- enmo（normalized）\n- hour_sin\n- hour_cos\n- minute_sin\n- minute_cos\n\n## Model\n- Label\n    1. awake\n        - BCEWithLogitsLoss\n    2. onset, wakeup\n        - BCEWithLogitsLoss\n    - loss = (awake loss) * (1 - 0.88) + (onset, wakeup loss) * 0.88\n\n- Data Augmentation\n    - GaussianNoise\n        - min_amplitude: 0.01\n        - max_amplitude: 0.1\n    - [Zebra Mixup](https://www.kaggle.com/competitions/g2net-gravitational-wave-detection/discussion/275335)\n\n- encoder: UNet\n| feature extractor | decoder | downsample | CV |\n| --- | --- | --- | --- |\n| LSTM | UNet1D | 2 | 0.7611 |\n| CNN | UNet1D | 2 | 0.7628 |\n| Spectrogram | UNet1D | 2 | 0.7463 |\n| CNN | Transformer | 6 | 0.7480 |\n| Spectrogram | Transformer | 6 | 0.7725 |\n| 2CNN+ time feature embedding | UNet1D | 2 | 0.7705 |\n\n- 2CNN+time feature embedding\n  - anglez and enmo are input separately into CNN feature extractors\n  - In this model, month, hour, and minute are input as categorical variables.\n  - month, hour and minute are converted into embeddings and concatenated with the encoder output before being input to the decoder.\n\n```python\nmonth = self.month_embedding(month) # (batch_size, 4, n_timesteps)\nhour = self.hour_embedding(hour) # (batch_size, 8, n_timesteps)\nminute = self.minute_embedding(minute) # (batch_size, 16, n_timesteps)\nx = x[:, 3:, :] # (batch_size, n_channels, n_timesteps)\nx1 = self.feature_extractor1(x[:, :x.shape[1]//2, :])  # (batch_size, n_kernel, height, n_timesteps)\nx2 = self.feature_extractor2(x[:, x.shape[1]//2:, :])  # (batch_size, n_kernel, height, n_timesteps)\nx = torch.cat([x1, x2], dim=2) # (batch_size, n_kernel, height*2, n_timesteps)\n\nx = self.encoder(x).squeeze(1)  # (batch_size, height, n_timesteps)\nx = torch.cat([x, month, hour, minute], dim=1) # (batch_size, height+28, n_timesteps)\nlogits = self.decoder(x)  # (batch_size, n_timesteps, n_classes)\n```\n\n## PostProcess\n- scipy.signal find peaks (after ensemble)\n    - Chose the smallest possible value for height (0.003)\n    - distance optimized with optuna\n- overlap inference\n\n## Ensemble\n- 4fold * 6model\n- Ensemble with weighted output heatmaps\n- Weights optimized with optuna\n  - ensemble (mean) -> cv: 0.795\n  - ensemble (weighted mean) -> cv: 0.7981 (public: 0.753 private: 0.809)\n\n"
  }
}