{
  "id": 234713,
  "title": "How to handle large size predicted masks in memory?",
  "url": "/competitions/hubmap-kidney-segmentation/discussion/234713",
  "author_name": "",
  "post_date": "2021-04-25T19:12:40.234367200Z",
  "votes": 3,
  "comment_count": 8,
  "views": 0,
  "content": "<p>With the nature of the competition we need to find the masks which are of pixel dimensions such as at least 25k by 35k. These type of file consumes almost all the available memory and causes to fail with memory run out error when dealing with them. Even I have tried saving the predicted masks in disks and loading them back, but it doesn't seems to work as well. Can someone tell me is there any workaround for this? Or am I doing something wrong here? Many thanks.</p>",
  "messages": [
    {
      "id": "1284296",
      "postDate": "04/25/2021 19:12:40",
      "content": "<p>With the nature of the competition we need to find the masks which are of pixel dimensions such as at least 25k by 35k. These type of file consumes almost all the available memory and causes to fail with memory run out error when dealing with them. Even I have tried saving the predicted masks in disks and loading them back, but it doesn't seems to work as well. Can someone tell me is there any workaround for this? Or am I doing something wrong here? Many thanks.</p>",
      "rawMarkdown": "With the nature of the competition we need to find the masks which are of pixel dimensions such as at least 25k by 35k. These type of file consumes almost all the available memory and causes to fail with memory run out error when dealing with them. Even I have tried saving the predicted masks in disks and loading them back, but it doesn't seems to work as well. Can someone tell me is there any workaround for this? Or am I doing something wrong here? Many thanks.",
      "votes": null
    },
    {
      "id": "1285819",
      "postDate": "04/27/2021 09:34:19",
      "content": "<p>Use uint8 mask <br>\n<code>preds = np.zeros(dataset.shape, dtype=np.uint8)</code><br>\nFloat mask is too big for whole image</p>",
      "rawMarkdown": "Use uint8 mask \n`preds = np.zeros(dataset.shape, dtype=np.uint8)`\nFloat mask is too big for whole image",
      "votes": null
    },
    {
      "id": "1285922",
      "postDate": "04/27/2021 11:40:57",
      "content": "<p>Will this also help when reading large tiff files from the HDD?</p>",
      "rawMarkdown": "Will this also help when reading large tiff files from the HDD?",
      "votes": null
    },
    {
      "id": "1286124",
      "postDate": "04/27/2021 15:35:50",
      "content": "<p>No. Use rasterio and read data with the window</p>",
      "rawMarkdown": "No. Use rasterio and read data with the window",
      "votes": null
    },
    {
      "id": "1295137",
      "postDate": "05/06/2021 08:22:23",
      "content": "<p>You can use also zarr library. It is storing arrays in memory chunked and compressed.</p>",
      "rawMarkdown": "You can use also zarr library. It is storing arrays in memory chunked and compressed.",
      "votes": null
    },
    {
      "id": "1295263",
      "postDate": "05/06/2021 10:43:20",
      "content": "<p>Thanks for the advice, but if we use it, then it need to take special actions to install that library when we submit the notebook because internet is disabled while submitting.</p>",
      "rawMarkdown": "Thanks for the advice, but if we use it, then it need to take special actions to install that library when we submit the notebook because internet is disabled while submitting.",
      "votes": null
    },
    {
      "id": "1295265",
      "postDate": "05/06/2021 10:45:49",
      "content": "<p>I tried using it. But it seems every time the tiff files are open with only single band.</p>\n<p>dataset = rasterio.open(\"filename.tiff\")<br>\ndataset.count ==&gt; gives 1, not 3</p>\n<p>I've not used rasterio before, so may be Im doing something wrong here, but couldn't figure it out.</p>",
      "rawMarkdown": "I tried using it. But it seems every time the tiff files are open with only single band.\n\ndataset = rasterio.open(\"filename.tiff\")\ndataset.count ==> gives 1, not 3\n\nI've not used rasterio before, so may be Im doing something wrong here, but couldn't figure it out.",
      "votes": null
    },
    {
      "id": "1295291",
      "postDate": "05/06/2021 10:59:55",
      "content": "<p>Look at open notebooks - there is an example with similar code somewhere</p>\n<p>`for i, filename in tqdm(enumerate(p.glob('test/<em>.tiff')), \n                        total = len(list(p.glob('test/</em>.tiff')))):</p>\n<pre><code>print(f'{i+1} Predicting {filename.stem}')\ndataset = rasterio.open(filename.as_posix(), transform = identity)\nslices = make_grid(dataset.shape, window=WINDOW, min_overlap=MIN_OVERLAP)\npreds = np.zeros(dataset.shape, dtype=np.uint8)\nif dataset.count != 3:\n    print('Image file with subdatasets as channels')\n    layers = [rasterio.open(subd) for subd in dataset.subdatasets]\npbar = tqdm(total=len(slices))\nfor (x1,x2,y1,y2) in slices:             \n    if dataset.count == 3:\n        image = dataset.read([1,2,3],\n                        window=Window.from_slices((x1,x2),(y1,y2)))\n        image = np.moveaxis(image, 0, -1)\n    else:\n        image = np.zeros((WINDOW, WINDOW, 3), dtype=np.uint8)\n        for fl in range(3):\n            image[:,:,fl] = layers[fl].read(window=Window.from_slices((x1,x2),(y1,y2)))                        \n    image = cv2.resize(image, (NEW_SIZE, NEW_SIZE),interpolation = cv2.INTER_AREA)        \n    image = cv2.cvtColor(image, cv2.COLOR_RGB2BGR)                            \n    hsv = cv2.cvtColor(image, cv2.COLOR_BGR2HSV)\n    h_, s, v = cv2.split(hsv)\n    if (s&gt;s_th).sum() &lt;= p_th or image.sum() &lt;= p_th: \n        pbar.update(1)\n        continue        \n    image2 = np.zeros(image.shape, dtype=np.uint8)\n    np.copyto(image2,image)\n    image = np.expand_dims(image, 0)\n\n    pred = None\n\n    for fold_model in fold_models:\n        if pred is None:\n            pred = np.squeeze(fold_model.predict(image))\n        else:\n            pred += np.squeeze(fold_model.predict(image))\n\n    pred = pred/(len(fold_models))\n\n    pred = cv2.resize(pred, (WINDOW, WINDOW))\n\n    preds[x1:x2,y1:y2] |= mask_filter2((pred &gt; 0.5).astype(np.uint8))       \n    pbar.update(1)\nsubm[i] = {'id':filename.stem, 'predicted': rle_numba_encode(preds)}\nprint(np.sum(preds))\ndel preds\ngc.collect();    `\n</code></pre>",
      "rawMarkdown": "Look at open notebooks - there is an example with similar code somewhere\n\n`for i, filename in tqdm(enumerate(p.glob('test/*.tiff')), \n                        total = len(list(p.glob('test/*.tiff')))):\n    \n    print(f'{i+1} Predicting {filename.stem}')\n    dataset = rasterio.open(filename.as_posix(), transform = identity)\n    slices = make_grid(dataset.shape, window=WINDOW, min_overlap=MIN_OVERLAP)\n    preds = np.zeros(dataset.shape, dtype=np.uint8)\n    if dataset.count != 3:\n        print('Image file with subdatasets as channels')\n        layers = [rasterio.open(subd) for subd in dataset.subdatasets]\n    pbar = tqdm(total=len(slices))\n    for (x1,x2,y1,y2) in slices:             \n        if dataset.count == 3:\n            image = dataset.read([1,2,3],\n                            window=Window.from_slices((x1,x2),(y1,y2)))\n            image = np.moveaxis(image, 0, -1)\n        else:\n            image = np.zeros((WINDOW, WINDOW, 3), dtype=np.uint8)\n            for fl in range(3):\n                image[:,:,fl] = layers[fl].read(window=Window.from_slices((x1,x2),(y1,y2)))                        \n        image = cv2.resize(image, (NEW_SIZE, NEW_SIZE),interpolation = cv2.INTER_AREA)        \n        image = cv2.cvtColor(image, cv2.COLOR_RGB2BGR)                            \n        hsv = cv2.cvtColor(image, cv2.COLOR_BGR2HSV)\n        h_, s, v = cv2.split(hsv)\n        if (s>s_th).sum() <= p_th or image.sum() <= p_th: \n            pbar.update(1)\n            continue        \n        image2 = np.zeros(image.shape, dtype=np.uint8)\n        np.copyto(image2,image)\n        image = np.expand_dims(image, 0)\n        \n        pred = None\n        \n        for fold_model in fold_models:\n            if pred is None:\n                pred = np.squeeze(fold_model.predict(image))\n            else:\n                pred += np.squeeze(fold_model.predict(image))\n                \n        pred = pred/(len(fold_models))\n        \n        pred = cv2.resize(pred, (WINDOW, WINDOW))\n\n        preds[x1:x2,y1:y2] |= mask_filter2((pred > 0.5).astype(np.uint8))       \n        pbar.update(1)\n    subm[i] = {'id':filename.stem, 'predicted': rle_numba_encode(preds)}\n    print(np.sum(preds))\n    del preds\n    gc.collect();    `",
      "votes": null
    },
    {
      "id": "1295831",
      "postDate": "05/06/2021 18:17:46",
      "content": "<p>Well…. a big thanks for this. I just did some work with this and it seems to be working. Appreciate the time taken to share your knowledge. As you mentioned I did search and found following kernel, but your part of the code should be added in to there. I'm just sharing it hoping that someone may need it.</p>\n<p><a href=\"https://www.kaggle.com/alinaherderich/submisson-alina-resnet34-v2\" target=\"_blank\">https://www.kaggle.com/alinaherderich/submisson-alina-resnet34-v2</a></p>",
      "rawMarkdown": "Well.... a big thanks for this. I just did some work with this and it seems to be working. Appreciate the time taken to share your knowledge. As you mentioned I did search and found following kernel, but your part of the code should be added in to there. I'm just sharing it hoping that someone may need it.\n\nhttps://www.kaggle.com/alinaherderich/submisson-alina-resnet34-v2",
      "votes": null
    }
  ],
  "comments": [
    {
      "id": 1285819,
      "author_name": "aleksandrkruchinin",
      "author_url": "",
      "post_date": "04/27/2021 09:34:19",
      "content": "<p>Use uint8 mask <br>\n<code>preds = np.zeros(dataset.shape, dtype=np.uint8)</code><br>\nFloat mask is too big for whole image</p>",
      "votes": null,
      "replies": [
        {
          "id": 1285922,
          "author_name": "gssdatamanager",
          "author_url": "",
          "post_date": "04/27/2021 11:40:57",
          "content": "<p>Will this also help when reading large tiff files from the HDD?</p>",
          "votes": null,
          "replies": []
        },
        {
          "id": 1286124,
          "author_name": "aleksandrkruchinin",
          "author_url": "",
          "post_date": "04/27/2021 15:35:50",
          "content": "<p>No. Use rasterio and read data with the window</p>",
          "votes": null,
          "replies": []
        },
        {
          "id": 1295265,
          "author_name": "gssdatamanager",
          "author_url": "",
          "post_date": "05/06/2021 10:45:49",
          "content": "<p>I tried using it. But it seems every time the tiff files are open with only single band.</p>\n<p>dataset = rasterio.open(\"filename.tiff\")<br>\ndataset.count ==&gt; gives 1, not 3</p>\n<p>I've not used rasterio before, so may be Im doing something wrong here, but couldn't figure it out.</p>",
          "votes": null,
          "replies": []
        },
        {
          "id": 1295291,
          "author_name": "aleksandrkruchinin",
          "author_url": "",
          "post_date": "05/06/2021 10:59:55",
          "content": "<p>Look at open notebooks - there is an example with similar code somewhere</p>\n<p>`for i, filename in tqdm(enumerate(p.glob('test/<em>.tiff')), \n                        total = len(list(p.glob('test/</em>.tiff')))):</p>\n<pre><code>print(f'{i+1} Predicting {filename.stem}')\ndataset = rasterio.open(filename.as_posix(), transform = identity)\nslices = make_grid(dataset.shape, window=WINDOW, min_overlap=MIN_OVERLAP)\npreds = np.zeros(dataset.shape, dtype=np.uint8)\nif dataset.count != 3:\n    print('Image file with subdatasets as channels')\n    layers = [rasterio.open(subd) for subd in dataset.subdatasets]\npbar = tqdm(total=len(slices))\nfor (x1,x2,y1,y2) in slices:             \n    if dataset.count == 3:\n        image = dataset.read([1,2,3],\n                        window=Window.from_slices((x1,x2),(y1,y2)))\n        image = np.moveaxis(image, 0, -1)\n    else:\n        image = np.zeros((WINDOW, WINDOW, 3), dtype=np.uint8)\n        for fl in range(3):\n            image[:,:,fl] = layers[fl].read(window=Window.from_slices((x1,x2),(y1,y2)))                        \n    image = cv2.resize(image, (NEW_SIZE, NEW_SIZE),interpolation = cv2.INTER_AREA)        \n    image = cv2.cvtColor(image, cv2.COLOR_RGB2BGR)                            \n    hsv = cv2.cvtColor(image, cv2.COLOR_BGR2HSV)\n    h_, s, v = cv2.split(hsv)\n    if (s&gt;s_th).sum() &lt;= p_th or image.sum() &lt;= p_th: \n        pbar.update(1)\n        continue        \n    image2 = np.zeros(image.shape, dtype=np.uint8)\n    np.copyto(image2,image)\n    image = np.expand_dims(image, 0)\n\n    pred = None\n\n    for fold_model in fold_models:\n        if pred is None:\n            pred = np.squeeze(fold_model.predict(image))\n        else:\n            pred += np.squeeze(fold_model.predict(image))\n\n    pred = pred/(len(fold_models))\n\n    pred = cv2.resize(pred, (WINDOW, WINDOW))\n\n    preds[x1:x2,y1:y2] |= mask_filter2((pred &gt; 0.5).astype(np.uint8))       \n    pbar.update(1)\nsubm[i] = {'id':filename.stem, 'predicted': rle_numba_encode(preds)}\nprint(np.sum(preds))\ndel preds\ngc.collect();    `\n</code></pre>",
          "votes": null,
          "replies": []
        },
        {
          "id": 1295831,
          "author_name": "gssdatamanager",
          "author_url": "",
          "post_date": "05/06/2021 18:17:46",
          "content": "<p>Well…. a big thanks for this. I just did some work with this and it seems to be working. Appreciate the time taken to share your knowledge. As you mentioned I did search and found following kernel, but your part of the code should be added in to there. I'm just sharing it hoping that someone may need it.</p>\n<p><a href=\"https://www.kaggle.com/alinaherderich/submisson-alina-resnet34-v2\" target=\"_blank\">https://www.kaggle.com/alinaherderich/submisson-alina-resnet34-v2</a></p>",
          "votes": null,
          "replies": []
        }
      ]
    },
    {
      "id": 1295137,
      "author_name": "trytolose",
      "author_url": "",
      "post_date": "05/06/2021 08:22:23",
      "content": "<p>You can use also zarr library. It is storing arrays in memory chunked and compressed.</p>",
      "votes": null,
      "replies": [
        {
          "id": 1295263,
          "author_name": "gssdatamanager",
          "author_url": "",
          "post_date": "05/06/2021 10:43:20",
          "content": "<p>Thanks for the advice, but if we use it, then it need to take special actions to install that library when we submit the notebook because internet is disabled while submitting.</p>",
          "votes": null,
          "replies": []
        }
      ]
    }
  ],
  "raw_markdown_by_id": {
    "1284296": "With the nature of the competition we need to find the masks which are of pixel dimensions such as at least 25k by 35k. These type of file consumes almost all the available memory and causes to fail with memory run out error when dealing with them. Even I have tried saving the predicted masks in disks and loading them back, but it doesn't seems to work as well. Can someone tell me is there any workaround for this? Or am I doing something wrong here? Many thanks.",
    "1285819": "Use uint8 mask \n`preds = np.zeros(dataset.shape, dtype=np.uint8)`\nFloat mask is too big for whole image",
    "1285922": "Will this also help when reading large tiff files from the HDD?",
    "1286124": "No. Use rasterio and read data with the window",
    "1295137": "You can use also zarr library. It is storing arrays in memory chunked and compressed.",
    "1295263": "Thanks for the advice, but if we use it, then it need to take special actions to install that library when we submit the notebook because internet is disabled while submitting.",
    "1295265": "I tried using it. But it seems every time the tiff files are open with only single band.\n\ndataset = rasterio.open(\"filename.tiff\")\ndataset.count ==> gives 1, not 3\n\nI've not used rasterio before, so may be Im doing something wrong here, but couldn't figure it out.",
    "1295291": "Look at open notebooks - there is an example with similar code somewhere\n\n`for i, filename in tqdm(enumerate(p.glob('test/*.tiff')), \n                        total = len(list(p.glob('test/*.tiff')))):\n    \n    print(f'{i+1} Predicting {filename.stem}')\n    dataset = rasterio.open(filename.as_posix(), transform = identity)\n    slices = make_grid(dataset.shape, window=WINDOW, min_overlap=MIN_OVERLAP)\n    preds = np.zeros(dataset.shape, dtype=np.uint8)\n    if dataset.count != 3:\n        print('Image file with subdatasets as channels')\n        layers = [rasterio.open(subd) for subd in dataset.subdatasets]\n    pbar = tqdm(total=len(slices))\n    for (x1,x2,y1,y2) in slices:             \n        if dataset.count == 3:\n            image = dataset.read([1,2,3],\n                            window=Window.from_slices((x1,x2),(y1,y2)))\n            image = np.moveaxis(image, 0, -1)\n        else:\n            image = np.zeros((WINDOW, WINDOW, 3), dtype=np.uint8)\n            for fl in range(3):\n                image[:,:,fl] = layers[fl].read(window=Window.from_slices((x1,x2),(y1,y2)))                        \n        image = cv2.resize(image, (NEW_SIZE, NEW_SIZE),interpolation = cv2.INTER_AREA)        \n        image = cv2.cvtColor(image, cv2.COLOR_RGB2BGR)                            \n        hsv = cv2.cvtColor(image, cv2.COLOR_BGR2HSV)\n        h_, s, v = cv2.split(hsv)\n        if (s>s_th).sum() <= p_th or image.sum() <= p_th: \n            pbar.update(1)\n            continue        \n        image2 = np.zeros(image.shape, dtype=np.uint8)\n        np.copyto(image2,image)\n        image = np.expand_dims(image, 0)\n        \n        pred = None\n        \n        for fold_model in fold_models:\n            if pred is None:\n                pred = np.squeeze(fold_model.predict(image))\n            else:\n                pred += np.squeeze(fold_model.predict(image))\n                \n        pred = pred/(len(fold_models))\n        \n        pred = cv2.resize(pred, (WINDOW, WINDOW))\n\n        preds[x1:x2,y1:y2] |= mask_filter2((pred > 0.5).astype(np.uint8))       \n        pbar.update(1)\n    subm[i] = {'id':filename.stem, 'predicted': rle_numba_encode(preds)}\n    print(np.sum(preds))\n    del preds\n    gc.collect();    `",
    "1295831": "Well.... a big thanks for this. I just did some work with this and it seems to be working. Appreciate the time taken to share your knowledge. As you mentioned I did search and found following kernel, but your part of the code should be added in to there. I'm just sharing it hoping that someone may need it.\n\nhttps://www.kaggle.com/alinaherderich/submisson-alina-resnet34-v2"
  },
  "source": "meta"
}