{
  "id": 391398,
  "title": "22th place solution",
  "url": "/competitions/rsna-breast-cancer-detection/discussion/391398",
  "author_name": "Zichen Wang",
  "post_date": "2023-03-01T11:14:09.902000",
  "votes": 15,
  "comment_count": 5,
  "views": 0,
  "content": "<p>First of all, many thanks to everyone who contributed to this competition and I've learnt a lot from this comp, thanks very much!<br>\nMy solution doesn't have much innovation, but I want to share some tricks that improve the performance in my practice.</p>\n<h2>Preprocessing</h2>\n<ul>\n<li>dicom2png<br>\nMostly refers to <br>\n<a href=\"https://www.kaggle.com/code/hengck23/3hr-tensorrt-nextvit-example\" target=\"_blank\">3hr tensorRT NextVIT example</a><br>\n<a href=\"https://www.kaggle.com/competitions/rsna-breast-cancer-detection/discussion/372275\" target=\"_blank\">Easy load the image with nvJPEG2000(5x faster)</a><br>\n<a href=\"https://www.kaggle.com/code/radek1/how-to-process-dicom-images-to-pngs\" target=\"_blank\">how to process DICOM images to PNGs</a></li>\n<li>roi<br>\nUse opencv findContours() to extract roi following <a href=\"https://www.kaggle.com/code/snnclsr/roi-extraction-using-opencv\" target=\"_blank\">ROI Extraction using OpenCV</a></li>\n</ul>\n<h2>Augmentation</h2>\n<ul>\n<li>The augmentations are hflip, vflip, translation(shift), scale</li>\n<li>We keep aspect ratio the same and only resize down once to avoid distortion or blur. (Images before transformation are png files with original resolution. )</li>\n<li>Mix up (with class max as target)</li>\n</ul>\n<h2>Training setting</h2>\n<ul>\n<li><p>Data<br>\nresolution 1536x960<br>\nbatch size = 8<br>\npositive images upsample x6 (use high dropout rate due to upsampling)</p></li>\n<li><p>Model</p></li>\n</ul>\n<pre><code> timm.models  efficientnet\nbackbone = efficientnet.tf_efficientnetv2_b2(drop_rate=, drop_path_rate=)\n</code></pre>\n<ul>\n<li>Optimizer</li>\n</ul>\n<pre><code>optimizer = AdamW(param_group, lr=, betas=(, ), weight_decay=)\n</code></pre>\n<ul>\n<li><p>Loss Function<br>\nBCEWithLogitsLoss()</p></li>\n<li><p>Soft target (or self distillation?)<br>\nMay help model pay less attention to dataset noise, i.e., hard positive and negative samples</p></li>\n</ul>\n<pre><code>logits = ddp_model(images)\n torch.no_grad():\n    lam = \n    targets = lam*targets + ( - lam) * logits.sigmoid()\nloss = loss_func(logits, targets)\n</code></pre>\n<ul>\n<li>SWA<br>\nPerform swa following this blog <a href=\"https://pytorch.org/blog/stochastic-weight-averaging-in-pytorch/\" target=\"_blank\">Stochastic Weight Averaging in PyTorch</a></li>\n</ul>\n<pre><code> torchcontrib.optim  SWA\nopt = SWA(optimizer, swa_start=, swa_freq=, swa_lr=)\n</code></pre>\n<h2>Submission</h2>\n<p>The final submisstion is an ensemble of 8 tf_efficientnetv2_b2 models training with different settings, e.g., whether to use mix up, resolution 1536x960 or 1024x640, using focal loss or not<br>\nThe PF1 score curve on LB is quite stable and has a wide flat region of max value</p>\n<h2>Code for Augmentations</h2>\n<pre><code>\n torchvision  transforms\n torchvision.transforms  functional  F\n torchvision.transforms.functional  InterpolationMode\n\ntransform = transforms.Compose([\n    transforms.ToTensor(),\n    transforms.RandomHorizontalFlip(p=),\n    transforms.RandomVerticalFlip(p=),\n    ScaleTransform(size=, scale=(, ), transl=),\n])\n\n (torch.nn.Module):\n     ():\n        (ScaleTransform, self).__init__()\n        self.size = size\n        self.scale = scale\n        self.transl = transl\n        self.train = train\n        self.interpolation = InterpolationMode.BILINEAR\n\n     ():\n        \n\n        \n        _, h, w = im.shape\n        scale_ = np.random.uniform(self.scale[], self.scale[])\n        height, width = (scale_ * self.size), (scale_ * self.size / )\n        s = (height / h, width / w)\n        im = F.resize(im, [(h * s), (w * s)], interpolation=self.interpolation)\n\n        \n        ms = \n        _, h, w = im.shape\n        height, width = (ms * self.size), (ms * (self.size / ))  \n        top, left = ((height - h) / ), ((width - w) / )\n        bottom, right = height - h - top, width - w - left\n        pad_value = \n        padding = [left, top, right, bottom]\n        im = F.pad(im, padding, fill=pad_value, padding_mode=)\n\n        \n        y0 = height /  - self.size /  + np.random.uniform(-self.transl * self.size, self.transl * self.size)\n        x0 = width /  - self.size /  /  + np.random.uniform(-self.transl * (self.size / ), self.transl * (self.size / ))\n        im = im[:, (y0):(y0 + self.size), (x0):(x0 + self.size / )]\n         im\n</code></pre>",
  "messages": [
    {
      "id": 2164170,
      "postDate": "2023-03-01T11:14:09.903Z",
      "content": "<p>First of all, many thanks to everyone who contributed to this competition and I've learnt a lot from this comp, thanks very much!<br>\nMy solution doesn't have much innovation, but I want to share some tricks that improve the performance in my practice.</p>\n<h2>Preprocessing</h2>\n<ul>\n<li>dicom2png<br>\nMostly refers to <br>\n<a href=\"https://www.kaggle.com/code/hengck23/3hr-tensorrt-nextvit-example\" target=\"_blank\">3hr tensorRT NextVIT example</a><br>\n<a href=\"https://www.kaggle.com/competitions/rsna-breast-cancer-detection/discussion/372275\" target=\"_blank\">Easy load the image with nvJPEG2000(5x faster)</a><br>\n<a href=\"https://www.kaggle.com/code/radek1/how-to-process-dicom-images-to-pngs\" target=\"_blank\">how to process DICOM images to PNGs</a></li>\n<li>roi<br>\nUse opencv findContours() to extract roi following <a href=\"https://www.kaggle.com/code/snnclsr/roi-extraction-using-opencv\" target=\"_blank\">ROI Extraction using OpenCV</a></li>\n</ul>\n<h2>Augmentation</h2>\n<ul>\n<li>The augmentations are hflip, vflip, translation(shift), scale</li>\n<li>We keep aspect ratio the same and only resize down once to avoid distortion or blur. (Images before transformation are png files with original resolution. )</li>\n<li>Mix up (with class max as target)</li>\n</ul>\n<h2>Training setting</h2>\n<ul>\n<li><p>Data<br>\nresolution 1536x960<br>\nbatch size = 8<br>\npositive images upsample x6 (use high dropout rate due to upsampling)</p></li>\n<li><p>Model</p></li>\n</ul>\n<pre><code> timm.models  efficientnet\nbackbone = efficientnet.tf_efficientnetv2_b2(drop_rate=, drop_path_rate=)\n</code></pre>\n<ul>\n<li>Optimizer</li>\n</ul>\n<pre><code>optimizer = AdamW(param_group, lr=, betas=(, ), weight_decay=)\n</code></pre>\n<ul>\n<li><p>Loss Function<br>\nBCEWithLogitsLoss()</p></li>\n<li><p>Soft target (or self distillation?)<br>\nMay help model pay less attention to dataset noise, i.e., hard positive and negative samples</p></li>\n</ul>\n<pre><code>logits = ddp_model(images)\n torch.no_grad():\n    lam = \n    targets = lam*targets + ( - lam) * logits.sigmoid()\nloss = loss_func(logits, targets)\n</code></pre>\n<ul>\n<li>SWA<br>\nPerform swa following this blog <a href=\"https://pytorch.org/blog/stochastic-weight-averaging-in-pytorch/\" target=\"_blank\">Stochastic Weight Averaging in PyTorch</a></li>\n</ul>\n<pre><code> torchcontrib.optim  SWA\nopt = SWA(optimizer, swa_start=, swa_freq=, swa_lr=)\n</code></pre>\n<h2>Submission</h2>\n<p>The final submisstion is an ensemble of 8 tf_efficientnetv2_b2 models training with different settings, e.g., whether to use mix up, resolution 1536x960 or 1024x640, using focal loss or not<br>\nThe PF1 score curve on LB is quite stable and has a wide flat region of max value</p>\n<h2>Code for Augmentations</h2>\n<pre><code>\n torchvision  transforms\n torchvision.transforms  functional  F\n torchvision.transforms.functional  InterpolationMode\n\ntransform = transforms.Compose([\n    transforms.ToTensor(),\n    transforms.RandomHorizontalFlip(p=),\n    transforms.RandomVerticalFlip(p=),\n    ScaleTransform(size=, scale=(, ), transl=),\n])\n\n (torch.nn.Module):\n     ():\n        (ScaleTransform, self).__init__()\n        self.size = size\n        self.scale = scale\n        self.transl = transl\n        self.train = train\n        self.interpolation = InterpolationMode.BILINEAR\n\n     ():\n        \n\n        \n        _, h, w = im.shape\n        scale_ = np.random.uniform(self.scale[], self.scale[])\n        height, width = (scale_ * self.size), (scale_ * self.size / )\n        s = (height / h, width / w)\n        im = F.resize(im, [(h * s), (w * s)], interpolation=self.interpolation)\n\n        \n        ms = \n        _, h, w = im.shape\n        height, width = (ms * self.size), (ms * (self.size / ))  \n        top, left = ((height - h) / ), ((width - w) / )\n        bottom, right = height - h - top, width - w - left\n        pad_value = \n        padding = [left, top, right, bottom]\n        im = F.pad(im, padding, fill=pad_value, padding_mode=)\n\n        \n        y0 = height /  - self.size /  + np.random.uniform(-self.transl * self.size, self.transl * self.size)\n        x0 = width /  - self.size /  /  + np.random.uniform(-self.transl * (self.size / ), self.transl * (self.size / ))\n        im = im[:, (y0):(y0 + self.size), (x0):(x0 + self.size / )]\n         im\n</code></pre>",
      "rawMarkdown": "First of all, many thanks to everyone who contributed to this competition and I've learnt a lot from this comp, thanks very much!\nMy solution doesn't have much innovation, but I want to share some tricks that improve the performance in my practice.\n\n## Preprocessing\n- dicom2png\nMostly refers to \n[3hr tensorRT NextVIT example](https://www.kaggle.com/code/hengck23/3hr-tensorrt-nextvit-example)\n[Easy load the image with nvJPEG2000(5x faster)](https://www.kaggle.com/competitions/rsna-breast-cancer-detection/discussion/372275)\n[how to process DICOM images to PNGs](https://www.kaggle.com/code/radek1/how-to-process-dicom-images-to-pngs)\n- roi\nUse opencv findContours() to extract roi following [ROI Extraction using OpenCV](https://www.kaggle.com/code/snnclsr/roi-extraction-using-opencv)\n\n## Augmentation\n- The augmentations are hflip, vflip, translation(shift), scale\n- We keep aspect ratio the same and only resize down once to avoid distortion or blur. (Images before transformation are png files with original resolution. )\n- Mix up (with class max as target)\n\n## Training setting\n- Data\nresolution 1536x960\nbatch size = 8\npositive images upsample x6 (use high dropout rate due to upsampling)\n\n- Model\n```python\nfrom timm.models import efficientnet\nbackbone = efficientnet.tf_efficientnetv2_b2(drop_rate=0.4, drop_path_rate=0.4)\n```\n\n- Optimizer\n```python\noptimizer = AdamW(param_group, lr=1e-4, betas=(0.9, 0.935), weight_decay=1e-2)\n```\n\n- Loss Function\nBCEWithLogitsLoss()\n\n- Soft target (or self distillation?)\nMay help model pay less attention to dataset noise, i.e., hard positive and negative samples\n```python\nlogits = ddp_model(images)\nwith torch.no_grad():\n    lam = 0.7\n    targets = lam*targets + (1 - lam) * logits.sigmoid()\nloss = loss_func(logits, targets)\n```\n- SWA\nPerform swa following this blog [Stochastic Weight Averaging in PyTorch](https://pytorch.org/blog/stochastic-weight-averaging-in-pytorch/)\n```python\nfrom torchcontrib.optim import SWA\nopt = SWA(optimizer, swa_start=3000, swa_freq=100, swa_lr=None)\n```\n\n## Submission\nThe final submisstion is an ensemble of 8 tf_efficientnetv2_b2 models training with different settings, e.g., whether to use mix up, resolution 1536x960 or 1024x640, using focal loss or not\nThe PF1 score curve on LB is quite stable and has a wide flat region of max value\n\n## Code for Augmentations\n```python\n''' python code of augmentations '''\nfrom torchvision import transforms\nfrom torchvision.transforms import functional as F\nfrom torchvision.transforms.functional import InterpolationMode\n\ntransform = transforms.Compose([\n    transforms.ToTensor(),\n    transforms.RandomHorizontalFlip(p=0.5),\n    transforms.RandomVerticalFlip(p=0.5),\n    ScaleTransform(size=1536, scale=(0.85, 1.13), transl=0.1),\n])\n\nclass ScaleTransform(torch.nn.Module):\n    def __init__(self, size=1024, scale=(0.7, 1.3), transl=0.1, train=True):\n        super(ScaleTransform, self).__init__()\n        self.size = size\n        self.scale = scale\n        self.transl = transl\n        self.train = train\n        self.interpolation = InterpolationMode.BILINEAR\n\n    def forward(self, im):\n        # # assert abs(scale - 1) > 2*transl\n\n        # resize to a certain scale\n        _, h, w = im.shape\n        scale_ = np.random.uniform(self.scale[0], self.scale[1])\n        height, width = int(scale_ * self.size), int(scale_ * self.size / 1.6)\n        s = min(height / h, width / w)\n        im = F.resize(im, [int(h * s), int(w * s)], interpolation=self.interpolation)\n\n        # pad image to big enough\n        ms = 1.4\n        _, h, w = im.shape\n        height, width = int(ms * self.size), int(ms * (self.size / 1.6))  # biggest scale\n        top, left = int((height - h) / 2), int((width - w) / 2)\n        bottom, right = height - h - top, width - w - left\n        pad_value = 0\n        padding = [left, top, right, bottom]\n        im = F.pad(im, padding, fill=pad_value, padding_mode='constant')\n\n        # translation & crop\n        y0 = height / 2 - self.size / 2 + np.random.uniform(-self.transl * self.size, self.transl * self.size)\n        x0 = width / 2 - self.size / 1.6 / 2 + np.random.uniform(-self.transl * (self.size / 1.6), self.transl * (self.size / 1.6))\n        im = im[:, int(y0):int(y0 + self.size), int(x0):int(x0 + self.size / 1.6)]\n        return im\n```\n\n",
      "votes": 15
    },
    {
      "id": 2169268,
      "postDate": "2023-03-05T00:35:59.633Z",
      "content": "<p>Thanks for sharing a great solution! <br>\nI could learn a lot from your description. <br>\nThank you.</p>",
      "rawMarkdown": "Thanks for sharing a great solution! \nI could learn a lot from your description. \nThank you.",
      "votes": 1
    },
    {
      "id": 2164237,
      "postDate": "2023-03-01T12:34:54.253Z",
      "content": "<p>Congratulations on the silver medal!</p>\n<blockquote>\n  <p>The PF1 score curve on LB is quite stable and has a wide flat region of max value</p>\n</blockquote>\n<p>👍</p>\n<p>Anything that you would do differently?</p>",
      "rawMarkdown": "Congratulations on the silver medal!\n\n>The PF1 score curve on LB is quite stable and has a wide flat region of max value\n\n👍\n\nAnything that you would do differently?",
      "votes": 1,
      "replies": [
        {
          "id": 2164336,
          "postDate": "2023-03-01T13:35:24.857Z",
          "content": "<p>Thanks!<br>\n I submit the ensemble model many times with different threshold values</p>\n<table>\n<thead>\n<tr>\n<th>threshold</th>\n<th>0.61</th>\n<th>0.57</th>\n<th>0.54</th>\n<th>0.52</th>\n<th>0.46</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td>Public</td>\n<td>0.54</td>\n<td>0.59</td>\n<td>0.58</td>\n<td>0.59</td>\n<td>0.57</td>\n</tr>\n<tr>\n<td>Private</td>\n<td>0.45</td>\n<td>0.48</td>\n<td>0.48</td>\n<td>0.47</td>\n<td>0.46</td>\n</tr>\n</tbody>\n</table>",
          "rawMarkdown": "Thanks!\n I submit the ensemble model many times with different threshold values\n| threshold | 0.61 | 0.57 | 0.54 | 0.52 | 0.46 |\n| --- | --- | --- |\n| Public | 0.54 | 0.59 | 0.58 | 0.59 | 0.57 |\n| Private | 0.45 | 0.48 | 0.48 | 0.47 | 0.46 |",
          "votes": 1
        }
      ]
    },
    {
      "id": 2165017,
      "postDate": "2023-03-01T23:41:23.910Z",
      "content": "<p>Thanks for sharing a great solution! Would i ask you some questions?</p>\n<p>What gpu did you use to train the model? Also I don’t understand why high dropout rate is needed due to upsamling.</p>",
      "rawMarkdown": "Thanks for sharing a great solution! Would i ask you some questions?\n\nWhat gpu did you use to train the model? Also I don’t understand why high dropout rate is needed due to upsamling.\n\n\n",
      "replies": [
        {
          "id": 2165075,
          "postDate": "2023-03-02T01:16:18.423Z",
          "content": "<p>Thank you! <br>\nI use two 3090 gpu to train the model. Upsampling duplicates positive images many times in one epoch, and makes it easy to overfit positive cases.</p>",
          "rawMarkdown": "Thank you! \nI use two 3090 gpu to train the model. Upsampling duplicates positive images many times in one epoch, and makes it easy to overfit positive cases."
        }
      ]
    }
  ],
  "comments": [
    {
      "id": 2169268,
      "author_name": "Nana-chan",
      "author_url": "",
      "post_date": "2023-03-05T00:35:59.633000",
      "content": "<p>Thanks for sharing a great solution! <br>\nI could learn a lot from your description. <br>\nThank you.</p>",
      "votes": 1,
      "replies": []
    },
    {
      "id": 2164237,
      "author_name": "Antti Isosalo",
      "author_url": "",
      "post_date": "2023-03-01T12:34:54.253000",
      "content": "<p>Congratulations on the silver medal!</p>\n<blockquote>\n  <p>The PF1 score curve on LB is quite stable and has a wide flat region of max value</p>\n</blockquote>\n<p>👍</p>\n<p>Anything that you would do differently?</p>",
      "votes": 1,
      "replies": [
        {
          "id": 2164336,
          "author_name": "Zichen Wang",
          "author_url": "",
          "post_date": "2023-03-01T13:35:24.857000",
          "content": "<p>Thanks!<br>\n I submit the ensemble model many times with different threshold values</p>\n<table>\n<thead>\n<tr>\n<th>threshold</th>\n<th>0.61</th>\n<th>0.57</th>\n<th>0.54</th>\n<th>0.52</th>\n<th>0.46</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td>Public</td>\n<td>0.54</td>\n<td>0.59</td>\n<td>0.58</td>\n<td>0.59</td>\n<td>0.57</td>\n</tr>\n<tr>\n<td>Private</td>\n<td>0.45</td>\n<td>0.48</td>\n<td>0.48</td>\n<td>0.47</td>\n<td>0.46</td>\n</tr>\n</tbody>\n</table>",
          "votes": 1,
          "replies": []
        }
      ]
    },
    {
      "id": 2165017,
      "author_name": "Ju7on9",
      "author_url": "",
      "post_date": "2023-03-01T23:41:23.910000",
      "content": "<p>Thanks for sharing a great solution! Would i ask you some questions?</p>\n<p>What gpu did you use to train the model? Also I don’t understand why high dropout rate is needed due to upsamling.</p>",
      "votes": 0,
      "replies": [
        {
          "id": 2165075,
          "author_name": "Zichen Wang",
          "author_url": "",
          "post_date": "2023-03-02T01:16:18.423000",
          "content": "<p>Thank you! <br>\nI use two 3090 gpu to train the model. Upsampling duplicates positive images many times in one epoch, and makes it easy to overfit positive cases.</p>",
          "votes": 0,
          "replies": []
        }
      ]
    }
  ],
  "raw_markdown_by_id": {
    "2164170": "First of all, many thanks to everyone who contributed to this competition and I've learnt a lot from this comp, thanks very much!\nMy solution doesn't have much innovation, but I want to share some tricks that improve the performance in my practice.\n\n## Preprocessing\n- dicom2png\nMostly refers to \n[3hr tensorRT NextVIT example](https://www.kaggle.com/code/hengck23/3hr-tensorrt-nextvit-example)\n[Easy load the image with nvJPEG2000(5x faster)](https://www.kaggle.com/competitions/rsna-breast-cancer-detection/discussion/372275)\n[how to process DICOM images to PNGs](https://www.kaggle.com/code/radek1/how-to-process-dicom-images-to-pngs)\n- roi\nUse opencv findContours() to extract roi following [ROI Extraction using OpenCV](https://www.kaggle.com/code/snnclsr/roi-extraction-using-opencv)\n\n## Augmentation\n- The augmentations are hflip, vflip, translation(shift), scale\n- We keep aspect ratio the same and only resize down once to avoid distortion or blur. (Images before transformation are png files with original resolution. )\n- Mix up (with class max as target)\n\n## Training setting\n- Data\nresolution 1536x960\nbatch size = 8\npositive images upsample x6 (use high dropout rate due to upsampling)\n\n- Model\n```python\nfrom timm.models import efficientnet\nbackbone = efficientnet.tf_efficientnetv2_b2(drop_rate=0.4, drop_path_rate=0.4)\n```\n\n- Optimizer\n```python\noptimizer = AdamW(param_group, lr=1e-4, betas=(0.9, 0.935), weight_decay=1e-2)\n```\n\n- Loss Function\nBCEWithLogitsLoss()\n\n- Soft target (or self distillation?)\nMay help model pay less attention to dataset noise, i.e., hard positive and negative samples\n```python\nlogits = ddp_model(images)\nwith torch.no_grad():\n    lam = 0.7\n    targets = lam*targets + (1 - lam) * logits.sigmoid()\nloss = loss_func(logits, targets)\n```\n- SWA\nPerform swa following this blog [Stochastic Weight Averaging in PyTorch](https://pytorch.org/blog/stochastic-weight-averaging-in-pytorch/)\n```python\nfrom torchcontrib.optim import SWA\nopt = SWA(optimizer, swa_start=3000, swa_freq=100, swa_lr=None)\n```\n\n## Submission\nThe final submisstion is an ensemble of 8 tf_efficientnetv2_b2 models training with different settings, e.g., whether to use mix up, resolution 1536x960 or 1024x640, using focal loss or not\nThe PF1 score curve on LB is quite stable and has a wide flat region of max value\n\n## Code for Augmentations\n```python\n''' python code of augmentations '''\nfrom torchvision import transforms\nfrom torchvision.transforms import functional as F\nfrom torchvision.transforms.functional import InterpolationMode\n\ntransform = transforms.Compose([\n    transforms.ToTensor(),\n    transforms.RandomHorizontalFlip(p=0.5),\n    transforms.RandomVerticalFlip(p=0.5),\n    ScaleTransform(size=1536, scale=(0.85, 1.13), transl=0.1),\n])\n\nclass ScaleTransform(torch.nn.Module):\n    def __init__(self, size=1024, scale=(0.7, 1.3), transl=0.1, train=True):\n        super(ScaleTransform, self).__init__()\n        self.size = size\n        self.scale = scale\n        self.transl = transl\n        self.train = train\n        self.interpolation = InterpolationMode.BILINEAR\n\n    def forward(self, im):\n        # # assert abs(scale - 1) > 2*transl\n\n        # resize to a certain scale\n        _, h, w = im.shape\n        scale_ = np.random.uniform(self.scale[0], self.scale[1])\n        height, width = int(scale_ * self.size), int(scale_ * self.size / 1.6)\n        s = min(height / h, width / w)\n        im = F.resize(im, [int(h * s), int(w * s)], interpolation=self.interpolation)\n\n        # pad image to big enough\n        ms = 1.4\n        _, h, w = im.shape\n        height, width = int(ms * self.size), int(ms * (self.size / 1.6))  # biggest scale\n        top, left = int((height - h) / 2), int((width - w) / 2)\n        bottom, right = height - h - top, width - w - left\n        pad_value = 0\n        padding = [left, top, right, bottom]\n        im = F.pad(im, padding, fill=pad_value, padding_mode='constant')\n\n        # translation & crop\n        y0 = height / 2 - self.size / 2 + np.random.uniform(-self.transl * self.size, self.transl * self.size)\n        x0 = width / 2 - self.size / 1.6 / 2 + np.random.uniform(-self.transl * (self.size / 1.6), self.transl * (self.size / 1.6))\n        im = im[:, int(y0):int(y0 + self.size), int(x0):int(x0 + self.size / 1.6)]\n        return im\n```\n\n",
    "2169268": "Thanks for sharing a great solution! \nI could learn a lot from your description. \nThank you.",
    "2164237": "Congratulations on the silver medal!\n\n>The PF1 score curve on LB is quite stable and has a wide flat region of max value\n\n👍\n\nAnything that you would do differently?",
    "2165017": "Thanks for sharing a great solution! Would i ask you some questions?\n\nWhat gpu did you use to train the model? Also I don’t understand why high dropout rate is needed due to upsamling.\n\n\n"
  }
}