{"cells":[{"metadata":{"_uuid":"8f2839f25d086af736a60e9eeb907d3b93b6e0e5","_cell_guid":"b1076dfc-b9ad-4769-8c92-a6c4dae69d19","trusted":true,"collapsed":true},"cell_type":"code","source":"# This Python 3 environment comes with many helpful analytics libraries installed\n# It is defined by the kaggle/python Docker image: https://github.com/kaggle/docker-python\n# For example, here's several helpful packages to load\n\nimport numpy as np # linear algebra\nimport pandas as pd # data processing, CSV file I/O (e.g. pd.read_csv)\n\n# Input data files are available in the read-only \"../input/\" directory\n# For example, running this (by clicking run or pressing Shift+Enter) will list all files under the input directory\n\nimport os\nfor dirname, _, filenames in os.walk('/kaggle/input'):\n    for filename in filenames:\n        print(os.path.join(dirname, filename))\n\n# You can write up to 5GB to the current directory (/kaggle/working/) that gets preserved as output when you create a version using \"Save & Run All\" \n# You can also write temporary files to /kaggle/temp/, but they won't be saved outside of the current session","execution_count":null,"outputs":[]},{"metadata":{"trusted":true,"collapsed":true},"cell_type":"code","source":"!pip install ../input/fastai017-whl/fastprogress-0.2.3-py3-none-any.whl\n!pip install ../input/fastai017-whl/fastcore-0.1.18-py3-none-any.whl\n!pip install ../input/fastai017-whl/fastai2-0.0.17-py3-none-any.whl","execution_count":null,"outputs":[]},{"metadata":{"_uuid":"d629ff2d2480ee46fbb7e2d37f6b5fab8052498a","_cell_guid":"79c7e3d0-c299-4dcb-8224-4455121ee9b0","trusted":true},"cell_type":"code","source":"#Load the dependancies\nfrom fastai2.basics import *\nfrom fastai2.callback.all import *\nfrom fastai2.vision.all import *\n\nimport seaborn as sns\nimport numpy as np\nimport pandas as pd\nimport os\nimport cv2\nimport openslide\n\nfrom tqdm.notebook import tqdm\nimport skimage.io\nfrom skimage.transform import resize, rescale","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"sns.set(style=\"whitegrid\")\nsns.set_context(\"paper\")","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"source = Path(\"../input/prostate-cancer-grade-assessment\")\nfiles = os.listdir(source)\nfiles","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"train = source/'train_images'\nmask = source/'train_label_masks'\ntrain_labels = pd.read_csv(source/'train.csv')","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"train_labels.head()","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"# Plotting isup_grade","execution_count":null},{"metadata":{"trusted":true},"cell_type":"code","source":"def plot_count(df, feature, title='', size=2):\n    f, ax = plt.subplots(1,1, figsize=(3*size,2*size))\n    total = float(len(df))\n    sns.countplot(df[feature],order = df[feature].value_counts().index, palette='Set1')\n    plt.title(title)\n    for p in ax.patches:\n        height = p.get_height()\n        ax.text(p.get_x()+p.get_width()/2.,\n                height + 3,\n                '{:1.2f}%'.format(100*height/total),\n                ha=\"center\") \n    plt.show()","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"plot_count(train_labels, 'isup_grade','ISUP grade - data count and percent', size=3)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"isup_0 = train_labels[train_labels.isup_grade == 0]\nisup_1 = train_labels[train_labels.isup_grade == 1]\nisup_2 = train_labels[train_labels.isup_grade == 2]\nisup_3 = train_labels[train_labels.isup_grade == 3]\nisup_4 = train_labels[train_labels.isup_grade == 4]\nisup_5 = train_labels[train_labels.isup_grade == 5]\n\nprint(f'isup_0: {len(isup_0)}, isup_1: {len(isup_1)}, isup_2: {len(isup_2)}, isup_3: {len(isup_3)}, isup_4: {len(isup_4)}, isup_5: {len(isup_5)}')","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"#  balancing the data using sample so that each class has 1224 images each and then create a balanced dataset","execution_count":null},{"metadata":{"trusted":true},"cell_type":"code","source":"isup_sam0 = isup_0.sample(n=1224)\nisup_sam1 = isup_1.sample(n=1224)\nisup_sam2 = isup_2.sample(n=1224)\nisup_sam3 = isup_3.sample(n=1224)\nisup_sam4 = isup_4.sample(n=1224)\n\nframes = [isup_sam0, isup_sam1, isup_sam2, isup_sam3, isup_sam4, isup_5]\nbalanced_df = pd. concat(frames)\nbalanced_df.head()","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"# Plotting Balanced isup_grade","execution_count":null},{"metadata":{"trusted":true},"cell_type":"code","source":"plot_count(balanced_df, 'isup_grade','ISUP grade - data count and percent', size=3)","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"# Splitting Data","execution_count":null},{"metadata":{"trusted":true},"cell_type":"code","source":"df_copy = balanced_df.copy()\n\n# 80/20 split or whatever you choose\ntrain_set = df_copy.sample(frac=0.8, random_state=7)\ntest_set = df_copy.drop(train_set.index)\nprint(len(train_set), len(test_set))","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"# Viewing images \nUsing Fastai Openslide to view images ","execution_count":null},{"metadata":{"trusted":true},"cell_type":"code","source":"def view_image(folder, fn):\n    filename = f'{folder}/{fn}.tiff'\n    file = openslide.OpenSlide(str(filename))\n    t = tensor(file.get_thumbnail(size=(255, 255)))\n    pil = PILImage.create(t) \n    return pil","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"glee_35 = train_labels[train_labels.gleason_score == '3+5']\nglee_35.head()","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"glee_35.info()","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"train","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"view_image(train, '05819281002c55258bb3086cc55e3b48')","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"view_image(train, '08134913a9aa1d541f719e9f356f9378')","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"view_image(train, '0f958c8bbbc828b2e043e49ea39e16e2')","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"view_image(train, '847db624a7a975df11caca3c97743359')","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"creating function that can get the images from the folder, open it and change it into a tensor as Fastai2 needs batches to be in the form of tensors or arrays","execution_count":null},{"metadata":{"trusted":true},"cell_type":"code","source":"import os\n\n# There are two ways to load the data from the PANDA dataset:\n# Option 1: Load images using openslide\nimport openslide\n# Option 2: Load images using skimage (requires that tifffile is installed)\nimport skimage.io\n\n# General packages\nimport pandas as pd\nimport numpy as np\nimport matplotlib\nimport matplotlib.pyplot as plt\nimport PIL\nfrom IPython.display import Image, display\n\n# Plotly for the interactive viewer (see last section)\nimport plotly.graph_objs as go\n\n# Location of the training images\ndata_dir = '/kaggle/input/prostate-cancer-grade-assessment/train_images'\nmask_dir = '/kaggle/input/prostate-cancer-grade-assessment/train_label_masks'\n\n# Location of training labels\ntrain_labels1 = pd.read_csv('/kaggle/input/prostate-cancer-grade-assessment/train.csv').set_index('image_id')","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"# Open the image (does not yet read the image into memory)\nimage = openslide.OpenSlide(os.path.join(data_dir, '005e66f06bce9c2e49142536caf2f6ee.tiff'))\n\n# Read a specific region of the image starting at upper left coordinate (x=17800, y=19500) on level 0 and extracting a 256*256 pixel patch.\n# At this point image data is read from the file and loaded into memory.\npatch = image.read_region((17800,19500), 0, (256, 256))\n\n# Display the image\ndisplay(patch)\n\n# Close the opened slide after use\nimage.close()","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"def print_slide_details(slide, show_thumbnail=True, max_size=(600,400)):\n    \"\"\"Print some basic information about a slide\"\"\"\n    # Generate a small image thumbnail\n    if show_thumbnail:\n        display(slide.get_thumbnail(size=max_size))\n\n    # Here we compute the \"pixel spacing\": the physical size of a pixel in the image.\n    # OpenSlide gives the resolution in centimeters so we convert this to microns.\n    spacing = 1 / (float(slide.properties['tiff.XResolution']) / 10000)\n    \n    print(f\"File id: {slide}\")\n    print(f\"Dimensions: {slide.dimensions}\")\n    print(f\"Microns per pixel / pixel spacing: {spacing:.3f}\")\n    print(f\"Number of levels in the image: {slide.level_count}\")\n    print(f\"Downsample factor per level: {slide.level_downsamples}\")\n    print(f\"Dimensions of levels: {slide.level_dimensions}\")","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"example_slides = [\n    '00951a7fad040bf7e90f32e81fc0746f',\n    '00a26aaa82c959624d90dfb69fcf259c',\n    '007433133235efc27a39f11df6940829',\n    '024ed1244a6d817358cedaea3783bbde',\n]\n\nfor case_id in example_slides:\n    biopsy = openslide.OpenSlide(os.path.join(data_dir, f'{case_id}.tiff'))\n    print_slide_details(biopsy)\n    biopsy.close()\n    \n    # Print the case-level label\n    print(f\"ISUP grade: {train_labels.loc[case_id, 'isup_grade']}\")\n    print(f\"Gleason score: {train_labels.loc[case_id, 'gleason_score']}\\n\\n\")","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"biopsy = openslide.OpenSlide(os.path.join(data_dir, '00928370e2dfeb8a507667ef1d4efcbb.tiff'))\n\nx = 5150\ny = 21000\nlevel = 0\nwidth = 512\nheight = 512\n\nregion = biopsy.read_region((x,y), level, (width, height))\ndisplay(region)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"x = 5140\ny = 21000\nlevel = 2\nwidth = 512\nheight = 512\n\nregion = biopsy.read_region((x,y), level, (width, height))\ndisplay(region)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"def print_mask_details(slide, center='radboud', show_thumbnail=True, max_size=(400,400)):\n    \"\"\"Print some basic information about a slide\"\"\"\n\n    if center not in ['radboud', 'karolinska']:\n        raise Exception(\"Unsupported palette, should be one of [radboud, karolinska].\")\n\n    # Generate a small image thumbnail\n    if show_thumbnail:\n        # Read in the mask data from the highest level\n        # We cannot use thumbnail() here because we need to load the raw label data.\n        mask_data = slide.read_region((0,0), slide.level_count - 1, slide.level_dimensions[-1])\n        # Mask data is present in the R channel\n        mask_data = mask_data.split()[0]\n\n        # To show the masks we map the raw label values to RGB values\n        preview_palette = np.zeros(shape=768, dtype=int)\n        if center == 'radboud':\n            # Mapping: {0: background, 1: stroma, 2: benign epithelium, 3: Gleason 3, 4: Gleason 4, 5: Gleason 5}\n            preview_palette[0:18] = (np.array([0, 0, 0, 0.5, 0.5, 0.5, 0, 1, 0, 1, 1, 0.7, 1, 0.5, 0, 1, 0, 0]) * 255).astype(int)\n        elif center == 'karolinska':\n            # Mapping: {0: background, 1: benign, 2: cancer}\n            preview_palette[0:9] = (np.array([0, 0, 0, 0.5, 0.5, 0.5, 1, 0, 0]) * 255).astype(int)\n        mask_data.putpalette(data=preview_palette.tolist())\n        mask_data = mask_data.convert(mode='RGB')\n        mask_data.thumbnail(size=max_size, resample=0)\n        display(mask_data)\n\n    # Compute microns per pixel (openslide gives resolution in centimeters)\n    spacing = 1 / (float(slide.properties['tiff.XResolution']) / 10000)\n    \n    print(f\"File id: {slide}\")\n    print(f\"Dimensions: {slide.dimensions}\")\n    print(f\"Microns per pixel / pixel spacing: {spacing:.3f}\")\n    print(f\"Number of levels in the image: {slide.level_count}\")\n    print(f\"Downsample factor per level: {slide.level_downsamples}\")\n    print(f\"Dimensions of levels: {slide.level_dimensions}\")","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"mask = openslide.OpenSlide(os.path.join(mask_dir, '090a77c517a7a2caa23e443a77a78bc7_mask.tiff'))\nprint_mask_details(mask, center='karolinska')\nmask.close()","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"mask = openslide.OpenSlide(os.path.join(mask_dir, '08ab45297bfe652cc0397f4b37719ba1_mask.tiff'))\nmask_data = mask.read_region((0,0), mask.level_count - 1, mask.level_dimensions[-1])\n\nplt.figure(figsize = (8, 15) )\nplt.title(\"Mask with default cmap\")\nplt.imshow(np.asarray(mask_data)[:,:,0], interpolation='nearest')\nplt.show()\n\nplt.figure(figsize = (8, 15) )\nplt.title(\"Mask with custom cmap\")\n# Optional: create a custom color map\ncmap = matplotlib.colors.ListedColormap(['black', 'gray', 'olive', 'yellow', 'mediumslateblue', 'fuchsia'])\nplt.imshow(np.asarray(mask_data)[:,:,0], cmap=cmap, interpolation='nearest', vmin=0, vmax=5)\nplt.show()\n\nmask.close()","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"def overlay_mask_on_slide(slide, mask, center='radboud', alpha=0.8, max_size=(800, 800)):\n    \"\"\"Show a mask overlayed on a slide.\"\"\"\n\n    if center not in ['radboud', 'karolinska']:\n        raise Exception(\"Unsupported palette, should be one of [radboud, karolinska].\")\n\n    # Load data from the highest level\n    slide_data = slide.read_region((0,0), slide.level_count - 1, slide.level_dimensions[-1])\n    mask_data = mask.read_region((0,0), mask.level_count - 1, mask.level_dimensions[-1])\n\n    # Mask data is present in the R channel\n    mask_data = mask_data.split()[0]\n\n    # Create alpha mask\n    alpha_int = int(round(255*alpha))\n    if center == 'radboud':\n        alpha_content = np.less(mask_data.split()[0], 2).astype('uint8') * alpha_int + (255 - alpha_int)\n    elif center == 'karolinska':\n        alpha_content = np.less(mask_data.split()[0], 1).astype('uint8') * alpha_int + (255 - alpha_int)\n    \n    alpha_content = PIL.Image.fromarray(alpha_content)\n    preview_palette = np.zeros(shape=768, dtype=int)\n    \n    if center == 'radboud':\n        # Mapping: {0: background, 1: stroma, 2: benign epithelium, 3: Gleason 3, 4: Gleason 4, 5: Gleason 5}\n        preview_palette[0:18] = (np.array([0, 0, 0, 0.5, 0.5, 0.5, 0, 1, 0, 1, 1, 0.7, 1, 0.5, 0, 1, 0, 0]) * 255).astype(int)\n    elif center == 'karolinska':\n        # Mapping: {0: background, 1: benign, 2: cancer}\n        preview_palette[0:9] = (np.array([0, 0, 0, 0, 1, 0, 1, 0, 0]) * 255).astype(int)\n    \n    mask_data.putpalette(data=preview_palette.tolist())\n    mask_rgb = mask_data.convert(mode='RGB')\n\n    overlayed_image = PIL.Image.composite(image1=slide_data, image2=mask_rgb, mask=alpha_content)\n    overlayed_image.thumbnail(size=max_size, resample=0)\n\n    display(overlayed_image)\n","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"slide = openslide.OpenSlide(os.path.join(data_dir, '08ab45297bfe652cc0397f4b37719ba1.tiff'))\nmask = openslide.OpenSlide(os.path.join(mask_dir, '08ab45297bfe652cc0397f4b37719ba1_mask.tiff'))\noverlay_mask_on_slide(slide, mask, center='radboud')\nslide.close()\nmask.close()","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"biopsy = skimage.io.MultiImage(os.path.join(data_dir, '0b373388b189bee3ef6e320b841264dd.tiff'))","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"def get_i(fn):\n    filename = f'{train}/{fn.image_id}.tiff'\n    example2 = openslide.OpenSlide(str(filename))\n    ee = example2.get_thumbnail(size=(255, 255))\n    return tensor(ee)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"blocks = (\n          ImageBlock,\n          CategoryBlock\n          )\n         \ngetters = [\n           get_i,\n           ColReader('isup_grade')\n\n          ]\n\ntrends = DataBlock(blocks=blocks,\n              getters=getters,\n              item_tfms=Resize(194),\n              n_inp=1\n              )","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"blocks","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"dls = trends.dataloaders(train_set, bs=32)\ndls.show_batch()","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"dls.c","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"set_seed(7)\nmodel = xresnet34(n_out=dls.c, sa=True, act_cls=Mish)\n\nlearn = Learner(dls, model, \n                opt_func=ranger,\n                loss_func=LabelSmoothingCrossEntropy(),\n                metrics=[accuracy],\n                cbs = ShowGraphCallback())","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"learn.lr_find()","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"learn.freeze()\nlearn.fit_flat_cos(1, 5e-2)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"learn.save('test_one')\ninterp = Interpretation.from_learner(learn)\ninterp.plot_top_losses(12)","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"# Loading Test Data","execution_count":null},{"metadata":{"trusted":true},"cell_type":"code","source":"test_set.head()","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"for i in test_set.image_id:\n    filename = f'{train}/{i}.tiff'\n    example2 = openslide.OpenSlide(str(filename))\n    ee = example2.get_thumbnail(size=(255, 255))\n    ten = tensor(ee)\n    clas, tens, prob = learn.predict(ten) \n    \n    ","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"test_df = test_set.copy()\ntest_df","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"del test_df['data_provider']\ndel test_df['gleason_score']\ntest_df","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"test_df['isup_grade_pred'] = clas\ntest_df[['image_id', 'isup_grade', 'isup_grade_pred']]\n\ntest_df","execution_count":null,"outputs":[]}],"metadata":{"kernelspec":{"language":"python","display_name":"Python 3","name":"python3"},"language_info":{"pygments_lexer":"ipython3","nbconvert_exporter":"python","version":"3.6.4","file_extension":".py","codemirror_mode":{"name":"ipython","version":3},"name":"python","mimetype":"text/x-python"}},"nbformat":4,"nbformat_minor":4}