{
  "id": 229706,
  "title": "4th place solution",
  "url": "/competitions/ranzcr-clip-catheter-line-classification/discussion/229706",
  "author_name": "Dieter",
  "post_date": "2021-03-31T09:59:36.709000",
  "votes": 44,
  "comment_count": 4,
  "views": 0,
  "content": "<h2>Summary</h2>\n<p>Our solution is based on a simple average of single-stage classification models with a surrogate loss for segmentation. Our solution only utilizes the training data provided by the hosts and does not resort to any other additional data. For modeling, we rely on a set of EfficientNet models with a separate Unet head for segmentation. We believe that the simplicity of the solution as well as the lack of external data usage makes this solution unique in the context of other top solutions.</p>\n<h2>Pipeline</h2>\n<p>We approached the competition collaboratively, with each team member working off one central pipeline. We used the following:<br>\nGithub: Versioning and code sharing<br>\nNeptune.ai: logging and visualisation<br>\nKaggle API: dataset upload/download<br>\nAWS: data storage</p>\n<h2>Data setup &amp; CV</h2>\n<p>We only used training data provided by the competition hosts, and did not resort to any external data like additional Chest14 data. Our validation setup was based on a 5-fold random stratified cross validation. We observed good correlation between validation and public leaderboard while developing our solution. Also, our best selected submission was the one that achieved best local cross validation, best public leaderboard score as well as best private leaderboard score demonstrating the robustness of our solution.</p>\n<h2>Models</h2>\n<p>Each model in the blend is a single stage model that consists of an EfficientNet backbone and one classification and one Unet segmentation head. The Unet head operates as a form of regularization for the model and only the output of the classification head is used for final predictions. That enables delete the segmentation part for inference and to reduce the model to a simple EfficentNet.</p>\n<p>We train models by combining the classification loss and segmentation loss and we weight the segmentation loss by 50. We only calculate the segmentation loss on samples where we also have annotations in train data and ignore samples without. For annotations, we interpolate a line between the annotation points using cv2.polylines with a certain thickness. The classification head employs Max Pooling.</p>\n<p>We fit models using Adam optimizer and cosine learning rate decay. For train augmentations, we utilize random horizontal flip, shift/scale/rotate, and random brightness. To better handle inverted images we also randomly invert images while training. We also attempt to keep the aspect ratios of images by applying LongestMaxSize and then randomly cropping parts of the image for training. For inference, we use a slightly larger image size (non-cropped) than while training, but do not apply any further TTA.</p>\n<h2>Blend</h2>\n<p>Our final submission includes 16 models trained on full training data. The models are based on EfficientNet B7 or B8 and trained on either 896 or 1024 squared image size. The blend was a simple average of probability outputs of each model. Our final submission constitutes our best local CV score, best public LB score, and best private LB score.</p>",
  "messages": [
    {
      "id": 1258062,
      "postDate": "2021-03-31T09:59:36.710Z",
      "content": "<h2>Summary</h2>\n<p>Our solution is based on a simple average of single-stage classification models with a surrogate loss for segmentation. Our solution only utilizes the training data provided by the hosts and does not resort to any other additional data. For modeling, we rely on a set of EfficientNet models with a separate Unet head for segmentation. We believe that the simplicity of the solution as well as the lack of external data usage makes this solution unique in the context of other top solutions.</p>\n<h2>Pipeline</h2>\n<p>We approached the competition collaboratively, with each team member working off one central pipeline. We used the following:<br>\nGithub: Versioning and code sharing<br>\nNeptune.ai: logging and visualisation<br>\nKaggle API: dataset upload/download<br>\nAWS: data storage</p>\n<h2>Data setup &amp; CV</h2>\n<p>We only used training data provided by the competition hosts, and did not resort to any external data like additional Chest14 data. Our validation setup was based on a 5-fold random stratified cross validation. We observed good correlation between validation and public leaderboard while developing our solution. Also, our best selected submission was the one that achieved best local cross validation, best public leaderboard score as well as best private leaderboard score demonstrating the robustness of our solution.</p>\n<h2>Models</h2>\n<p>Each model in the blend is a single stage model that consists of an EfficientNet backbone and one classification and one Unet segmentation head. The Unet head operates as a form of regularization for the model and only the output of the classification head is used for final predictions. That enables delete the segmentation part for inference and to reduce the model to a simple EfficentNet.</p>\n<p>We train models by combining the classification loss and segmentation loss and we weight the segmentation loss by 50. We only calculate the segmentation loss on samples where we also have annotations in train data and ignore samples without. For annotations, we interpolate a line between the annotation points using cv2.polylines with a certain thickness. The classification head employs Max Pooling.</p>\n<p>We fit models using Adam optimizer and cosine learning rate decay. For train augmentations, we utilize random horizontal flip, shift/scale/rotate, and random brightness. To better handle inverted images we also randomly invert images while training. We also attempt to keep the aspect ratios of images by applying LongestMaxSize and then randomly cropping parts of the image for training. For inference, we use a slightly larger image size (non-cropped) than while training, but do not apply any further TTA.</p>\n<h2>Blend</h2>\n<p>Our final submission includes 16 models trained on full training data. The models are based on EfficientNet B7 or B8 and trained on either 896 or 1024 squared image size. The blend was a simple average of probability outputs of each model. Our final submission constitutes our best local CV score, best public LB score, and best private LB score.</p>",
      "rawMarkdown": "## Summary\nOur solution is based on a simple average of single-stage classification models with a surrogate loss for segmentation. Our solution only utilizes the training data provided by the hosts and does not resort to any other additional data. For modeling, we rely on a set of EfficientNet models with a separate Unet head for segmentation. We believe that the simplicity of the solution as well as the lack of external data usage makes this solution unique in the context of other top solutions.\n\n\n## Pipeline\nWe approached the competition collaboratively, with each team member working off one central pipeline. We used the following:\nGithub: Versioning and code sharing\nNeptune.ai: logging and visualisation\nKaggle API: dataset upload/download\nAWS: data storage\n\n## Data setup & CV\n\nWe only used training data provided by the competition hosts, and did not resort to any external data like additional Chest14 data. Our validation setup was based on a 5-fold random stratified cross validation. We observed good correlation between validation and public leaderboard while developing our solution. Also, our best selected submission was the one that achieved best local cross validation, best public leaderboard score as well as best private leaderboard score demonstrating the robustness of our solution.\n\n## Models\nEach model in the blend is a single stage model that consists of an EfficientNet backbone and one classification and one Unet segmentation head. The Unet head operates as a form of regularization for the model and only the output of the classification head is used for final predictions. That enables delete the segmentation part for inference and to reduce the model to a simple EfficentNet.\n\nWe train models by combining the classification loss and segmentation loss and we weight the segmentation loss by 50. We only calculate the segmentation loss on samples where we also have annotations in train data and ignore samples without. For annotations, we interpolate a line between the annotation points using cv2.polylines with a certain thickness. The classification head employs Max Pooling.\n\n\nWe fit models using Adam optimizer and cosine learning rate decay. For train augmentations, we utilize random horizontal flip, shift/scale/rotate, and random brightness. To better handle inverted images we also randomly invert images while training. We also attempt to keep the aspect ratios of images by applying LongestMaxSize and then randomly cropping parts of the image for training. For inference, we use a slightly larger image size (non-cropped) than while training, but do not apply any further TTA.\n\n## Blend\nOur final submission includes 16 models trained on full training data. The models are based on EfficientNet B7 or B8 and trained on either 896 or 1024 squared image size. The blend was a simple average of probability outputs of each model. Our final submission constitutes our best local CV score, best public LB score, and best private LB score.\n",
      "votes": 44
    },
    {
      "id": 1362061,
      "postDate": "2021-06-23T07:45:08.040Z",
      "rawMarkdown": "",
      "isDeleted": true,
      "replies": [
        {
          "id": 1362156,
          "postDate": "2021-06-23T08:40:35.377Z",
          "content": "<p>Yes, the weight has some impact. We tried several weights and used the ones giving the best cv score</p>",
          "rawMarkdown": "Yes, the weight has some impact. We tried several weights and used the ones giving the best cv score"
        }
      ]
    },
    {
      "id": 1258963,
      "postDate": "2021-04-01T04:00:49.530Z",
      "rawMarkdown": "",
      "isDeleted": true,
      "replies": [
        {
          "id": 1258992,
          "postDate": "2021-04-01T04:34:43.047Z",
          "content": "<p>You can just set the segmentation loss to 0 for the samples with no annotation. That works with the data here, but might lead to unstable training. A more stable variant is to track the loss of the last batch and put that as loss instead. </p>",
          "rawMarkdown": "You can just set the segmentation loss to 0 for the samples with no annotation. That works with the data here, but might lead to unstable training. A more stable variant is to track the loss of the last batch and put that as loss instead. "
        }
      ]
    }
  ],
  "comments": [
    {
      "id": 1362061,
      "author_name": "",
      "author_url": "",
      "post_date": "2021-06-23T07:45:08.040000",
      "content": "",
      "votes": 0,
      "replies": [
        {
          "id": 1362156,
          "author_name": "Dieter",
          "author_url": "",
          "post_date": "2021-06-23T08:40:35.377000",
          "content": "<p>Yes, the weight has some impact. We tried several weights and used the ones giving the best cv score</p>",
          "votes": 0,
          "replies": []
        }
      ]
    },
    {
      "id": 1258963,
      "author_name": "",
      "author_url": "",
      "post_date": "2021-04-01T04:00:49.530000",
      "content": "",
      "votes": 0,
      "replies": [
        {
          "id": 1258992,
          "author_name": "Dieter",
          "author_url": "",
          "post_date": "2021-04-01T04:34:43.047000",
          "content": "<p>You can just set the segmentation loss to 0 for the samples with no annotation. That works with the data here, but might lead to unstable training. A more stable variant is to track the loss of the last batch and put that as loss instead. </p>",
          "votes": 0,
          "replies": []
        }
      ]
    }
  ],
  "raw_markdown_by_id": {
    "1258062": "## Summary\nOur solution is based on a simple average of single-stage classification models with a surrogate loss for segmentation. Our solution only utilizes the training data provided by the hosts and does not resort to any other additional data. For modeling, we rely on a set of EfficientNet models with a separate Unet head for segmentation. We believe that the simplicity of the solution as well as the lack of external data usage makes this solution unique in the context of other top solutions.\n\n\n## Pipeline\nWe approached the competition collaboratively, with each team member working off one central pipeline. We used the following:\nGithub: Versioning and code sharing\nNeptune.ai: logging and visualisation\nKaggle API: dataset upload/download\nAWS: data storage\n\n## Data setup & CV\n\nWe only used training data provided by the competition hosts, and did not resort to any external data like additional Chest14 data. Our validation setup was based on a 5-fold random stratified cross validation. We observed good correlation between validation and public leaderboard while developing our solution. Also, our best selected submission was the one that achieved best local cross validation, best public leaderboard score as well as best private leaderboard score demonstrating the robustness of our solution.\n\n## Models\nEach model in the blend is a single stage model that consists of an EfficientNet backbone and one classification and one Unet segmentation head. The Unet head operates as a form of regularization for the model and only the output of the classification head is used for final predictions. That enables delete the segmentation part for inference and to reduce the model to a simple EfficentNet.\n\nWe train models by combining the classification loss and segmentation loss and we weight the segmentation loss by 50. We only calculate the segmentation loss on samples where we also have annotations in train data and ignore samples without. For annotations, we interpolate a line between the annotation points using cv2.polylines with a certain thickness. The classification head employs Max Pooling.\n\n\nWe fit models using Adam optimizer and cosine learning rate decay. For train augmentations, we utilize random horizontal flip, shift/scale/rotate, and random brightness. To better handle inverted images we also randomly invert images while training. We also attempt to keep the aspect ratios of images by applying LongestMaxSize and then randomly cropping parts of the image for training. For inference, we use a slightly larger image size (non-cropped) than while training, but do not apply any further TTA.\n\n## Blend\nOur final submission includes 16 models trained on full training data. The models are based on EfficientNet B7 or B8 and trained on either 896 or 1024 squared image size. The blend was a simple average of probability outputs of each model. Our final submission constitutes our best local CV score, best public LB score, and best private LB score.\n",
    "1362061": "",
    "1258963": ""
  }
}