{"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_minor":4,"nbformat":4,"cells":[{"cell_type":"code","source":"import numpy as np\nimport pandas as pd\nimport cv2\nimport os\nimport random\nimport datetime\nimport matplotlib.pyplot as plt\nfrom shapely.wkt import loads as wkt_loads\nimport tifffile as tiff\n\nfrom keras import backend as K\n# from sklearn.metrics import jaccard_similarity_score\n\nfrom shapely.geometry import MultiPolygon, Polygon\nimport shapely.wkt\nimport shapely.affinity\nfrom collections import defaultdict\nfrom keras.models import *\nfrom keras.layers import *\nfrom keras.optimizers import *\nfrom keras.callbacks import ModelCheckpoint, LearningRateScheduler\nfrom keras import backend as keras\nimport gc\nimport warnings\nimport zipfile\nwarnings.filterwarnings(\"ignore\")\nfrom keras.models import load_model\nimport tensorflow as tf\nimport random as rn\nfrom tqdm import tqdm\nfrom tensorflow.keras.callbacks import Callback, ModelCheckpoint, ReduceLROnPlateau, LearningRateScheduler\nfrom tqdm import tqdm","metadata":{"_uuid":"2a32ba79-57a2-445d-bea3-3d5f6443c1a6","_cell_guid":"85a35830-a004-419f-8fcc-466884f9a508","execution":{"iopub.status.busy":"2022-06-13T02:37:07.32318Z","iopub.execute_input":"2022-06-13T02:37:07.323604Z","iopub.status.idle":"2022-06-13T02:37:12.713698Z","shell.execute_reply.started":"2022-06-13T02:37:07.323519Z","shell.execute_reply":"2022-06-13T02:37:12.712627Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"os.mkdir('/kaggle/data')\nos.mkdir('/kaggle/msk')\nos.mkdir('/kaggle/model_weights')\nos.mkdir('/kaggle/subm')","metadata":{"execution":{"iopub.status.busy":"2022-06-13T02:37:12.716366Z","iopub.execute_input":"2022-06-13T02:37:12.717012Z","iopub.status.idle":"2022-06-13T02:37:12.724903Z","shell.execute_reply.started":"2022-06-13T02:37:12.716973Z","shell.execute_reply":"2022-06-13T02:37:12.723931Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"os.mkdir('/kaggle/x_tr_a')\nos.mkdir('/kaggle/x_tr_na')\nos.mkdir('/kaggle/y_tr_a')\nos.mkdir('/kaggle/y_tr_na')\n\nos.mkdir('/kaggle/x_val_a')\nos.mkdir('/kaggle/x_val_na')\nos.mkdir('/kaggle/y_val_a')\nos.mkdir('/kaggle/y_val_na')\n\nos.mkdir('/kaggle/x_test_a')\nos.mkdir('/kaggle/x_test_na')\nos.mkdir('/kaggle/y_test_a')\nos.mkdir('/kaggle/y_test_na')","metadata":{"execution":{"iopub.status.busy":"2022-06-13T02:37:12.72654Z","iopub.execute_input":"2022-06-13T02:37:12.726969Z","iopub.status.idle":"2022-06-13T02:37:12.741201Z","shell.execute_reply.started":"2022-06-13T02:37:12.726892Z","shell.execute_reply":"2022-06-13T02:37:12.740378Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"num_cls = 10\nsize = 160\nsmooth = 1e-12\ninDir = '../input/dstl-satellite-imagery-feature-detection'\nTR = pd.read_csv(inDir + '/train_wkt_v4.csv.zip')\nGS = pd.read_csv(inDir + '/grid_sizes.csv.zip', names=['ImageId', 'Xmax', 'Ymin'], skiprows=1)\n\n#SF = pd.read_csv('/content/sample_submission.csv')\nGS = GS.rename( columns={'Unnamed: 0':'ImageId'}) #rename 'ImageId'","metadata":{"execution":{"iopub.status.busy":"2022-06-13T02:37:12.742847Z","iopub.execute_input":"2022-06-13T02:37:12.743396Z","iopub.status.idle":"2022-06-13T02:37:13.76961Z","shell.execute_reply.started":"2022-06-13T02:37:12.743357Z","shell.execute_reply":"2022-06-13T02:37:13.768639Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"## Preprocessing","metadata":{}},{"cell_type":"code","source":"#https://www.kaggle.com/aamaia/rgb-using-m-bands-example\n\n# \"Contrast enhancement\", similar to the default when opening an image using QGIS.\n\ndef adjust_contrast(bands, lower_percent=2, higher_percent=98):\n    \"\"\"\n    to adjust the contrast of the image \n    bands is the image \n    \"\"\"\n    out = np.zeros_like(bands).astype(np.float32)\n    n = bands.shape[2]\n    for i in range(n):\n        a = 0  # np.min(band)\n        b = 1  # np.max(band)\n        c = np.percentile(bands[:, :, i], lower_percent)\n        d = np.percentile(bands[:, :, i], higher_percent)\n        t = a + (bands[:, :, i] - c) * (b - a) / (d - c)\n        t[t < a] = a\n        t[t > b] = b\n        out[:, :, i] = t\n\n    return out.astype(np.float32)","metadata":{"execution":{"iopub.status.busy":"2022-06-13T02:37:13.774254Z","iopub.execute_input":"2022-06-13T02:37:13.774597Z","iopub.status.idle":"2022-06-13T02:37:13.784573Z","shell.execute_reply.started":"2022-06-13T02:37:13.774569Z","shell.execute_reply":"2022-06-13T02:37:13.783569Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"\ndef coordi_to_raster(coords, img_size, xmax, ymax):\n    \"\"\"\n    converts coordinates(polygons) to raster(pixels).\n    \"\"\"\n  \n    H, W = img_size\n    W1 = 1.0 * W * W / (W + 1)\n    H1 = 1.0 * H * H / (H + 1)\n    xf = W1 / xmax\n    yf = H1 / ymax\n    coords[:, 1] *= yf\n    coords[:, 0] *= xf\n    coords_int = np.round(coords).astype(np.int32)\n    return coords_int\n\ndef convert_contours(polygonList, raster_img_size, xmax, ymax):\n    \"\"\"\n    Returns exterior and interior coords of the given multipolygon,\n    which are then used to create image masks with multipolygon objects.\n    \"\"\"\n    perim_list = []\n    interior_list = []\n    if polygonList is None:\n        return None\n    for k in range(len(polygonList)):\n        poly = polygonList[k]\n        perim = np.array(list(poly.exterior.coords))\n        perim_c = coordi_to_raster(perim, raster_img_size, xmax, ymax)\n        perim_list.append(perim_c)\n        for pi in poly.interiors:\n            interior = np.array(list(pi.coords))\n            interior_c = coordi_to_raster(interior, raster_img_size, xmax, ymax)\n            interior_list.append(interior_c)\n    return perim_list, interior_list\n\n\ndef generate_mask_for_image_and_class(raster_size, image_id, class_type):\n\n    \"\"\"\n    returns generated image_mask using img_size(raster_size), image_id and class_type.\n    \"\"\"\n    xmax, ymax = GS[GS.ImageId == image_id].iloc[0, 1:].astype(float)\n\n    df_image = TR[TR.ImageId == image_id]\n    multipoly_def = df_image[df_image.ClassType == class_type].MultipolygonWKT\n    polygonList = None\n    if len(multipoly_def) > 0:\n        assert len(multipoly_def) == 1\n        polygonList = wkt_loads(multipoly_def.values[0])\n    \n    contours = convert_contours(polygonList, raster_size, xmax, ymax)\n\n    img_mask = np.zeros(raster_size, np.uint8)\n    if contours is None:\n        return img_mask\n    perim_list, interior_list = contours\n    cv2.fillPoly(img_mask, perim_list, 1)\n    cv2.fillPoly(img_mask, interior_list, 0)\n\n    return img_mask","metadata":{"execution":{"iopub.status.busy":"2022-06-13T02:37:13.787935Z","iopub.execute_input":"2022-06-13T02:37:13.788592Z","iopub.status.idle":"2022-06-13T02:37:13.803933Z","shell.execute_reply.started":"2022-06-13T02:37:13.78855Z","shell.execute_reply":"2022-06-13T02:37:13.80284Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"def get_patches(img, msk, name1, name2, name3, name4, amt, aug=True):\n\n    \"\"\"\n    returns image pathces(crops) of given image and mask\n    patch_size = 160*160\n    \"\"\"\n\n    random.seed(42)\n    is2 = int(1.0 * size)\n\n    xm, ym = img.shape[0] - is2, img.shape[1] - is2\n\n    a, b , c, d = [], [], [], []\n\n    # thresholds for each class to get patches\n    tr = [0.4, 0.1, 0.1, 0.15, 0.3, 0.95, 0.1, 0.05, 0.001, 0.005]\n    \n    xyz = np.ceil(amt*0.10).astype(int)\n    amt1 = amt-xyz\n    amt2 = xyz\n\n   # to get augmented data\n    for i in range(amt1):\n\n        xc = random.randint(0, xm)\n        yc = random.randint(0, ym)\n\n        im = img[xc:xc + is2, yc:yc + is2]\n        ms = msk[xc:xc + is2, yc:yc + is2]\n\n     \n        for j in range(num_cls):\n            sm = np.sum(ms[:, :, j])\n\n            if 1.0 * sm / is2 ** 2 > tr[j]:\n               \n                #augmentation\n                if aug:\n                    \n                    # reversing\n                    if random.uniform(0, 1) > 0.5:\n                        im = im[::-1]\n                        ms = ms[::-1]\n\n                    #flipping \n                    if random.uniform(0, 1) > 0.5:\n                        im = im[:, ::-1]\n                        ms = ms[:, ::-1]\n                    rotation = np.random.randint(4) # 0, 1, 2, 3\n\n                    #transpose & rotation\n                    if random.uniform(0, 1) > 0.5:\n                       im = np.rot90(im.transpose((1,0,2)), k=rotation)\n                       ms = np.rot90(ms.transpose((1,0,2)), k=rotation)\n                    \n                    #rotation\n                    if random.uniform(0, 1) > 0.5:\n                      im = np.rot90(im, k=rotation)\n                      ms = np.rot90(ms, k=rotation)\n                    \n                    #shearing \n                    if random.uniform(0, 1) > 0.5:\n                       im = tf.keras.preprocessing.image.apply_affine_transform(im, shear=0)\n                       im = tf.keras.preprocessing.image.apply_affine_transform(im, shear=0)\n                                     \n                \n                im = im.astype(np.float16)\n                ms = ms.astype(np.float16)\n                \n                \n                np.save(\"/kaggle/{}/{}\".format(name1, i),im)  \n                np.save(\"/kaggle/{}/{}\".format(name2, i),ms)  \n               \n                a.append(\"/kaggle/{}/{}.npy\".format(name1, i))\n                b.append(\"/kaggle/{}/{}.npy\".format(name2, i))\n\n    # to get non-augmented data\n    for i in range(amt2):\n        xc = random.randint(0, xm)\n        yc = random.randint(0, ym)\n\n        im = img[xc:xc + is2, yc:yc + is2]\n        ms = msk[xc:xc + is2, yc:yc + is2]\n\n        im = im.astype(np.float16)\n        ms = ms.astype(np.float16)\n                                  \n        np.save(\"/kaggle/{}/{}\".format(name3, i),im)  \n        np.save(\"/kaggle/{}/{}\".format(name4, i),ms)  \n                \n        c.append(\"/kaggle/{}/{}.npy\".format(name3, i))\n        d.append(\"/kaggle/{}/{}.npy\".format(name4, i))\n\n    \n    print(len(a), len(b))\n    print(len(c), len(d))\n  \n    return a+c, b+d","metadata":{"execution":{"iopub.status.busy":"2022-06-13T02:37:13.807946Z","iopub.execute_input":"2022-06-13T02:37:13.808278Z","iopub.status.idle":"2022-06-13T02:37:13.831592Z","shell.execute_reply.started":"2022-06-13T02:37:13.808253Z","shell.execute_reply":"2022-06-13T02:37:13.830468Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"class Dataloder(tf.keras.utils.Sequence):    \n    def __init__(self, dataset, batch_size=1, shuffle=False):\n        self.dataset = dataset\n        self.batch_size = batch_size\n        self.shuffle = shuffle\n        self.indexes = np.arange(len(dataset))\n\n    def __getitem__(self, i):\n        \n        # collect batch data\n        start = i * self.batch_size\n        stop = (i + 1) * self.batch_size\n        data = []\n        for j in range(start, stop):\n            data.append(self.dataset[j])\n        \n        batch = [np.stack(samples, axis=0) for samples in zip(*data)]\n        \n        #print(len(batch))\n        return tuple(batch)\n    \n    def __len__(self):\n        return len(self.indexes) // self.batch_size\n\nclass Dataset:\n  \n    def __init__(self, images_dir, mask_dir):\n        \n        self.ids = images_dir\n        self.images_fps = images_dir\n        self.masks_fps  = mask_dir\n    \n    def __getitem__(self, i):\n        \n        # read data\n        image = np.load(self.images_fps[i]) \n        mask  = np.load(self.masks_fps[i])\n\n          \n        image = np.stack(image, axis=-1).astype('float')\n        mask = np.stack(mask, axis=-1).astype('float')\n\n        #image = np.transpose(image, (1,0,2)) \n        #mask = np.transpose(mask, (1,0,2)) \n    \n        image = np.transpose(image, (0,2,1)) \n        mask = np.transpose(mask, (0,2,1)) \n  \n        return image, mask\n      \n    def __len__(self):\n        return len(self.ids)","metadata":{"execution":{"iopub.status.busy":"2022-06-13T02:37:13.833065Z","iopub.execute_input":"2022-06-13T02:37:13.833406Z","iopub.status.idle":"2022-06-13T02:37:13.848147Z","shell.execute_reply.started":"2022-06-13T02:37:13.833371Z","shell.execute_reply":"2022-06-13T02:37:13.847206Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"\ndef M(image_id):\n    # __author__ = amaia\n    # https://www.kaggle.com/aamaia/dstl-satellite-imagery-feature-detection/rgb-using-m-bands-example\n    zip_path = '../input/dstl-satellite-imagery-feature-detection/sixteen_band.zip'\n    tgtImg = '{}_M.tif'.format(image_id)\n    with zipfile.ZipFile(zip_path) as myzip:\n        files_in_zip = myzip.namelist()\n        for fname in files_in_zip:\n            if fname.endswith(tgtImg):\n                with myzip.open(fname) as myfile:\n                    img = tiff.imread(myfile)\n                    img = np.rollaxis(img, 0, 3)\n                    return img\n                \n                \n\nprint (\"let's combine all imgs together\")\ns = 835\n\nX = np.zeros((5 * s, 5 * s, 8))\nY = np.zeros((5 * s, 5 * s, num_cls))  \n\nids = sorted(set(TR.ImageId))\nprint (len(ids))\n\nfor i in range(5):\n    for j in range(5):\n        id = ids[5 * i + j]\n\n        rgb_img = M(id)\n        img = adjust_contrast(rgb_img).copy()\n        \n        \n        print (img.shape, id)\n        X[s * i:s * i + s, s * j:s * j + s, :] = img[:s, :s, :]\n        for z in range(num_cls):\n            Y[s * i:s * i + s, s * j:s * j + s, z] = generate_mask_for_image_and_class(\n                (img.shape[0], img.shape[1]), id, z + 1)[:s, :s]\n\nnp.save('/kaggle/data/X', X)\nnp.save('/kaggle/data/Y', Y)\nprint(X.shape)\nprint(Y.shape)\n","metadata":{"execution":{"iopub.status.busy":"2022-06-13T02:37:13.850001Z","iopub.execute_input":"2022-06-13T02:37:13.850562Z","iopub.status.idle":"2022-06-13T02:37:39.859038Z","shell.execute_reply.started":"2022-06-13T02:37:13.850527Z","shell.execute_reply":"2022-06-13T02:37:39.857908Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"## split the data into train, val and test ","metadata":{}},{"cell_type":"code","source":"x_trn, y_trn = get_patches(X, Y, 'x_tr_a', 'y_tr_a', 'x_tr_na', 'y_tr_na', 20000, aug=True)","metadata":{"execution":{"iopub.status.busy":"2022-06-13T02:37:39.862273Z","iopub.execute_input":"2022-06-13T02:37:39.862529Z","iopub.status.idle":"2022-06-13T02:39:38.73991Z","shell.execute_reply.started":"2022-06-13T02:37:39.862503Z","shell.execute_reply":"2022-06-13T02:39:38.738101Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"x_val, y_val = get_patches(X, Y, 'x_val_a', 'y_val_a', 'x_val_na', 'y_val_na', 4000, aug=True)\n","metadata":{"execution":{"iopub.status.busy":"2022-06-13T02:39:38.74149Z","iopub.execute_input":"2022-06-13T02:39:38.741885Z","iopub.status.idle":"2022-06-13T02:40:04.527301Z","shell.execute_reply.started":"2022-06-13T02:39:38.741847Z","shell.execute_reply":"2022-06-13T02:40:04.526384Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"x_test, y_test = get_patches(X, Y, 'x_test_a', 'y_test_na', 'x_test_a', 'y_test_na', 4000, aug=True)\n","metadata":{"execution":{"iopub.status.busy":"2022-06-13T02:40:04.528866Z","iopub.execute_input":"2022-06-13T02:40:04.529487Z","iopub.status.idle":"2022-06-13T02:40:29.202571Z","shell.execute_reply.started":"2022-06-13T02:40:04.529445Z","shell.execute_reply":"2022-06-13T02:40:29.201766Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"train_dataset = Dataset(x_trn, y_trn)\ntrain_dataloader = Dataloder(train_dataset, batch_size=8)\nval_dataset = Dataset(x_val, y_val)\nval_dataloader = Dataloder(val_dataset, batch_size=8)","metadata":{"execution":{"iopub.status.busy":"2022-06-13T02:40:29.203872Z","iopub.execute_input":"2022-06-13T02:40:29.204218Z","iopub.status.idle":"2022-06-13T02:40:29.213603Z","shell.execute_reply.started":"2022-06-13T02:40:29.204186Z","shell.execute_reply":"2022-06-13T02:40:29.212749Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"train_dataloader[0][0].shape","metadata":{"execution":{"iopub.status.busy":"2022-06-13T02:40:29.21507Z","iopub.execute_input":"2022-06-13T02:40:29.215719Z","iopub.status.idle":"2022-06-13T02:40:30.745895Z","shell.execute_reply.started":"2022-06-13T02:40:29.215686Z","shell.execute_reply":"2022-06-13T02:40:30.745131Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"## Modelling","metadata":{}},{"cell_type":"code","source":"def jaccard_coef(y_true, y_pred):\n    \"\"\"\n    Jaccard Index: Intersection over Union.\n    J(A,B) = |A∩B| / |A∪B| \n         = |A∩B| / |A|+|B|-|A∩B|\n    \"\"\"\n    intersection = K.sum(y_true * y_pred, axis=[0, -1, -2])\n    total = K.sum(y_true + y_pred, axis=[0, -1, -2])\n    union = total - intersection\n\n    jac = (intersection + smooth) / (union+ smooth)\n\n    return K.mean(jac)","metadata":{"execution":{"iopub.status.busy":"2022-06-13T02:40:30.748867Z","iopub.execute_input":"2022-06-13T02:40:30.749132Z","iopub.status.idle":"2022-06-13T02:40:30.757599Z","shell.execute_reply.started":"2022-06-13T02:40:30.749106Z","shell.execute_reply":"2022-06-13T02:40:30.756767Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"##fixing numpy RS\nnp.random.seed(42)\n\n##fixing tensorflow RS\ntf.random.set_seed(32)\n\n##python RS\nrn.seed(12)\n\ndef SegNet():\n    \n    tf.random.set_seed(32)\n    classes= 10\n    img_input = Input(shape=(size, size, 8))\n    x = img_input\n\n    # Encoder \n    \n    x = Conv2D(64, (3, 3), activation='relu', padding='same', kernel_initializer = tf.keras.initializers.he_normal(seed= 23))(x)\n    x = BatchNormalization()(x)\n    x = Conv2D(64, (3, 3), activation='relu', padding='same',  kernel_initializer = tf.keras.initializers.he_normal(seed= 43))(x)\n   # x = BatchNormalization()(x)\n    x = MaxPooling2D((2, 2), strides=(2, 2))(x)\n    x = Dropout(0.25)(x)\n    \n    x = Conv2D(128, (3, 3), activation='relu', padding='same', kernel_initializer = tf.keras.initializers.he_normal(seed= 32))(x)\n    x = BatchNormalization()(x)\n    x = Conv2D(128, (3, 3), activation='relu', padding='same', kernel_initializer = tf.keras.initializers.he_normal(seed= 41))(x)\n   # x = BatchNormalization()(x)\n    x = Conv2D(128, (3, 3), activation='relu', padding='same', kernel_initializer = tf.keras.initializers.he_normal(seed= 33))(x)\n    x = BatchNormalization()(x)\n    x = MaxPooling2D((2, 2), strides=(2, 2))(x)\n    x = Dropout(0.5)(x)\n\n    x = Conv2D(256, (3, 3), activation='relu', padding='same', kernel_initializer = tf.keras.initializers.he_normal(seed= 35))(x)\n    x = BatchNormalization()(x)\n    x = Conv2D(256, (3, 3), activation='relu', padding='same', kernel_initializer = tf.keras.initializers.he_normal(seed= 54))(x)\n    x = BatchNormalization()(x)\n    x = Conv2D(256, (3, 3), activation='relu', padding='same', kernel_initializer = tf.keras.initializers.he_normal(seed= 39))(x)\n    x = BatchNormalization()(x)\n    x = Dropout(0.5)(x)\n    \n    #Decoder\n    \n    x = UpSampling2D(size=(2, 2))(x)\n    x = Conv2D(128, kernel_size=3, activation='relu', padding='same', kernel_initializer = tf.keras.initializers.he_normal(seed= 45))(x)\n   # x = BatchNormalization()(x)\n    x = Conv2D(128, kernel_size=3, activation='relu', padding='same', kernel_initializer = tf.keras.initializers.he_normal(seed= 41))(x)\n    x = BatchNormalization()(x)\n    x = Conv2D(128, kernel_size=3, activation='relu', padding='same', kernel_initializer = tf.keras.initializers.he_normal(seed= 49))(x)\n    x = BatchNormalization()(x)\n    x = Dropout(0.25)(x)\n      \n    x = UpSampling2D(size=(2, 2))(x)\n    x = Conv2D(64, kernel_size=3, activation='relu', padding='same', kernel_initializer = tf.keras.initializers.he_normal(seed= 18))(x)\n    x = BatchNormalization()(x)\n    x = Conv2D(64, kernel_size=3, activation='relu', padding='same', kernel_initializer = tf.keras.initializers.he_normal(seed= 21))(x)\n    x = BatchNormalization()(x)\n    x = Conv2D(classes, kernel_size=3, activation='relu', padding='same', kernel_initializer = tf.keras.initializers.he_normal(seed= 16))(x)\n    x = Dropout(0.25)(x)\n  \n    x = Activation(\"softmax\")(x)\n    \n    model = Model(img_input, x)\n  \n    model.compile(optimizer=Adam(lr=1e-4),loss='binary_crossentropy', metrics=[jaccard_coef])\n    return model","metadata":{"execution":{"iopub.status.busy":"2022-06-13T02:40:30.760624Z","iopub.execute_input":"2022-06-13T02:40:30.760874Z","iopub.status.idle":"2022-06-13T02:40:30.78159Z","shell.execute_reply.started":"2022-06-13T02:40:30.760842Z","shell.execute_reply":"2022-06-13T02:40:30.78078Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"def changeLearningRate(epoch):\n\n    #lr=0.001\n    lr=0.0001\n    if epoch > 10 and epoch <=20:\n      lr*=0.1\n    elif epoch > 20 and epoch <=30:\n      lr*=0.01\n    elif epoch > 30 and epoch <=40:\n      lr*=0.001\n    elif epoch > 40 and epoch <=50:  \n      lr*=0.0001\n    elif epoch > 50 and epoch <=60:  \n      lr*=0.0001  \n    elif epoch > 60:\n      lr*=0.0001\n\n    return lr","metadata":{"execution":{"iopub.status.busy":"2022-06-13T02:40:30.784529Z","iopub.execute_input":"2022-06-13T02:40:30.7848Z","iopub.status.idle":"2022-06-13T02:40:30.796363Z","shell.execute_reply.started":"2022-06-13T02:40:30.784775Z","shell.execute_reply":"2022-06-13T02:40:30.795296Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"#https://towardsdatascience.com/neural-network-with-tensorflow-how-to-stop-training-using-callback-5c8d575c18a9\n\nACCURACY_THRESHOLD=0.502\nclass myCallback(tf.keras.callbacks.Callback): \n    \n    def on_epoch_end(self, epoch, logs={}): \n        if (logs.get('val_jaccard_coef') > ACCURACY_THRESHOLD) and (logs.get('jaccard_coef') > ACCURACY_THRESHOLD):   #and ((logs.get('accuracy')-logs.get('val_accuracy'))<=5):\n          print(\"\\nReached %2.2f%% accuracy, so stopping training!!\" %(ACCURACY_THRESHOLD*100))   \n          self.model.stop_training = True\n\nstop = myCallback()","metadata":{"execution":{"iopub.status.busy":"2022-06-13T02:40:30.797633Z","iopub.execute_input":"2022-06-13T02:40:30.798206Z","iopub.status.idle":"2022-06-13T02:40:30.807911Z","shell.execute_reply.started":"2022-06-13T02:40:30.798169Z","shell.execute_reply":"2022-06-13T02:40:30.80692Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"filepath=\"/kaggle/model_weights/weights-{epoch:02d}-{val_jaccard_coef:.4f}.hdf5\"\n\ncheckpoint = ModelCheckpoint(filepath=filepath, monitor='val_loss',  verbose=1, save_best_only=True, mode='auto')","metadata":{"execution":{"iopub.status.busy":"2022-06-13T02:40:30.809412Z","iopub.execute_input":"2022-06-13T02:40:30.809879Z","iopub.status.idle":"2022-06-13T02:40:30.821173Z","shell.execute_reply.started":"2022-06-13T02:40:30.809844Z","shell.execute_reply":"2022-06-13T02:40:30.820336Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"rlrop = ReduceLROnPlateau(monitor='val_loss', factor=0.1, patience=3, verbose = 1, min_delta = 0.0001)\nlrschedule = LearningRateScheduler(changeLearningRate, verbose=1)\n#call_list = [checkpoint, lrschedule, rlrop, stop]","metadata":{"execution":{"iopub.status.busy":"2022-06-13T02:40:30.823162Z","iopub.execute_input":"2022-06-13T02:40:30.823518Z","iopub.status.idle":"2022-06-13T02:40:30.830896Z","shell.execute_reply.started":"2022-06-13T02:40:30.823483Z","shell.execute_reply":"2022-06-13T02:40:30.829957Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"model = SegNet()","metadata":{"execution":{"iopub.status.busy":"2022-06-13T02:40:30.832151Z","iopub.execute_input":"2022-06-13T02:40:30.832552Z","iopub.status.idle":"2022-06-13T02:40:33.735475Z","shell.execute_reply.started":"2022-06-13T02:40:30.832516Z","shell.execute_reply":"2022-06-13T02:40:33.734605Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"model.summary()","metadata":{"execution":{"iopub.status.busy":"2022-06-13T02:40:33.736649Z","iopub.execute_input":"2022-06-13T02:40:33.736968Z","iopub.status.idle":"2022-06-13T02:40:33.757975Z","shell.execute_reply.started":"2022-06-13T02:40:33.736934Z","shell.execute_reply":"2022-06-13T02:40:33.757351Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"history = model.fit(train_dataloader, \n                              steps_per_epoch=len(train_dataloader),\n                              epochs=20,\n                              validation_data=val_dataloader, \n                              callbacks=checkpoint\n                              )","metadata":{"_kg_hide-output":true,"execution":{"iopub.status.busy":"2022-06-13T02:40:33.761497Z","iopub.execute_input":"2022-06-13T02:40:33.761731Z","iopub.status.idle":"2022-06-13T03:24:19.223959Z","shell.execute_reply.started":"2022-06-13T02:40:33.761708Z","shell.execute_reply":"2022-06-13T03:24:19.220478Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"test_dataset = Dataset(x_test, y_test)\ntest_dataloader = Dataloder(test_dataset, batch_size=1)","metadata":{"execution":{"iopub.status.busy":"2022-06-13T03:24:19.228226Z","iopub.execute_input":"2022-06-13T03:24:19.228674Z","iopub.status.idle":"2022-06-13T03:24:19.241334Z","shell.execute_reply.started":"2022-06-13T03:24:19.228628Z","shell.execute_reply":"2022-06-13T03:24:19.2403Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# I have set the weights name manually\n\nmodel = SegNet()\n#model.load_weights(\"/kaggle/model_weights/weights-20-0.2539.hdf5\")","metadata":{"execution":{"iopub.status.busy":"2022-06-13T03:25:08.597182Z","iopub.execute_input":"2022-06-13T03:25:08.597536Z","iopub.status.idle":"2022-06-13T03:25:08.823893Z","shell.execute_reply.started":"2022-06-13T03:25:08.597503Z","shell.execute_reply":"2022-06-13T03:25:08.82313Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"Score= []\nfor i in tqdm(range(len(test_dataloader))):\n   pred_msk = model.predict(test_dataloader[i][0])\n   score = jaccard_coef(test_dataloader[i][1], pred_msk)\n   Score.append(score)","metadata":{"execution":{"iopub.status.busy":"2022-06-13T03:25:09.900687Z","iopub.execute_input":"2022-06-13T03:25:09.901024Z","iopub.status.idle":"2022-06-13T03:26:44.130006Z","shell.execute_reply.started":"2022-06-13T03:25:09.900992Z","shell.execute_reply":"2022-06-13T03:26:44.129131Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"\nscore = sum(Score)/len(test_dataloader)\nprint(\"The score on test data is\", score.numpy())","metadata":{"execution":{"iopub.status.busy":"2022-06-13T03:28:12.127146Z","iopub.execute_input":"2022-06-13T03:28:12.1275Z","iopub.status.idle":"2022-06-13T03:28:12.180097Z","shell.execute_reply.started":"2022-06-13T03:28:12.127469Z","shell.execute_reply":"2022-06-13T03:28:12.1792Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"## Error Analysis","metadata":{}},{"cell_type":"code","source":"model = SegNet()\n#model.load_weights(\"/kaggle/model_weights/weights-20-0.2539.hdf5\")","metadata":{"execution":{"iopub.status.busy":"2022-06-13T03:28:14.68608Z","iopub.execute_input":"2022-06-13T03:28:14.686418Z","iopub.status.idle":"2022-06-13T03:28:14.921938Z","shell.execute_reply.started":"2022-06-13T03:28:14.686387Z","shell.execute_reply":"2022-06-13T03:28:14.921217Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"\ntotal_x = x_trn + x_val + x_test\ntotal_y = y_trn + y_val+ y_test","metadata":{"execution":{"iopub.status.busy":"2022-06-13T03:28:16.279058Z","iopub.execute_input":"2022-06-13T03:28:16.279396Z","iopub.status.idle":"2022-06-13T03:28:16.284344Z","shell.execute_reply.started":"2022-06-13T03:28:16.279366Z","shell.execute_reply":"2022-06-13T03:28:16.28313Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"total_dataset = Dataset(total_x, total_y)\ntotal_dataloader = Dataloder(total_dataset, batch_size=1)","metadata":{"execution":{"iopub.status.busy":"2022-06-13T03:28:17.550557Z","iopub.execute_input":"2022-06-13T03:28:17.550888Z","iopub.status.idle":"2022-06-13T03:28:17.555639Z","shell.execute_reply.started":"2022-06-13T03:28:17.550857Z","shell.execute_reply":"2022-06-13T03:28:17.554219Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"Score= []\nvery_low_jaccard=[]\nmedium_jaccard= []\nvery_high_jaccard= []\n\nfor i in tqdm(range(len(total_dataloader))):\n\n   pred_msk = model.predict(total_dataloader[i][0])\n   score = jaccard_coef(total_dataloader[i][1], pred_msk)\n   \n   if score>0 and score <=0.20:\n      very_low_jaccard.append(i)\n\n   elif score>0.20 and score <=0.70:\n      medium_jaccard.append(i)\n   \n   elif score>0.70 and score <=1:\n      very_high_jaccard.append(i)","metadata":{"execution":{"iopub.status.busy":"2022-06-13T03:28:18.532817Z","iopub.execute_input":"2022-06-13T03:28:18.533187Z","iopub.status.idle":"2022-06-13T03:39:30.639434Z","shell.execute_reply.started":"2022-06-13T03:28:18.533151Z","shell.execute_reply":"2022-06-13T03:39:30.636882Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"\nVery_low_jaccard_x = []\nMedium_jaccard_x = []\nVery_high_jaccard_x = []\n\nVery_low_jaccard_y = []\nMedium_jaccard_y = []\nVery_high_jaccard_y = []\n\nfor i in very_low_jaccard:\n   Very_low_jaccard_x.append(total_x[i])\nfor i in medium_jaccard:\n   Medium_jaccard_x.append(total_x[i])\nfor i in very_high_jaccard:\n   Very_high_jaccard_x.append(total_x[i])      \n\nfor i in very_low_jaccard:\n   Very_low_jaccard_y.append(total_y[i])\nfor i in medium_jaccard:\n   Medium_jaccard_y.append(total_y[i])\nfor i in very_high_jaccard:\n   Very_high_jaccard_y.append(total_y[i])","metadata":{"execution":{"iopub.status.busy":"2022-06-13T03:39:46.143765Z","iopub.execute_input":"2022-06-13T03:39:46.144102Z","iopub.status.idle":"2022-06-13T03:39:46.162335Z","shell.execute_reply.started":"2022-06-13T03:39:46.144066Z","shell.execute_reply":"2022-06-13T03:39:46.161202Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"np.save(\"vljx\", Very_low_jaccard_x)\nnp.save(\"vljy\", Very_low_jaccard_y)","metadata":{"execution":{"iopub.status.busy":"2022-06-13T03:39:47.469735Z","iopub.execute_input":"2022-06-13T03:39:47.470318Z","iopub.status.idle":"2022-06-13T03:39:47.489833Z","shell.execute_reply.started":"2022-06-13T03:39:47.470269Z","shell.execute_reply":"2022-06-13T03:39:47.488917Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"\nvljx = np.load(\"vljx.npy\")\nvljy = np.load(\"vljy.npy\")","metadata":{"execution":{"iopub.status.busy":"2022-06-13T03:39:48.441381Z","iopub.execute_input":"2022-06-13T03:39:48.441708Z","iopub.status.idle":"2022-06-13T03:39:48.449405Z","shell.execute_reply.started":"2022-06-13T03:39:48.441678Z","shell.execute_reply":"2022-06-13T03:39:48.448154Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"\ndef mask_to_polygons(mask, epsilon=5, min_area=1.):\n    \"\"\"\n    converts a mask into polygons.\n    \"\"\"\n    \n    contours, hierarchy = cv2.findContours(((mask == 1) * 255).astype(np.uint8), cv2.RETR_CCOMP, cv2.CHAIN_APPROX_TC89_KCOS)\n    approx_contours = [cv2.approxPolyDP(cnt, epsilon, True)\n                       for cnt in contours]\n    if not contours:\n        return MultiPolygon()\n\n    cnt_children = defaultdict(list)\n    child_contours = set()\n    assert hierarchy.shape[0] == 1\n\n    for idx, (_, _, _, parent_idx) in enumerate(hierarchy[0]):\n        if parent_idx != -1:\n            child_contours.add(idx)\n            cnt_children[parent_idx].append(approx_contours[idx])\n\n    # create actual polygons filtering by area (removes artifacts)\n    all_polygons = []\n    for idx, cnt in enumerate(approx_contours):\n        if idx not in child_contours and cv2.contourArea(cnt) >= min_area:\n            assert cnt.shape[1] == 1\n            poly = Polygon(\n                shell=cnt[:, 0, :],\n                holes=[c[:, 0, :] for c in cnt_children.get(idx, [])\n                       if cv2.contourArea(c) >= min_area])\n            all_polygons.append(poly)\n    # approximating polygons might have created invalid ones, fix them\n    all_polygons = MultiPolygon(all_polygons)\n    if not all_polygons.is_valid:\n        all_polygons = all_polygons.buffer(0)\n        # Sometimes buffer() converts a simple Multipolygon to just a Polygon,\n        # need to keep it a Multi throughout\n        if all_polygons.type == 'Polygon':\n            all_polygons = MultiPolygon([all_polygons])\n    return all_polygons","metadata":{"execution":{"iopub.status.busy":"2022-06-13T03:39:49.489581Z","iopub.execute_input":"2022-06-13T03:39:49.489906Z","iopub.status.idle":"2022-06-13T03:39:49.501369Z","shell.execute_reply.started":"2022-06-13T03:39:49.489873Z","shell.execute_reply":"2022-06-13T03:39:49.500187Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"\nDF  = pd.DataFrame(columns=[\"image\", \"class\", \"poly\"])\n\nfor i in range(25):\n   abcd = np.load(vljy[i])\n   image, cl , ploy = [],[],[]\n  \n   for j in range(10):\n     ab = mask_to_polygons(abcd[:,:,j], epsilon=1)\n     image.append(i+1)\n     cl.append(j+1)\n     ploy.append(len(ab))\n     df = pd.DataFrame(list(zip(image, cl, ploy)), columns = ['image', 'class', 'poly'])\n\n   DF = pd.concat([DF,df], ignore_index=True)","metadata":{"execution":{"iopub.status.busy":"2022-06-13T03:39:50.81657Z","iopub.execute_input":"2022-06-13T03:39:50.8169Z","iopub.status.idle":"2022-06-13T03:39:51.487813Z","shell.execute_reply.started":"2022-06-13T03:39:50.81687Z","shell.execute_reply":"2022-06-13T03:39:51.486942Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"objects_per_image = DF.pivot(index='class', columns='image', values='poly')","metadata":{"execution":{"iopub.status.busy":"2022-06-13T03:39:52.972961Z","iopub.execute_input":"2022-06-13T03:39:52.973337Z","iopub.status.idle":"2022-06-13T03:39:53.005132Z","shell.execute_reply.started":"2022-06-13T03:39:52.973303Z","shell.execute_reply":"2022-06-13T03:39:53.004166Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"%matplotlib inline\nfigure, axis = plt.subplots(figsize=(20, 5))\naxis.set_aspect('equal')\nplt.imshow(objects_per_image.astype(np.uint), cmap='Accent_r', extent=[0, 25, 10, 0])\n\nplt.xticks(np.arange(1, 25, 1.0))\nplt.yticks(np.arange(1, 11, 1.0))\nplt.title('Number of objects per image')\nplt.xlabel('Images')\nplt.ylabel('Classes')\nplt.colorbar()\nplt.show()","metadata":{"execution":{"iopub.status.busy":"2022-06-13T03:39:54.409753Z","iopub.execute_input":"2022-06-13T03:39:54.410093Z","iopub.status.idle":"2022-06-13T03:39:54.815188Z","shell.execute_reply.started":"2022-06-13T03:39:54.410053Z","shell.execute_reply":"2022-06-13T03:39:54.814216Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"### Observations","metadata":{}},{"cell_type":"code","source":"\nprint(\"minimum value in an image\",np.amin(np.load(vljx[0])))\nprint(\"maximum value in an image\",np.amax(np.load(vljx[0])))","metadata":{"execution":{"iopub.status.busy":"2022-06-13T03:39:57.201903Z","iopub.execute_input":"2022-06-13T03:39:57.202248Z","iopub.status.idle":"2022-06-13T03:39:57.22443Z","shell.execute_reply.started":"2022-06-13T03:39:57.202217Z","shell.execute_reply":"2022-06-13T03:39:57.223504Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"threshold = 0.4\nSum = []\n\nfor i in tqdm(range(25)):\n   a = np.load(vljx[i])\n   im= []\n   for j in range(8):\n     im.append(np.count_nonzero(np.less(a[:,:,j], threshold))) \n   x = sum(im)\n   Sum.append(x)  \npercentage = (sum(Sum)/(160*160*8*25))*100","metadata":{"execution":{"iopub.status.busy":"2022-06-13T03:39:58.952065Z","iopub.execute_input":"2022-06-13T03:39:58.95242Z","iopub.status.idle":"2022-06-13T03:39:59.092676Z","shell.execute_reply.started":"2022-06-13T03:39:58.952381Z","shell.execute_reply":"2022-06-13T03:39:59.091782Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"### Observations","metadata":{}},{"cell_type":"code","source":"\ndef plot_image(image_id):\n\n  m = np.load(vljx[image_id])\n  m = adjust_contrast(m)\n  img = np.zeros((m.shape[0],m.shape[1],3))\n  img[:,:,0] = m[:,:,4] #red\n  img[:,:,1] = m[:,:,2] #green\n  img[:,:,2] = m[:,:,1] #blue\n  #plt.figure(figsize=(7,7))\n  plt.imshow(img, interpolation='nearest')\n  plt.show()","metadata":{"execution":{"iopub.status.busy":"2022-06-13T03:40:01.849984Z","iopub.execute_input":"2022-06-13T03:40:01.850374Z","iopub.status.idle":"2022-06-13T03:40:01.85646Z","shell.execute_reply.started":"2022-06-13T03:40:01.85034Z","shell.execute_reply":"2022-06-13T03:40:01.855307Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"def plot_mask(mask_id):\n  m = np.load(vljy[i])\n  m = adjust_contrast(m)\n  img = np.zeros((m.shape[0],m.shape[1],3)) \n  img[:,:,0] = m[:,:,4] #red\n  img[:,:,1] = m[:,:,2] #green\n  img[:,:,2] = m[:,:,1] #blue\n  #plt.figure(figsize=(7,7))\n  plt.imshow(img, interpolation='nearest')\n  plt.show()","metadata":{"execution":{"iopub.status.busy":"2022-06-13T03:40:03.041874Z","iopub.execute_input":"2022-06-13T03:40:03.042217Z","iopub.status.idle":"2022-06-13T03:40:03.048558Z","shell.execute_reply.started":"2022-06-13T03:40:03.042186Z","shell.execute_reply":"2022-06-13T03:40:03.047005Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"for i in range(15):\n   plot_image(i)\n   plot_mask(i)","metadata":{"execution":{"iopub.status.busy":"2022-06-13T03:40:19.794871Z","iopub.execute_input":"2022-06-13T03:40:19.795212Z","iopub.status.idle":"2022-06-13T03:40:24.904707Z","shell.execute_reply.started":"2022-06-13T03:40:19.795178Z","shell.execute_reply":"2022-06-13T03:40:24.903784Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"","metadata":{},"execution_count":null,"outputs":[]}]}