{"cells":[{"metadata":{},"cell_type":"markdown","source":"The code below selects 16 128x128 tiles for each image and mask based on the maximum number of tissue pixels. The kernel also provides computed image stats. Please check my kernels to see how to use this data. \n![](https://i.ibb.co/RzSWP56/convert.png)"},{"metadata":{},"cell_type":"markdown","source":"# Imports"},{"metadata":{"_uuid":"8f2839f25d086af736a60e9eeb907d3b93b6e0e5","_cell_guid":"b1076dfc-b9ad-4769-8c92-a6c4dae69d19","trusted":true},"cell_type":"code","source":"import os\nimport cv2\nimport skimage.io\nfrom tqdm.notebook import tqdm\nimport zipfile\nimport numpy as np\nimport pandas as pd\nimport matplotlib.pyplot as plt\nfrom sklearn.model_selection import train_test_split\nfrom keras.preprocessing.image import ImageDataGenerator\nfrom keras.utils import to_categorical\nfrom keras.models import Sequential, load_model\nfrom keras.layers import Dense, Dropout, Flatten\nfrom keras.layers import Conv2D, MaxPooling2D, BatchNormalization\nfrom keras.optimizers import Adam\nfrom keras.callbacks import LearningRateScheduler\nfrom keras.callbacks import EarlyStopping\nfrom tensorflow.keras.utils import to_categorical\nfrom tqdm import tqdm\nfrom glob import glob\nfrom keras.layers.core import Activation\nfrom keras.layers.core import Flatten\nfrom keras.layers.core import Dropout\nfrom keras.layers.core import Dense\nfrom keras import backend as K\nimport tensorflow as tf\n\n\n\n## Setting the seeds for Reproducibility.\nseed = 3141\nnp.random.seed(seed)","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"# Loading Data"},{"metadata":{"trusted":true},"cell_type":"code","source":"df = pd.read_csv('../input/prostate-cancer-grade-assessment/train.csv')\ndf = df[df['data_provider'] == 'karolinska'].reset_index(drop=True)\nids = df['image_id'].values\ndf.head(60)","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"# Constant Varibles"},{"metadata":{"trusted":true},"cell_type":"code","source":"TRAIN = '../input/prostate-cancer-grade-assessment/train_images/'\nMASKS = '../input/prostate-cancer-grade-assessment/train_label_masks/'\nOUT_TRAIN = 'train.zip'\nOUT_MASKS = 'masks.zip'","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"# Modifable Variables"},{"metadata":{"trusted":true},"cell_type":"code","source":"sz = 120\nN = 20\npatients = 1000","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"# Demo of Size of Images"},{"metadata":{"trusted":true},"cell_type":"code","source":"img = skimage.io.MultiImage(os.path.join(TRAIN,ids[0]+'.tiff'))\nimg[0].shape, img[1].shape, img[2].shape","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"# Function to create tiles"},{"metadata":{"trusted":true},"cell_type":"code","source":"def tile(img, mask):\n    result = []\n    shape = img.shape\n    pad0,pad1 = (sz - shape[0]%sz)%sz, (sz - shape[1]%sz)%sz\n    img = np.pad(img,[[pad0//2,pad0-pad0//2],[pad1//2,pad1-pad1//2],[0,0]],\n                constant_values=255)\n    mask = np.pad(mask,[[pad0//2,pad0-pad0//2],[pad1//2,pad1-pad1//2],[0,0]],\n                constant_values=0)\n    img = img.reshape(img.shape[0]//sz,sz,img.shape[1]//sz,sz,3)\n    img = img.transpose(0,2,1,3,4).reshape(-1,sz,sz,3)\n    mask = mask.reshape(mask.shape[0]//sz,sz,mask.shape[1]//sz,sz,3)\n    mask = mask.transpose(0,2,1,3,4).reshape(-1,sz,sz,3)\n    if len(img) < N:\n        mask = np.pad(mask,[[0,N-len(img)],[0,0],[0,0],[0,0]],constant_values=0)\n        img = np.pad(img,[[0,N-len(img)],[0,0],[0,0],[0,0]],constant_values=255)\n    idxs = np.argsort(img.reshape(img.shape[0],-1).sum(-1))[:N]\n    img = img[idxs]\n    mask = mask[idxs]\n    return img, mask","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"\n# create_tiles and Labels"},{"metadata":{"trusted":true},"cell_type":"code","source":"X = []\nY = []\nfor name in tqdm(ids[0:patients], total=patients):\n    img = skimage.io.MultiImage(os.path.join(TRAIN,name+'.tiff'))[-1]\n    mask = skimage.io.MultiImage(os.path.join(MASKS,name+'_mask.tiff'))[-1]\n    img, mask = tile(img,mask)\n    k = 0\n    while k < N:\n        label = 0\n        if 2 in np.unique(mask[k, ]):\n            label = 1\n        X.append(img[k, ])\n        Y.append(label)\n        k += 1","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"X = np.array(X)\nY = np.array(Y)","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"# Train Test Split"},{"metadata":{"trusted":true},"cell_type":"code","source":"from sklearn.model_selection import train_test_split\nX_train,X_test,Y_train,Y_test=train_test_split(X, Y,random_state=0,test_size=0.25)","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"# Fill Remaining Notebook.....!"},{"metadata":{"trusted":true},"cell_type":"code","source":"print('X shape:', X.shape)\nprint('Y_train shape:', X_train.shape)\nprint(X_train.shape[0], 'train samples')\nprint(X_test.shape[0], 'test samples')","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"plt.figure(figsize=(20,8))\nfor i in range(10,18):\n    plt.subplot(231 + (i))\n    plt.imshow(X_train[i])","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"from keras.utils import Sequence\nfrom albumentations import (\n    HorizontalFlip, IAAPerspective, ShiftScaleRotate, CLAHE, RandomRotate90,\n    Transpose, ShiftScaleRotate, Blur, OpticalDistortion, GridDistortion, HueSaturationValue,\n    IAAAdditiveGaussianNoise, GaussNoise, MotionBlur, MedianBlur, RandomBrightnessContrast, IAAPiecewiseAffine,\n    IAASharpen, IAAEmboss, Flip, OneOf, Compose)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"image_dim=(120,120,3)\nBATCH_SIZE=50","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"\nclass Generator(Sequence):\n    def __init__(self,input_data,batch_size=BATCH_SIZE,dims=image_dim,is_shuffle=True,n_classes=3,is_train=True):\n        self.image_ids=input_data[0]\n        self.labels=input_data[1]\n        self.batch_size=batch_size\n        self.dims=image_dim\n        self.shuffle=is_shuffle\n        self.n_classes=n_classes\n        self.is_train=is_train\n        self.on_epoch_end()\n    \n    def __len__(self):\n        return int(np.floor(len(self.image_ids) / self.batch_size))\n    \n    def on_epoch_end(self):\n        self.indexes = np.arange(len(self.image_ids))\n        if self.shuffle == True:\n            np.random.shuffle(self.indexes)\n    \n    def __getitem__(self, index):\n        indexes = self.indexes[index*self.batch_size:(index+1)*self.batch_size]\n\n        image_ids_temp = [self.image_ids[k] for k in indexes]\n        labels_temp = [self.labels[k] for k in indexes]\n\n        # Generate data\n        X, y = self.__data_generation(image_ids_temp,labels_temp)\n\n        return X, y\n    \n    def augment_flips_color(self,p=.5):\n        return Compose([\n            Flip(),\n            RandomRotate90(),\n            Transpose(),\n            HorizontalFlip(),\n            ShiftScaleRotate(shift_limit=0.0625, scale_limit=0.50, rotate_limit=45, p=.75),\n            Blur(blur_limit=3),\n        ], p=p)\n    \n    def __data_generation(self, list_IDs_temp,lbls):\n        X = np.zeros((self.batch_size, *self.dims))\n        y = np.zeros((self.batch_size), dtype=int)\n\n        # Generate data\n        for i, ID in enumerate(list_IDs_temp):\n            # Store sample\n            img=MultiImage(os.path.join(main_path,'train_images',ID+'.tiff'))\n            img = resize(img[-1], (self.dims[0], self.dims[1]))\n            #Augmentation\n            if self.is_train:\n                aug = self.augment_flips_color(p=1)\n                img = aug(image=img)['image']\n                \n            X[i] = img\n\n            # Store class\n            y[i] = lbls[i]\n\n        return X, to_categorical(y, num_classes=self.n_classes)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"#convert values to float as result will be a float. If not done vals are set to zero\nX_train = X_train.astype(\"float32\")/255\nX_test = X_test.astype(\"float32\")/255\n\n\n","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"#notice num_classes is set to 2 as we have 2 different labels\nY_train = to_categorical(Y_train, num_classes=2)\nY_test = to_categorical(Y_test, num_classes=2)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"\nfrom keras.layers.convolutional import SeparableConv2D\n","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"channelDim = -1\n\nmodel=Sequential()\nmodel.add(SeparableConv2D(30, (3,3), padding=\"same\",input_shape=(120,120,3)))\nmodel.add(Activation(\"relu\"))\nmodel.add(BatchNormalization(axis=channelDim))\nmodel.add(MaxPooling2D(pool_size=(2,2)))\nmodel.add(Dropout(0.4))\n\nmodel.add(SeparableConv2D(60, (3,3), padding=\"same\"))\nmodel.add(Activation(\"relu\"))\nmodel.add(BatchNormalization(axis=channelDim))\nmodel.add(SeparableConv2D(60, (3,3), padding=\"same\"))\nmodel.add(Activation(\"relu\"))\nmodel.add(BatchNormalization(axis=channelDim))\nmodel.add(MaxPooling2D(pool_size=(2,2)))\nmodel.add(Dropout(0.4))\n\nmodel.add(SeparableConv2D(120, (3,3), padding=\"same\"))\nmodel.add(Activation(\"relu\"))\nmodel.add(BatchNormalization(axis=channelDim))\nmodel.add(SeparableConv2D(120, (3,3), padding=\"same\"))\nmodel.add(Activation(\"relu\"))\nmodel.add(BatchNormalization(axis=channelDim))\nmodel.add(SeparableConv2D(240, (3,3), padding=\"same\"))\nmodel.add(Activation(\"relu\"))\nmodel.add(BatchNormalization(axis=channelDim))\nmodel.add(MaxPooling2D(pool_size=(2,2)))\nmodel.add(Dropout(0.4))\n\n\nmodel.add(Flatten())\nmodel.add(Dense(240))\nmodel.add(Activation(\"relu\"))\nmodel.add(BatchNormalization())\nmodel.add(Dropout(0.4))\n\nmodel.add(Dense(1))\nmodel.add(Activation(\"sigmoid\")) \noptimizer = Adam(lr=0.001, beta_1=0.9, beta_2=0.999)\n","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"dot_img_file = '/tmp/model_1.png'\ntf.keras.utils.plot_model(model, to_file=dot_img_file, show_shapes=True)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"\nmodel.compile(loss='binary_crossentropy',optimizer=Adam (0.001),metrics=['acc'])","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"history=model.fit(X,Y,epochs=5,validation_split=0.25,batch_size=50)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"plt.figure(figsize=(12,5))\nplt.plot(history.history['loss'])\nplt.plot(history.history['val_loss'])\nplt.xlabel('epochs')\nplt.ylabel('loss')\nplt.legend(['train_data','test_data'])\nplt.title('loss analysis')\nplt.show()","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"plt.figure(figsize=(12,5))\nplt.plot(history.history['acc'])\nplt.plot(history.history['val_acc'])\nplt.xlabel('epochs')\nplt.ylabel('accuracy')\nplt.legend(['train_data','test_data'])\nplt.title('accuracy analysis')\nplt.show()","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"img = X_test[0, ]\nprint (img.shape)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"plt.figure(figsize=(20,8))\nplt.subplot(241)\nplt.imshow(img[:, :, 0], cmap=\"gray\")","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}