{
  "id": 146855,
  "title": "PANDA concat tile pooling starter [0.79 LB]",
  "url": "/competitions/prostate-cancer-grade-assessment/discussion/146855",
  "author_name": "Iafoss",
  "post_date": "2020-04-28T17:38:15.474000",
  "votes": 129,
  "comment_count": 69,
  "views": 0,
  "content": "<p>Welcome to Prostate cANcer graDe Assessment (PANDA) Challenge. I have prepared a starter pack based on my idea of concat tile pooling (see the image below and <a href=\"https://www.kaggle.com/iafoss/panda-concat-tile-pooling-starter-0-79-lb\">this kernel</a>). Specifically, I provide a <a href=\"https://www.kaggle.com/iafoss/panda-16x128x128-tiles\">data preprocessing kernel</a> creating 16 128x128 tiles for each image selected based on the number of tissue pixels, <a href=\"https://www.kaggle.com/iafoss/panda-concat-tile-pooling-starter-0-79-lb\">model training kernel</a> with detailed description of the proposed method, and <a href=\"https://www.kaggle.com/iafoss/panda-concat-tile-pooling-starter-inference\">inference kernel</a>, which reached 0.79 public LB. I hope you will enjoy the competition and find these kernels to be useful to start with the challenge.</p>\n\n<p><img src=\"https://www.googleapis.com/download/storage/v1/b/kaggle-user-content/o/inbox%2F1212661%2Fe6fe32d759a28480343001aa3c661723%2FTILE.png?generation=1588094975239255&amp;alt=media\" alt=\"\"></p>",
  "messages": [
    {
      "id": 824954,
      "postDate": "2020-04-28T17:38:15.473Z",
      "content": "<p>Welcome to Prostate cANcer graDe Assessment (PANDA) Challenge. I have prepared a starter pack based on my idea of concat tile pooling (see the image below and <a href=\"https://www.kaggle.com/iafoss/panda-concat-tile-pooling-starter-0-79-lb\">this kernel</a>). Specifically, I provide a <a href=\"https://www.kaggle.com/iafoss/panda-16x128x128-tiles\">data preprocessing kernel</a> creating 16 128x128 tiles for each image selected based on the number of tissue pixels, <a href=\"https://www.kaggle.com/iafoss/panda-concat-tile-pooling-starter-0-79-lb\">model training kernel</a> with detailed description of the proposed method, and <a href=\"https://www.kaggle.com/iafoss/panda-concat-tile-pooling-starter-inference\">inference kernel</a>, which reached 0.79 public LB. I hope you will enjoy the competition and find these kernels to be useful to start with the challenge.</p>\n\n<p><img src=\"https://www.googleapis.com/download/storage/v1/b/kaggle-user-content/o/inbox%2F1212661%2Fe6fe32d759a28480343001aa3c661723%2FTILE.png?generation=1588094975239255&amp;alt=media\" alt=\"\"></p>",
      "rawMarkdown": "Welcome to Prostate cANcer graDe Assessment (PANDA) Challenge. I have prepared a starter pack based on my idea of concat tile pooling (see the image below and [this kernel](https://www.kaggle.com/iafoss/panda-concat-tile-pooling-starter-0-79-lb)). Specifically, I provide a [data preprocessing kernel](https://www.kaggle.com/iafoss/panda-16x128x128-tiles) creating 16 128x128 tiles for each image selected based on the number of tissue pixels, [model training kernel](https://www.kaggle.com/iafoss/panda-concat-tile-pooling-starter-0-79-lb) with detailed description of the proposed method, and [inference kernel](https://www.kaggle.com/iafoss/panda-concat-tile-pooling-starter-inference), which reached 0.79 public LB. I hope you will enjoy the competition and find these kernels to be useful to start with the challenge.\n\n![](https://www.googleapis.com/download/storage/v1/b/kaggle-user-content/o/inbox%2F1212661%2Fe6fe32d759a28480343001aa3c661723%2FTILE.png?generation=1588094975239255&amp;alt=media)\n",
      "votes": 128
    },
    {
      "id": 833079,
      "postDate": "2020-05-04T15:30:25.827Z",
      "content": "<p>Just an update on the number N:\n<code>\nN=12 - 0.843 CV\n[[2290  424  106   41   11    1]\n [ 463 1563  455  116   17    2]\n [  60  396  547  261   67   10]\n [  26   81  213  397  395  114]\n [  29   65  128  182  450  391]\n [  13   31   42   91  270  768]]\n</code>\n<code>\nN=8 - 0.830 CV\n[[2176  519  126   37   12    3]\n [ 474 1512  490  107   30    3]\n [  70  367  544  264   83   13]\n [  30   78  206  396  388  128]\n [  31   74  115  187  424  414]\n [  24   30   43   82  261  775]]\n</code>\n<code>\nN=16 (smaller bs) - 0.840 CV\n[[2269  442  115   35   11    1]\n [ 435 1541  510  103   25    2]\n [  59  333  565  284   87   13]\n [  21   71  210  400  362  162]\n [  32   64  111  185  407  446]\n [  19   29   40   95  249  783]]\n</code>\nThese results are obtained for 4-fold CV on 128x128 tiles, while LB is ~0.80.</p>",
      "rawMarkdown": "Just an update on the number N:\n```\nN=12 - 0.843 CV\n[[2290  424  106   41   11    1]\n [ 463 1563  455  116   17    2]\n [  60  396  547  261   67   10]\n [  26   81  213  397  395  114]\n [  29   65  128  182  450  391]\n [  13   31   42   91  270  768]]\n```\n```\nN=8 - 0.830 CV\n[[2176  519  126   37   12    3]\n [ 474 1512  490  107   30    3]\n [  70  367  544  264   83   13]\n [  30   78  206  396  388  128]\n [  31   74  115  187  424  414]\n [  24   30   43   82  261  775]]\n```\n```\nN=16 (smaller bs) - 0.840 CV\n[[2269  442  115   35   11    1]\n [ 435 1541  510  103   25    2]\n [  59  333  565  284   87   13]\n [  21   71  210  400  362  162]\n [  32   64  111  185  407  446]\n [  19   29   40   95  249  783]]\n```\nThese results are obtained for 4-fold CV on 128x128 tiles, while LB is ~0.80.",
      "votes": 6
    },
    {
      "id": 910115,
      "postDate": "2020-07-01T02:12:31.623Z",
      "content": "<p>New candidate at 0.90 LB single fold:\nCV 0.8911 <br>\nEfficientNet-b0 256x256x16 Tiles\nLot of extra computations during inference (TTA and more).</p>\n\n<p>Still using very naive head...</p>",
      "rawMarkdown": "New candidate at 0.90 LB single fold:\nCV 0.8911  \nEfficientNet-b0 256x256x16 Tiles\nLot of extra computations during inference (TTA and more).\n\nStill using very naive head...",
      "votes": 3,
      "replies": [
        {
          "id": 910132,
          "postDate": "2020-07-01T02:25:22.377Z",
          "content": "<p>Wow.</p>",
          "rawMarkdown": "Wow."
        },
        {
          "id": 910133,
          "postDate": "2020-07-01T02:25:45.563Z",
          "content": "<p>Intermediate Resolution or Mixture?</p>",
          "rawMarkdown": "Intermediate Resolution or Mixture?"
        }
      ]
    },
    {
      "id": 827847,
      "postDate": "2020-04-30T15:21:48.127Z",
      "content": "<p>To verify I am looking at the model correctly, you utilize the mask values to determine those tiles with tissue cells in them? Does this then effect the results as the test images as the tiles created are not scaled down for maximizing tissue presence? </p>",
      "rawMarkdown": "To verify I am looking at the model correctly, you utilize the mask values to determine those tiles with tissue cells in them? Does this then effect the results as the test images as the tiles created are not scaled down for maximizing tissue presence? ",
      "votes": 3,
      "replies": [
        {
          "id": 827979,
          "postDate": "2020-04-30T17:22:39.877Z",
          "content": "<p>I check how much the pixels are different from the background (255) and sort the tiles based on it, I do not use masks to create tiles.</p>",
          "rawMarkdown": "I check how much the pixels are different from the background (255) and sort the tiles based on it, I do not use masks to create tiles.",
          "votes": 3
        },
        {
          "id": 828610,
          "postDate": "2020-05-01T07:22:32.500Z",
          "content": "<p>I think this is a very good think to investigate Zac. There is a specific line of code that does the selection. It's with np.argsort(......)[:N]. If you study this in depth you'll see lafoss indeed filters tiles according to their pixels values (a tile with all black pixels would be selected first, because its sum would be 0).</p>",
          "rawMarkdown": "I think this is a very good think to investigate Zac. There is a specific line of code that does the selection. It's with np.argsort(......)[:N]. If you study this in depth you'll see lafoss indeed filters tiles according to their pixels values (a tile with all black pixels would be selected first, because its sum would be 0).",
          "votes": 2
        }
      ]
    },
    {
      "id": 830271,
      "postDate": "2020-05-02T13:11:42.213Z",
      "content": "<p>Congratz on getting that well deserved Kernel Grandmaster <a href=\"/iafoss\">@iafoss</a> !</p>",
      "rawMarkdown": "Congratz on getting that well deserved Kernel Grandmaster @iafoss !",
      "votes": 1,
      "replies": [
        {
          "id": 830273,
          "postDate": "2020-05-02T13:13:59.683Z",
          "content": "<p>Thanks so much <a href=\"/theoviel\">@theoviel</a> </p>",
          "rawMarkdown": "Thanks so much @theoviel ",
          "votes": 1
        }
      ]
    },
    {
      "id": 825412,
      "postDate": "2020-04-29T01:43:48.700Z",
      "content": "<p>Amazing! Thanks for sharing your idea about the intelligent way of data preprocessing.</p>",
      "rawMarkdown": "Amazing! Thanks for sharing your idea about the intelligent way of data preprocessing.",
      "votes": 1
    },
    {
      "id": 825148,
      "postDate": "2020-04-28T20:14:48.580Z",
      "content": "<p>This is simply amazing. That's very high quality content. Thank you so much for sharing that kind of stuff ! </p>",
      "rawMarkdown": "This is simply amazing. That's very high quality content. Thank you so much for sharing that kind of stuff ! ",
      "votes": 1,
      "replies": [
        {
          "id": 825157,
          "postDate": "2020-04-28T20:25:45.747Z",
          "content": "<p>You are welcome.</p>",
          "rawMarkdown": "You are welcome."
        }
      ]
    },
    {
      "id": 825128,
      "postDate": "2020-04-28T19:53:36.133Z",
      "content": "<p>Thanks for sharing! As DrHB said we all appropriate your amazing sharing in these comps!</p>\n\n<p>But there appears to be an issue with the dataset you provided, there are missing images when trying to run. Did you name any images weirdly?</p>",
      "rawMarkdown": "Thanks for sharing! As DrHB said we all appropriate your amazing sharing in these comps!\n\nBut there appears to be an issue with the dataset you provided, there are missing images when trying to run. Did you name any images weirdly?",
      "votes": 1,
      "replies": [
        {
          "id": 825137,
          "postDate": "2020-04-28T20:05:42.703Z",
          "content": "<p>You are welcome. I think you are referring to images that do not have masks, I saw a few of them, like tens if I remember correctly. Since I'm planning also to explore segmentation based aux, I considered only images with masks when created this dataset.</p>",
          "rawMarkdown": "You are welcome. I think you are referring to images that do not have masks, I saw a few of them, like tens if I remember correctly. Since I'm planning also to explore segmentation based aux, I considered only images with masks when created this dataset.",
          "votes": 1
        },
        {
          "id": 829023,
          "postDate": "2020-05-01T12:53:15.143Z",
          "content": "<p>Congrats on becoming Notebook GM!!</p>",
          "rawMarkdown": "Congrats on becoming Notebook GM!!",
          "votes": 1
        },
        {
          "id": 830546,
          "postDate": "2020-05-02T17:10:05.570Z",
          "content": "<p>Thanks so much.</p>",
          "rawMarkdown": "Thanks so much.",
          "votes": 1
        }
      ]
    },
    {
      "id": 825446,
      "postDate": "2020-04-29T02:43:20.783Z",
      "content": "<p>Just a small question: how you decide the tile size and the number of tiles for each image?\nI am wondering if the image is extremely super resolution, then insufficient number of small tiles\nmight lose some information of the original image.</p>",
      "rawMarkdown": "Just a small question: how you decide the tile size and the number of tiles for each image?\nI am wondering if the image is extremely super resolution, then insufficient number of small tiles\nmight lose some information of the original image.",
      "votes": 2,
      "replies": [
        {
          "id": 825467,
          "postDate": "2020-04-29T03:06:37.603Z",
          "content": "<p>You could check the number N' after which the next tiles are nearly empty for most of the images. For example here when I tried to use 16x128x128 tiles, I found that in most cases 3-5 last tiles are almost completely white. So I decided to go 12, but I didn't evaluate the model performance for different setups. Also, make sure that the tiles are not too small especially for intermediate and high resolution images.</p>",
          "rawMarkdown": "You could check the number N' after which the next tiles are nearly empty for most of the images. For example here when I tried to use 16x128x128 tiles, I found that in most cases 3-5 last tiles are almost completely white. So I decided to go 12, but I didn't evaluate the model performance for different setups. Also, make sure that the tiles are not too small especially for intermediate and high resolution images.",
          "votes": 2
        },
        {
          "id": 826951,
          "postDate": "2020-04-30T01:12:06.167Z",
          "content": "<p>Thanks for illustration. It is really helpful : )</p>",
          "rawMarkdown": "Thanks for illustration. It is really helpful : )"
        }
      ]
    },
    {
      "id": 825055,
      "postDate": "2020-04-28T18:51:33.227Z",
      "content": "<p>As per usual high quality kernels. Your starter  public kernels were extremely useful in Bengali Competition as well =) And well deserved future (very soon) Kernel Grandmaster =) </p>",
      "rawMarkdown": "As per usual high quality kernels. Your starter  public kernels were extremely useful in Bengali Competition as well =) And well deserved future (very soon) Kernel Grandmaster =) ",
      "votes": 2,
      "replies": [
        {
          "id": 825073,
          "postDate": "2020-04-28T19:02:20.497Z",
          "content": "<p>Thanks so much. At Bengali competition it was quite surprising that my public starter kernel got to the upper bronze zone at private LB while public score was quite low. I hope it will not happen again, and the final LB would represent the real efforts made by participants.</p>",
          "rawMarkdown": "Thanks so much. At Bengali competition it was quite surprising that my public starter kernel got to the upper bronze zone at private LB while public score was quite low. I hope it will not happen again, and the final LB would represent the real efforts made by participants.",
          "votes": 6
        },
        {
          "id": 826651,
          "postDate": "2020-04-29T19:02:09.710Z",
          "content": "<p>Your model did good in private , because it generalized well and you built a nice model :) </p>",
          "rawMarkdown": "Your model did good in private , because it generalized well and you built a nice model :) ",
          "votes": 1
        }
      ]
    },
    {
      "id": 3052294,
      "postDate": "2024-11-22T08:54:27.383Z",
      "content": "<p>Great Job! How to reference your method in a research paper?</p>",
      "rawMarkdown": "Great Job! How to reference your method in a research paper?"
    },
    {
      "id": 905831,
      "postDate": "2020-06-28T21:03:09.827Z",
      "content": "<p>hi, there @lafoss, can you share a way to make a vanilla submission with AI. thanks.</p>",
      "rawMarkdown": "hi, there @lafoss, can you share a way to make a vanilla submission with AI. thanks.",
      "replies": [
        {
          "id": 905886,
          "postDate": "2020-06-28T22:56:18.673Z",
          "content": "<p>Check my public kernels listed above</p>",
          "rawMarkdown": "Check my public kernels listed above"
        },
        {
          "id": 905934,
          "postDate": "2020-06-29T00:49:14.800Z",
          "content": "<p>Hi @lafoss thanks for the replay, besides I am learning still how to do kaggle submission, I am using your technique of breaking down the large image into pieces, and passing them on to the model with other techniques.\n~~~\nepoch   train_loss  valid_loss  accuracy    error_rate  cohen_kappa_score   time\n16     1.090601     0.925868    0.981913    0.018087    0.979144                    02:58\n~~~\nI want to be able to test the models I have created,  but I am having a little bit of a problem understanding what you are doing on your code ( I have learned a lot from you and your postings, and answer to my questions, thanks).</p>\n\n<p>1.- It looks to me that you are not using fastai predict method, learn.get_preds, but strait PyTorch code, right?\n2.- I was wondering how you will go about and right your Pytorch code with fastai methods, sorry it that I have looked everywhere on the web, and cant find something that will help me.\n3.- when you do this, x = x.cuda() I thought it was best to set the inference images into the CPU not GPU.\n4.- \n            #dihedral TTA\n            x = torch.stack([x,x.flip(-1),x.flip(-2),x.flip(-1,-2),\n              x.transpose(-1,-2),x.transpose(-1,-2).flip(-1),\n              x.transpose(-1,-2).flip(-2),x.transpose(-1,-2).flip(-1,-2)],1)\n            x = x.view(-1,N,3,sz,sz)</p>\n\n<p>no idea what you are doing here.. hehehe.... but I guess it does not work with one image, as it meant to be used with many fragments of sz size.</p>\n\n<p>I have other questions, but I think I can understand the rest if I can get to understand these ones.</p>\n\n<p>Thanks again!</p>",
          "rawMarkdown": "Hi @lafoss thanks for the replay, besides I am learning still how to do kaggle submission, I am using your technique of breaking down the large image into pieces, and passing them on to the model with other techniques.\n~~~\nepoch \ttrain_loss \tvalid_loss \taccuracy \terror_rate \tcohen_kappa_score \ttime\n16     1.090601 \t0.925868 \t0.981913 \t0.018087 \t0.979144 \t                02:58\n~~~\nI want to be able to test the models I have created,  but I am having a little bit of a problem understanding what you are doing on your code ( I have learned a lot from you and your postings, and answer to my questions, thanks).\n\n1.- It looks to me that you are not using fastai predict method, learn.get_preds, but strait PyTorch code, right?\n2.- I was wondering how you will go about and right your Pytorch code with fastai methods, sorry it that I have looked everywhere on the web, and cant find something that will help me.\n3.- when you do this, x = x.cuda() I thought it was best to set the inference images into the CPU not GPU.\n4.- \n            #dihedral TTA\n            x = torch.stack([x,x.flip(-1),x.flip(-2),x.flip(-1,-2),\n              x.transpose(-1,-2),x.transpose(-1,-2).flip(-1),\n              x.transpose(-1,-2).flip(-2),x.transpose(-1,-2).flip(-1,-2)],1)\n            x = x.view(-1,N,3,sz,sz)\n\nno idea what you are doing here.. hehehe.... but I guess it does not work with one image, as it meant to be used with many fragments of sz size.\n\nI have other questions, but I think I can understand the rest if I can get to understand these ones.\n\nThanks again!"
        },
        {
          "id": 905963,
          "postDate": "2020-06-29T01:59:15.323Z",
          "content": "<p>1) Yes\n2) fast.ai inference pipeline is quite limited. So, if you want to get prediction for multiple models without reading the data several times, or doing proper TTA, Pytorch is your way to go. If you want to use fast.ai for inference, u can refer to  learn.get_preds method, if I remember correctly, but you will need to write your own code.\n3) If u do inference on CPU, it will take really forever. You can try to run CPU kernel (and comment all cuda related stuff) and see how many images per second u can get (change the path to train to do this test interactively).\n4) TTA means Test Time Augmentation. Google it to see further details. I just create a list of augmented images and combine them into a single batch. I recommend u to play with a dummy image and printout the shape after each operation to understand how it works.</p>",
          "rawMarkdown": "1) Yes\n2) fast.ai inference pipeline is quite limited. So, if you want to get prediction for multiple models without reading the data several times, or doing proper TTA, Pytorch is your way to go. If you want to use fast.ai for inference, u can refer to  learn.get_preds method, if I remember correctly, but you will need to write your own code.\n3) If u do inference on CPU, it will take really forever. You can try to run CPU kernel (and comment all cuda related stuff) and see how many images per second u can get (change the path to train to do this test interactively).\n4) TTA means Test Time Augmentation. Google it to see further details. I just create a list of augmented images and combine them into a single batch. I recommend u to play with a dummy image and printout the shape after each operation to understand how it works."
        },
        {
          "id": 906635,
          "postDate": "2020-06-29T13:09:50.143Z",
          "content": "<p>Hey @lafoss thanks for your response, I appreciate it.\n2.- I see, <br>\n3.- I see,\n4.a- Will do bro. \n4.b- then when you do \"x = x.view(-1,N,3,sz,sz)\" is when you combine the images into one and then pass the single image into the model with mode(x), right?</p>\n\n<p>Thanks a lot again.</p>",
          "rawMarkdown": "Hey @lafoss thanks for your response, I appreciate it.\n2.- I see,  \n3.- I see,\n4.a- Will do bro. \n4.b- then when you do \"x = x.view(-1,N,3,sz,sz)\" is when you combine the images into one and then pass the single image into the model with mode(x), right?\n\nThanks a lot again."
        },
        {
          "id": 906962,
          "postDate": "2020-06-29T16:30:30.207Z",
          "content": "<p>As I wrote, it combines augmented images into a single batch.</p>",
          "rawMarkdown": "As I wrote, it combines augmented images into a single batch."
        }
      ]
    },
    {
      "id": 899064,
      "postDate": "2020-06-24T00:11:10.157Z",
      "content": "<p>Great work, thanks for sharing!\nHowever, is there any resource to better understand the used concat tile pooling technique?\nI'm kinda new in image nets 😩 </p>",
      "rawMarkdown": "Great work, thanks for sharing!\nHowever, is there any resource to better understand the used concat tile pooling technique?\nI'm kinda new in image nets 😩 ",
      "replies": [
        {
          "id": 899139,
          "postDate": "2020-06-24T02:53:14.437Z",
          "content": "<p>It's a brand new idea, and I haven't seen anything related to it. Though, it's quite simple one, and I wouldn't be surprised if something similar to it already exists.</p>",
          "rawMarkdown": "It's a brand new idea, and I haven't seen anything related to it. Though, it's quite simple one, and I wouldn't be surprised if something similar to it already exists.",
          "votes": 5
        },
        {
          "id": 899259,
          "postDate": "2020-06-24T05:50:51.140Z",
          "content": "<p>I would recommend maybe to read some review paper on the topic of Multiple Instance Learning. It helped me at least to clarify the idea more or less.</p>",
          "rawMarkdown": "I would recommend maybe to read some review paper on the topic of Multiple Instance Learning. It helped me at least to clarify the idea more or less.",
          "votes": 3
        },
        {
          "id": 900491,
          "postDate": "2020-06-24T20:48:35.653Z",
          "content": "<p>Thanks, everyone &lt;3</p>",
          "rawMarkdown": "Thanks, everyone &lt;3"
        }
      ]
    },
    {
      "id": 873199,
      "postDate": "2020-06-03T22:25:07.513Z",
      "content": "<ol>\n<li>what governs the output shape? I'm assuming the 4X4 is the image size after the convolutions</li>\n<li>Does it matter how you reshape the output? Wouldn't it be more intuitive if the output was B X C*N X 4 X 4 instead?</li>\n</ol>",
      "rawMarkdown": "1. what governs the output shape? I'm assuming the 4X4 is the image size after the convolutions\n2. Does it matter how you reshape the output? Wouldn't it be more intuitive if the output was B X C*N X 4 X 4 instead?",
      "replies": [
        {
          "id": 873217,
          "postDate": "2020-06-03T23:09:33.537Z",
          "content": "<p>1) Almost for all computer vision models the CNN part reduces the res by 32 times, so 128/32=4.\n2) The tiles should be concatenated specially to be an approximation of classification on entire images. The proposed method, ideally, should be the same to one when an entire image is given as an input. However, the issues with different image shape and overhead because of empty white space are solved. \nMeanwhile, channel-wise concatenation, which u mentioned, is based on quite different idea: stacking a conv model based on tiles and NN generating labels for it. Training with just individual tiles is challenging here because labels assigned to entire images are different from one assigned to tiles forming the images. So one could have a net that would generate some pseudo labels in high dim space in end-to-end manner. I didn't check the idea you mentioned, but it may work as well. The thing u should consider in this case, though, is permutation invariance with respect to the order of tiles.</p>",
          "rawMarkdown": "1) Almost for all computer vision models the CNN part reduces the res by 32 times, so 128/32=4.\n2) The tiles should be concatenated specially to be an approximation of classification on entire images. The proposed method, ideally, should be the same to one when an entire image is given as an input. However, the issues with different image shape and overhead because of empty white space are solved. \nMeanwhile, channel-wise concatenation, which u mentioned, is based on quite different idea: stacking a conv model based on tiles and NN generating labels for it. Training with just individual tiles is challenging here because labels assigned to entire images are different from one assigned to tiles forming the images. So one could have a net that would generate some pseudo labels in high dim space in end-to-end manner. I didn't check the idea you mentioned, but it may work as well. The thing u should consider in this case, though, is permutation invariance with respect to the order of tiles."
        },
        {
          "id": 873261,
          "postDate": "2020-06-04T01:22:34.780Z",
          "content": "<p>You'll also have to consider the size of the Linear layer after that. If you use a resnet50 your C is probably already 1K or 2K can't remember. So if you use 32 tiles it is a 32K 64K wide... Transforming that into say 512 is a pretty high number of parameters.</p>",
          "rawMarkdown": "You'll also have to consider the size of the Linear layer after that. If you use a resnet50 your C is probably already 1K or 2K can't remember. So if you use 32 tiles it is a 32K 64K wide... Transforming that into say 512 is a pretty high number of parameters."
        }
      ]
    },
    {
      "id": 854157,
      "postDate": "2020-05-19T19:54:49.193Z",
      "content": "<p>Thanks :)\nI have one question, I am new in this field , so my question might look like a naive question 👀 \nEvery image now is represent in 12 images, I am using keras , how to fit this data into CNN model ? \nCan you provide me a kernel or any reference where I can learn from ?</p>\n\n<p>Thansk :)</p>",
      "rawMarkdown": "Thanks :)\nI have one question, I am new in this field , so my question might look like a naive question 👀 \nEvery image now is represent in 12 images, I am using keras , how to fit this data into CNN model ? \nCan you provide me a kernel or any reference where I can learn from ?\n\nThansk :)",
      "replies": [
        {
          "id": 854212,
          "postDate": "2020-05-19T21:17:46.053Z",
          "content": "<p>Unfortunately, I'm not very familiar with keras. I believe that there should be a way to implement it in this framework, but <a href=\"/xiejialun\">@xiejialun</a> pointed out below that there are some difficulties related to TensorFlow itself, which keras also may inherit.\nI saw <a href=\"https://www.kaggle.com/vgarshin/panda-keras-baseline\">one keras public kernel</a> where the tiles are combined into a big single image given to the network. It is not exactly that I do but presumably works similar.</p>",
          "rawMarkdown": "Unfortunately, I'm not very familiar with keras. I believe that there should be a way to implement it in this framework, but @xiejialun pointed out below that there are some difficulties related to TensorFlow itself, which keras also may inherit.\nI saw [one keras public kernel](https://www.kaggle.com/vgarshin/panda-keras-baseline) where the tiles are combined into a big single image given to the network. It is not exactly that I do but presumably works similar.",
          "votes": 2
        },
        {
          "id": 854225,
          "postDate": "2020-05-19T21:52:31.113Z",
          "content": "<p>Thanks alot :)</p>",
          "rawMarkdown": "Thanks alot :)"
        },
        {
          "id": 854269,
          "postDate": "2020-05-19T23:23:54.033Z",
          "content": "<p><a href=\"/yaheaal\">@yaheaal</a> You might not able to perform this idea on keras due to the reason I wrote below, but after some experiments I found that tensorflow is okay. In tensorflow, you need to customize the training loop and create two separated model for tiles training. I already shared a notebook(see below link) how to perform this idea in tensorflow, you only need to modify some of your code in keras. Good luck.</p>\n\n<p><a href=\"https://www.kaggle.com/xiejialun/panda-tiles-training-on-tensorflow-0-7-cv\">https://www.kaggle.com/xiejialun/panda-tiles-training-on-tensorflow-0-7-cv</a></p>",
          "rawMarkdown": "@yaheaal You might not able to perform this idea on keras due to the reason I wrote below, but after some experiments I found that tensorflow is okay. In tensorflow, you need to customize the training loop and create two separated model for tiles training. I already shared a notebook(see below link) how to perform this idea in tensorflow, you only need to modify some of your code in keras. Good luck.\n\nhttps://www.kaggle.com/xiejialun/panda-tiles-training-on-tensorflow-0-7-cv",
          "votes": 3
        },
        {
          "id": 864874,
          "postDate": "2020-05-28T08:40:15.457Z",
          "content": "<p>Thank you for helping :), I am really surprised that keras can't preform this idea :/</p>",
          "rawMarkdown": "Thank you for helping :), I am really surprised that keras can't preform this idea :/"
        },
        {
          "id": 865843,
          "postDate": "2020-05-28T23:43:44.037Z",
          "content": "<p>What I have found is that you can use a TimeDistributed layer to wrap around your CNN model and then apply the pooling by reshaping the feature map to a grid. However, it is a little inconvenient to implement.</p>",
          "rawMarkdown": "What I have found is that you can use a TimeDistributed layer to wrap around your CNN model and then apply the pooling by reshaping the feature map to a grid. However, it is a little inconvenient to implement.",
          "votes": 2
        },
        {
          "id": 866298,
          "postDate": "2020-05-29T09:21:38.560Z",
          "content": "<p><a href=\"/richardxiao03\">@richardxiao03</a>  yea I found this idea <a href=\"https://www.kaggle.com/vgarshin/panda-keras-timedistributed\">here</a></p>\n\n<p><code>\nbottleneck = efn.EfficientNetB1(\n    weights='../input/effnetweights/efficientnet-b1_weights_tf_dim_ordering_tf_kernels_autoaugment_notop.h5', \n    include_top=False, \n    pooling='avg'\n)\nbottleneck = Model(inputs=bottleneck.inputs, outputs=bottleneck.layers[-2].output)\nmodel = Sequential()\nmodel.add(TimeDistributed(bottleneck, input_shape=(SEQ_LEN, IMG_SIZE, IMG_SIZE, 3)))\nmodel.add(TimeDistributed(BatchNormalization()))\nmodel.add(GlobalMaxPooling3D())\nmodel.add(BatchNormalization())\nmodel.add(Dropout(.4))\nmodel.add(Dense(512, activation='Mish'))\nmodel.add(BatchNormalization())\nmodel.add(Dropout(.4))\nmodel.add(Dense(128, activation='Mish'))\nmodel.add(BatchNormalization())\nmodel.add(Dropout(.4))\nmodel.add(Dense(6, activation='softmax'))\n</code></p>",
          "rawMarkdown": "@richardxiao03  yea I found this idea [here](https://www.kaggle.com/vgarshin/panda-keras-timedistributed)\n\n\n```\nbottleneck = efn.EfficientNetB1(\n    weights='../input/effnetweights/efficientnet-b1_weights_tf_dim_ordering_tf_kernels_autoaugment_notop.h5', \n    include_top=False, \n    pooling='avg'\n)\nbottleneck = Model(inputs=bottleneck.inputs, outputs=bottleneck.layers[-2].output)\nmodel = Sequential()\nmodel.add(TimeDistributed(bottleneck, input_shape=(SEQ_LEN, IMG_SIZE, IMG_SIZE, 3)))\nmodel.add(TimeDistributed(BatchNormalization()))\nmodel.add(GlobalMaxPooling3D())\nmodel.add(BatchNormalization())\nmodel.add(Dropout(.4))\nmodel.add(Dense(512, activation='Mish'))\nmodel.add(BatchNormalization())\nmodel.add(Dropout(.4))\nmodel.add(Dense(128, activation='Mish'))\nmodel.add(BatchNormalization())\nmodel.add(Dropout(.4))\nmodel.add(Dense(6, activation='softmax'))\n```",
          "votes": 3
        },
        {
          "id": 867709,
          "postDate": "2020-05-30T14:48:33.957Z",
          "content": "<p>I think I should share this (works fine for me):</p>\n\n<p>```\nclass ConvNet(tf.keras.Model):</p>\n\n<pre><code>def __init__(self, engine, input_shape, weights):\n    super(ConvNet, self).__init__()\n    self.engine = engine(\n        include_top=False, input_shape=input_shape, weights=weights)\n    self.avg_pool2d = tf.keras.layers.GlobalAveragePooling2D()\n    self.dropout = tf.keras.layers.Dropout(0.5)\n    self.dense_1 = tf.keras.layers.Dense(512)\n    self.dense_2 = tf.keras.layers.Dense(1)\n\n@tf.function\ndef call(self, inputs, **kwargs):\n    x = self.engine(inputs)\n    x = tf.reshape(x, (-1, 16*4, 4, 2048)) # 16 tiles\n    x = self.avg_pool2d(x)\n    x = self.dropout(x, training=kwargs.get('training', False))\n    x = self.dense_1(x)\n    x = tf.nn.relu(x)\n    return self.dense_2(x)\n</code></pre>\n\n<p>model = ConvNet(\n    engine=Xception, input_shape=(128, 128, 3), weights='imagenet'\n) \n```</p>",
          "rawMarkdown": "I think I should share this (works fine for me):\n\n```\nclass ConvNet(tf.keras.Model):\n\n    def __init__(self, engine, input_shape, weights):\n        super(ConvNet, self).__init__()\n        self.engine = engine(\n            include_top=False, input_shape=input_shape, weights=weights)\n        self.avg_pool2d = tf.keras.layers.GlobalAveragePooling2D()\n        self.dropout = tf.keras.layers.Dropout(0.5)\n        self.dense_1 = tf.keras.layers.Dense(512)\n        self.dense_2 = tf.keras.layers.Dense(1)\n\n    @tf.function\n    def call(self, inputs, **kwargs):\n        x = self.engine(inputs)\n        x = tf.reshape(x, (-1, 16*4, 4, 2048)) # 16 tiles\n        x = self.avg_pool2d(x)\n        x = self.dropout(x, training=kwargs.get('training', False))\n        x = self.dense_1(x)\n        x = tf.nn.relu(x)\n        return self.dense_2(x)\n\nmodel = ConvNet(\n    engine=Xception, input_shape=(128, 128, 3), weights='imagenet'\n) \n```",
          "votes": 5
        },
        {
          "id": 899163,
          "postDate": "2020-06-24T03:33:52.710Z",
          "content": "<p>Can you please share <a href=\"/akensert\">@akensert</a> if my input is like 16x128x128x3 then how can I pass through this network. It gives me error like dynamic shape error etc. So I have to stick with tiles concatenation..</p>",
          "rawMarkdown": "Can you please share @akensert if my input is like 16x128x128x3 then how can I pass through this network. It gives me error like dynamic shape error etc. So I have to stick with tiles concatenation.."
        },
        {
          "id": 899401,
          "postDate": "2020-06-24T08:01:17.297Z",
          "content": "<p><a href=\"/micheomaano\">@micheomaano</a> Is it possible to give me some more information? It's hard for me to tell you what to do atm. The above code snippet works fine for me (should work for <code>16 x 128 x 128 x 3</code> input. Although the <code>tf.reshape(...)</code> is hardcoded and could cause problems. I suggest you remove the hardcoding by obtaining the shape from the previous layer (output of <code>self.engine</code>) like this:\n<code>\nnum_tiles = 16\n...\n...\nh = x.get_shape()[-3]\nw = x.get_shape()[-2]\nc = x.get_shape()[-1]\nx = tf.reshape(x, (-1, num_tiles*h, w, c))\n</code></p>",
          "rawMarkdown": "@micheomaano Is it possible to give me some more information? It's hard for me to tell you what to do atm. The above code snippet works fine for me (should work for `16 x 128 x 128 x 3` input. Although the `tf.reshape(...)` is hardcoded and could cause problems. I suggest you remove the hardcoding by obtaining the shape from the previous layer (output of `self.engine`) like this:\n```\nnum_tiles = 16\n...\n...\nh = x.get_shape()[-3]\nw = x.get_shape()[-2]\nc = x.get_shape()[-1]\nx = tf.reshape(x, (-1, num_tiles*h, w, c))\n```"
        },
        {
          "id": 903923,
          "postDate": "2020-06-27T08:08:45.100Z",
          "content": "<p>Hi <a href=\"/akensert\">@akensert</a> \nI face the following errors while loading weights with your model class.\nValueError: You are trying to load a weight file containing 3 layers into a model with 1 layers.</p>",
          "rawMarkdown": "Hi @akensert \nI face the following errors while loading weights with your model class.\nValueError: You are trying to load a weight file containing 3 layers into a model with 1 layers."
        },
        {
          "id": 904047,
          "postDate": "2020-06-27T10:09:01.930Z",
          "content": "<p><a href=\"/micheomaano\">@micheomaano</a> Ok! So you are trying to load finetuned weights into the model? (for example, you trained some weights locally and now want to load them into your model on kaggle?). What you need to do is to build the model <code>model.build(input_shape)</code> before loading the weights. Or pass some dummy data to your model before loading the finetuned weights.</p>\n\n<p>Example 1:\n<code>\nmodel = Model(...)\nmodel.build((None, 128, 128, 3))\nmodel.load_weights('my-finetuned-weights.h5')\n</code></p>\n\n<p>Example 2:\n<code>\nmodel = Model(...)\ndummy_data = tf.zeros((1, 128, 128, 3), dtype=tf.uint8))\n_ = model(dummy_data)\nmodel.load_weights('my-finetuned-weights.h5')\n</code></p>\n\n<p>I think both should work!</p>",
          "rawMarkdown": "@micheomaano Ok! So you are trying to load finetuned weights into the model? (for example, you trained some weights locally and now want to load them into your model on kaggle?). What you need to do is to build the model `model.build(input_shape)` before loading the weights. Or pass some dummy data to your model before loading the finetuned weights.\n\nExample 1:\n```\nmodel = Model(...)\nmodel.build((None, 128, 128, 3))\nmodel.load_weights('my-finetuned-weights.h5')\n```\n\nExample 2:\n```\nmodel = Model(...)\ndummy_data = tf.zeros((1, 128, 128, 3), dtype=tf.uint8))\n_ = model(dummy_data)\nmodel.load_weights('my-finetuned-weights.h5')\n```\n\nI think both should work!\n"
        },
        {
          "id": 904073,
          "postDate": "2020-06-27T10:35:51.370Z",
          "content": "<p>It worked. Thanks a lot.\nTraining on GPU is too slow.\nI am trying to shift to TPU.\nThanks.</p>",
          "rawMarkdown": "It worked. Thanks a lot.\nTraining on GPU is too slow.\nI am trying to shift to TPU.\nThanks.",
          "votes": 1
        },
        {
          "id": 904121,
          "postDate": "2020-06-27T11:30:07.767Z",
          "content": "<p><a href=\"/micheomaano\">@micheomaano</a> Side note: If you have an RTX graphics card for example, I recommend using mixed precision. That speeds up training significantly (not as fast as TPU, but still much faster). Find more info <a href=\"https://www.tensorflow.org/guide/mixed_precision\">here</a>. Further, I recommend using a small architecture like EfficientNetB0. You are probably already aware of these two recommendations, but I still put it out there :-)</p>",
          "rawMarkdown": "@micheomaano Side note: If you have an RTX graphics card for example, I recommend using mixed precision. That speeds up training significantly (not as fast as TPU, but still much faster). Find more info [here](https://www.tensorflow.org/guide/mixed_precision). Further, I recommend using a small architecture like EfficientNetB0. You are probably already aware of these two recommendations, but I still put it out there :-)"
        },
        {
          "id": 905144,
          "postDate": "2020-06-28T09:45:20.553Z",
          "content": "<p><a href=\"/akensert\">@akensert</a> xD I don't even have a GPU. \nI am training using TPU.\nConsidering to create a public notebook to train Model with TPU in less than 3 hours with 48x256x256x3. This is Fun....</p>",
          "rawMarkdown": "@akensert xD I don't even have a GPU. \nI am training using TPU.\nConsidering to create a public notebook to train Model with TPU in less than 3 hours with 48x256x256x3. This is Fun....",
          "votes": 1
        },
        {
          "id": 905500,
          "postDate": "2020-06-28T15:43:57.263Z",
          "content": "<p><a href=\"/akensert\">@akensert</a> I am facing a problem with tensorflow. There is different loss for model.evaluate and different validation loss while model.fit operation. I passed training=False while evaluation in dropouts and BatchNormalizations. Kind of strange. </p>",
          "rawMarkdown": "@akensert I am facing a problem with tensorflow. There is different loss for model.evaluate and different validation loss while model.fit operation. I passed training=False while evaluation in dropouts and BatchNormalizations. Kind of strange. "
        },
        {
          "id": 905598,
          "postDate": "2020-06-28T17:07:24.677Z",
          "content": "<p><a href=\"/micheomaano\">@micheomaano</a> I'm not sure exactly how the validation loss is computed when passed to fit (there should be info about this online). Perhaps the validation loss is computed during the training of the epoch, in contrast to being computed after the training epoch is done.</p>\n\n<p>Side note about training=False: I think there's some keras magic where training=False is automatically set during predicting phase. That said, it's still good/safe to explicitly set training=False like you now did :-)</p>",
          "rawMarkdown": "@micheomaano I'm not sure exactly how the validation loss is computed when passed to fit (there should be info about this online). Perhaps the validation loss is computed during the training of the epoch, in contrast to being computed after the training epoch is done.\n\nSide note about training=False: I think there's some keras magic where training=False is automatically set during predicting phase. That said, it's still good/safe to explicitly set training=False like you now did :-)"
        }
      ]
    },
    {
      "id": 844288,
      "postDate": "2020-05-12T14:43:30.617Z",
      "content": "<p>Thanks for sharing! A very interesting idea to start exploring</p>",
      "rawMarkdown": "\nThanks for sharing! A very interesting idea to start exploring"
    },
    {
      "id": 836104,
      "postDate": "2020-05-06T18:00:03.220Z",
      "content": "<p>Great approach! Which downsampled version are you using? Using the highest resolution version won't work if the size of tile is 128 x 128 as there will be too many tiles having entire tile filled up. Correct me if I'm wrong. Thanks!</p>",
      "rawMarkdown": "Great approach! Which downsampled version are you using? Using the highest resolution version won't work if the size of tile is 128 x 128 as there will be too many tiles having entire tile filled up. Correct me if I'm wrong. Thanks!",
      "replies": [
        {
          "id": 836143,
          "postDate": "2020-05-06T18:44:32.077Z",
          "content": "<p>I have used only low and intermediate res tiff layer so far and can say that it is is still working for the later one (but locally).</p>",
          "rawMarkdown": "I have used only low and intermediate res tiff layer so far and can say that it is is still working for the later one (but locally)."
        }
      ]
    },
    {
      "id": 831940,
      "postDate": "2020-05-03T17:41:52.423Z",
      "content": "<p>nice work</p>",
      "rawMarkdown": "nice work\n"
    },
    {
      "id": 831886,
      "postDate": "2020-05-03T16:55:22.783Z",
      "content": "<p>It was very helpful!</p>",
      "rawMarkdown": "\nIt was very helpful!"
    },
    {
      "id": 830544,
      "postDate": "2020-05-02T17:07:09.170Z",
      "content": "<p>nice</p>",
      "rawMarkdown": "nice"
    },
    {
      "id": 829230,
      "postDate": "2020-05-01T15:59:54.663Z",
      "content": "<p>Good work</p>",
      "rawMarkdown": "Good work"
    },
    {
      "id": 827696,
      "postDate": "2020-04-30T13:17:46Z",
      "content": "<p>Such an awesome idea! Too bad it seems quite difficult to implement in tensorflow framework. Another competition makes me want to switch to Pytorch/Fast.ai 😂 </p>",
      "rawMarkdown": "Such an awesome idea! Too bad it seems quite difficult to implement in tensorflow framework. Another competition makes me want to switch to Pytorch/Fast.ai 😂 ",
      "replies": [
        {
          "id": 827823,
          "postDate": "2020-04-30T15:05:50.530Z",
          "content": "<p>@Xie29 I was also thinking the same.</p>",
          "rawMarkdown": "@Xie29 I was also thinking the same.",
          "votes": 1
        },
        {
          "id": 827976,
          "postDate": "2020-04-30T17:20:22.663Z",
          "content": "<p>I'm not not very familiar with tensorflow, but the only thing needed to implement my idea is tensor permutation and reshaping, and also a dataloader that combines the images in the corresponding manner.</p>",
          "rawMarkdown": "I'm not not very familiar with tensorflow, but the only thing needed to implement my idea is tensor permutation and reshaping, and also a dataloader that combines the images in the corresponding manner.",
          "votes": 3
        },
        {
          "id": 828327,
          "postDate": "2020-04-30T22:53:58.367Z",
          "content": "<p>Since the shape of batch_size need to be fixed during training while using tensorflow, so we are not able to reshape the N tile images to bs*N x 128 x 128 x3 at the beginning or reshape back to bs x c x 4*N x4 in the end. But thanks for the great idea anyway, learned a good lesson.</p>",
          "rawMarkdown": "Since the shape of batch_size need to be fixed during training while using tensorflow, so we are not able to reshape the N tile images to bs*N x 128 x 128 x3 at the beginning or reshape back to bs x c x 4*N x4 in the end. But thanks for the great idea anyway, learned a good lesson.",
          "votes": 2
        }
      ]
    },
    {
      "id": 825138,
      "postDate": "2020-04-28T20:07:05.367Z",
      "content": "<p>Wow, great work. This gives me hope that my method will work out well</p>",
      "rawMarkdown": "Wow, great work. This gives me hope that my method will work out well"
    },
    {
      "id": 825116,
      "postDate": "2020-04-28T19:41:44.357Z",
      "content": "<p>Upvote</p>",
      "rawMarkdown": "Upvote"
    },
    {
      "id": 829674,
      "postDate": "2020-05-02T02:15:49.720Z",
      "rawMarkdown": "",
      "isDeleted": true
    },
    {
      "id": 825063,
      "postDate": "2020-04-28T18:57:02.917Z",
      "content": "<p>very neat idea, thank you for sharing!</p>",
      "rawMarkdown": "very neat idea, thank you for sharing!"
    },
    {
      "id": 829079,
      "postDate": "2020-05-01T13:37:28.220Z",
      "content": "<p>Good Job. Thank you.</p>",
      "rawMarkdown": "Good Job. Thank you."
    }
  ],
  "comments": [
    {
      "id": 833079,
      "author_name": "Iafoss",
      "author_url": "",
      "post_date": "2020-05-04T15:30:25.827000",
      "content": "<p>Just an update on the number N:\n<code>\nN=12 - 0.843 CV\n[[2290  424  106   41   11    1]\n [ 463 1563  455  116   17    2]\n [  60  396  547  261   67   10]\n [  26   81  213  397  395  114]\n [  29   65  128  182  450  391]\n [  13   31   42   91  270  768]]\n</code>\n<code>\nN=8 - 0.830 CV\n[[2176  519  126   37   12    3]\n [ 474 1512  490  107   30    3]\n [  70  367  544  264   83   13]\n [  30   78  206  396  388  128]\n [  31   74  115  187  424  414]\n [  24   30   43   82  261  775]]\n</code>\n<code>\nN=16 (smaller bs) - 0.840 CV\n[[2269  442  115   35   11    1]\n [ 435 1541  510  103   25    2]\n [  59  333  565  284   87   13]\n [  21   71  210  400  362  162]\n [  32   64  111  185  407  446]\n [  19   29   40   95  249  783]]\n</code>\nThese results are obtained for 4-fold CV on 128x128 tiles, while LB is ~0.80.</p>",
      "votes": 6,
      "replies": []
    },
    {
      "id": 910115,
      "author_name": "Arnaud Roussel",
      "author_url": "",
      "post_date": "2020-07-01T02:12:31.623000",
      "content": "<p>New candidate at 0.90 LB single fold:\nCV 0.8911 <br>\nEfficientNet-b0 256x256x16 Tiles\nLot of extra computations during inference (TTA and more).</p>\n\n<p>Still using very naive head...</p>",
      "votes": 3,
      "replies": [
        {
          "id": 910132,
          "author_name": "Salman",
          "author_url": "",
          "post_date": "2020-07-01T02:25:22.377000",
          "content": "<p>Wow.</p>",
          "votes": 0,
          "replies": []
        },
        {
          "id": 910133,
          "author_name": "Salman",
          "author_url": "",
          "post_date": "2020-07-01T02:25:45.563000",
          "content": "<p>Intermediate Resolution or Mixture?</p>",
          "votes": 0,
          "replies": []
        }
      ]
    },
    {
      "id": 827847,
      "author_name": "Zac Dannelly",
      "author_url": "",
      "post_date": "2020-04-30T15:21:48.127000",
      "content": "<p>To verify I am looking at the model correctly, you utilize the mask values to determine those tiles with tissue cells in them? Does this then effect the results as the test images as the tiles created are not scaled down for maximizing tissue presence? </p>",
      "votes": 3,
      "replies": [
        {
          "id": 827979,
          "author_name": "Iafoss",
          "author_url": "",
          "post_date": "2020-04-30T17:22:39.877000",
          "content": "<p>I check how much the pixels are different from the background (255) and sort the tiles based on it, I do not use masks to create tiles.</p>",
          "votes": 3,
          "replies": []
        },
        {
          "id": 828610,
          "author_name": "Benjamin Dubreu",
          "author_url": "",
          "post_date": "2020-05-01T07:22:32.500000",
          "content": "<p>I think this is a very good think to investigate Zac. There is a specific line of code that does the selection. It's with np.argsort(......)[:N]. If you study this in depth you'll see lafoss indeed filters tiles according to their pixels values (a tile with all black pixels would be selected first, because its sum would be 0).</p>",
          "votes": 2,
          "replies": []
        }
      ]
    },
    {
      "id": 830271,
      "author_name": "Theo Viel",
      "author_url": "",
      "post_date": "2020-05-02T13:11:42.213000",
      "content": "<p>Congratz on getting that well deserved Kernel Grandmaster <a href=\"/iafoss\">@iafoss</a> !</p>",
      "votes": 1,
      "replies": [
        {
          "id": 830273,
          "author_name": "Iafoss",
          "author_url": "",
          "post_date": "2020-05-02T13:13:59.683000",
          "content": "<p>Thanks so much <a href=\"/theoviel\">@theoviel</a> </p>",
          "votes": 1,
          "replies": []
        }
      ]
    },
    {
      "id": 825412,
      "author_name": "Wees Jun",
      "author_url": "",
      "post_date": "2020-04-29T01:43:48.700000",
      "content": "<p>Amazing! Thanks for sharing your idea about the intelligent way of data preprocessing.</p>",
      "votes": 1,
      "replies": []
    },
    {
      "id": 825148,
      "author_name": "Benjamin Dubreu",
      "author_url": "",
      "post_date": "2020-04-28T20:14:48.580000",
      "content": "<p>This is simply amazing. That's very high quality content. Thank you so much for sharing that kind of stuff ! </p>",
      "votes": 1,
      "replies": [
        {
          "id": 825157,
          "author_name": "Iafoss",
          "author_url": "",
          "post_date": "2020-04-28T20:25:45.747000",
          "content": "<p>You are welcome.</p>",
          "votes": 0,
          "replies": []
        }
      ]
    },
    {
      "id": 825128,
      "author_name": "GreatGameDota",
      "author_url": "",
      "post_date": "2020-04-28T19:53:36.133000",
      "content": "<p>Thanks for sharing! As DrHB said we all appropriate your amazing sharing in these comps!</p>\n\n<p>But there appears to be an issue with the dataset you provided, there are missing images when trying to run. Did you name any images weirdly?</p>",
      "votes": 1,
      "replies": [
        {
          "id": 825137,
          "author_name": "Iafoss",
          "author_url": "",
          "post_date": "2020-04-28T20:05:42.703000",
          "content": "<p>You are welcome. I think you are referring to images that do not have masks, I saw a few of them, like tens if I remember correctly. Since I'm planning also to explore segmentation based aux, I considered only images with masks when created this dataset.</p>",
          "votes": 1,
          "replies": []
        },
        {
          "id": 829023,
          "author_name": "GreatGameDota",
          "author_url": "",
          "post_date": "2020-05-01T12:53:15.143000",
          "content": "<p>Congrats on becoming Notebook GM!!</p>",
          "votes": 1,
          "replies": []
        },
        {
          "id": 830546,
          "author_name": "Iafoss",
          "author_url": "",
          "post_date": "2020-05-02T17:10:05.570000",
          "content": "<p>Thanks so much.</p>",
          "votes": 1,
          "replies": []
        }
      ]
    },
    {
      "id": 825446,
      "author_name": "Wees Jun",
      "author_url": "",
      "post_date": "2020-04-29T02:43:20.783000",
      "content": "<p>Just a small question: how you decide the tile size and the number of tiles for each image?\nI am wondering if the image is extremely super resolution, then insufficient number of small tiles\nmight lose some information of the original image.</p>",
      "votes": 2,
      "replies": [
        {
          "id": 825467,
          "author_name": "Iafoss",
          "author_url": "",
          "post_date": "2020-04-29T03:06:37.603000",
          "content": "<p>You could check the number N' after which the next tiles are nearly empty for most of the images. For example here when I tried to use 16x128x128 tiles, I found that in most cases 3-5 last tiles are almost completely white. So I decided to go 12, but I didn't evaluate the model performance for different setups. Also, make sure that the tiles are not too small especially for intermediate and high resolution images.</p>",
          "votes": 2,
          "replies": []
        },
        {
          "id": 826951,
          "author_name": "Wees Jun",
          "author_url": "",
          "post_date": "2020-04-30T01:12:06.167000",
          "content": "<p>Thanks for illustration. It is really helpful : )</p>",
          "votes": 0,
          "replies": []
        }
      ]
    },
    {
      "id": 825055,
      "author_name": "DrHB",
      "author_url": "",
      "post_date": "2020-04-28T18:51:33.227000",
      "content": "<p>As per usual high quality kernels. Your starter  public kernels were extremely useful in Bengali Competition as well =) And well deserved future (very soon) Kernel Grandmaster =) </p>",
      "votes": 2,
      "replies": [
        {
          "id": 825073,
          "author_name": "Iafoss",
          "author_url": "",
          "post_date": "2020-04-28T19:02:20.497000",
          "content": "<p>Thanks so much. At Bengali competition it was quite surprising that my public starter kernel got to the upper bronze zone at private LB while public score was quite low. I hope it will not happen again, and the final LB would represent the real efforts made by participants.</p>",
          "votes": 6,
          "replies": []
        },
        {
          "id": 826651,
          "author_name": "Nirjhar Roy",
          "author_url": "",
          "post_date": "2020-04-29T19:02:09.710000",
          "content": "<p>Your model did good in private , because it generalized well and you built a nice model :) </p>",
          "votes": 1,
          "replies": []
        }
      ]
    },
    {
      "id": 3052294,
      "author_name": "Mahmoud Essam",
      "author_url": "",
      "post_date": "2024-11-22T08:54:27.383000",
      "content": "<p>Great Job! How to reference your method in a research paper?</p>",
      "votes": 0,
      "replies": []
    },
    {
      "id": 905831,
      "author_name": "TheStoneMX",
      "author_url": "",
      "post_date": "2020-06-28T21:03:09.827000",
      "content": "<p>hi, there @lafoss, can you share a way to make a vanilla submission with AI. thanks.</p>",
      "votes": 0,
      "replies": [
        {
          "id": 905886,
          "author_name": "Iafoss",
          "author_url": "",
          "post_date": "2020-06-28T22:56:18.673000",
          "content": "<p>Check my public kernels listed above</p>",
          "votes": 0,
          "replies": []
        },
        {
          "id": 905934,
          "author_name": "TheStoneMX",
          "author_url": "",
          "post_date": "2020-06-29T00:49:14.800000",
          "content": "<p>Hi @lafoss thanks for the replay, besides I am learning still how to do kaggle submission, I am using your technique of breaking down the large image into pieces, and passing them on to the model with other techniques.\n~~~\nepoch   train_loss  valid_loss  accuracy    error_rate  cohen_kappa_score   time\n16     1.090601     0.925868    0.981913    0.018087    0.979144                    02:58\n~~~\nI want to be able to test the models I have created,  but I am having a little bit of a problem understanding what you are doing on your code ( I have learned a lot from you and your postings, and answer to my questions, thanks).</p>\n\n<p>1.- It looks to me that you are not using fastai predict method, learn.get_preds, but strait PyTorch code, right?\n2.- I was wondering how you will go about and right your Pytorch code with fastai methods, sorry it that I have looked everywhere on the web, and cant find something that will help me.\n3.- when you do this, x = x.cuda() I thought it was best to set the inference images into the CPU not GPU.\n4.- \n            #dihedral TTA\n            x = torch.stack([x,x.flip(-1),x.flip(-2),x.flip(-1,-2),\n              x.transpose(-1,-2),x.transpose(-1,-2).flip(-1),\n              x.transpose(-1,-2).flip(-2),x.transpose(-1,-2).flip(-1,-2)],1)\n            x = x.view(-1,N,3,sz,sz)</p>\n\n<p>no idea what you are doing here.. hehehe.... but I guess it does not work with one image, as it meant to be used with many fragments of sz size.</p>\n\n<p>I have other questions, but I think I can understand the rest if I can get to understand these ones.</p>\n\n<p>Thanks again!</p>",
          "votes": 0,
          "replies": []
        },
        {
          "id": 905963,
          "author_name": "Iafoss",
          "author_url": "",
          "post_date": "2020-06-29T01:59:15.323000",
          "content": "<p>1) Yes\n2) fast.ai inference pipeline is quite limited. So, if you want to get prediction for multiple models without reading the data several times, or doing proper TTA, Pytorch is your way to go. If you want to use fast.ai for inference, u can refer to  learn.get_preds method, if I remember correctly, but you will need to write your own code.\n3) If u do inference on CPU, it will take really forever. You can try to run CPU kernel (and comment all cuda related stuff) and see how many images per second u can get (change the path to train to do this test interactively).\n4) TTA means Test Time Augmentation. Google it to see further details. I just create a list of augmented images and combine them into a single batch. I recommend u to play with a dummy image and printout the shape after each operation to understand how it works.</p>",
          "votes": 0,
          "replies": []
        },
        {
          "id": 906635,
          "author_name": "TheStoneMX",
          "author_url": "",
          "post_date": "2020-06-29T13:09:50.143000",
          "content": "<p>Hey @lafoss thanks for your response, I appreciate it.\n2.- I see, <br>\n3.- I see,\n4.a- Will do bro. \n4.b- then when you do \"x = x.view(-1,N,3,sz,sz)\" is when you combine the images into one and then pass the single image into the model with mode(x), right?</p>\n\n<p>Thanks a lot again.</p>",
          "votes": 0,
          "replies": []
        },
        {
          "id": 906962,
          "author_name": "Iafoss",
          "author_url": "",
          "post_date": "2020-06-29T16:30:30.207000",
          "content": "<p>As I wrote, it combines augmented images into a single batch.</p>",
          "votes": 0,
          "replies": []
        }
      ]
    },
    {
      "id": 899064,
      "author_name": "Fernandes",
      "author_url": "",
      "post_date": "2020-06-24T00:11:10.157000",
      "content": "<p>Great work, thanks for sharing!\nHowever, is there any resource to better understand the used concat tile pooling technique?\nI'm kinda new in image nets 😩 </p>",
      "votes": 0,
      "replies": [
        {
          "id": 899139,
          "author_name": "Iafoss",
          "author_url": "",
          "post_date": "2020-06-24T02:53:14.437000",
          "content": "<p>It's a brand new idea, and I haven't seen anything related to it. Though, it's quite simple one, and I wouldn't be surprised if something similar to it already exists.</p>",
          "votes": 5,
          "replies": []
        },
        {
          "id": 899259,
          "author_name": "A.Demyanchuk",
          "author_url": "",
          "post_date": "2020-06-24T05:50:51.140000",
          "content": "<p>I would recommend maybe to read some review paper on the topic of Multiple Instance Learning. It helped me at least to clarify the idea more or less.</p>",
          "votes": 3,
          "replies": []
        },
        {
          "id": 900491,
          "author_name": "Fernandes",
          "author_url": "",
          "post_date": "2020-06-24T20:48:35.653000",
          "content": "<p>Thanks, everyone &lt;3</p>",
          "votes": 0,
          "replies": []
        }
      ]
    },
    {
      "id": 873199,
      "author_name": "Akshay Patel",
      "author_url": "",
      "post_date": "2020-06-03T22:25:07.513000",
      "content": "<ol>\n<li>what governs the output shape? I'm assuming the 4X4 is the image size after the convolutions</li>\n<li>Does it matter how you reshape the output? Wouldn't it be more intuitive if the output was B X C*N X 4 X 4 instead?</li>\n</ol>",
      "votes": 0,
      "replies": [
        {
          "id": 873217,
          "author_name": "Iafoss",
          "author_url": "",
          "post_date": "2020-06-03T23:09:33.537000",
          "content": "<p>1) Almost for all computer vision models the CNN part reduces the res by 32 times, so 128/32=4.\n2) The tiles should be concatenated specially to be an approximation of classification on entire images. The proposed method, ideally, should be the same to one when an entire image is given as an input. However, the issues with different image shape and overhead because of empty white space are solved. \nMeanwhile, channel-wise concatenation, which u mentioned, is based on quite different idea: stacking a conv model based on tiles and NN generating labels for it. Training with just individual tiles is challenging here because labels assigned to entire images are different from one assigned to tiles forming the images. So one could have a net that would generate some pseudo labels in high dim space in end-to-end manner. I didn't check the idea you mentioned, but it may work as well. The thing u should consider in this case, though, is permutation invariance with respect to the order of tiles.</p>",
          "votes": 0,
          "replies": []
        },
        {
          "id": 873261,
          "author_name": "Arnaud Roussel",
          "author_url": "",
          "post_date": "2020-06-04T01:22:34.780000",
          "content": "<p>You'll also have to consider the size of the Linear layer after that. If you use a resnet50 your C is probably already 1K or 2K can't remember. So if you use 32 tiles it is a 32K 64K wide... Transforming that into say 512 is a pretty high number of parameters.</p>",
          "votes": 0,
          "replies": []
        }
      ]
    },
    {
      "id": 854157,
      "author_name": "Yaheaal",
      "author_url": "",
      "post_date": "2020-05-19T19:54:49.193000",
      "content": "<p>Thanks :)\nI have one question, I am new in this field , so my question might look like a naive question 👀 \nEvery image now is represent in 12 images, I am using keras , how to fit this data into CNN model ? \nCan you provide me a kernel or any reference where I can learn from ?</p>\n\n<p>Thansk :)</p>",
      "votes": 0,
      "replies": [
        {
          "id": 854212,
          "author_name": "Iafoss",
          "author_url": "",
          "post_date": "2020-05-19T21:17:46.053000",
          "content": "<p>Unfortunately, I'm not very familiar with keras. I believe that there should be a way to implement it in this framework, but <a href=\"/xiejialun\">@xiejialun</a> pointed out below that there are some difficulties related to TensorFlow itself, which keras also may inherit.\nI saw <a href=\"https://www.kaggle.com/vgarshin/panda-keras-baseline\">one keras public kernel</a> where the tiles are combined into a big single image given to the network. It is not exactly that I do but presumably works similar.</p>",
          "votes": 2,
          "replies": []
        },
        {
          "id": 854225,
          "author_name": "Yaheaal",
          "author_url": "",
          "post_date": "2020-05-19T21:52:31.113000",
          "content": "<p>Thanks alot :)</p>",
          "votes": 0,
          "replies": []
        },
        {
          "id": 854269,
          "author_name": "Tsai29",
          "author_url": "",
          "post_date": "2020-05-19T23:23:54.033000",
          "content": "<p><a href=\"/yaheaal\">@yaheaal</a> You might not able to perform this idea on keras due to the reason I wrote below, but after some experiments I found that tensorflow is okay. In tensorflow, you need to customize the training loop and create two separated model for tiles training. I already shared a notebook(see below link) how to perform this idea in tensorflow, you only need to modify some of your code in keras. Good luck.</p>\n\n<p><a href=\"https://www.kaggle.com/xiejialun/panda-tiles-training-on-tensorflow-0-7-cv\">https://www.kaggle.com/xiejialun/panda-tiles-training-on-tensorflow-0-7-cv</a></p>",
          "votes": 3,
          "replies": []
        },
        {
          "id": 864874,
          "author_name": "Yaheaal",
          "author_url": "",
          "post_date": "2020-05-28T08:40:15.457000",
          "content": "<p>Thank you for helping :), I am really surprised that keras can't preform this idea :/</p>",
          "votes": 0,
          "replies": []
        },
        {
          "id": 865843,
          "author_name": "Richard Xiao",
          "author_url": "",
          "post_date": "2020-05-28T23:43:44.037000",
          "content": "<p>What I have found is that you can use a TimeDistributed layer to wrap around your CNN model and then apply the pooling by reshaping the feature map to a grid. However, it is a little inconvenient to implement.</p>",
          "votes": 2,
          "replies": []
        },
        {
          "id": 866298,
          "author_name": "Yaheaal",
          "author_url": "",
          "post_date": "2020-05-29T09:21:38.560000",
          "content": "<p><a href=\"/richardxiao03\">@richardxiao03</a>  yea I found this idea <a href=\"https://www.kaggle.com/vgarshin/panda-keras-timedistributed\">here</a></p>\n\n<p><code>\nbottleneck = efn.EfficientNetB1(\n    weights='../input/effnetweights/efficientnet-b1_weights_tf_dim_ordering_tf_kernels_autoaugment_notop.h5', \n    include_top=False, \n    pooling='avg'\n)\nbottleneck = Model(inputs=bottleneck.inputs, outputs=bottleneck.layers[-2].output)\nmodel = Sequential()\nmodel.add(TimeDistributed(bottleneck, input_shape=(SEQ_LEN, IMG_SIZE, IMG_SIZE, 3)))\nmodel.add(TimeDistributed(BatchNormalization()))\nmodel.add(GlobalMaxPooling3D())\nmodel.add(BatchNormalization())\nmodel.add(Dropout(.4))\nmodel.add(Dense(512, activation='Mish'))\nmodel.add(BatchNormalization())\nmodel.add(Dropout(.4))\nmodel.add(Dense(128, activation='Mish'))\nmodel.add(BatchNormalization())\nmodel.add(Dropout(.4))\nmodel.add(Dense(6, activation='softmax'))\n</code></p>",
          "votes": 3,
          "replies": []
        },
        {
          "id": 867709,
          "author_name": "Alex",
          "author_url": "",
          "post_date": "2020-05-30T14:48:33.957000",
          "content": "<p>I think I should share this (works fine for me):</p>\n\n<p>```\nclass ConvNet(tf.keras.Model):</p>\n\n<pre><code>def __init__(self, engine, input_shape, weights):\n    super(ConvNet, self).__init__()\n    self.engine = engine(\n        include_top=False, input_shape=input_shape, weights=weights)\n    self.avg_pool2d = tf.keras.layers.GlobalAveragePooling2D()\n    self.dropout = tf.keras.layers.Dropout(0.5)\n    self.dense_1 = tf.keras.layers.Dense(512)\n    self.dense_2 = tf.keras.layers.Dense(1)\n\n@tf.function\ndef call(self, inputs, **kwargs):\n    x = self.engine(inputs)\n    x = tf.reshape(x, (-1, 16*4, 4, 2048)) # 16 tiles\n    x = self.avg_pool2d(x)\n    x = self.dropout(x, training=kwargs.get('training', False))\n    x = self.dense_1(x)\n    x = tf.nn.relu(x)\n    return self.dense_2(x)\n</code></pre>\n\n<p>model = ConvNet(\n    engine=Xception, input_shape=(128, 128, 3), weights='imagenet'\n) \n```</p>",
          "votes": 5,
          "replies": []
        },
        {
          "id": 899163,
          "author_name": "Salman",
          "author_url": "",
          "post_date": "2020-06-24T03:33:52.710000",
          "content": "<p>Can you please share <a href=\"/akensert\">@akensert</a> if my input is like 16x128x128x3 then how can I pass through this network. It gives me error like dynamic shape error etc. So I have to stick with tiles concatenation..</p>",
          "votes": 0,
          "replies": []
        },
        {
          "id": 899401,
          "author_name": "Alex",
          "author_url": "",
          "post_date": "2020-06-24T08:01:17.297000",
          "content": "<p><a href=\"/micheomaano\">@micheomaano</a> Is it possible to give me some more information? It's hard for me to tell you what to do atm. The above code snippet works fine for me (should work for <code>16 x 128 x 128 x 3</code> input. Although the <code>tf.reshape(...)</code> is hardcoded and could cause problems. I suggest you remove the hardcoding by obtaining the shape from the previous layer (output of <code>self.engine</code>) like this:\n<code>\nnum_tiles = 16\n...\n...\nh = x.get_shape()[-3]\nw = x.get_shape()[-2]\nc = x.get_shape()[-1]\nx = tf.reshape(x, (-1, num_tiles*h, w, c))\n</code></p>",
          "votes": 0,
          "replies": []
        },
        {
          "id": 903923,
          "author_name": "Salman",
          "author_url": "",
          "post_date": "2020-06-27T08:08:45.100000",
          "content": "<p>Hi <a href=\"/akensert\">@akensert</a> \nI face the following errors while loading weights with your model class.\nValueError: You are trying to load a weight file containing 3 layers into a model with 1 layers.</p>",
          "votes": 0,
          "replies": []
        },
        {
          "id": 904047,
          "author_name": "Alex",
          "author_url": "",
          "post_date": "2020-06-27T10:09:01.930000",
          "content": "<p><a href=\"/micheomaano\">@micheomaano</a> Ok! So you are trying to load finetuned weights into the model? (for example, you trained some weights locally and now want to load them into your model on kaggle?). What you need to do is to build the model <code>model.build(input_shape)</code> before loading the weights. Or pass some dummy data to your model before loading the finetuned weights.</p>\n\n<p>Example 1:\n<code>\nmodel = Model(...)\nmodel.build((None, 128, 128, 3))\nmodel.load_weights('my-finetuned-weights.h5')\n</code></p>\n\n<p>Example 2:\n<code>\nmodel = Model(...)\ndummy_data = tf.zeros((1, 128, 128, 3), dtype=tf.uint8))\n_ = model(dummy_data)\nmodel.load_weights('my-finetuned-weights.h5')\n</code></p>\n\n<p>I think both should work!</p>",
          "votes": 0,
          "replies": []
        },
        {
          "id": 904073,
          "author_name": "Salman",
          "author_url": "",
          "post_date": "2020-06-27T10:35:51.370000",
          "content": "<p>It worked. Thanks a lot.\nTraining on GPU is too slow.\nI am trying to shift to TPU.\nThanks.</p>",
          "votes": 1,
          "replies": []
        },
        {
          "id": 904121,
          "author_name": "Alex",
          "author_url": "",
          "post_date": "2020-06-27T11:30:07.767000",
          "content": "<p><a href=\"/micheomaano\">@micheomaano</a> Side note: If you have an RTX graphics card for example, I recommend using mixed precision. That speeds up training significantly (not as fast as TPU, but still much faster). Find more info <a href=\"https://www.tensorflow.org/guide/mixed_precision\">here</a>. Further, I recommend using a small architecture like EfficientNetB0. You are probably already aware of these two recommendations, but I still put it out there :-)</p>",
          "votes": 0,
          "replies": []
        },
        {
          "id": 905144,
          "author_name": "Salman",
          "author_url": "",
          "post_date": "2020-06-28T09:45:20.553000",
          "content": "<p><a href=\"/akensert\">@akensert</a> xD I don't even have a GPU. \nI am training using TPU.\nConsidering to create a public notebook to train Model with TPU in less than 3 hours with 48x256x256x3. This is Fun....</p>",
          "votes": 1,
          "replies": []
        },
        {
          "id": 905500,
          "author_name": "Salman",
          "author_url": "",
          "post_date": "2020-06-28T15:43:57.263000",
          "content": "<p><a href=\"/akensert\">@akensert</a> I am facing a problem with tensorflow. There is different loss for model.evaluate and different validation loss while model.fit operation. I passed training=False while evaluation in dropouts and BatchNormalizations. Kind of strange. </p>",
          "votes": 0,
          "replies": []
        },
        {
          "id": 905598,
          "author_name": "Alex",
          "author_url": "",
          "post_date": "2020-06-28T17:07:24.677000",
          "content": "<p><a href=\"/micheomaano\">@micheomaano</a> I'm not sure exactly how the validation loss is computed when passed to fit (there should be info about this online). Perhaps the validation loss is computed during the training of the epoch, in contrast to being computed after the training epoch is done.</p>\n\n<p>Side note about training=False: I think there's some keras magic where training=False is automatically set during predicting phase. That said, it's still good/safe to explicitly set training=False like you now did :-)</p>",
          "votes": 0,
          "replies": []
        }
      ]
    },
    {
      "id": 844288,
      "author_name": "Juan Vallalta",
      "author_url": "",
      "post_date": "2020-05-12T14:43:30.617000",
      "content": "<p>Thanks for sharing! A very interesting idea to start exploring</p>",
      "votes": 0,
      "replies": []
    },
    {
      "id": 836104,
      "author_name": "Kaushal Shah",
      "author_url": "",
      "post_date": "2020-05-06T18:00:03.220000",
      "content": "<p>Great approach! Which downsampled version are you using? Using the highest resolution version won't work if the size of tile is 128 x 128 as there will be too many tiles having entire tile filled up. Correct me if I'm wrong. Thanks!</p>",
      "votes": 0,
      "replies": [
        {
          "id": 836143,
          "author_name": "Iafoss",
          "author_url": "",
          "post_date": "2020-05-06T18:44:32.077000",
          "content": "<p>I have used only low and intermediate res tiff layer so far and can say that it is is still working for the later one (but locally).</p>",
          "votes": 0,
          "replies": []
        }
      ]
    },
    {
      "id": 831940,
      "author_name": "Deepak Rajpurohit",
      "author_url": "",
      "post_date": "2020-05-03T17:41:52.423000",
      "content": "<p>nice work</p>",
      "votes": 0,
      "replies": []
    },
    {
      "id": 831886,
      "author_name": "hdate1091",
      "author_url": "",
      "post_date": "2020-05-03T16:55:22.783000",
      "content": "<p>It was very helpful!</p>",
      "votes": 0,
      "replies": []
    },
    {
      "id": 830544,
      "author_name": "Deepak Rajpurohit",
      "author_url": "",
      "post_date": "2020-05-02T17:07:09.170000",
      "content": "<p>nice</p>",
      "votes": 0,
      "replies": []
    },
    {
      "id": 829230,
      "author_name": "Utpal Dutta",
      "author_url": "",
      "post_date": "2020-05-01T15:59:54.663000",
      "content": "<p>Good work</p>",
      "votes": 0,
      "replies": []
    },
    {
      "id": 827696,
      "author_name": "Tsai29",
      "author_url": "",
      "post_date": "2020-04-30T13:17:46",
      "content": "<p>Such an awesome idea! Too bad it seems quite difficult to implement in tensorflow framework. Another competition makes me want to switch to Pytorch/Fast.ai 😂 </p>",
      "votes": 0,
      "replies": [
        {
          "id": 827823,
          "author_name": "Kurian Benoy",
          "author_url": "",
          "post_date": "2020-04-30T15:05:50.530000",
          "content": "<p>@Xie29 I was also thinking the same.</p>",
          "votes": 1,
          "replies": []
        },
        {
          "id": 827976,
          "author_name": "Iafoss",
          "author_url": "",
          "post_date": "2020-04-30T17:20:22.663000",
          "content": "<p>I'm not not very familiar with tensorflow, but the only thing needed to implement my idea is tensor permutation and reshaping, and also a dataloader that combines the images in the corresponding manner.</p>",
          "votes": 3,
          "replies": []
        },
        {
          "id": 828327,
          "author_name": "Tsai29",
          "author_url": "",
          "post_date": "2020-04-30T22:53:58.367000",
          "content": "<p>Since the shape of batch_size need to be fixed during training while using tensorflow, so we are not able to reshape the N tile images to bs*N x 128 x 128 x3 at the beginning or reshape back to bs x c x 4*N x4 in the end. But thanks for the great idea anyway, learned a good lesson.</p>",
          "votes": 2,
          "replies": []
        }
      ]
    },
    {
      "id": 825138,
      "author_name": "Matt",
      "author_url": "",
      "post_date": "2020-04-28T20:07:05.367000",
      "content": "<p>Wow, great work. This gives me hope that my method will work out well</p>",
      "votes": 0,
      "replies": []
    },
    {
      "id": 825116,
      "author_name": "Hanjoon Choe",
      "author_url": "",
      "post_date": "2020-04-28T19:41:44.357000",
      "content": "<p>Upvote</p>",
      "votes": 0,
      "replies": []
    },
    {
      "id": 829674,
      "author_name": "",
      "author_url": "",
      "post_date": "2020-05-02T02:15:49.720000",
      "content": "",
      "votes": 0,
      "replies": []
    },
    {
      "id": 825063,
      "author_name": "abzaliev",
      "author_url": "",
      "post_date": "2020-04-28T18:57:02.917000",
      "content": "<p>very neat idea, thank you for sharing!</p>",
      "votes": 0,
      "replies": []
    },
    {
      "id": 829079,
      "author_name": "OH SEOK KIM",
      "author_url": "",
      "post_date": "2020-05-01T13:37:28.220000",
      "content": "<p>Good Job. Thank you.</p>",
      "votes": 0,
      "replies": []
    }
  ],
  "raw_markdown_by_id": {
    "824954": "Welcome to Prostate cANcer graDe Assessment (PANDA) Challenge. I have prepared a starter pack based on my idea of concat tile pooling (see the image below and [this kernel](https://www.kaggle.com/iafoss/panda-concat-tile-pooling-starter-0-79-lb)). Specifically, I provide a [data preprocessing kernel](https://www.kaggle.com/iafoss/panda-16x128x128-tiles) creating 16 128x128 tiles for each image selected based on the number of tissue pixels, [model training kernel](https://www.kaggle.com/iafoss/panda-concat-tile-pooling-starter-0-79-lb) with detailed description of the proposed method, and [inference kernel](https://www.kaggle.com/iafoss/panda-concat-tile-pooling-starter-inference), which reached 0.79 public LB. I hope you will enjoy the competition and find these kernels to be useful to start with the challenge.\n\n![](https://www.googleapis.com/download/storage/v1/b/kaggle-user-content/o/inbox%2F1212661%2Fe6fe32d759a28480343001aa3c661723%2FTILE.png?generation=1588094975239255&amp;alt=media)\n",
    "833079": "Just an update on the number N:\n```\nN=12 - 0.843 CV\n[[2290  424  106   41   11    1]\n [ 463 1563  455  116   17    2]\n [  60  396  547  261   67   10]\n [  26   81  213  397  395  114]\n [  29   65  128  182  450  391]\n [  13   31   42   91  270  768]]\n```\n```\nN=8 - 0.830 CV\n[[2176  519  126   37   12    3]\n [ 474 1512  490  107   30    3]\n [  70  367  544  264   83   13]\n [  30   78  206  396  388  128]\n [  31   74  115  187  424  414]\n [  24   30   43   82  261  775]]\n```\n```\nN=16 (smaller bs) - 0.840 CV\n[[2269  442  115   35   11    1]\n [ 435 1541  510  103   25    2]\n [  59  333  565  284   87   13]\n [  21   71  210  400  362  162]\n [  32   64  111  185  407  446]\n [  19   29   40   95  249  783]]\n```\nThese results are obtained for 4-fold CV on 128x128 tiles, while LB is ~0.80.",
    "910115": "New candidate at 0.90 LB single fold:\nCV 0.8911  \nEfficientNet-b0 256x256x16 Tiles\nLot of extra computations during inference (TTA and more).\n\nStill using very naive head...",
    "827847": "To verify I am looking at the model correctly, you utilize the mask values to determine those tiles with tissue cells in them? Does this then effect the results as the test images as the tiles created are not scaled down for maximizing tissue presence? ",
    "830271": "Congratz on getting that well deserved Kernel Grandmaster @iafoss !",
    "825412": "Amazing! Thanks for sharing your idea about the intelligent way of data preprocessing.",
    "825148": "This is simply amazing. That's very high quality content. Thank you so much for sharing that kind of stuff ! ",
    "825128": "Thanks for sharing! As DrHB said we all appropriate your amazing sharing in these comps!\n\nBut there appears to be an issue with the dataset you provided, there are missing images when trying to run. Did you name any images weirdly?",
    "825446": "Just a small question: how you decide the tile size and the number of tiles for each image?\nI am wondering if the image is extremely super resolution, then insufficient number of small tiles\nmight lose some information of the original image.",
    "825055": "As per usual high quality kernels. Your starter  public kernels were extremely useful in Bengali Competition as well =) And well deserved future (very soon) Kernel Grandmaster =) ",
    "3052294": "Great Job! How to reference your method in a research paper?",
    "905831": "hi, there @lafoss, can you share a way to make a vanilla submission with AI. thanks.",
    "899064": "Great work, thanks for sharing!\nHowever, is there any resource to better understand the used concat tile pooling technique?\nI'm kinda new in image nets 😩 ",
    "873199": "1. what governs the output shape? I'm assuming the 4X4 is the image size after the convolutions\n2. Does it matter how you reshape the output? Wouldn't it be more intuitive if the output was B X C*N X 4 X 4 instead?",
    "854157": "Thanks :)\nI have one question, I am new in this field , so my question might look like a naive question 👀 \nEvery image now is represent in 12 images, I am using keras , how to fit this data into CNN model ? \nCan you provide me a kernel or any reference where I can learn from ?\n\nThansk :)",
    "844288": "\nThanks for sharing! A very interesting idea to start exploring",
    "836104": "Great approach! Which downsampled version are you using? Using the highest resolution version won't work if the size of tile is 128 x 128 as there will be too many tiles having entire tile filled up. Correct me if I'm wrong. Thanks!",
    "831940": "nice work\n",
    "831886": "\nIt was very helpful!",
    "830544": "nice",
    "829230": "Good work",
    "827696": "Such an awesome idea! Too bad it seems quite difficult to implement in tensorflow framework. Another competition makes me want to switch to Pytorch/Fast.ai 😂 ",
    "825138": "Wow, great work. This gives me hope that my method will work out well",
    "825116": "Upvote",
    "829674": "",
    "825063": "very neat idea, thank you for sharing!",
    "829079": "Good Job. Thank you."
  }
}