{"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":"!pip install -U -q torch_snippets\nfrom torch_snippets import *\nimport time\n\n\nDIR_INPUT = '/kaggle/input/global-wheat-detection/'\nDIR_TRAIN = '/kaggle/input/global-wheat-detection/train'\nDIR_TEST = '/kaggle/input/global-wheat-detection/test'","metadata":{"execution":{"iopub.status.busy":"2023-06-20T05:09:13.159847Z","iopub.execute_input":"2023-06-20T05:09:13.160204Z","iopub.status.idle":"2023-06-20T05:09:25.695867Z","shell.execute_reply.started":"2023-06-20T05:09:13.160176Z","shell.execute_reply":"2023-06-20T05:09:25.694573Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"%cd /kaggle/working\n!mkdir PyTorch-GAN\n%cd PyTorch-GAN\n!git clone https://github.com/eriklindernoren/PyTorch-GAN.git .","metadata":{"execution":{"iopub.status.busy":"2023-06-20T04:40:48.550597Z","iopub.execute_input":"2023-06-20T04:40:48.550964Z","iopub.status.idle":"2023-06-20T04:40:50.512415Z","shell.execute_reply.started":"2023-06-20T04:40:48.550937Z","shell.execute_reply":"2023-06-20T04:40:50.511048Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"!ls /kaggle/working/PyTorch-GAN/implementations/pix2pix","metadata":{"execution":{"iopub.status.busy":"2023-06-20T04:40:54.187336Z","iopub.execute_input":"2023-06-20T04:40:54.187728Z","iopub.status.idle":"2023-06-20T04:40:55.216587Z","shell.execute_reply.started":"2023-06-20T04:40:54.187695Z","shell.execute_reply":"2023-06-20T04:40:55.214247Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"import sys\nimport itertools\nimport time\nimport datetime\nsys.path.append('/kaggle/working/PyTorch-GAN/implementations')\n\nfrom pix2pix.models import *\nfrom pix2pix.datasets import *\n\nimport torchvision.transforms as transforms\nfrom torchvision.utils import save_image\n\nfrom torch.utils.data import DataLoader\nfrom torchvision import datasets\nfrom torch.autograd import Variable","metadata":{"execution":{"iopub.status.busy":"2023-06-20T05:12:08.923128Z","iopub.execute_input":"2023-06-20T05:12:08.923604Z","iopub.status.idle":"2023-06-20T05:12:08.930772Z","shell.execute_reply.started":"2023-06-20T05:12:08.923555Z","shell.execute_reply":"2023-06-20T05:12:08.929624Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"df = pd.read_csv(DIR_INPUT+'train.csv')\nbboxs = np.stack(df['bbox'].apply(lambda x: np.fromstring(x[1:-1], sep=',')))\nfor i, column in enumerate(['x', 'y', 'w', 'h']):\n    df[column] = bboxs[:,i]\ndf.drop(columns=['bbox'], inplace=True)\ndf = df[['image_id','x', 'y', 'w', 'h']]\nindex = list(set(df.image_id))","metadata":{"execution":{"iopub.status.busy":"2023-06-20T05:10:11.048372Z","iopub.execute_input":"2023-06-20T05:10:11.049126Z","iopub.status.idle":"2023-06-20T05:10:11.937470Z","shell.execute_reply.started":"2023-06-20T05:10:11.049077Z","shell.execute_reply":"2023-06-20T05:10:11.936504Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"class opt:\n    epoch = 0\n    n_epochs = 10 #change to 50 for train\n    dataset_name = 'test1'\n    batch_size = 8\n    lr = 0.0002\n    b1 = 0.5\n    b2 = 0.999\n    decay_epoch = 100\n    n_cpu = 4\n    img_height = 256\n    img_width = 256\n    channels = 3\n    sample_interval = 100\n    checkpoint_interval = 338","metadata":{"execution":{"iopub.status.busy":"2023-06-20T05:10:30.628028Z","iopub.execute_input":"2023-06-20T05:10:30.628395Z","iopub.status.idle":"2023-06-20T05:10:30.634348Z","shell.execute_reply.started":"2023-06-20T05:10:30.628367Z","shell.execute_reply":"2023-06-20T05:10:30.633237Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"os.makedirs(\"images/%s\" % opt.dataset_name, exist_ok=True)\nos.makedirs(\"saved_models/%s\" % opt.dataset_name, exist_ok=True)","metadata":{"execution":{"iopub.status.busy":"2023-06-20T05:10:32.812424Z","iopub.execute_input":"2023-06-20T05:10:32.813183Z","iopub.status.idle":"2023-06-20T05:10:32.818570Z","shell.execute_reply.started":"2023-06-20T05:10:32.813148Z","shell.execute_reply":"2023-06-20T05:10:32.817666Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"cuda = True if torch.cuda.is_available() else False\n\n# Loss functions\ncriterion_GAN = torch.nn.MSELoss()\ncriterion_pixelwise = torch.nn.L1Loss()\n\n# Loss weight of L1 pixel-wise loss between translated image and real image\nlambda_pixel = 100\n\n# Calculate output of image discriminator (PatchGAN)\npatch = (1, opt.img_height // 2 ** 4, opt.img_width // 2 ** 4)\n\n# Initialize generator and discriminator\ngenerator = GeneratorUNet()\ndiscriminator = Discriminator()\n\nif cuda:\n    generator = generator.cuda()\n    discriminator = discriminator.cuda()\n    criterion_GAN.cuda()\n    criterion_pixelwise.cuda()\n\nif opt.epoch != 0:\n    # Load pretrained models\n    generator.load_state_dict(torch.load(\"saved_models/%s/generator_%d.pth\" % (opt.dataset_name, opt.epoch)))\n    discriminator.load_state_dict(torch.load(\"saved_models/%s/discriminator_%d.pth\" % (opt.dataset_name, opt.epoch)))\nelse:\n    # Initialize weights\n    generator.apply(weights_init_normal)\n    discriminator.apply(weights_init_normal)","metadata":{"execution":{"iopub.status.busy":"2023-06-20T05:10:35.949276Z","iopub.execute_input":"2023-06-20T05:10:35.949658Z","iopub.status.idle":"2023-06-20T05:10:36.493723Z","shell.execute_reply.started":"2023-06-20T05:10:35.949629Z","shell.execute_reply":"2023-06-20T05:10:36.492670Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"optimizer_G = torch.optim.Adam(generator.parameters(), lr=opt.lr, betas=(opt.b1, opt.b2))\noptimizer_D = torch.optim.Adam(discriminator.parameters(), lr=opt.lr, betas=(opt.b1, opt.b2))","metadata":{"execution":{"iopub.status.busy":"2023-06-20T05:10:39.765499Z","iopub.execute_input":"2023-06-20T05:10:39.765917Z","iopub.status.idle":"2023-06-20T05:10:39.774543Z","shell.execute_reply.started":"2023-06-20T05:10:39.765886Z","shell.execute_reply":"2023-06-20T05:10:39.773350Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"class ImageDataset_color(Dataset):\n    def __init__(self, root, transforms_=None, mode=\"train\"):\n        self.transform = transforms.Compose(transforms_)\n        self.files = sorted(glob.glob(os.path.join(root, mode) + \"/*.*\"))\n    def __getitem__(self, index):\n\n        img_A = cv2.imread(self.files[index % len(self.files)])\n        img_A = cv2.cvtColor(img_A,cv2.COLOR_BGR2RGB)\n        img_B = cv2.cvtColor(cv2.cvtColor(img_A,cv2.COLOR_RGB2GRAY),cv2.COLOR_GRAY2RGB)\n        img_A = Image.fromarray(np.array(img_A), \"RGB\")\n        img_B = Image.fromarray(np.array(img_B), \"RGB\")\n        if np.random.random() < 0.5:\n            img_A = Image.fromarray(np.array(img_A)[:, ::-1, :], \"RGB\")\n            img_B = Image.fromarray(np.array(img_B)[:, ::-1, :], \"RGB\")\n\n        img_A = self.transform(img_A)\n        img_B = self.transform(img_B)\n\n        return {\"A\": img_A, \"B\": img_B}\n\n    def __len__(self):\n        return len(self.files)\n    \nclass ImageDataset_edge(Dataset):\n    def __init__(self, root, transforms_=None, mode=\"train\"):\n        self.transform = transforms.Compose(transforms_)\n        self.files = sorted(glob.glob(os.path.join(root, mode) + \"/*.*\"))\n    def __getitem__(self, index):\n\n        img_A = cv2.imread(self.files[index % len(self.files)])\n        gray = cv2.cvtColor(img_A, cv2.COLOR_BGR2GRAY)\n        blurred = cv2.GaussianBlur(gray, (5, 5), 0)\n        img_B = cv2.Canny(blurred,50,150)\n        img_B = cv2.cvtColor(img_B,cv2.COLOR_GRAY2RGB)\n        img_A = cv2.cvtColor(img_A,cv2.COLOR_BGR2RGB)\n        img_A = Image.fromarray(np.array(img_A), \"RGB\")\n        img_B = Image.fromarray(np.array(img_B), \"RGB\")\n        if np.random.random() < 0.5:\n            img_A = Image.fromarray(np.array(img_A)[:, ::-1, :], \"RGB\")\n            img_B = Image.fromarray(np.array(img_B)[:, ::-1, :], \"RGB\")\n\n        img_A = self.transform(img_A)\n        img_B = self.transform(img_B)\n\n        return {\"A\": img_A, \"B\": img_B}\n\n    def __len__(self):\n        return len(self.files)","metadata":{"execution":{"iopub.status.busy":"2023-06-20T05:10:41.807187Z","iopub.execute_input":"2023-06-20T05:10:41.807566Z","iopub.status.idle":"2023-06-20T05:10:41.825507Z","shell.execute_reply.started":"2023-06-20T05:10:41.807518Z","shell.execute_reply":"2023-06-20T05:10:41.824484Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# Configure dataloaders\ntransforms_ = [\n    transforms.Resize((opt.img_height, opt.img_width), Image.BICUBIC),\n    transforms.ToTensor(),\n    transforms.Normalize((0.5, 0.5, 0.5), (0.5, 0.5, 0.5)),\n]\n\ndataloader = DataLoader(\n    ImageDataset_color(\"/kaggle/input/global-wheat-detection/\", transforms_=transforms_),\n    batch_size=opt.batch_size,\n    shuffle=True,\n    num_workers=opt.n_cpu,\n)\n\nval_dataloader = DataLoader(\n    ImageDataset_color(\"/kaggle/input/global-wheat-detection/\", transforms_=transforms_, mode=\"test\"),\n    batch_size=10,\n    shuffle=True,\n    num_workers=1,\n)","metadata":{"execution":{"iopub.status.busy":"2023-06-20T05:10:45.001884Z","iopub.execute_input":"2023-06-20T05:10:45.002263Z","iopub.status.idle":"2023-06-20T05:10:45.028288Z","shell.execute_reply.started":"2023-06-20T05:10:45.002233Z","shell.execute_reply":"2023-06-20T05:10:45.027316Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"Tensor = torch.cuda.FloatTensor if cuda else torch.FloatTensor","metadata":{"execution":{"iopub.status.busy":"2023-06-20T05:10:50.509450Z","iopub.execute_input":"2023-06-20T05:10:50.509862Z","iopub.status.idle":"2023-06-20T05:10:50.514558Z","shell.execute_reply.started":"2023-06-20T05:10:50.509831Z","shell.execute_reply":"2023-06-20T05:10:50.513584Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"def sample_images(batches_done):\n    \"\"\"Saves a generated sample from the validation set\"\"\"\n    imgs = next(iter(val_dataloader))\n    real_A = Variable(imgs[\"B\"].type(Tensor))\n    real_B = Variable(imgs[\"A\"].type(Tensor))\n    fake_B = generator(real_A)\n    img_sample = torch.cat((real_A.data, fake_B.data, real_B.data), -2).cpu().numpy().astype(np.float32)\n    img_sample -=img_sample.min()\n    img_sample/=img_sample.max()\n    img_sample = img_sample.transpose(0,2,3,1)\n    plt.figure(figsize=[10,20])\n    for row in range(3):\n        plt.subplot(1,3,row+1)\n        plt.imshow(img_sample[row])\n    plt.show()","metadata":{"execution":{"iopub.status.busy":"2023-06-20T05:10:52.614487Z","iopub.execute_input":"2023-06-20T05:10:52.614920Z","iopub.status.idle":"2023-06-20T05:10:52.622973Z","shell.execute_reply.started":"2023-06-20T05:10:52.614888Z","shell.execute_reply":"2023-06-20T05:10:52.621817Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"prev_time = time.time()\n\nfor epoch in range(opt.epoch, opt.n_epochs):\n    for i, batch in enumerate(dataloader):\n\n        # Model inputs\n        real_A = Variable(batch[\"B\"].type(Tensor))\n        real_B = Variable(batch[\"A\"].type(Tensor))\n\n        # Adversarial ground truths\n        valid = Variable(Tensor(np.ones((real_A.size(0), *patch))), requires_grad=False)\n        fake = Variable(Tensor(np.zeros((real_A.size(0), *patch))), requires_grad=False)\n\n        # ------------------\n        #  Train Generators\n        # ------------------\n\n        optimizer_G.zero_grad()\n\n        # GAN loss\n        fake_B = generator(real_A)\n        pred_fake = discriminator(fake_B, real_A)\n        loss_GAN = criterion_GAN(pred_fake, valid)\n        # Pixel-wise loss\n        loss_pixel = criterion_pixelwise(fake_B, real_B)\n\n        # Total loss\n        loss_G = loss_GAN + lambda_pixel * loss_pixel\n\n        loss_G.backward()\n\n        optimizer_G.step()\n\n        # ---------------------\n        #  Train Discriminator\n        # ---------------------\n\n        optimizer_D.zero_grad()\n\n        # Real loss\n        pred_real = discriminator(real_B, real_A)\n        loss_real = criterion_GAN(pred_real, valid)\n\n        # Fake loss\n        pred_fake = discriminator(fake_B.detach(), real_A)\n        loss_fake = criterion_GAN(pred_fake, fake)\n\n        # Total loss\n        loss_D = 0.5 * (loss_real + loss_fake)\n\n        loss_D.backward()\n        optimizer_D.step()\n\n        # --------------\n        #  Log Progress\n        # --------------\n\n        # Determine approximate time left\n        batches_done = epoch * len(dataloader) + i\n        batches_left = opt.n_epochs * len(dataloader) - batches_done\n        time_left = datetime.timedelta(seconds=batches_left * (time.time() - prev_time))\n        prev_time = time.time()\n\n        # Print log\n        sys.stdout.write(\n            \"\\r[Epoch %d/%d] [Batch %d/%d] [D loss: %f] [G loss: %f, pixel: %f, adv: %f] ETA: %s\"\n            % (\n                epoch,\n                opt.n_epochs,\n                i,\n                len(dataloader),\n                loss_D.item(),\n                loss_G.item(),\n                loss_pixel.item(),\n                loss_GAN.item(),\n                time_left,\n            )\n        )\n\n        # If at sample interval save image\n        if batches_done % opt.sample_interval == 0:\n            sample_images(batches_done)\n\n    if opt.checkpoint_interval != -1 and epoch % opt.checkpoint_interval == 0:\n        # Save model checkpoints\n        torch.save(generator.state_dict(), \"saved_models/%s/generator_%d.pth\" % (opt.dataset_name, epoch))\n        torch.save(discriminator.state_dict(), \"saved_models/%s/discriminator_%d.pth\" % (opt.dataset_name, epoch))","metadata":{"execution":{"iopub.status.busy":"2023-06-20T05:12:17.059966Z","iopub.execute_input":"2023-06-20T05:12:17.060395Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"sample_images(batches_done)","metadata":{},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# Configure dataloaders\ntransforms_ = [\n    transforms.Resize((opt.img_height, opt.img_width), Image.BICUBIC),\n    transforms.ToTensor(),\n    transforms.Normalize((0.5, 0.5, 0.5), (0.5, 0.5, 0.5)),\n]\n\ndataloader = DataLoader(\n    ImageDataset_edge(\"/kaggle/input/global-wheat-detection/\", transforms_=transforms_),\n    batch_size=opt.batch_size,\n    shuffle=True,\n    num_workers=opt.n_cpu,\n)\n\nval_dataloader = DataLoader(\n    ImageDataset_edge(\"/kaggle/input/global-wheat-detection/\", transforms_=transforms_, mode=\"test\"),\n    batch_size=10,\n    shuffle=True,\n    num_workers=1,\n)","metadata":{},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"prev_time = time.time()\n\nfor epoch in range(opt.epoch, opt.n_epochs):\n    for i, batch in enumerate(dataloader):\n\n        # Model inputs\n        real_A = Variable(batch[\"B\"].type(Tensor))\n        real_B = Variable(batch[\"A\"].type(Tensor))\n\n        # Adversarial ground truths\n        valid = Variable(Tensor(np.ones((real_A.size(0), *patch))), requires_grad=False)\n        fake = Variable(Tensor(np.zeros((real_A.size(0), *patch))), requires_grad=False)\n\n        # ------------------\n        #  Train Generators\n        # ------------------\n\n        optimizer_G.zero_grad()\n\n        # GAN loss\n        fake_B = generator(real_A)\n        pred_fake = discriminator(fake_B, real_A)\n        loss_GAN = criterion_GAN(pred_fake, valid)\n        # Pixel-wise loss\n        loss_pixel = criterion_pixelwise(fake_B, real_B)\n\n        # Total loss\n        loss_G = loss_GAN + lambda_pixel * loss_pixel\n\n        loss_G.backward()\n\n        optimizer_G.step()\n\n        # ---------------------\n        #  Train Discriminator\n        # ---------------------\n\n        optimizer_D.zero_grad()\n\n        # Real loss\n        pred_real = discriminator(real_B, real_A)\n        loss_real = criterion_GAN(pred_real, valid)\n\n        # Fake loss\n        pred_fake = discriminator(fake_B.detach(), real_A)\n        loss_fake = criterion_GAN(pred_fake, fake)\n\n        # Total loss\n        loss_D = 0.5 * (loss_real + loss_fake)\n\n        loss_D.backward()\n        optimizer_D.step()\n\n        # --------------\n        #  Log Progress\n        # --------------\n\n        # Determine approximate time left\n        batches_done = epoch * len(dataloader) + i\n        batches_left = opt.n_epochs * len(dataloader) - batches_done\n        time_left = datetime.timedelta(seconds=batches_left * (time.time() - prev_time))\n        prev_time = time.time()\n\n        # Print log\n        sys.stdout.write(\n            \"\\r[Epoch %d/%d] [Batch %d/%d] [D loss: %f] [G loss: %f, pixel: %f, adv: %f] ETA: %s\"\n            % (\n                epoch,\n                opt.n_epochs,\n                i,\n                len(dataloader),\n                loss_D.item(),\n                loss_G.item(),\n                loss_pixel.item(),\n                loss_GAN.item(),\n                time_left,\n            )\n        )\n\n        # If at sample interval save image\n        if batches_done % opt.sample_interval == 0:\n            sample_images(batches_done)\n\n    if opt.checkpoint_interval != -1 and epoch % opt.checkpoint_interval == 0:\n        # Save model checkpoints\n        torch.save(generator.state_dict(), \"saved_models/%s/generator_%d.pth\" % (opt.dataset_name, epoch))\n        torch.save(discriminator.state_dict(), \"saved_models/%s/discriminator_%d.pth\" % (opt.dataset_name, epoch))","metadata":{},"execution_count":null,"outputs":[]}]}