{"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 matplotlib.pyplot as plt\n\nfrom PIL import Image\n\nimport json\nimport os\nfrom tqdm import tqdm\n\nimport torch\nimport torch.nn as nn\nimport torch.nn.functional as F\nfrom torch.utils.data import Dataset , DataLoader\nfrom torchvision import transforms\nfrom torch.optim import Adam\nfrom torch.autograd import Variable\n\nimport albumentations as A\nfrom albumentations.pytorch import ToTensorV2 \n\npath = \"../input/imaterialist-fashion-2020-fgvc7\"","metadata":{"_uuid":"8f2839f25d086af736a60e9eeb907d3b93b6e0e5","_cell_guid":"b1076dfc-b9ad-4769-8c92-a6c4dae69d19","execution":{"iopub.status.busy":"2022-05-24T07:14:10.038735Z","iopub.execute_input":"2022-05-24T07:14:10.039065Z","iopub.status.idle":"2022-05-24T07:14:13.664704Z","shell.execute_reply.started":"2022-05-24T07:14:10.038989Z","shell.execute_reply":"2022-05-24T07:14:13.661891Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"train_path = \"train\" \ntest_path = \"test\"\n\nDEVICE = 'cuda' if torch.cuda.is_available() else 'cpu'\nIMAGE_HEIGHT = 512\nIMAGE_WIDTH = 512\nBATCH_SIZE = 1\nNUM_WORKERS = 0\nLR = 0.0001\nEPOCHS = 1","metadata":{"execution":{"iopub.status.busy":"2022-05-24T07:14:13.666724Z","iopub.execute_input":"2022-05-24T07:14:13.667238Z","iopub.status.idle":"2022-05-24T07:14:13.73746Z","shell.execute_reply.started":"2022-05-24T07:14:13.667201Z","shell.execute_reply":"2022-05-24T07:14:13.736547Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"df_train = pd.read_csv(\"../input/imaterialist-fashion-2020-fgvc7/train.csv\")\n\nwith open(\"../input/imaterialist-fashion-2020-fgvc7/label_descriptions.json\", 'r') as file:\n    label_desc = json.load(file)","metadata":{"execution":{"iopub.status.busy":"2022-05-24T07:14:13.743143Z","iopub.execute_input":"2022-05-24T07:14:13.746469Z","iopub.status.idle":"2022-05-24T07:14:34.615592Z","shell.execute_reply.started":"2022-05-24T07:14:13.746428Z","shell.execute_reply":"2022-05-24T07:14:34.614828Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"class fashion_set(Dataset):\n    def __init__(self, path, subpath, df_train, transforms=None):\n        self.path = os.path.join(path, subpath)\n        self.img_id = os.listdir(self.path)\n        self.transforms = transforms\n        self.df_train = df_train\n    \n    def df2mask(self, df, image_path):\n        df_mask = df.copy()\n        images_meta=[]\n        \n        img = np.array(Image.open(image_path).convert(\"RGB\"))\n        images_meta.append({\n            'image': img,\n            'shape': img.shape,\n            'encoded_pixels': list(df_mask['EncodedPixels']),\n            'class_ids':  list(df_mask['ClassId']),\n            'height': int(df_mask[\"Height\"].mean()),\n            'width': int(df_mask[\"Width\"].mean())\n        })\n\n        masks = []\n        for image in images_meta:\n            shape = image.get('shape')\n            encoded_pixels = image.get('encoded_pixels')\n            class_ids = image.get('class_ids')\n        \n            # Initialize numpy array with shape same as image size\n            height, width = shape[:2]\n            mask = np.zeros((height, width)).reshape(-1)\n        \n            # Iterate over encoded pixels and create mask\n            for segment, (pixel_str, class_id) in enumerate(zip(encoded_pixels, class_ids)):\n                splitted_pixels = list(map(int, pixel_str.split()))\n                pixel_starts = splitted_pixels[::2]\n                run_lengths = splitted_pixels[1::2]\n                assert max(pixel_starts) < mask.shape[0]\n                for pixel_start, run_length in zip(pixel_starts, run_lengths):\n                    pixel_start = int(pixel_start) - 1\n                    run_length = int(run_length)\n                    mask[pixel_start:pixel_start+run_length] = 255 - class_id * 4\n            masks.append(mask.reshape((height, width), order='F'))\n        \n        return masks, images_meta\n    \n    def __len__(self):\n        return len(self.img_id)\n    \n    def __getitem__(self, idx):\n        img_idx = self.img_id[idx] #第N張圖片路徑名稱 str       \n        img_idx_path = os.path.join(self.path, img_idx)\n        img = np.array(Image.open(img_idx_path).convert(\"RGB\"))\n        df_train = self.df_train       \n        \n        Image_Id = img_idx.split(\".\")[0] #圖片ID\n        img_df = df_train[df_train[\"ImageId\"] == Image_Id] #找出圖片ID的所有值                \n        \n        masks, images_meta = self.df2mask(img_df, img_idx_path)       \n        \n        if self.transforms is not None:        \n            image = self.transforms(image=img, masks=masks)\n            \n        return image, images_meta[0]","metadata":{"execution":{"iopub.status.busy":"2022-05-24T07:14:34.617914Z","iopub.execute_input":"2022-05-24T07:14:34.618179Z","iopub.status.idle":"2022-05-24T07:14:34.63613Z","shell.execute_reply.started":"2022-05-24T07:14:34.618139Z","shell.execute_reply":"2022-05-24T07:14:34.635452Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"class img_show_set(fashion_set): \n    def __init__(self, path, subpath, df_train):\n        self.path = os.path.join(path, subpath)\n        self.img_id = os.listdir(self.path)\n        self.df_train = df_train\n    \n    def __len__(self):\n        return len(self.img_id)\n    \n    def df2mask(self, df, image_path): #繼承fashion_set df2mask\n        masks, images_meta = super().df2mask(df, image_path)\n        return masks, images_meta\n        \n    def __getitem__(self, idx):\n        img_idx = self.img_id[idx] #第N張圖片路徑名稱 str       \n        img_idx_path = os.path.join(self.path, img_idx)\n        img = np.array(Image.open(img_idx_path).convert(\"RGB\"))\n        df_train = self.df_train       \n        \n        Image_Id = img_idx.split(\".\")[0] #圖片ID\n        img_df = df_train[df_train[\"ImageId\"] == Image_Id] #找出圖片ID的所有值                      \n        \n        masks, images_meta = self.df2mask(img_df, img_idx_path)\n            \n        return img, masks    ","metadata":{"execution":{"iopub.status.busy":"2022-05-24T07:14:34.637401Z","iopub.execute_input":"2022-05-24T07:14:34.63769Z","iopub.status.idle":"2022-05-24T07:14:34.650024Z","shell.execute_reply.started":"2022-05-24T07:14:34.637643Z","shell.execute_reply":"2022-05-24T07:14:34.64926Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"def double_conv(in_channels, out_channels):\n    return nn.Sequential(\n        nn.Conv2d(in_channels, out_channels, 3, padding=1),\n        nn.ReLU(inplace=True),\n        nn.Conv2d(out_channels, out_channels, 3, padding=1),\n        nn.ReLU(inplace=True)\n    )   \n\nclass UNet(nn.Module):\n\n    def __init__(self, n_class):\n        super().__init__()\n                \n        self.dconv_down1 = double_conv(3, 64)\n        self.dconv_down2 = double_conv(64, 128)\n        self.dconv_down3 = double_conv(128, 256)\n        self.dconv_down4 = double_conv(256, 512)  \n\n        self.maxpool = nn.MaxPool2d(2)\n        \n        self.dconv_up3 = double_conv(512, 256)\n        self.dconv_up2 = double_conv(256, 128)\n        self.dconv_up1 = double_conv(128, 64)\n        \n        self.TConv3 = nn.ConvTranspose2d(512, 256, 2, stride=2)\n        self.TConv2 = nn.ConvTranspose2d(256, 128, 2, stride=2)\n        self.TConv1 = nn.ConvTranspose2d(128, 64, 2, stride=2)\n        \n        self.conv_last = nn.Conv2d(64, n_class, 1)\n        \n    def forward(self, x):\n        conv1 = self.dconv_down1(x)\n        x = self.maxpool(conv1)\n        \n        conv2 = self.dconv_down2(x)\n        x = self.maxpool(conv2)\n        \n        conv3 = self.dconv_down3(x)\n        x = self.maxpool(conv3)\n        \n        x = self.dconv_down4(x)\n        \n        x = self.TConv3(x)\n        x = torch.cat([x, conv3], dim=1)\n\n        x = self.dconv_up3(x)\n        x = self.TConv2(x)\n        x = torch.cat([x, conv2], dim=1)\n\n        x = self.dconv_up2(x)\n        x = self.TConv1(x)\n        x = torch.cat([x, conv1], dim=1)\n\n        x = self.dconv_up1(x)\n        out = self.conv_last(x)\n        out = F.sigmoid(out)\n        \n        return out","metadata":{"execution":{"iopub.status.busy":"2022-05-24T07:14:34.651118Z","iopub.execute_input":"2022-05-24T07:14:34.651474Z","iopub.status.idle":"2022-05-24T07:14:34.666919Z","shell.execute_reply.started":"2022-05-24T07:14:34.651439Z","shell.execute_reply":"2022-05-24T07:14:34.665066Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"train_transform = A.Compose([\n    A.Resize(IMAGE_HEIGHT,IMAGE_WIDTH),\n    A.Rotate(limit=35,p=1.0),\n    A.HorizontalFlip(p=0.5),\n    A.VerticalFlip(p=0.1),\n    A.Normalize(\n        mean=[0.0,0.0,0.0],\n        std = [1.0,1.0,1.0],\n        max_pixel_value=255.0\n    ),\n    ToTensorV2()  \n])\n\nlabel_desc_map = []\n#class_id to class_name\n#attributes_name to attributes_name\nfor l in label_desc:\n    map_ = {}\n    for ids in label_desc[l]:\n        map_[ids['id']] = ids['name']\n    label_desc_map.append(map_)","metadata":{"execution":{"iopub.status.busy":"2022-05-24T07:14:34.668679Z","iopub.execute_input":"2022-05-24T07:14:34.66915Z","iopub.status.idle":"2022-05-24T07:14:34.676987Z","shell.execute_reply.started":"2022-05-24T07:14:34.669117Z","shell.execute_reply":"2022-05-24T07:14:34.676284Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"def plot_individual_segment(images, masks):\n    plt.imshow(images)\n    plt.imshow(masks[0], alpha=0.75)\n    plt.axis('off')\n    plt.show()\n    \nimg_show = img_show_set(path, train_path, df_train)   \nimg_, masks_ = img_show[np.random.randint(0,len(img_show)+1)] #random idx_number\nplt.imshow(img_)","metadata":{"execution":{"iopub.status.busy":"2022-05-24T07:14:34.67853Z","iopub.execute_input":"2022-05-24T07:14:34.678992Z","iopub.status.idle":"2022-05-24T07:14:36.170842Z","shell.execute_reply.started":"2022-05-24T07:14:34.678957Z","shell.execute_reply":"2022-05-24T07:14:36.169293Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"plot_individual_segment(img_, masks_)","metadata":{"execution":{"iopub.status.busy":"2022-05-24T07:14:36.171841Z","iopub.execute_input":"2022-05-24T07:14:36.172173Z","iopub.status.idle":"2022-05-24T07:14:36.62714Z","shell.execute_reply.started":"2022-05-24T07:14:36.172143Z","shell.execute_reply":"2022-05-24T07:14:36.626435Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"train_dataset = fashion_set(path, train_path, df_train,  train_transform)\ntrain_dataloader = DataLoader(train_dataset, batch_size=BATCH_SIZE, num_workers=NUM_WORKERS, shuffle=True)","metadata":{"execution":{"iopub.status.busy":"2022-05-24T07:14:36.629578Z","iopub.execute_input":"2022-05-24T07:14:36.629856Z","iopub.status.idle":"2022-05-24T07:14:36.654556Z","shell.execute_reply.started":"2022-05-24T07:14:36.629819Z","shell.execute_reply":"2022-05-24T07:14:36.653934Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"model = UNet(n_class=1)\nmodel = model.cuda()\noptimizer = Adam(model.parameters(), lr=LR)\ncriterion = nn.BCELoss()\nmodel.train()","metadata":{"execution":{"iopub.status.busy":"2022-05-24T07:14:36.655774Z","iopub.execute_input":"2022-05-24T07:14:36.656011Z","iopub.status.idle":"2022-05-24T07:14:39.419259Z","shell.execute_reply.started":"2022-05-24T07:14:36.655978Z","shell.execute_reply":"2022-05-24T07:14:39.418504Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"for epoch in range(EPOCHS):\n    running_loss = 0.0\n    for i, (image, images_meta) in enumerate(tqdm(train_dataloader, position=0, leave=True)):\n        images = Variable(image[\"image\"].to(DEVICE))\n        masks = Variable(image[\"masks\"][0].to(DEVICE))\n        masks = torch.reshape(masks,[1, 1, 512, 512]).float()\n        #print(masks.shape,images.shape)\n        optimizer.zero_grad()\n        output = model(images)\n        loss = criterion(output, masks)\n        \n        loss.backward()\n        optimizer.step()\n        running_loss += loss.item()\n        print(loss.item())\n    #print(\"loss for epoch \" + str(epoch) + \":  \" + str(running_loss))","metadata":{"execution":{"iopub.status.busy":"2022-05-24T07:49:05.906555Z","iopub.execute_input":"2022-05-24T07:49:05.907309Z","iopub.status.idle":"2022-05-24T07:49:32.666007Z","shell.execute_reply.started":"2022-05-24T07:49:05.907262Z","shell.execute_reply":"2022-05-24T07:49:32.664248Z"},"trusted":true},"execution_count":null,"outputs":[]}]}