{"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 glob\nimport torch \nimport torch.nn as nn\nimport pandas as pd\nimport matplotlib.pyplot as plt\nimport cv2 \nfrom skimage import io, transform\nfrom torchvision.transforms import transforms\nfrom torchvision import utils\nimport numpy as np\nfrom torchvision import datasets,models\nfrom torch.utils.data import DataLoader, Dataset\nimport pandas as pd\nfrom tqdm import tqdm\nfrom sklearn import metrics\nfrom sklearn.metrics import f1_score, accuracy_score\nfrom sklearn.preprocessing import MultiLabelBinarizer\nimport os","metadata":{"_uuid":"8f2839f25d086af736a60e9eeb907d3b93b6e0e5","_cell_guid":"b1076dfc-b9ad-4769-8c92-a6c4dae69d19","trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"INPUT_PATH = '../input/plant-pathology-2021-fgvc8'\ntrain_fram = os.path.join(INPUT_PATH, 'train.csv')\ntrain_fram = pd.read_csv(train_fram)","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"mlb = MultiLabelBinarizer().fit(train_fram.labels.apply(lambda x : x.split()))\nlabels = pd.DataFrame(mlb.transform(train_fram.labels.apply(lambda x : x.split())), columns = mlb.classes_)\n\nlabels = pd.concat([train_fram['image'], labels], axis=1)\nlabels.head()","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"class LeafDataset(Dataset):\n    def __init__(self, csv_file, root_dir, transform):\n        self.train_fram = pd.read_csv(csv_file)\n        self.root_dir = root_dir\n        self.transform = transform\n    def __len__(self):\n        return len(self.train_fram)\n    def __getitem__(self, idx):\n        if torch.is_tensor(idx):\n            idx = idx.tolist()\n        img_name = os.path.join(self.root_dir, self.train_fram.values[idx][1])\n        print(img_name)\n        image = cv2.imread(img_name)\n        new_image = cv2.resize(image, (224, 224), interpolation = cv2.INTER_AREA)\n        num_image = np.array(new_image)\n        labels = self.train_fram.values[idx, 2:]\n        labels = labels.astype(float)\n        sample = {'image': num_image, 'labels': labels}\n        if self.transform :\n            sample = self.transform(sample)\n        return sample\nclass ToTensor(object):\n    def __call__(self, sample):\n        image = sample[\"image\"]\n        labels = sample[\"labels\"]\n        image = image.transpose((2,0,1))\n        return {\"image\" : torch.from_numpy(image),\n                \"labels\" : torch.from_numpy(labels)\n        }\n","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"leafDatasets = LeafDataset('../input/traintrain/train.csv', '../input/plant-pathology-2021-fgvc8/train_images/', transform=transforms.Compose([ToTensor()]))","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"batch_size = 64\nnum_workers = 0\ntrain_data_loader = DataLoader(leafDatasets, batch_size=batch_size, num_workers=num_workers)\nprint(len(train_data_loader))","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"device = torch.device(\"cuda:0\" if torch.cuda.is_available() else \"cpu\")","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"def create_model(pretrained=True):\n    model = models.resnet50(pretrained=pretrained).to(device)\n    \n    for param in model.layer1.parameters():\n        param.requires_grad = False\n        \n    for param in model.layer2.parameters():\n        param.requires_grad = False  \n        \n    for param in model.layer3.parameters():\n        param.requires_grad = False \n    \n    model.fc = torch.nn.Sequential(\n        torch.nn.Linear(\n            in_features=model.fc.in_features,\n            out_features=6\n        ),\n        torch.nn.Sigmoid()\n    ).to(device)\n    \n    return model","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"model = create_model(pretrained=True).to(device)","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"loss_fn = nn.MultiLabelMarginLoss()\noptimizer = torch.optim.Adam(model.parameters(),lr=0.0001)","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"class MetricMonitor:\n    def __init__(self):\n        self.reset()\n\n    def reset(self):\n        self.losses = []\n        self.accuracies = []\n        self.scores = []\n        self.metrics = dict({\n            'loss': self.losses,\n            'acc': self.accuracies,\n            'f1': self.scores\n        })\n\n    def update(self, metric_name, value):\n        self.metrics[metric_name] += [value]","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"def get_metrics(\n    y_pred_proba, \n    y_test, \n    threshold=0.4,\n    labels=6) -> None:\n    \"\"\"\n    \"\"\"\n    y_pred = np.where(y_pred_proba > threshold, 1, 0)\n\n    y1 = y_pred.round().astype(np.float)\n    y2 = y_test.round().astype(np.float)\n    \n    f1 = f1_score(y1, y2, average='micro')\n    acc = accuracy_score(y1, y2, normalize=True)\n\n    return acc, f1\n","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"def to_numpy(tensor):\n    \"\"\"Auxiliary function to convert tensors into numpy arrays\n    \"\"\"\n    return tensor.detach().cpu().numpy() if tensor.requires_grad else tensor.cpu().numpy()","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"def train_loop(\n    data_loader, \n    model, \n    loss_fn, \n    optimizer, \n    epoch, \n    monitor = MetricMonitor(), \n    is_train=True):\n\n    size = len(data_loader.dataset)\n    model.train()\n    \n    loss_val = 0\n    accuracy = 0\n    f1score = 0\n    train_loss = 0\n\n    steam = tqdm(data_loader)\n    for batch, sample in enumerate(steam):\n        X = sample['image']\n        X = X.float()\n        y = sample['labels']\n        y = torch.tensor(y, dtype=torch.long, device=device)\n        X = X.to(device)\n        \n        # compute prediction and loss\n        pred_prob = model(X)\n        loss = loss_fn(pred_prob, y)\n\n        train_loss += loss.item()*X.size(0)\n        if is_train:\n        # backpropagation\n            optimizer.zero_grad()\n            loss.backward()\n            optimizer.step()\n\n        # loss_val += loss.item()\n        acc, f1 = get_metrics(to_numpy(pred_prob), to_numpy(y))\n        \n    # train_loss = train_loss/len(data_loader.dataset)\n    # print(\"Epoch:\",  i+1, \"LOSS\", train_loss)\n    monitor.update('loss', loss_val/batch)\n    monitor.update('acc', accuracy/batch)\n    monitor.update('f1', f1score/batch) ","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"epoch = 1\nfor e in range(epoch):\n    train_loop(train_data_loader,model,loss_fn,optimizer,e,monitor = MetricMonitor(), is_train=True)","metadata":{"trusted":true},"execution_count":null,"outputs":[]}]}