{
  "id": 391088,
  "title": "66th (LB 10th) solution: k-means for background noise reduction ",
  "url": "/competitions/rsna-breast-cancer-detection/discussion/391088",
  "author_name": "taruto",
  "post_date": "2023-02-28T11:10:17.665000",
  "votes": 18,
  "comment_count": 4,
  "views": 0,
  "content": "<p>Thank you to everyone involved in this competition.<br>\nThis is my first image competition, so I learned a lots of things.<br>\n(To be honest, I am so disappointed to have dropped so far from the Gold Zone. However, this is what I am capable of now.)</p>\n<p>I want to write my brief summary of my solution.</p>\n<h1>Overview</h1>\n<ol>\n<li>Crop a breast area.</li>\n<li>Background noise reduction using k-means.</li>\n<li>Predict cancer for each image using efficientnet_v2</li>\n<li>Aggregate (mean aggregation)</li>\n</ol>\n<h1>Preprocess</h1>\n<h2>Windowing</h2>\n<p>I referred <a href=\"https://www.kaggle.com/code/hengck23/3hr-tensorrt-nextvit-example\" target=\"_blank\">this windowing code</a>. in this comp. I learned lots from <a href=\"https://www.kaggle.com/hengck23\" target=\"_blank\">@hengck23</a> . I really appreciate it.<br>\nSo windowing is just applied based on VOILUTFunction.<br>\nThen I put out images, which has 2048xXXXX size</p>\n<h2>Background noise reduction (kmeans)</h2>\n<p>I apply kmeans-clustering into each image using pixel values, then the pixel values of a cluster which has the lowest summation change into zero.<br>\nTo save time, I used the <a href=\"https://github.com/subhadarship/kmeans_pytorch\" target=\"_blank\">kmeans-pytorch</a><br>\nHere is <a href=\"https://www.kaggle.com/code/taruto1215/66th-lb-10th-simple-image-crop-kmeans/notebook\" target=\"_blank\">my code</a>.</p>\n<p><img src=\"https://www.googleapis.com/download/storage/v1/b/kaggle-forum-message-attachments/o/inbox%2F3830852%2F02777b71ba9b4886858ab554550f9a72%2Fkmeans.png?generation=1677580535294417&amp;alt=media\" alt=\"\"></p>\n<p>This method gave me almost same CV score, but it boosted my LB (~0.58 --&gt; ~0.63).</p>\n<h2>Image crop</h2>\n<p>I cropped images using below code.<br>\nThis approach gave me slightly better CV and LB score than cropping using YOLO v5  (ref <a href=\"https://www.kaggle.com/remekkinas\" target=\"_blank\">@remekkinas</a> 's code, thank you very much).<br>\nthen it put out  images (resize as 1536x960)<br>\n`</p>\n<pre><code>    frame_org = copy.copy(frame)\n    thres1 = np.min(frame)+68 #Adjustments were made while viewing the crop image.\n    np.place(frame, frame &lt; thres1, 0)\n    thres2 = frame_org.sum() / (h*w)\n\n    vertical_not_zero = [True if frame[:,idx].sum() &gt; thres2 else False for idx in range(w)]\n    horizontal_not_zero = [True if frame[idx,:].sum() &gt; thres2 else False for idx in range(h)]\n\n    crop = frame_org[horizontal_not_zero,:]\n    crop = crop[:,vertical_not_zero]\n</code></pre>\n<p>`</p>\n<h1>Model</h1>\n<ul>\n<li>I used EffecientNet_V2_s (Final sub: 3 models ensemble which has different hyper-parameters, etc.) </li>\n<li>I  train the model for cancer and aux targets. loss weight is cancer:aux = 1:2 the multi-task learning gave me better CV and LB result.</li>\n<li>Dropout_rate = 0.30, drop_path_rate=0.20</li>\n<li>Multi-sampled dropout (drop_rate=0.2, num_drop=5). it gave me better CV and LB score.</li>\n</ul>\n<h1>Training</h1>\n<ul>\n<li>Optimzer: AdamW</li>\n<li>Scheduler: CosineAnnealing (warmup=0.1)</li>\n<li>epoch = 5</li>\n<li>batch_size=36</li>\n</ul>\n<h2>Upsampling</h2>\n<p>I used <a href=\"https://github.com/louis-she/exhaustive-weighted-random-sampler\" target=\"_blank\">ExhaustiveWeightedRandomSampler</a> (weight: Pos:Neg=7:1)<br>\nthis sampler also worked well for me.</p>\n<h2>Loss function</h2>\n<p>I used the weighted binary cross entropy (weight: Pos:Neg = 2:1)</p>\n<h2>Data-augmentaion:</h2>\n<p>I used below code using Kornia. ( it also refered  <a href=\"https://www.kaggle.com/hengck23\" target=\"_blank\">@hengck23</a> 's code. Thanks)<br>\n`</p>\n<pre><code>    self.flip = nn.Sequential(\n        K.RandomHorizontalFlip(p=0.5),\n        K.RandomVerticalFlip(p=0.5),\n    )\n\n    p=0.8\n    self.transform_geometry = ImageSequential(\n        K.RandomAffine(degrees=20, translate=0.1, scale=[0.8,1.2], shear=20, p=p),\n        K.RandomThinPlateSpline(scale=0.25, p=p),\n        random_apply=1, #choose 1\n    )\n\n    p=0.5\n    self.transform_intensity = ImageSequential(\n        K.RandomGamma(gamma=(0.5, 1.5), gain=(0.5, 1.2), p=p),\n        K.RandomContrast(contrast=(0.8,1.2), p=p),\n        K.RandomBrightness(brightness=(0.8,1.2), p=p),\n        random_apply=1, #choose 1\n    )\n</code></pre>\n<p>`</p>\n<h2>Post-processing.</h2>\n<ul>\n<li>I tried some aggregration method, but just mean aggregation is the best for my best submission.</li>\n</ul>\n<p>Thank you.</p>",
  "messages": [
    {
      "id": 2162679,
      "postDate": "2023-02-28T11:10:17.667Z",
      "content": "<p>Thank you to everyone involved in this competition.<br>\nThis is my first image competition, so I learned a lots of things.<br>\n(To be honest, I am so disappointed to have dropped so far from the Gold Zone. However, this is what I am capable of now.)</p>\n<p>I want to write my brief summary of my solution.</p>\n<h1>Overview</h1>\n<ol>\n<li>Crop a breast area.</li>\n<li>Background noise reduction using k-means.</li>\n<li>Predict cancer for each image using efficientnet_v2</li>\n<li>Aggregate (mean aggregation)</li>\n</ol>\n<h1>Preprocess</h1>\n<h2>Windowing</h2>\n<p>I referred <a href=\"https://www.kaggle.com/code/hengck23/3hr-tensorrt-nextvit-example\" target=\"_blank\">this windowing code</a>. in this comp. I learned lots from <a href=\"https://www.kaggle.com/hengck23\" target=\"_blank\">@hengck23</a> . I really appreciate it.<br>\nSo windowing is just applied based on VOILUTFunction.<br>\nThen I put out images, which has 2048xXXXX size</p>\n<h2>Background noise reduction (kmeans)</h2>\n<p>I apply kmeans-clustering into each image using pixel values, then the pixel values of a cluster which has the lowest summation change into zero.<br>\nTo save time, I used the <a href=\"https://github.com/subhadarship/kmeans_pytorch\" target=\"_blank\">kmeans-pytorch</a><br>\nHere is <a href=\"https://www.kaggle.com/code/taruto1215/66th-lb-10th-simple-image-crop-kmeans/notebook\" target=\"_blank\">my code</a>.</p>\n<p><img src=\"https://www.googleapis.com/download/storage/v1/b/kaggle-forum-message-attachments/o/inbox%2F3830852%2F02777b71ba9b4886858ab554550f9a72%2Fkmeans.png?generation=1677580535294417&amp;alt=media\" alt=\"\"></p>\n<p>This method gave me almost same CV score, but it boosted my LB (~0.58 --&gt; ~0.63).</p>\n<h2>Image crop</h2>\n<p>I cropped images using below code.<br>\nThis approach gave me slightly better CV and LB score than cropping using YOLO v5  (ref <a href=\"https://www.kaggle.com/remekkinas\" target=\"_blank\">@remekkinas</a> 's code, thank you very much).<br>\nthen it put out  images (resize as 1536x960)<br>\n`</p>\n<pre><code>    frame_org = copy.copy(frame)\n    thres1 = np.min(frame)+68 #Adjustments were made while viewing the crop image.\n    np.place(frame, frame &lt; thres1, 0)\n    thres2 = frame_org.sum() / (h*w)\n\n    vertical_not_zero = [True if frame[:,idx].sum() &gt; thres2 else False for idx in range(w)]\n    horizontal_not_zero = [True if frame[idx,:].sum() &gt; thres2 else False for idx in range(h)]\n\n    crop = frame_org[horizontal_not_zero,:]\n    crop = crop[:,vertical_not_zero]\n</code></pre>\n<p>`</p>\n<h1>Model</h1>\n<ul>\n<li>I used EffecientNet_V2_s (Final sub: 3 models ensemble which has different hyper-parameters, etc.) </li>\n<li>I  train the model for cancer and aux targets. loss weight is cancer:aux = 1:2 the multi-task learning gave me better CV and LB result.</li>\n<li>Dropout_rate = 0.30, drop_path_rate=0.20</li>\n<li>Multi-sampled dropout (drop_rate=0.2, num_drop=5). it gave me better CV and LB score.</li>\n</ul>\n<h1>Training</h1>\n<ul>\n<li>Optimzer: AdamW</li>\n<li>Scheduler: CosineAnnealing (warmup=0.1)</li>\n<li>epoch = 5</li>\n<li>batch_size=36</li>\n</ul>\n<h2>Upsampling</h2>\n<p>I used <a href=\"https://github.com/louis-she/exhaustive-weighted-random-sampler\" target=\"_blank\">ExhaustiveWeightedRandomSampler</a> (weight: Pos:Neg=7:1)<br>\nthis sampler also worked well for me.</p>\n<h2>Loss function</h2>\n<p>I used the weighted binary cross entropy (weight: Pos:Neg = 2:1)</p>\n<h2>Data-augmentaion:</h2>\n<p>I used below code using Kornia. ( it also refered  <a href=\"https://www.kaggle.com/hengck23\" target=\"_blank\">@hengck23</a> 's code. Thanks)<br>\n`</p>\n<pre><code>    self.flip = nn.Sequential(\n        K.RandomHorizontalFlip(p=0.5),\n        K.RandomVerticalFlip(p=0.5),\n    )\n\n    p=0.8\n    self.transform_geometry = ImageSequential(\n        K.RandomAffine(degrees=20, translate=0.1, scale=[0.8,1.2], shear=20, p=p),\n        K.RandomThinPlateSpline(scale=0.25, p=p),\n        random_apply=1, #choose 1\n    )\n\n    p=0.5\n    self.transform_intensity = ImageSequential(\n        K.RandomGamma(gamma=(0.5, 1.5), gain=(0.5, 1.2), p=p),\n        K.RandomContrast(contrast=(0.8,1.2), p=p),\n        K.RandomBrightness(brightness=(0.8,1.2), p=p),\n        random_apply=1, #choose 1\n    )\n</code></pre>\n<p>`</p>\n<h2>Post-processing.</h2>\n<ul>\n<li>I tried some aggregration method, but just mean aggregation is the best for my best submission.</li>\n</ul>\n<p>Thank you.</p>",
      "rawMarkdown": "Thank you to everyone involved in this competition.\nThis is my first image competition, so I learned a lots of things.\n(To be honest, I am so disappointed to have dropped so far from the Gold Zone. However, this is what I am capable of now.)\n\nI want to write my brief summary of my solution.\n\n\n# Overview\n1. Crop a breast area.\n2. Background noise reduction using k-means.\n3. Predict cancer for each image using efficientnet_v2\n4. Aggregate (mean aggregation)\n\n# Preprocess\n## Windowing\nI referred [this windowing code](https://www.kaggle.com/code/hengck23/3hr-tensorrt-nextvit-example). in this comp. I learned lots from @hengck23 . I really appreciate it.\nSo windowing is just applied based on VOILUTFunction.\nThen I put out images, which has 2048xXXXX size\n\n## Background noise reduction (kmeans)\nI apply kmeans-clustering into each image using pixel values, then the pixel values of a cluster which has the lowest summation change into zero.\nTo save time, I used the [kmeans-pytorch](https://github.com/subhadarship/kmeans_pytorch)\nHere is [my code](https://www.kaggle.com/code/taruto1215/66th-lb-10th-simple-image-crop-kmeans/notebook).\n\n![](https://www.googleapis.com/download/storage/v1/b/kaggle-forum-message-attachments/o/inbox%2F3830852%2F02777b71ba9b4886858ab554550f9a72%2Fkmeans.png?generation=1677580535294417&alt=media)\n\nThis method gave me almost same CV score, but it boosted my LB (~0.58 --> ~0.63).\n## Image crop\n I cropped images using below code.\nThis approach gave me slightly better CV and LB score than cropping using YOLO v5  (ref @remekkinas 's code, thank you very much).\nthen it put out  images (resize as 1536x960)\n`\n\n        frame_org = copy.copy(frame)\n        thres1 = np.min(frame)+68 #Adjustments were made while viewing the crop image.\n        np.place(frame, frame < thres1, 0)\n        thres2 = frame_org.sum() / (h*w)\n        \n        vertical_not_zero = [True if frame[:,idx].sum() > thres2 else False for idx in range(w)]\n        horizontal_not_zero = [True if frame[idx,:].sum() > thres2 else False for idx in range(h)]\n        \n        crop = frame_org[horizontal_not_zero,:]\n        crop = crop[:,vertical_not_zero]\n`\n\n# Model\n- I used EffecientNet_V2_s (Final sub: 3 models ensemble which has different hyper-parameters, etc.) \n- I  train the model for cancer and aux targets. loss weight is cancer:aux = 1:2 the multi-task learning gave me better CV and LB result.\n- Dropout_rate = 0.30, drop_path_rate=0.20\n- Multi-sampled dropout (drop_rate=0.2, num_drop=5). it gave me better CV and LB score.\n\n# Training\n- Optimzer: AdamW\n- Scheduler: CosineAnnealing (warmup=0.1)\n- epoch = 5\n- batch_size=36\n\n## Upsampling\nI used [ExhaustiveWeightedRandomSampler](https://github.com/louis-she/exhaustive-weighted-random-sampler) (weight: Pos:Neg=7:1)\nthis sampler also worked well for me.\n\n## Loss function \nI used the weighted binary cross entropy (weight: Pos:Neg = 2:1)\n\n## Data-augmentaion:\nI used below code using Kornia. ( it also refered  @hengck23 's code. Thanks)\n`\n\n        self.flip = nn.Sequential(\n            K.RandomHorizontalFlip(p=0.5),\n            K.RandomVerticalFlip(p=0.5),\n        )\n\n        p=0.8\n        self.transform_geometry = ImageSequential(\n            K.RandomAffine(degrees=20, translate=0.1, scale=[0.8,1.2], shear=20, p=p),\n            K.RandomThinPlateSpline(scale=0.25, p=p),\n            random_apply=1, #choose 1\n        )\n\n        p=0.5\n        self.transform_intensity = ImageSequential(\n            K.RandomGamma(gamma=(0.5, 1.5), gain=(0.5, 1.2), p=p),\n            K.RandomContrast(contrast=(0.8,1.2), p=p),\n            K.RandomBrightness(brightness=(0.8,1.2), p=p),\n            random_apply=1, #choose 1\n        )\n`\n\n## Post-processing.\n\n - I tried some aggregration method, but just mean aggregation is the best for my best submission.\n\nThank you.",
      "votes": 18
    },
    {
      "id": 2162717,
      "postDate": "2023-02-28T11:31:23.877Z",
      "content": "<p>Good effort! There is no reason to feel disappointed. K-means clustering for background noice reduction is interesting. I have seen the methodology being used also for segmentation in some IEEE paper ages ago.</p>",
      "rawMarkdown": "Good effort! There is no reason to feel disappointed. K-means clustering for background noice reduction is interesting. I have seen the methodology being used also for segmentation in some IEEE paper ages ago.",
      "votes": 2,
      "replies": [
        {
          "id": 2162732,
          "postDate": "2023-02-28T11:42:00.457Z",
          "content": "<p>Thanks for the encouragement!</p>",
          "rawMarkdown": "Thanks for the encouragement!",
          "votes": 1
        }
      ]
    },
    {
      "id": 2165356,
      "postDate": "2023-03-02T06:22:50.960Z",
      "content": "<p>Thank you for sharing your solution.<br>\nI didn't come up with kmeans noise reduction. How background noise reduction affected PB scores?</p>",
      "rawMarkdown": "Thank you for sharing your solution.\nI didn't come up with kmeans noise reduction. How background noise reduction affected PB scores?",
      "replies": [
        {
          "id": 2179597,
          "postDate": "2023-03-13T09:27:41.773Z",
          "content": "<p><a href=\"https://www.kaggle.com/ludditep\" target=\"_blank\">@ludditep</a> <br>\nSorry for my late response.<br>\nThere were a little improve (less than 0.01) in the PB.</p>",
          "rawMarkdown": "@ludditep \nSorry for my late response.\nThere were a little improve (less than 0.01) in the PB.",
          "votes": 1
        }
      ]
    }
  ],
  "comments": [
    {
      "id": 2162717,
      "author_name": "Antti Isosalo",
      "author_url": "",
      "post_date": "2023-02-28T11:31:23.877000",
      "content": "<p>Good effort! There is no reason to feel disappointed. K-means clustering for background noice reduction is interesting. I have seen the methodology being used also for segmentation in some IEEE paper ages ago.</p>",
      "votes": 2,
      "replies": [
        {
          "id": 2162732,
          "author_name": "taruto",
          "author_url": "",
          "post_date": "2023-02-28T11:42:00.457000",
          "content": "<p>Thanks for the encouragement!</p>",
          "votes": 1,
          "replies": []
        }
      ]
    },
    {
      "id": 2165356,
      "author_name": "luddite^",
      "author_url": "",
      "post_date": "2023-03-02T06:22:50.960000",
      "content": "<p>Thank you for sharing your solution.<br>\nI didn't come up with kmeans noise reduction. How background noise reduction affected PB scores?</p>",
      "votes": 0,
      "replies": [
        {
          "id": 2179597,
          "author_name": "taruto",
          "author_url": "",
          "post_date": "2023-03-13T09:27:41.773000",
          "content": "<p><a href=\"https://www.kaggle.com/ludditep\" target=\"_blank\">@ludditep</a> <br>\nSorry for my late response.<br>\nThere were a little improve (less than 0.01) in the PB.</p>",
          "votes": 1,
          "replies": []
        }
      ]
    }
  ],
  "raw_markdown_by_id": {
    "2162679": "Thank you to everyone involved in this competition.\nThis is my first image competition, so I learned a lots of things.\n(To be honest, I am so disappointed to have dropped so far from the Gold Zone. However, this is what I am capable of now.)\n\nI want to write my brief summary of my solution.\n\n\n# Overview\n1. Crop a breast area.\n2. Background noise reduction using k-means.\n3. Predict cancer for each image using efficientnet_v2\n4. Aggregate (mean aggregation)\n\n# Preprocess\n## Windowing\nI referred [this windowing code](https://www.kaggle.com/code/hengck23/3hr-tensorrt-nextvit-example). in this comp. I learned lots from @hengck23 . I really appreciate it.\nSo windowing is just applied based on VOILUTFunction.\nThen I put out images, which has 2048xXXXX size\n\n## Background noise reduction (kmeans)\nI apply kmeans-clustering into each image using pixel values, then the pixel values of a cluster which has the lowest summation change into zero.\nTo save time, I used the [kmeans-pytorch](https://github.com/subhadarship/kmeans_pytorch)\nHere is [my code](https://www.kaggle.com/code/taruto1215/66th-lb-10th-simple-image-crop-kmeans/notebook).\n\n![](https://www.googleapis.com/download/storage/v1/b/kaggle-forum-message-attachments/o/inbox%2F3830852%2F02777b71ba9b4886858ab554550f9a72%2Fkmeans.png?generation=1677580535294417&alt=media)\n\nThis method gave me almost same CV score, but it boosted my LB (~0.58 --> ~0.63).\n## Image crop\n I cropped images using below code.\nThis approach gave me slightly better CV and LB score than cropping using YOLO v5  (ref @remekkinas 's code, thank you very much).\nthen it put out  images (resize as 1536x960)\n`\n\n        frame_org = copy.copy(frame)\n        thres1 = np.min(frame)+68 #Adjustments were made while viewing the crop image.\n        np.place(frame, frame < thres1, 0)\n        thres2 = frame_org.sum() / (h*w)\n        \n        vertical_not_zero = [True if frame[:,idx].sum() > thres2 else False for idx in range(w)]\n        horizontal_not_zero = [True if frame[idx,:].sum() > thres2 else False for idx in range(h)]\n        \n        crop = frame_org[horizontal_not_zero,:]\n        crop = crop[:,vertical_not_zero]\n`\n\n# Model\n- I used EffecientNet_V2_s (Final sub: 3 models ensemble which has different hyper-parameters, etc.) \n- I  train the model for cancer and aux targets. loss weight is cancer:aux = 1:2 the multi-task learning gave me better CV and LB result.\n- Dropout_rate = 0.30, drop_path_rate=0.20\n- Multi-sampled dropout (drop_rate=0.2, num_drop=5). it gave me better CV and LB score.\n\n# Training\n- Optimzer: AdamW\n- Scheduler: CosineAnnealing (warmup=0.1)\n- epoch = 5\n- batch_size=36\n\n## Upsampling\nI used [ExhaustiveWeightedRandomSampler](https://github.com/louis-she/exhaustive-weighted-random-sampler) (weight: Pos:Neg=7:1)\nthis sampler also worked well for me.\n\n## Loss function \nI used the weighted binary cross entropy (weight: Pos:Neg = 2:1)\n\n## Data-augmentaion:\nI used below code using Kornia. ( it also refered  @hengck23 's code. Thanks)\n`\n\n        self.flip = nn.Sequential(\n            K.RandomHorizontalFlip(p=0.5),\n            K.RandomVerticalFlip(p=0.5),\n        )\n\n        p=0.8\n        self.transform_geometry = ImageSequential(\n            K.RandomAffine(degrees=20, translate=0.1, scale=[0.8,1.2], shear=20, p=p),\n            K.RandomThinPlateSpline(scale=0.25, p=p),\n            random_apply=1, #choose 1\n        )\n\n        p=0.5\n        self.transform_intensity = ImageSequential(\n            K.RandomGamma(gamma=(0.5, 1.5), gain=(0.5, 1.2), p=p),\n            K.RandomContrast(contrast=(0.8,1.2), p=p),\n            K.RandomBrightness(brightness=(0.8,1.2), p=p),\n            random_apply=1, #choose 1\n        )\n`\n\n## Post-processing.\n\n - I tried some aggregration method, but just mean aggregation is the best for my best submission.\n\nThank you.",
    "2162717": "Good effort! There is no reason to feel disappointed. K-means clustering for background noice reduction is interesting. I have seen the methodology being used also for segmentation in some IEEE paper ages ago.",
    "2165356": "Thank you for sharing your solution.\nI didn't come up with kmeans noise reduction. How background noise reduction affected PB scores?"
  }
}