{
  "id": 459632,
  "title": "33th Place Solution - 1D-Unet with GRU, Detect repeating signals",
  "url": "/competitions/child-mind-institute-detect-sleep-states/discussion/459632",
  "author_name": "kfuji",
  "post_date": "2023-12-06T04:08:48.569000",
  "votes": 23,
  "comment_count": 0,
  "views": 0,
  "content": "<p>First of all, we express our gratitude to the hosting team for organizing this intriguing competition.</p>\n<p>This was my first chance to tackle the challenge of event detection, and I gained valuable insights from participating in this competition.</p>\n<h1>Team Member</h1>\n<p><a href=\"https://www.kaggle.com/sugupoko\" target=\"_blank\">@sugupoko</a></p>\n<h1>Overview and Summary</h1>\n<p><img src=\"https://www.googleapis.com/download/storage/v1/b/kaggle-forum-message-attachments/o/inbox%2F8448924%2F15564725296900e1f17b99106f400e06%2Fcmi_overview.png?generation=1701834611847219&amp;alt=media\" alt=\"\"><br>\nWe utilized <a href=\"https://www.kaggle.com/tubotubo\" target=\"_blank\">@tubotubo</a> 's excellent notebook and code, implementing the following improvements. </p>\n<ul>\n<li>Ensemble (Multi Duration, Multi Encoder Model)</li>\n<li>Insert BiGRU into 1D-Unet</li>\n<li>​Parameter tuning for scipy.signal.find_peaks.</li>\n<li>Detect and repeating signals</li>\n</ul>\n<p>I will explain these approaches in the order in which we tackled them in this competition.</p>\n<h1>Ensemble</h1>\n<p>In this event detection task, we speculated that accurate predictions could be achieved by ensemble averaging the outputs of multiple models. Therefore, we applied the following ensemble approach:</p>\n<h3>Multi Duration</h3>\n<p>We trained models with input durations of 8 hours (5760 steps), 16 hours (11520 steps), and 24 hours (17280 steps). During inference, we took the average of the outputs from these models.\"</p>\n<h3>Multi Encoder Model</h3>\n<p>For the encoder model, we adopted timm-gernet-l, resnext101, and se-resnet50, and averaged the outputs of these three models, similar to the duration ensemble.</p>\n<h1>Insert BiGRU into skip connection of 1D-Unet</h1>\n<p>With the idea from <a href=\"https://www.kaggle.com/sugupoko\" target=\"_blank\">@sugupoko</a>, we inserted BiGRU into the skip connections of the 1D-Unet decoder. We believe that this has improved the prediction accuracy in the temporal dimension.</p>\n<h1>Parameter tuning for scipy.signal.find_peaks</h1>\n<p>While conducting several experiments, we noticed that the parameters of the <code>scipy.signal.find_peaks</code> function, used in post-processing, have an impact on accuracy. <br>\nInitially, we lowered the <code>height</code> (score_th) to 0.001, as setting a lower threshold is advantageous in terms of the evaluation metric for this competition. Subsequently, we adjusted the <code>distance</code> to 65. This parameter determines the distance between peaks, and we are confident that setting an appropriate value helped reduce false positives.</p>\n<h1>Detect repeating signals</h1>\n<p>While analyzing the data, we noticed that some input data contained unnatural periodic signals. In many cases, these signals lacked event labels and could potentially be a cause of false positives.<br>\nWe didn't understand the reason for the presence of such signals, but we found that they occurred approximately every 24 hours (17280 steps). Therefore, we attempted to remove these repeating signals using a rule-based approach.<br>\nWe created a function to detect repeating signals as follows. We segmented the anglez data at intervals of 17280 steps, calculating the correlation coefficient between the previous and current segments. If this correlation coefficient exceeded a certain threshold, it was determined to be a repeating signal. By invalidating the model output for the detected repeating segments, we were able to significantly reduce false positives.</p>\n<pre><code>def (series_id, cycle_length=, cor_th=, phase='test'):​\n    anglez = np.(f)​\n    ​\n    valid_area = np.(anglez.shape[])​\n    x1_list = ((, anglez.shape[], cycle_length))​\n    pre_anglez = np.(cycle_length)​\n    for x1 in x1_list:​\n        x2 = x1 + cycle_length​\n        cur_anglez = anglez[x1:x2]​\n        ​\n        if (cur_anglez) &lt; cycle_length:​\n            cur_anglez = np.(cur_anglez, (, cycle_length - (cur_anglez)), constant_values=)​\n        ​\n        correlation_coefficient_anglez = np.(pre_anglez, cur_anglez)[, ]​\n        ​\n        if correlation_coefficient_anglez &gt; cor_th:​\n            valid_area[x1-cycle_length:x2] = ​\n        ​\n        pre_anglez = cur_anglez​\n        ​\n    return valid_area\n</code></pre>\n<p><img src=\"https://www.googleapis.com/download/storage/v1/b/kaggle-forum-message-attachments/o/inbox%2F8448924%2F901ddaca907928fafc411dd08c7163e3%2Fdetect_repeating_signals.png?generation=1701834185197721&amp;alt=media\" alt=\"\"></p>\n<h1>Transition of LB Scores:</h1>\n<ul>\n<li>Baseline : 0.707​</li>\n<li>(5fold ensemble: 0.730)​</li>\n<li>Multi duration ensemble :0.745​</li>\n<li>Multi encoder model ensemble : 0.746​</li>\n<li>Insert BiGRU into 1D-Unet : 0.756​</li>\n<li>Parameter tuning for scipy.signal.find_peaks : 0.759​</li>\n<li>Detect repeating signals:0.764</li>\n</ul>\n<h1>Things that didn't go well:</h1>\n<ul>\n<li>Utilize sleep state prediction</li>\n<li>Ensemble longer and shorter durations</li>\n</ul>",
  "messages": [
    {
      "id": 2550478,
      "postDate": "2023-12-06T04:08:48.570Z",
      "content": "<p>First of all, we express our gratitude to the hosting team for organizing this intriguing competition.</p>\n<p>This was my first chance to tackle the challenge of event detection, and I gained valuable insights from participating in this competition.</p>\n<h1>Team Member</h1>\n<p><a href=\"https://www.kaggle.com/sugupoko\" target=\"_blank\">@sugupoko</a></p>\n<h1>Overview and Summary</h1>\n<p><img src=\"https://www.googleapis.com/download/storage/v1/b/kaggle-forum-message-attachments/o/inbox%2F8448924%2F15564725296900e1f17b99106f400e06%2Fcmi_overview.png?generation=1701834611847219&amp;alt=media\" alt=\"\"><br>\nWe utilized <a href=\"https://www.kaggle.com/tubotubo\" target=\"_blank\">@tubotubo</a> 's excellent notebook and code, implementing the following improvements. </p>\n<ul>\n<li>Ensemble (Multi Duration, Multi Encoder Model)</li>\n<li>Insert BiGRU into 1D-Unet</li>\n<li>​Parameter tuning for scipy.signal.find_peaks.</li>\n<li>Detect and repeating signals</li>\n</ul>\n<p>I will explain these approaches in the order in which we tackled them in this competition.</p>\n<h1>Ensemble</h1>\n<p>In this event detection task, we speculated that accurate predictions could be achieved by ensemble averaging the outputs of multiple models. Therefore, we applied the following ensemble approach:</p>\n<h3>Multi Duration</h3>\n<p>We trained models with input durations of 8 hours (5760 steps), 16 hours (11520 steps), and 24 hours (17280 steps). During inference, we took the average of the outputs from these models.\"</p>\n<h3>Multi Encoder Model</h3>\n<p>For the encoder model, we adopted timm-gernet-l, resnext101, and se-resnet50, and averaged the outputs of these three models, similar to the duration ensemble.</p>\n<h1>Insert BiGRU into skip connection of 1D-Unet</h1>\n<p>With the idea from <a href=\"https://www.kaggle.com/sugupoko\" target=\"_blank\">@sugupoko</a>, we inserted BiGRU into the skip connections of the 1D-Unet decoder. We believe that this has improved the prediction accuracy in the temporal dimension.</p>\n<h1>Parameter tuning for scipy.signal.find_peaks</h1>\n<p>While conducting several experiments, we noticed that the parameters of the <code>scipy.signal.find_peaks</code> function, used in post-processing, have an impact on accuracy. <br>\nInitially, we lowered the <code>height</code> (score_th) to 0.001, as setting a lower threshold is advantageous in terms of the evaluation metric for this competition. Subsequently, we adjusted the <code>distance</code> to 65. This parameter determines the distance between peaks, and we are confident that setting an appropriate value helped reduce false positives.</p>\n<h1>Detect repeating signals</h1>\n<p>While analyzing the data, we noticed that some input data contained unnatural periodic signals. In many cases, these signals lacked event labels and could potentially be a cause of false positives.<br>\nWe didn't understand the reason for the presence of such signals, but we found that they occurred approximately every 24 hours (17280 steps). Therefore, we attempted to remove these repeating signals using a rule-based approach.<br>\nWe created a function to detect repeating signals as follows. We segmented the anglez data at intervals of 17280 steps, calculating the correlation coefficient between the previous and current segments. If this correlation coefficient exceeded a certain threshold, it was determined to be a repeating signal. By invalidating the model output for the detected repeating segments, we were able to significantly reduce false positives.</p>\n<pre><code>def (series_id, cycle_length=, cor_th=, phase='test'):​\n    anglez = np.(f)​\n    ​\n    valid_area = np.(anglez.shape[])​\n    x1_list = ((, anglez.shape[], cycle_length))​\n    pre_anglez = np.(cycle_length)​\n    for x1 in x1_list:​\n        x2 = x1 + cycle_length​\n        cur_anglez = anglez[x1:x2]​\n        ​\n        if (cur_anglez) &lt; cycle_length:​\n            cur_anglez = np.(cur_anglez, (, cycle_length - (cur_anglez)), constant_values=)​\n        ​\n        correlation_coefficient_anglez = np.(pre_anglez, cur_anglez)[, ]​\n        ​\n        if correlation_coefficient_anglez &gt; cor_th:​\n            valid_area[x1-cycle_length:x2] = ​\n        ​\n        pre_anglez = cur_anglez​\n        ​\n    return valid_area\n</code></pre>\n<p><img src=\"https://www.googleapis.com/download/storage/v1/b/kaggle-forum-message-attachments/o/inbox%2F8448924%2F901ddaca907928fafc411dd08c7163e3%2Fdetect_repeating_signals.png?generation=1701834185197721&amp;alt=media\" alt=\"\"></p>\n<h1>Transition of LB Scores:</h1>\n<ul>\n<li>Baseline : 0.707​</li>\n<li>(5fold ensemble: 0.730)​</li>\n<li>Multi duration ensemble :0.745​</li>\n<li>Multi encoder model ensemble : 0.746​</li>\n<li>Insert BiGRU into 1D-Unet : 0.756​</li>\n<li>Parameter tuning for scipy.signal.find_peaks : 0.759​</li>\n<li>Detect repeating signals:0.764</li>\n</ul>\n<h1>Things that didn't go well:</h1>\n<ul>\n<li>Utilize sleep state prediction</li>\n<li>Ensemble longer and shorter durations</li>\n</ul>",
      "rawMarkdown": "First of all, we express our gratitude to the hosting team for organizing this intriguing competition.\n\nThis was my first chance to tackle the challenge of event detection, and I gained valuable insights from participating in this competition.\n\n# Team Member\n@sugupoko\n\n# Overview and Summary\n![](https://www.googleapis.com/download/storage/v1/b/kaggle-forum-message-attachments/o/inbox%2F8448924%2F15564725296900e1f17b99106f400e06%2Fcmi_overview.png?generation=1701834611847219&alt=media)\nWe utilized @tubotubo 's excellent notebook and code, implementing the following improvements. \n- Ensemble (Multi Duration, Multi Encoder Model)\n- Insert BiGRU into 1D-Unet\n- ​Parameter tuning for scipy.signal.find_peaks.\n- Detect and repeating signals\n\nI will explain these approaches in the order in which we tackled them in this competition.\n\n# Ensemble\nIn this event detection task, we speculated that accurate predictions could be achieved by ensemble averaging the outputs of multiple models. Therefore, we applied the following ensemble approach:\n### Multi Duration\nWe trained models with input durations of 8 hours (5760 steps), 16 hours (11520 steps), and 24 hours (17280 steps). During inference, we took the average of the outputs from these models.\"\n\n### Multi Encoder Model\nFor the encoder model, we adopted timm-gernet-l, resnext101, and se-resnet50, and averaged the outputs of these three models, similar to the duration ensemble.\n\n# Insert BiGRU into skip connection of 1D-Unet\nWith the idea from @sugupoko, we inserted BiGRU into the skip connections of the 1D-Unet decoder. We believe that this has improved the prediction accuracy in the temporal dimension.\n\n# Parameter tuning for scipy.signal.find_peaks\nWhile conducting several experiments, we noticed that the parameters of the `scipy.signal.find_peaks` function, used in post-processing, have an impact on accuracy. \nInitially, we lowered the `height` (score_th) to 0.001, as setting a lower threshold is advantageous in terms of the evaluation metric for this competition. Subsequently, we adjusted the `distance` to 65. This parameter determines the distance between peaks, and we are confident that setting an appropriate value helped reduce false positives.\n\n# Detect repeating signals\nWhile analyzing the data, we noticed that some input data contained unnatural periodic signals. In many cases, these signals lacked event labels and could potentially be a cause of false positives.\nWe didn't understand the reason for the presence of such signals, but we found that they occurred approximately every 24 hours (17280 steps). Therefore, we attempted to remove these repeating signals using a rule-based approach.\nWe created a function to detect repeating signals as follows. We segmented the anglez data at intervals of 17280 steps, calculating the correlation coefficient between the previous and current segments. If this correlation coefficient exceeded a certain threshold, it was determined to be a repeating signal. By invalidating the model output for the detected repeating segments, we were able to significantly reduce false positives.\n\n```\ndef detect_repeated_area(series_id, cycle_length=17280, cor_th=0.8, phase='test'):​\n    anglez = np.load(f\"{CFG.processed_dir}/{phase}/{series_id}/anglez.npy\")​\n    ​\n    valid_area = np.ones(anglez.shape[0])​\n    x1_list = list(range(0, anglez.shape[0], cycle_length))​\n    pre_anglez = np.zeros(cycle_length)​\n    for x1 in x1_list:​\n        x2 = x1 + cycle_length​\n        cur_anglez = anglez[x1:x2]​\n        ​\n        if len(cur_anglez) < cycle_length:​\n            cur_anglez = np.pad(cur_anglez, (0, cycle_length - len(cur_anglez)), constant_values=0.0)​\n        ​\n        correlation_coefficient_anglez = np.corrcoef(pre_anglez, cur_anglez)[0, 1]​\n        ​\n        if correlation_coefficient_anglez > cor_th:​\n            valid_area[x1-cycle_length:x2] = 0​\n        ​\n        pre_anglez = cur_anglez​\n        ​\n    return valid_area\n```\n![](https://www.googleapis.com/download/storage/v1/b/kaggle-forum-message-attachments/o/inbox%2F8448924%2F901ddaca907928fafc411dd08c7163e3%2Fdetect_repeating_signals.png?generation=1701834185197721&alt=media)\n\n# Transition of LB Scores: \n- Baseline : 0.707​\n- (5fold ensemble: 0.730)​\n- Multi duration ensemble :0.745​\n- Multi encoder model ensemble : 0.746​\n- Insert BiGRU into 1D-Unet : 0.756​\n- Parameter tuning for scipy.signal.find_peaks : 0.759​\n- Detect repeating signals:0.764\n\n# Things that didn't go well:\n- Utilize sleep state prediction\n- Ensemble longer and shorter durations",
      "votes": 23
    }
  ],
  "comments": [],
  "raw_markdown_by_id": {
    "2550478": "First of all, we express our gratitude to the hosting team for organizing this intriguing competition.\n\nThis was my first chance to tackle the challenge of event detection, and I gained valuable insights from participating in this competition.\n\n# Team Member\n@sugupoko\n\n# Overview and Summary\n![](https://www.googleapis.com/download/storage/v1/b/kaggle-forum-message-attachments/o/inbox%2F8448924%2F15564725296900e1f17b99106f400e06%2Fcmi_overview.png?generation=1701834611847219&alt=media)\nWe utilized @tubotubo 's excellent notebook and code, implementing the following improvements. \n- Ensemble (Multi Duration, Multi Encoder Model)\n- Insert BiGRU into 1D-Unet\n- ​Parameter tuning for scipy.signal.find_peaks.\n- Detect and repeating signals\n\nI will explain these approaches in the order in which we tackled them in this competition.\n\n# Ensemble\nIn this event detection task, we speculated that accurate predictions could be achieved by ensemble averaging the outputs of multiple models. Therefore, we applied the following ensemble approach:\n### Multi Duration\nWe trained models with input durations of 8 hours (5760 steps), 16 hours (11520 steps), and 24 hours (17280 steps). During inference, we took the average of the outputs from these models.\"\n\n### Multi Encoder Model\nFor the encoder model, we adopted timm-gernet-l, resnext101, and se-resnet50, and averaged the outputs of these three models, similar to the duration ensemble.\n\n# Insert BiGRU into skip connection of 1D-Unet\nWith the idea from @sugupoko, we inserted BiGRU into the skip connections of the 1D-Unet decoder. We believe that this has improved the prediction accuracy in the temporal dimension.\n\n# Parameter tuning for scipy.signal.find_peaks\nWhile conducting several experiments, we noticed that the parameters of the `scipy.signal.find_peaks` function, used in post-processing, have an impact on accuracy. \nInitially, we lowered the `height` (score_th) to 0.001, as setting a lower threshold is advantageous in terms of the evaluation metric for this competition. Subsequently, we adjusted the `distance` to 65. This parameter determines the distance between peaks, and we are confident that setting an appropriate value helped reduce false positives.\n\n# Detect repeating signals\nWhile analyzing the data, we noticed that some input data contained unnatural periodic signals. In many cases, these signals lacked event labels and could potentially be a cause of false positives.\nWe didn't understand the reason for the presence of such signals, but we found that they occurred approximately every 24 hours (17280 steps). Therefore, we attempted to remove these repeating signals using a rule-based approach.\nWe created a function to detect repeating signals as follows. We segmented the anglez data at intervals of 17280 steps, calculating the correlation coefficient between the previous and current segments. If this correlation coefficient exceeded a certain threshold, it was determined to be a repeating signal. By invalidating the model output for the detected repeating segments, we were able to significantly reduce false positives.\n\n```\ndef detect_repeated_area(series_id, cycle_length=17280, cor_th=0.8, phase='test'):​\n    anglez = np.load(f\"{CFG.processed_dir}/{phase}/{series_id}/anglez.npy\")​\n    ​\n    valid_area = np.ones(anglez.shape[0])​\n    x1_list = list(range(0, anglez.shape[0], cycle_length))​\n    pre_anglez = np.zeros(cycle_length)​\n    for x1 in x1_list:​\n        x2 = x1 + cycle_length​\n        cur_anglez = anglez[x1:x2]​\n        ​\n        if len(cur_anglez) < cycle_length:​\n            cur_anglez = np.pad(cur_anglez, (0, cycle_length - len(cur_anglez)), constant_values=0.0)​\n        ​\n        correlation_coefficient_anglez = np.corrcoef(pre_anglez, cur_anglez)[0, 1]​\n        ​\n        if correlation_coefficient_anglez > cor_th:​\n            valid_area[x1-cycle_length:x2] = 0​\n        ​\n        pre_anglez = cur_anglez​\n        ​\n    return valid_area\n```\n![](https://www.googleapis.com/download/storage/v1/b/kaggle-forum-message-attachments/o/inbox%2F8448924%2F901ddaca907928fafc411dd08c7163e3%2Fdetect_repeating_signals.png?generation=1701834185197721&alt=media)\n\n# Transition of LB Scores: \n- Baseline : 0.707​\n- (5fold ensemble: 0.730)​\n- Multi duration ensemble :0.745​\n- Multi encoder model ensemble : 0.746​\n- Insert BiGRU into 1D-Unet : 0.756​\n- Parameter tuning for scipy.signal.find_peaks : 0.759​\n- Detect repeating signals:0.764\n\n# Things that didn't go well:\n- Utilize sleep state prediction\n- Ensemble longer and shorter durations"
  },
  "complete": true,
  "source": "existing_discussion",
  "competition_id": 53666,
  "competition_slug": "child-mind-institute-detect-sleep-states",
  "team_id": 11105569,
  "solution_url": "/competitions/child-mind-institute-detect-sleep-states/writeups/kfuji-sugupoko-33th-place-solution-1d-unet-with-gr"
}