{"cells":[{"metadata":{},"cell_type":"markdown","source":"## Introduction\n### This nootbook was created to study and understand the following great notebook in my own way.  \n[Cassava / resnext50_32x4d starter](https://www.kaggle.com/yasufuminakama/cassava-resnext50-32x4d-starter-training)  \n### I am deeply grateful to Y.Nakama!!\n\nThis may only be for my own reference..."},{"metadata":{"_uuid":"8f2839f25d086af736a60e9eeb907d3b93b6e0e5","_cell_guid":"b1076dfc-b9ad-4769-8c92-a6c4dae69d19","trusted":true},"cell_type":"code","source":"import os\n\nos.listdir(\"../input\")","execution_count":null,"outputs":[]},{"metadata":{"_uuid":"d629ff2d2480ee46fbb7e2d37f6b5fab8052498a","collapsed":true,"_cell_guid":"79c7e3d0-c299-4dcb-8224-4455121ee9b0","trusted":false},"cell_type":"code","source":"#\nimport os\nimport random\nimport re\n\nimport numpy as np\nimport pandas as pd\nimport seaborn as sn\nimport matplotlib.pyplot as plt\nimport cv2\n\nimport matplotlib.pyplot as plt\nimport seaborn as sns\n\n#sklearn\nfrom sklearn.metrics import accuracy_score\nfrom sklearn.model_selection import StratifiedKFold\n\n#Pytorch\nimport torch\nimport torch.nn as nn\nimport torch.nn.functional as F\nfrom torch.optim import Adam, SGD\nimport torchvision.models as models\nfrom torch.nn.parameter import Parameter\nfrom torch.utils.data import DataLoader, Dataset\nfrom torch.optim.lr_scheduler import(\n    CosineAnnealingWarmRestarts,CosineAnnealingLR,\n    ReduceLROnPlateau\n    )\n\nfrom albumentations import(\n    Compose,OneOf, Normalize, Resize, RandomResizedCrop, RandomCrop,\n    HorizontalFlip, VerticalFlip, RandomBrightness, RandomContrast,\n    RandomBrightnessContrast, Rotate, ShiftScaleRotate, Cutout,\n    IAAAdditiveGaussianNoise, Transpose\n    )\nfrom albumentations.pytorch import ToTensor, ToTensorV2\nfrom albumentations import ImageOnlyTransform\n\nimport time\nimport datetime\n\nimport warnings\nwarnings.filterwarnings('ignore')\n#\n\n#device = torch.device('cpu')\ndevice = torch.device('cuda' if torch.cuda.is_available() else 'cpu')","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"#-------------------------------------------\n# Path and Data Loading\n#-------------------------------------------\n\ndata_top = \"../input/\"\ncommpe_name = \"cassava-leaf-disease-classification\"\ndata_path = data_top + commpe_name\n\nOUTPUT_DIR = './'\nif not os.path.exists(OUTPUT_DIR):\n    os.makedirs(OUTPUT_DIR)\n\n#labels\nlabel_map = pd.read_json(os.path.join(data_path, \n                                      \"label_num_to_disease_map.json\"),\n                         orient = \"index\")\nlabel_names = label_map.iloc[:,0].values\n\n#表記の短縮\nnew_names = []\nfor name in [val for val in label_names]:\n    name = name.replace(\" \", \"\")\n    name = re.sub(\"^Cassava\", \"\", name)\n    name = re.sub(\"\\(.+\\)$\", \"\", name)\n    new_names.append(name)\n\nnew_map = dict(zip(np.arange(len(new_names)), new_names))\n\n#train\ntrain = pd.read_csv(os.path.join(data_path, \"train.csv\"))\ntrain.columns\ntrain['label'].value_counts().reset_index().sort_values(\"index\")\n\ntrain['class_name'] = train['label'].map(new_map)\n\n#test\ntest = pd.read_csv(os.path.join(data_path, \"sample_submission.csv\"))","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"### Creating a confirmation dataset\n\nCreate testing dataset to see how the augmentaion works."},{"metadata":{"trusted":true},"cell_type":"code","source":"#---------------------------------------------\n# Dataset for Observation\n#---------------------------------------------\n\nN_DATA = 4 # サンプル数はこの5倍\nDEBUG = False # 画像データ構造確認用\n\nrandom.seed(11)\n\n#label順にサンプルを1個づつ取り出す\ntmp = []\ndf_sample = pd.DataFrame()\nfor i in range(N_DATA):\n    #print(i)\n    tmp = [train[train['label'] == val].sample(1) for val in range(5)]\n    df_tmp = pd.concat(tmp, axis = 0)\n    df_sample = pd.concat([df_sample, df_tmp], axis = 0)\n\n# Normarizeをかけずにaugmenttion画像を確認するのに使用する。","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"### Class for dataset"},{"metadata":{"trusted":true},"cell_type":"code","source":"#--------------------------------------------\n# Dataset\n#--------------------------------------------\n\nclass SampleDataset(Dataset):\n    def __init__(self, df, transform):\n        self.df = df\n        self.file_names = df['image_id'].values\n        self.labels = df['label'].values\n        self.transform = transform\n        \n    def __len__(self):\n        return len(self.df)\n        \n    def __getitem__(self, index):\n        file_name = self.file_names[index]\n        file_path = os.path.join(data_path, \"train_images\", file_name)\n        image = cv2.imread(file_path)\n        image = cv2.cvtColor(image, cv2.COLOR_BGR2RGB)\n        if DEBUG:\n            print(\"shape = \", image.shape)\n            print(type(image))\n            im = image[:, :, 0]\n            print(np.max(im), np.min(im))\n            plt.imshow(image)\n            plt.title(\"Original\")\n            plt.show()\n            \n        trans_org  = Compose([Resize(255,255), ToTensorV2()])\n        image_org = trans_org(image = image)\n        image_org = image_org['image']\n        \n        if DEBUG:\n            print(image_org.shape)\n\n        if self.transform:\n            augmented = self.transform(image = image)\n            image_aug = augmented['image']\n            if DEBUG:\n                print(\"After trans shpe = \", image_aug.shape)\n                image_np = image_aug.cpu().numpy()#image\n                image_np = np.rollaxis(image_np, 0, 3)#image\n                print(image_np.shape)\n                im = image_np[:, :, 0]\n                print(np.max(im), np.min(im))\n                   \n        image = image_aug\n        \n        label = torch.tensor(self.labels[index]).long()\n        \n        if DEBUG: print(\"Return Shape = \", image.shape)\n        \n        return image, image_org, label\n        # images after augmentation, original images, labels","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"def get_transforms(aug_list, data):\n    \n    if data == \"train\": \n        return Compose(aug_list)\n    \n    elif data == 'valid':\n        return Compose([Resize(255, 255),\n                        Normalize(mean=[0.485, 0.456, 0.406], \n                                  std=[0.229, 0.224, 0.225]),\n                        ToTensorV2()\n                        ])\n\n    return\n\n#augmentationの内容はリストで受け渡しすることにした","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"**Function for plot**"},{"metadata":{"trusted":true},"cell_type":"code","source":"def image_for_plt(sample_loader):\n\n    image_data = torch.empty(0,0,0,0)\n    for (image, image_org, label) in sample_loader:\n        #print(image.shape)\n\n        if JOIN:\n            image = torch.cat([image_org, image], dim = 0)\n            if DEBUG: print(\"image shape = \", image.shape)\n\n        if DEBUG:\n            image_np = image.cpu().numpy()\n            label_np = label.cpu().numpy()\n            image_np.shape\n            image_np2 = np.rollaxis(image_np, 1, 4)\n            plt.imshow(image_np2[1])\n            np.max(image_np2[0])\n            np.min(image_np2[0])\n            image.shape\n\n        if len(image_data) == 0:\n            image_data = image\n        else:\n            image_data = torch.cat([image_data, image], dim = 0)\n            \n    return image_data\n\n# 表示用画像データセット作成。\n# JOIN=1のときはオリジナルとaugmentation 画像を上下に並べて表示。\n#　DataLoaderで読み出すと、画像のチャンネルが最初にくるので、np.rollaxis で入れ替える。","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"### Preparation to select a combination of argumentaion"},{"metadata":{"trusted":true},"cell_type":"code","source":"#-----------------------------------\n# DataFrame to define Augmentaion\n#-----------------------------------\n\ndf_aug = pd.DataFrame()\ndf_aug['item'] = [\"RRC\", \"TR\", \"HF\", \"VF\", \"SSR\", \"NOR\",\"TTR\"]\n\ndf_aug[\"augment\"] = [\n    RandomResizedCrop(255, 255),\n    Transpose(p = 0.5),\n    HorizontalFlip(p = 0.5),\n    VerticalFlip(p = 0.5),\n    ShiftScaleRotate(p=1),\n    Normalize(mean=[0.485, 0.456, 0.406], \n              std=[0.229, 0.224, 0.225]),\n    ToTensorV2()\n    ]\n\n# RandomResizedCropは、サイズを揃えるために必ず入れる。\n# もっとスマートなやり方がありそうだが。。。","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"### Let's confirm the images after augmentation"},{"metadata":{"trusted":true},"cell_type":"code","source":"random.seed(11)\nDEBUG = 0\nJOIN = 1 # オリジナルデータとくっつけるとき使用\n\naug_list = df_aug.query('\\\n                        item == \"RRC\" |\\\n                        item == \"TR\" |\\\n                        item == \"HF\" |\\\n                        item == \"VF\" |\\\n                        item == \"SSR\" |\\\n                        item == \"\" |\\\n                        item == \"TTR\"')['augment'].values\n\n# やめたい変換、例えば　\"TR\" を　””とする。上記は\"NOR\"をやめる。\n\nsample_data = SampleDataset(df_sample, \n                            transform = get_transforms(aug_list, data = \"train\"))\n\nsample_loader = DataLoader(sample_data, \n                           batch_size = 5,\n                           shuffle=False)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"image_data = image_for_plt(sample_loader)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"#----------------------------------------\n# Vilualization\n#----------------------------------------\n\nimage_data_np = image_data.cpu().numpy()\nimage_data_np.shape\nimage_data_np = np.rollaxis(image_data_np, 1, 4)\n\nfig = plt.figure(figsize=(12, 24))\n#fig.suptitle(\"The upper row is original (with resizing), the lower row is Augmented\\n without normalizing\")\n\nfor i in range(N_DATA):\n    for j in range(10):\n        image_number = i * 10 + j\n        image_show = image_data_np[image_number]\n        fig.add_subplot(8, 5, image_number + 1)\n        plt.imshow(image_show)\n        try:\n            title_show = new_names[image_number - i*10]\n            plt.title(title_show)\n        except:\n            if JOIN:\n                plt.title('Augmented')\n            else:\n                pass","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"### Confirm normalized data images"},{"metadata":{"trusted":true},"cell_type":"code","source":"DEBUG = 0\nJOIN = 0 # オリジナルデータとくっつけるとき使用\n\naug_list = df_aug.query('\\\n                        item == \"RRC\" |\\\n                        item == \"TR\" |\\\n                        item == \"HF\" |\\\n                        item == \"VF\" |\\\n                        item == \"SSR\" |\\\n                        item == \"NOR\" |\\\n                        item == \"TTR\"')['augment'].values\n\nsample_data = SampleDataset(df_sample, \n                            transform = get_transforms(aug_list, data = \"train\"))\n\nsample_loader = DataLoader(sample_data, \n                           batch_size = 5,\n                           shuffle=False)\n\n# パラメータは以下のため、Normalizeといっても、平均≒0.45、std≒0.22としている。\n# Normalize(mean=[0.485, 0.456, 0.406], std=[0.229, 0.224, 0.225])\n# 平均=0, std = 1　ではない。","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"image_data = image_for_plt(sample_loader)","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"### Images applied normalization"},{"metadata":{"trusted":true},"cell_type":"code","source":"#----------------------------------------\n# Vilualization of the normalized data\n#----------------------------------------\n\nimage_data_np = image_data.cpu().numpy()\nimage_data_np.shape\nimage_data_np = np.rollaxis(image_data_np, 1, 4)\n\nfig = plt.figure(figsize=(12, 10))\nfor i in range(20):\n    image_number = i \n    image_show = image_data_np[image_number]\n    fig.add_subplot(4, 5, image_number + 1)\n    plt.imshow(image_show)\n    fig.suptitle('Augmented images with normalization')","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"## Next, let's build a CV with a simple CNN."},{"metadata":{"trusted":true},"cell_type":"code","source":"#!pip -q install torchsummary\n\n# インターネットがONできないので、使用できない。\n# inference と分ければ使用できる。","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"### Chaeck train labels"},{"metadata":{"trusted":true},"cell_type":"code","source":"print(train['label'].value_counts())\nprint(train['label'].value_counts()[3]/train.shape[0])","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"Due to imbalanced data, the correct answer rate is 61.5% even if all are predicted to be level 3.  \nI think that the correct answer rate needs to be 62% or more."},{"metadata":{},"cell_type":"markdown","source":"### Create a simple network with four convolution layers."},{"metadata":{"trusted":true},"cell_type":"code","source":"#from torchsummary import summary\n# 上記でモデルの確認ができる。\n\n#-----------------------------\n#  Moddel\n#-----------------------------\n\nclass CnnTrial(nn.Module):\n    def __init__(self):\n        super().__init__()\n        \n        self.conv1 = nn.Conv2d(3, 16, 5)\n        self.conv2 = nn.Conv2d(16, 32, 5)\n        self.conv3 = nn.Conv2d(32, 64, 5)\n        self.conv4 = nn.Conv2d(64, 128, 5)\n        \n        self.bn1 = nn.BatchNorm2d(16)\n        self.bn2 = nn.BatchNorm2d(32)\n        self.bn3 = nn.BatchNorm2d(64)\n        self.bn4 = nn.BatchNorm2d(128)\n        \n        self.pool = nn.MaxPool2d(2, 2)\n        self.drop = nn.Dropout2d(p = 0.5)\n        \n        self.relu = nn.ReLU(inplace = True)\n        self.fc1 = nn.Linear(128*12*12, 1024)\n        self.fc2 = nn.Linear(1024, 5)\n        \n        self.softmax = nn.Softmax(dim = 1)\n        \n    def forward(self,x):\n        x = self.conv1(x)\n        x = self.bn1(x) #batch_norm がないと収束しない。\n        x = self.relu(x)\n        x = self.pool(x)\n        #x = self.drop(x)\n        x = self.conv2(x)\n        x = self.bn2(x)\n        x = self.relu(x)\n        x = self.pool(x)\n        \n        x = self.conv3(x)\n        x = self.bn3(x)\n        x = self.relu(x)\n        x = self.pool(x)\n        \n        x = self.conv4(x)\n        x = self.bn4(x)\n        x = self.relu(x)\n        x = self.pool(x)\n    \n        x = x.view(x.size()[0], -1)\n        x = self.fc1(x)\n        x = self.fc2(x)\n        #x = self.softmax(x) # 不要、ロス計算時に考慮されている\n        \n        return x\n        \nmodel = CnnTrial() \nprint(model) \n\n#summary(model.to('cuda'),(3,255,255)) \n# モデルの構造、OK/NGの確認ができる。","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"### Then, let's start classifications!!"},{"metadata":{"trusted":true},"cell_type":"code","source":"#-------------------------------------------------\n# Configration and helper functions\n#-------------------------------------------------\n\nclass CFG:\n    debug = False\n    epochs = 12\n    n_fold = 5\n    num_workers = 4\n    seed = 11\n\n\nclass AverageMeter(object):\n    \n    def __init__(self):\n        self.reset()\n        \n    def reset(self):\n        self.val = 0\n        self.avg = 0\n        self.sum = 0\n        self.count = 0\n        \n    def update(self, val, n = 1):\n        self.val = val\n        self.sum += val *n\n        self.count += n\n        self.avg = self.sum / self.count\n#\n\ndef get_score(y_true, y_pred):\n    return accuracy_score(y_true, y_pred)\n\n\ndef get_result(result_df):\n    preds = result_df['preds'].values\n    labels = result_df['label'].values\n    score = get_score(labels, preds)\n    #print(f'oof_score = {score:<.5f}')\n    return score\n\n\ndef seed_torch(seed=42):\n    random.seed(seed)\n    os.environ['PYTHONHASHSEED'] = str(seed)\n    np.random.seed(seed)\n    torch.manual_seed(seed)\n    torch.cuda.manual_seed(seed)\n    torch.backends.cudnn.deterministic = True\n\nseed_torch(seed=CFG.seed)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"#===== training =====\n\ndef train_fn(train_loader, model, criterion, optimizer, \n             epoch, scheduler, device):\n       \n    model.train()\n    \n    loss_step = []\n    losses = AverageMeter()\n    for step, (images, _, labels) in enumerate(train_loader):\n        \n        images = images.to(device)\n        labels = labels.to(device)\n        #上記がないとCPU/GPU不整合エラーとなる\n        #!!!!! images.to(device)だとNGとなる　!!!\n        \n        batch_size = labels.size(0)\n        \n        y_pred = model(images)\n       \n        loss = criterion(y_pred, labels)\n        if CFG.debug: print(\"loss = \", loss.item())\n        loss_step.append(loss)\n        losses.update(loss.item(), batch_size)\n    \n        loss.backward()\n        grad_norm = torch.nn.utils.clip_grad_norm_(model.parameters(),1000)\n        if CFG.debug: print(\"grad = \", grad_norm)\n        optimizer.step()\n        optimizer.zero_grad()\n        \n    if CFG.debug: plt.plot(loss_step[50:])\n\n    print(f'Training Results\\nloss_avg = {losses.avg:.3f}\\ngrad = {grad_norm:.3f}')\n    \n    return losses.avg\n\n#===== validation =====\n\ndef valid_fn(valid_loader, model, criterion, device):\n\n    losses = AverageMeter()\n\n    model.eval()\n    \n    preds = []\n    for step, (images, _, labels) in enumerate(valid_loader):\n        \n        images = images.to(device)\n        labels = labels.to(device)\n        #上記がないとCPU/GPU不整合エラーとなる\n        #!!!!! images.to(device)だとNGとなる　!!!\n        \n        batch_size = labels.size(0)\n        \n        with torch.no_grad():\n            y_pred = model(images)\n        loss = criterion(y_pred, labels)\n        losses.update(loss.item(), batch_size)\n        preds.append(y_pred.softmax(1).to('cpu').numpy())\n        \n        if CFG.debug: print(f'Loss = {loss}')\n        #if step%50 ==0: print(f'step{step} calculating...')\n    \n    predictions = np.concatenate(preds)\n\n    return losses.avg, predictions\n","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"#------------------------------------------------\n# CV split\n#------------------------------------------------\n\nif CFG.debug:\n    folds = train.sample(200).copy().reset_index(drop = True)\nelse:\n    folds = train.copy()\n\nfolds['label'].value_counts()\n\nkFold = StratifiedKFold(n_splits = 5, shuffle = True,\n                        random_state = 11) \n\nfor n ,(train_index, valid_index) in enumerate(kFold.split(folds, folds['label'])):\n    folds.loc[valid_index, 'fold'] = n\n\nfolds.dtypes\nfolds['fold'] = folds['fold'].astype(int)\nprint(folds.groupby(['fold', 'label']).size())\n","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"#------------------------------------------------\n# trainig loop \n#------------------------------------------------\n\ndef train_loop(folds, fold):\n\n    print(f'Fold: {fold + 1}')\n                    \n    aug_list = df_aug.query('\\\n                            item == \"RRC\" |\\\n                            item == \"TR\" |\\\n                            item == \"HF\" |\\\n                            item == \"VF\" |\\\n                            item == \"SSR\" |\\\n                            item == \"NOR\" |\\\n                            item == \"TTR\"')['augment'].values\n    #\n    \n    train_folds = folds.loc[train_index].reset_index(drop = True)\n    valid_folds = folds.loc[valid_index].reset_index(drop = True)\n    \n    train_dataset = SampleDataset(train_folds, \n                                transform = get_transforms(aug_list, data = \"train\"))\n    \n    train_loader = DataLoader(train_dataset, \n                               batch_size = 5,\n                               #num_workers=2,\n                               shuffle = True,\n                               num_workers=CFG.num_workers, \n                               pin_memory=True, drop_last=True)\n    \n    \n    valid_dataset = SampleDataset(valid_folds,\n                                transform = get_transforms(aug_list, data = \"valid\"))\n    valid_loader = DataLoader(valid_dataset,\n                              batch_size = 10,\n                              shuffle = False,\n                              num_workers=CFG.num_workers, \n                               pin_memory=True, drop_last=False)\n                               #ラベル順がわかるようにすうためシャフルしない\n    \n    model = CnnTrial()\n    model.to(device)\n    \n    optimizer = Adam(model.parameters(), lr = 0.001)\n    scheduler = ReduceLROnPlateau(optimizer = optimizer, verbose = True)\n    criterion = nn.CrossEntropyLoss()\n    \n    best_score = 0.\n    best_loss = np.inf\n    best_model = []\n    \n    for epoch in range(CFG.epochs):\n        \n        print(f'Fold-{fold+1}: EPOCH {epoch+1} started at {datetime.datetime.now()}.')\n        avg_loss = train_fn(train_loader, model, criterion, \n                            optimizer, epoch, scheduler, device)\n        \n        avg_val_loss, preds = valid_fn(valid_loader, model, criterion, device)\n        \n        if isinstance(scheduler, ReduceLROnPlateau):\n            scheduler.step(avg_val_loss)\n    \n    \n        valid_labels = valid_folds['label'].values\n        \n        preds_valid = preds.argmax(1)\n        score = get_score(valid_labels, preds_valid)\n        print(f'EPOCH {epoch+1}: vaildation score = {score:.3f}\\n')\n    \n        if score > best_score: # FOLDの全EPOCH中のベストスコアを保存する\n            best_score = score\n            torch.save({'model': model.state_dict(),\n                        'preds': preds},\n                       os.path.join(OUTPUT_DIR , 'fold_'+str(fold+1)+'_best.pth'))\n            best_model = model\n        \n       \n    check_point = torch.load(os.path.join(OUTPUT_DIR , 'fold_'+str(fold+1)+'_best.pth'))\n    #valid_folds[[str(c) for c in range(5)]] = check_point['preds'] \n    #自分のローカル環境では上記はエラーとなった。 \n    \n    for i in range(CFG.n_fold):\n         valid_folds[f'pred_{i}'] = check_point['preds'][:, i]\n    valid_folds['preds'] = check_point['preds'].argmax(1)\n    \n    return valid_folds, best_model","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"#--------------------------------------------\n# training\n#--------------------------------------------\n    \noof_df = pd.DataFrame()\nbest_models =[]\nfor fold in range(CFG.n_fold):\n    _oof_df, best_model = train_loop(folds, fold)\n    oof_df = pd.concat([oof_df, _oof_df])\n    fold_score = get_result(_oof_df)\n    print(f'fold {fold+1} score = {fold_score:.5f}')\n    best_models.append(best_model)\n    \noof_score = get_result(oof_df)\nprint(f'\\nCV score = {oof_score:.5f}')","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"#-----------------------------------\n# inference\n#-----------------------------------\n\nclass TestDataset(Dataset):\n    def __init__(self, df, transform):\n        self.df = df\n        self.file_names = df['image_id'].values\n        #self.labels = df['label'].values\n        self.transform = transform\n        \n    def __len__(self):\n        return len(self.df)\n        \n    def __getitem__(self, index):\n        file_name = self.file_names[index]\n        #file_path = os.path.join(data_path, \"train_images\", file_name)\n        file_path = os.path.join(data_path, \"test_images\", file_name)\n        image = cv2.imread(file_path)\n        image = cv2.cvtColor(image, cv2.COLOR_BGR2RGB)\n\n        if self.transform:\n            augmented = self.transform(image = image)\n            image_aug = augmented['image']\n        \n        image = image_aug\n               \n        #print(\"Return Shape = \", image.shape)\n        \n        return image\n##","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"test_dataset = TestDataset(test, transform=get_transforms(aug_list = [], data='valid'))\ntest_loader = DataLoader(test_dataset, batch_size=5, shuffle=False,\n                        num_workers=CFG.num_workers, pin_memory=True)\n\n\nfrom scipy.special import softmax\n\ninferences = []\nfor i, (images) in enumerate(test_loader):\n    #print(images)\n    #print(images.shape)\n    #print(images.size()[0])\n    inference = np.zeros(images.shape[0]*5, dtype = 'float32').reshape(-1, 5)\n    #print(inference.shape)\n    images = images.to(device)\n    #break\n\n    for j in range(CFG.n_fold):\n        model_inf = best_models[j]\n        model_inf.to(device)\n        model_inf.eval()\n        with torch.no_grad():\n            y_preds = model_inf(images)\n            y_preds_np =  y_preds.cpu().numpy()\n        inference += y_preds_np\n    inference /= CFG.n_fold\n    inference = softmax(inference, axis=1)\n    inferences.append(np.argmax(inference, axis = 1))\n   \ntest_inferences = np.concatenate(inferences, axis = 0)\ntest['label'] = test_inferences\n\ntest.to_csv(os.path.join(OUTPUT_DIR, \"submission.csv\"), index = False)","execution_count":null,"outputs":[]}],"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":4,"nbformat_minor":4}