{"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":"%matplotlib inline\nimport os\nimport time\nimport tqdm\nimport torch\nimport numpy as np\nimport pandas as pd\nfrom PIL import Image\nimport torch.nn as nn\nimport torch.optim as optim\nimport torch.nn.functional as F\nimport matplotlib.pyplot as plt\nfrom torchvision import models, transforms\nfrom torch.utils.data import TensorDataset,DataLoader , Dataset\nimport cv2","metadata":{"execution":{"iopub.status.busy":"2022-07-23T05:12:55.034051Z","iopub.execute_input":"2022-07-23T05:12:55.034807Z","iopub.status.idle":"2022-07-23T05:12:57.101107Z","shell.execute_reply.started":"2022-07-23T05:12:55.034703Z","shell.execute_reply":"2022-07-23T05:12:57.099936Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"train_csv = pd.read_csv('../input/severstal-steel-defect-detection/train.csv')\ntrain_csv.head(20)","metadata":{"execution":{"iopub.status.busy":"2022-07-23T05:13:07.714924Z","iopub.execute_input":"2022-07-23T05:13:07.715601Z","iopub.status.idle":"2022-07-23T05:13:08.145430Z","shell.execute_reply.started":"2022-07-23T05:13:07.715544Z","shell.execute_reply":"2022-07-23T05:13:08.144333Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"train_df = train_csv.dropna(subset=['EncodedPixels'], axis='rows', inplace=True)\n\ntrain_df = (\n    train_csv[['ImageId', 'ClassId', 'EncodedPixels']]\n        .groupby('ImageId', as_index=False) \n        .agg(list) \n)\ntrain_df.head(10)","metadata":{"execution":{"iopub.status.busy":"2022-07-23T05:13:15.833497Z","iopub.execute_input":"2022-07-23T05:13:15.834422Z","iopub.status.idle":"2022-07-23T05:13:15.982146Z","shell.execute_reply.started":"2022-07-23T05:13:15.834386Z","shell.execute_reply":"2022-07-23T05:13:15.981031Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"def rle2mask(idx,df):\n    img_name = df.iloc[idx , 0]\n    \n    labels = df.iloc[idx , 2]\n    mask = np.zeros((256,1600,4) , dtype = np.uint8)\n    cl = df.iloc[idx , 1]\n    for i,label in enumerate(labels): \n        \n        runss = np.asarray([int(x) for x in label.split(' ')])\n        runss[1::2] += runss[0::2]\n        runss -= 1\n        run_starts, run_ends = runss[0::2], runss[1::2]\n        h, w = (1600,256)\n        mask_label = np.zeros(h*w, dtype=np.uint8)\n        for start, end in zip(run_starts, run_ends):\n            mask_label[start:end] = 1\n    \n        mask[:,:,cl[i]-1] = mask_label.reshape(256,1600,order = 'F')\n    return img_name , mask    ","metadata":{"execution":{"iopub.status.busy":"2022-07-23T05:13:22.836567Z","iopub.execute_input":"2022-07-23T05:13:22.836944Z","iopub.status.idle":"2022-07-23T05:13:22.846325Z","shell.execute_reply.started":"2022-07-23T05:13:22.836915Z","shell.execute_reply":"2022-07-23T05:13:22.845307Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"for i in range(6):\n    plt.figure(figsize=(20,10))\n    img_name , mask = rle2mask(i,train_df)\n    img = cv2.imread('../input/severstal-steel-defect-detection/train_images' + '/' + img_name)\n    img = cv2.cvtColor(img, cv2.COLOR_BGR2RGB)\n    for ch in range(4):\n        contours, hierarchy = cv2.findContours(mask[:,:,ch], cv2.RETR_TREE, cv2.CHAIN_APPROX_SIMPLE)\n        cv2.drawContours(img, contours, -1, (255,255,0), 2)\n    plt.imshow(img)","metadata":{"execution":{"iopub.status.busy":"2022-07-23T05:13:30.726019Z","iopub.execute_input":"2022-07-23T05:13:30.726354Z","iopub.status.idle":"2022-07-23T05:13:32.738185Z","shell.execute_reply.started":"2022-07-23T05:13:30.726327Z","shell.execute_reply":"2022-07-23T05:13:32.737279Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"class SteelDataset(Dataset):\n    def __init__(self,df , path):\n        self.df = df\n        self.path = path\n    \n    def __getitem__(self,index):\n        img_name , mask = rle2mask(index,self.df)\n        img_path = os.path.join(self.path , img_name)\n        img = cv2.imread(img_path)\n        img = np.array(img)/255\n        img = torch.from_numpy(img).permute(2,0,1)\n        mask = torch.from_numpy(mask).permute(2,0,1)\n        return img,mask\n    \n    def __len__(self):\n        return len(self.df)","metadata":{"execution":{"iopub.status.busy":"2022-07-23T05:13:42.677050Z","iopub.execute_input":"2022-07-23T05:13:42.677409Z","iopub.status.idle":"2022-07-23T05:13:42.685920Z","shell.execute_reply.started":"2022-07-23T05:13:42.677379Z","shell.execute_reply":"2022-07-23T05:13:42.684952Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"use_gpu = torch.cuda.is_available()\nif use_gpu:\n    print('GPU is available!')\n    device = \"cuda\"\n    pinMem = True\nelse:\n    print('GPU is not available!')\n    device = \"cpu\"\n    pinMem = False","metadata":{"execution":{"iopub.status.busy":"2022-07-23T05:13:49.902256Z","iopub.execute_input":"2022-07-23T05:13:49.902625Z","iopub.status.idle":"2022-07-23T05:13:49.968499Z","shell.execute_reply.started":"2022-07-23T05:13:49.902573Z","shell.execute_reply":"2022-07-23T05:13:49.967333Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"trainpath = '../input/severstal-steel-defect-detection/train_images'\ntrainDataset = SteelDataset(train_df.iloc[:int(0.8*len(train_df))] ,trainpath )\nvalDataset = SteelDataset(train_df.iloc[int(0.8*len(train_df)):] ,trainpath )\nbatch_size = 16\n\ntrainDataLoader = DataLoader(trainDataset , batch_size = batch_size , shuffle = True, num_workers=2,pin_memory =True)\nvalDataLoader = DataLoader(valDataset, batch_size = batch_size, shuffle = True , num_workers = 2, pin_memory=True)","metadata":{"execution":{"iopub.status.busy":"2022-07-23T05:13:57.544931Z","iopub.execute_input":"2022-07-23T05:13:57.545291Z","iopub.status.idle":"2022-07-23T05:13:57.552536Z","shell.execute_reply.started":"2022-07-23T05:13:57.545261Z","shell.execute_reply":"2022-07-23T05:13:57.551522Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"!pip install segmentation-models-pytorch","metadata":{"execution":{"iopub.status.busy":"2022-07-23T05:14:04.359150Z","iopub.execute_input":"2022-07-23T05:14:04.359719Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"#https://pypi.org/project/segmentation-models-pytorch/\nimport segmentation_models_pytorch as smp\nfrom segmentation_models_pytorch import Unet\n","metadata":{"execution":{"iopub.status.busy":"2022-07-23T03:15:08.094265Z","iopub.execute_input":"2022-07-23T03:15:08.094670Z","iopub.status.idle":"2022-07-23T03:15:10.039592Z","shell.execute_reply.started":"2022-07-23T03:15:08.094632Z","shell.execute_reply":"2022-07-23T03:15:10.038534Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"model = Unet(encoder_name='resnet18' , encoder_weights = 'imagenet' , classes=4 , activation = 'sigmoid')\nmode = model.to(device)\nprint(model)","metadata":{"execution":{"iopub.status.busy":"2022-07-23T05:15:26.499009Z","iopub.execute_input":"2022-07-23T05:15:26.499372Z","iopub.status.idle":"2022-07-23T05:15:26.868446Z","shell.execute_reply.started":"2022-07-23T05:15:26.499343Z","shell.execute_reply":"2022-07-23T05:15:26.866652Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"#The Dice coefficient can be used to compare the pixel-wise agreement between a predicted segmentation and its ground truth. \ndef dice_coef(y_pred,y_true,smooth=1):\n    y_pred = y_pred.view(batch_size,-1)\n    y_true = y_true.view(batch_size,-1)\n    y_pred = (y_pred > 0.5).float()\n    y_true = (y_true > 0.5).float()\n    dice = (2* torch.sum(y_pred*y_true)+smooth)/(torch.sum(y_pred)+torch.sum(y_true)+smooth)\n    dice = torch.mean(dice , axis=0)\n    return dice","metadata":{"execution":{"iopub.status.busy":"2022-07-23T07:20:27.078352Z","iopub.execute_input":"2022-07-23T07:20:27.079163Z","iopub.status.idle":"2022-07-23T07:20:27.085644Z","shell.execute_reply.started":"2022-07-23T07:20:27.079119Z","shell.execute_reply":"2022-07-23T07:20:27.084565Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"criterion = nn.BCELoss() \noptimizer = optim.Adam(model.parameters(), lr=1e-3)","metadata":{"execution":{"iopub.status.busy":"2022-07-23T07:19:37.120559Z","iopub.execute_input":"2022-07-23T07:19:37.120935Z","iopub.status.idle":"2022-07-23T07:19:37.126924Z","shell.execute_reply.started":"2022-07-23T07:19:37.120903Z","shell.execute_reply":"2022-07-23T07:19:37.125643Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"iterations = 15\ntrainLoss = []\nvalLoss = []\nvalDice = []\nstart = time.time()\n\nfor epoch in range(iterations):\n    epochStart = time.time()\n    runningLoss = 0   \n    model.train() # For training\n    for data in tqdm.notebook.tqdm(trainDataLoader):\n        inputs,labels = data\n        inputs, labels = inputs.float().to(device), labels.float().to(device) \n        \n        # Feed-forward input data through the network\n        outputs = model(inputs)\n        # Compute loss/error\n        loss = criterion(outputs, labels)      \n        # Initialize gradients to zero\n        optimizer.zero_grad()                  \n        # Backpropagate loss and compute gradients\n        loss.backward()\n        # Update the network parameters\n        optimizer.step()\n        # Accumulate loss per batch\n        runningLoss += loss.item()\n    avgTrainLoss = runningLoss/(5332 /batch_size)   \n    trainLoss.append(avgTrainLoss)\n  \n    \n    # Evaluating performance on test set for each epoch\n    model.eval() # For testing\n    val_runningLoss = 0\n    val_runningDice = 0\n    with torch.no_grad():\n        for data in tqdm.notebook.tqdm(valDataLoader):\n            inputs,labels = data\n            inputs, labels = inputs.float().to(device), labels.float().to(device)         \n            outputs = model(inputs)       \n             # Compute loss/error\n            loss = criterion(outputs, labels)      \n            # Accumulate loss per batch\n            val_runningLoss += loss.item() \n            val_runningDice += dice_coef(outputs,labels)\n    avgValLoss = val_runningLoss/(1334/batch_size)  \n    valLoss.append(avgValLoss)\n    avgValDice = (val_runningDice/(1334/batch_size)).cpu()  \n    valDice.append(avgValDice)\n    # Plotting Loss vs Epochs\n    fig1 = plt.figure(1)        \n    plt.plot(range(epoch+1),trainLoss,'r--',label='train')        \n    plt.plot(range(epoch+1),valLoss,'g--',label='valid')        \n    if epoch==0:\n        plt.legend(loc='upper left')\n        plt.xlabel('Epochs')\n        plt.ylabel('Loss')   \n    fig2 = plt.figure(2)        \n    plt.plot(range(epoch+1),valDice,'g-',label='valid')        \n    if epoch==0:\n        plt.legend(loc='upper left')\n        plt.xlabel('Epochs')\n        plt.ylabel('dice_coef')   \n    \n    epochEnd = time.time()-epochStart\n    print('At Iteration: {:.0f} /{:.0f}  ;  Training Loss: {:.6f}; Time consumed: {:.0f}m {:.0f}s '\\\n          .format(epoch + 1,iterations,avgTrainLoss,epochEnd//60,epochEnd%60))\n    print('At Iteration: {:.0f} /{:.0f}  ;  Validation Loss: {:.6f} ; Validation Dice: {:.3f}; Time consumed: {:.0f}m {:.0f}s '\\\n          .format(epoch + 1,iterations,avgValLoss,avgValDice,epochEnd//60,epochEnd%60))\nend = time.time()-start\nprint('Training completed in {:.0f}m {:.0f}s'.format(end//60,end%60))","metadata":{"execution":{"iopub.status.busy":"2022-07-23T05:15:38.833452Z","iopub.execute_input":"2022-07-23T05:15:38.833817Z","iopub.status.idle":"2022-07-23T06:45:46.340671Z","shell.execute_reply.started":"2022-07-23T05:15:38.833786Z","shell.execute_reply":"2022-07-23T06:45:46.339565Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"torch.save(model.state_dict(), 'Unetresnet18_adam.pt')","metadata":{"execution":{"iopub.status.busy":"2022-07-23T06:48:51.249190Z","iopub.execute_input":"2022-07-23T06:48:51.250329Z","iopub.status.idle":"2022-07-23T06:48:51.556969Z","shell.execute_reply.started":"2022-07-23T06:48:51.250290Z","shell.execute_reply":"2022-07-23T06:48:51.556000Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"torch.cuda.empty_cache()","metadata":{"execution":{"iopub.status.busy":"2022-07-23T06:59:11.190652Z","iopub.execute_input":"2022-07-23T06:59:11.191089Z","iopub.status.idle":"2022-07-23T06:59:11.196542Z","shell.execute_reply.started":"2022-07-23T06:59:11.191054Z","shell.execute_reply":"2022-07-23T06:59:11.195528Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"model.load_state_dict(torch.load('../input/notebook/Unetresnet18_adam.pt'))","metadata":{"execution":{"iopub.status.busy":"2022-07-23T07:20:01.914483Z","iopub.execute_input":"2022-07-23T07:20:01.914903Z","iopub.status.idle":"2022-07-23T07:20:02.870372Z","shell.execute_reply.started":"2022-07-23T07:20:01.914870Z","shell.execute_reply":"2022-07-23T07:20:02.869370Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"testpath = '../input/severstal-steel-defect-detection/test_images'\nimages = os.listdir('../input/severstal-steel-defect-detection/test_images')\ntest_df = pd.read_csv('../input/severstal-steel-defect-detection/sample_submission.csv')\ntest_df['ImageId'] = images\ntest_df","metadata":{"execution":{"iopub.status.busy":"2022-07-23T07:20:37.999415Z","iopub.execute_input":"2022-07-23T07:20:37.999771Z","iopub.status.idle":"2022-07-23T07:20:38.024151Z","shell.execute_reply.started":"2022-07-23T07:20:37.999738Z","shell.execute_reply":"2022-07-23T07:20:38.023292Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"class TestDataset(Dataset):\n    def __init__(self,df , path):\n        self.df = df\n        self.path = path\n    \n    def __getitem__(self,index):\n        img_name = self.df.iloc[index,0]\n        img_path = os.path.join(self.path , img_name)\n        img = cv2.imread(img_path)\n        img = np.array(img)/255\n        img = torch.from_numpy(img).permute(2,0,1)\n        return img , img_name\n    \n    def __len__(self):\n        return len(self.df)","metadata":{"execution":{"iopub.status.busy":"2022-07-23T07:20:43.254260Z","iopub.execute_input":"2022-07-23T07:20:43.255359Z","iopub.status.idle":"2022-07-23T07:20:43.262918Z","shell.execute_reply.started":"2022-07-23T07:20:43.255312Z","shell.execute_reply":"2022-07-23T07:20:43.261788Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"testDataset = TestDataset(test_df , testpath)\ntestDataLoader = DataLoader(testDataset, batch_size = 8, shuffle = False , num_workers = 2, pin_memory=True)","metadata":{"execution":{"iopub.status.busy":"2022-07-23T07:20:54.377869Z","iopub.execute_input":"2022-07-23T07:20:54.378451Z","iopub.status.idle":"2022-07-23T07:20:54.384305Z","shell.execute_reply.started":"2022-07-23T07:20:54.378407Z","shell.execute_reply":"2022-07-23T07:20:54.383354Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"#https://www.kaggle.com/paulorzp/rle-functions-run-lenght-encode-decode\ndef mask2rle(img):\n    img = img.flatten()\n    img = np.concatenate([[0],img ,[0]])\n    runs = np.where(img[1:] != img[:-1])[0] + 1\n    runs[1::2] -= runs[::2]\n    return ' '.join(str(x) for x in runs)","metadata":{"execution":{"iopub.status.busy":"2022-07-23T07:20:56.469080Z","iopub.execute_input":"2022-07-23T07:20:56.469532Z","iopub.status.idle":"2022-07-23T07:20:56.477970Z","shell.execute_reply.started":"2022-07-23T07:20:56.469497Z","shell.execute_reply":"2022-07-23T07:20:56.476867Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"#https://www.kaggle.com/code/carnav0400/individual-models-normal-pytorch-main-600-6b2ed3\nthreshold_min = [0.7,0.7,0.7,0.7]\nthresholds_max=[0.7,0.7,0.7,0.7]\nthresholds_min=[0.2,0.2,0.3,0.3]\nmin_area=[350, 500, 750, 1000]\nres = []\nmodel.eval()\nfor data in tqdm.notebook.tqdm(testDataLoader):\n    inputs , img_names = data\n    inputs = inputs.float().to(device)\n    preds = model(inputs)\n    \n    for pred,file in zip(preds,img_names):\n        file = os.path.basename(file)\n        \n        for i in range(4):\n            p_channel = pred[i]\n            p_channel_ = p_channel\n            imageid_classid = file+'_'+str(i+1)\n            p_channel = (p_channel>thresholds_max[i]).cpu().numpy().astype(np.uint8)\n            if p_channel.sum() < min_area[i]:\n                p_channel = np.zeros(p_channel.shape, dtype=p_channel.dtype)\n            else:\n                p_channel = (p_channel_>thresholds_min[i]).cpu().numpy().astype(np.uint8)\n            res.append({\n                'ImageId_ClassId': imageid_classid,\n                'EncodedPixels': mask2rle(p_channel)\n            })\n\nsubmit_df = pd.DataFrame(res)            \n    ","metadata":{"execution":{"iopub.status.busy":"2022-07-23T07:21:05.627398Z","iopub.execute_input":"2022-07-23T07:21:05.627765Z","iopub.status.idle":"2022-07-23T07:24:01.128530Z","shell.execute_reply.started":"2022-07-23T07:21:05.627731Z","shell.execute_reply":"2022-07-23T07:24:01.127393Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"submit_df.head(10)","metadata":{"execution":{"iopub.status.busy":"2022-07-23T07:36:05.808681Z","iopub.execute_input":"2022-07-23T07:36:05.809044Z","iopub.status.idle":"2022-07-23T07:36:05.822184Z","shell.execute_reply.started":"2022-07-23T07:36:05.809009Z","shell.execute_reply":"2022-07-23T07:36:05.821005Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"submit_df.to_csv('submission.csv' , index = False)","metadata":{"execution":{"iopub.status.busy":"2022-07-23T07:37:09.598072Z","iopub.execute_input":"2022-07-23T07:37:09.599215Z","iopub.status.idle":"2022-07-23T07:37:10.025539Z","shell.execute_reply.started":"2022-07-23T07:37:09.599173Z","shell.execute_reply":"2022-07-23T07:37:10.024546Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"","metadata":{},"execution_count":null,"outputs":[]}]}