{"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":"markdown","source":"https://www.kaggle.com/code/michaln/hotel-id-starter-similarity-training","metadata":{"tags":[]}},{"cell_type":"code","source":"import numpy as np\nimport pandas as pd\nimport random\nimport os\n\nfrom PIL import Image as pil_image\nfrom tqdm import tqdm\n\nimport matplotlib\nimport matplotlib.pyplot as plt\n\nimport plotly.graph_objects as go\nimport plotly.express as px\nfrom plotly.subplots import make_subplots\n\nimport torch\nimport torch.nn as nn\nfrom torch.utils.data import DataLoader\n\nimport sys\nsys.path.append('../input/timm-pytorch-image-models/pytorch-image-models-master')\nimport timm\n\nfrom sklearn.metrics.pairwise import cosine_similarity","metadata":{"tags":[],"execution":{"iopub.status.busy":"2022-08-01T08:37:36.388715Z","iopub.execute_input":"2022-08-01T08:37:36.389064Z","iopub.status.idle":"2022-08-01T08:37:48.250822Z","shell.execute_reply.started":"2022-08-01T08:37:36.388979Z","shell.execute_reply":"2022-08-01T08:37:48.249645Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"IMG_SIZE = 256\nSEED = 42\nN_MATCHES = 5\n\nPROJECT_FOLDER = \"../input/hotel-id-to-combat-human-trafficking-2022-fgvc9/\"\nDATA_FOLDER = \"../input/hotelid-2022-train-images-256x256/\"\nIMAGE_FOLDER = DATA_FOLDER + \"images/\"\nOUTPUT_FOLDER = \"\"\n\ntrain_df = pd.read_csv(os.path.join(DATA_FOLDER, 'train.csv'))","metadata":{"execution":{"iopub.status.busy":"2022-08-01T08:37:48.254298Z","iopub.execute_input":"2022-08-01T08:37:48.256387Z","iopub.status.idle":"2022-08-01T08:37:48.308234Z","shell.execute_reply.started":"2022-08-01T08:37:48.256345Z","shell.execute_reply":"2022-08-01T08:37:48.304817Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"print(os.listdir(PROJECT_FOLDER))","metadata":{"execution":{"iopub.status.busy":"2022-08-01T08:37:48.309822Z","iopub.execute_input":"2022-08-01T08:37:48.310171Z","iopub.status.idle":"2022-08-01T08:37:48.321138Z","shell.execute_reply.started":"2022-08-01T08:37:48.310134Z","shell.execute_reply":"2022-08-01T08:37:48.319810Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"def seed_everything(seed):\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","metadata":{"execution":{"iopub.status.busy":"2022-08-01T08:37:48.324841Z","iopub.execute_input":"2022-08-01T08:37:48.325137Z","iopub.status.idle":"2022-08-01T08:37:48.331148Z","shell.execute_reply.started":"2022-08-01T08:37:48.325109Z","shell.execute_reply":"2022-08-01T08:37:48.329901Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"import albumentations as A\nimport albumentations.pytorch as APT\nimport cv2 \n\n# used for training dataset - augmentations and occlusions\ntrain_transform = A.Compose([\n    A.HorizontalFlip(p=0.75),\n    A.VerticalFlip(p=0.25),\n    A.ShiftScaleRotate(p=0.5, border_mode=cv2.BORDER_CONSTANT),\n    A.OpticalDistortion(p=0.25),\n    A.Perspective(p=0.25),\n    A.CoarseDropout(p=0.5, min_holes=1, max_holes=6, \n                    min_height=IMG_SIZE//16, max_height=IMG_SIZE//4,\n                    min_width=IMG_SIZE//16,  max_width=IMG_SIZE//4), # normal coarse dropout\n    \n    A.CoarseDropout(p=1., max_holes=1, \n                    min_height=IMG_SIZE//4, max_height=IMG_SIZE//2,\n                    min_width=IMG_SIZE//4,  max_width=IMG_SIZE//2, \n                    fill_value=(255,0,0)),# simulating occlusions in test data\n\n    A.RandomBrightnessContrast(p=0.75),\n    A.ToFloat(),\n    APT.transforms.ToTensorV2(),\n])\n\n# used for validation dataset - only occlusions\nval_transform = A.Compose([\n    A.CoarseDropout(p=1., max_holes=1, \n                    min_height=IMG_SIZE//4, max_height=IMG_SIZE//2,\n                    min_width=IMG_SIZE//4,  max_width=IMG_SIZE//2, \n                    fill_value=(255,0,0)),# simulating occlusions\n    A.ToFloat(),\n    APT.transforms.ToTensorV2(),\n])\n\n# no augmentations\nbase_transform = A.Compose([\n    A.ToFloat(),\n    APT.transforms.ToTensorV2(),\n])","metadata":{"execution":{"iopub.status.busy":"2022-08-01T08:37:48.332932Z","iopub.execute_input":"2022-08-01T08:37:48.333363Z","iopub.status.idle":"2022-08-01T08:37:49.083543Z","shell.execute_reply.started":"2022-08-01T08:37:48.333326Z","shell.execute_reply":"2022-08-01T08:37:49.082613Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"class HotelTrainDataset:\n    def __init__(self, data, transform=None, data_path=\"train_images/\"):\n        self.data = data\n        self.data_path = data_path\n        self.transform = transform\n\n    def __len__(self):\n        return len(self.data)\n    \n    def __getitem__(self, idx):\n        record = self.data.iloc[idx]\n        image_path = self.data_path + record[\"image_id\"]\n        image = np.array(pil_image.open(image_path)).astype(np.uint8)\n\n        if self.transform:\n            transformed = self.transform(image=image)\n            image = transformed[\"image\"]\n        \n        return {\n            \"image\" : image,\n            \"target\" : record['hotel_id_code'],\n        }","metadata":{"execution":{"iopub.status.busy":"2022-08-01T08:37:49.085016Z","iopub.execute_input":"2022-08-01T08:37:49.086452Z","iopub.status.idle":"2022-08-01T08:37:49.095079Z","shell.execute_reply.started":"2022-08-01T08:37:49.086412Z","shell.execute_reply":"2022-08-01T08:37:49.094031Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"class EmbeddingModel(nn.Module):\n    def __init__(self, n_classes=100, embedding_size=64, backbone_name=\"efficientnet_b0\"):\n        super(EmbeddingModel, self).__init__()\n        \n        self.backbone = timm.create_model(backbone_name, num_classes=n_classes, pretrained=True)\n        in_features = self.backbone.get_classifier().in_features\n        \n        self.backbone.classifier = nn.Identity()\n        self.embedding = nn.Linear(in_features, embedding_size)\n        self.classifier = nn.Linear(embedding_size, n_classes)\n\n    def embed_and_classify(self, x):\n        x = self.forward(x)\n        return x, self.classifier(x)\n\n    def forward(self, x):\n        x = self.backbone(x)\n        x = x.view(x.size(0), -1)\n        x = self.embedding(x)\n        return x","metadata":{"execution":{"iopub.status.busy":"2022-08-01T08:37:49.096742Z","iopub.execute_input":"2022-08-01T08:37:49.097147Z","iopub.status.idle":"2022-08-01T08:37:49.109930Z","shell.execute_reply.started":"2022-08-01T08:37:49.097063Z","shell.execute_reply":"2022-08-01T08:37:49.108933Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# method to iterate loader and generate embeddings of images\n# returns embeddings and image class\ndef generate_embeddings(loader, model, bar_desc=\"Generating embeds\"):\n    targets_all = []\n    outputs_all = []\n    \n    model.eval()\n    with torch.no_grad():\n        t = tqdm(loader, desc=bar_desc)\n        for i, sample in enumerate(t):\n            input = sample['image'].to(args.device)\n            target = sample['target'].to(args.device)\n            output = model(input)\n            \n            targets_all.extend(target.cpu().numpy())\n            outputs_all.extend(output.detach().cpu().numpy())\n\n    targets_all = np.array(targets_all).astype(np.float32)\n    outputs_all = np.array(outputs_all).astype(np.float32)\n            \n    return outputs_all, targets_all","metadata":{"execution":{"iopub.status.busy":"2022-08-01T08:37:49.111060Z","iopub.execute_input":"2022-08-01T08:37:49.112764Z","iopub.status.idle":"2022-08-01T08:37:49.122165Z","shell.execute_reply.started":"2022-08-01T08:37:49.112728Z","shell.execute_reply":"2022-08-01T08:37:49.121262Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"def save_checkpoint(model, scheduler, optimizer, epoch, name, loss=None, score=None):\n    checkpoint = {\"epoch\": epoch,\n                  \"model\": model.state_dict(),\n                  \"scheduler\": scheduler.state_dict(),\n                  \"optimizer\": optimizer.state_dict(),\n                  \"loss\": loss,\n                  \"score\": score,\n                  }\n\n    torch.save(checkpoint, f\"{OUTPUT_FOLDER}checkpoint-{name}.pt\")\n\n\ndef load_checkpoint(model, scheduler, optimizer, name):\n    checkpoint = torch.load(f\"{OUTPUT_FOLDER}checkpoint-{name}.pt\")\n\n    model.load_state_dict(checkpoint[\"model\"])\n    scheduler.load_state_dict(checkpoint[\"scheduler\"])\n    return model, scheduler, optimizer, checkpoint[\"epoch\"]","metadata":{"execution":{"iopub.status.busy":"2022-08-01T08:37:49.123790Z","iopub.execute_input":"2022-08-01T08:37:49.124824Z","iopub.status.idle":"2022-08-01T08:37:49.135659Z","shell.execute_reply.started":"2022-08-01T08:37:49.124779Z","shell.execute_reply":"2022-08-01T08:37:49.134752Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"def train_epoch(args, model, loader, criterion, optimizer, scheduler, epoch):\n    losses = []\n    targets_all = []\n    outputs_all = []\n    \n    model.train()\n    t = tqdm(loader)\n    \n    for i, sample in enumerate(t):\n        optimizer.zero_grad()\n        \n        images = sample['image'].to(args.device)\n        targets = sample['target'].to(args.device)\n        \n        _, outputs = model.embed_and_classify(images)\n        loss = criterion(outputs, targets)\n        \n        loss.backward()\n        optimizer.step()\n        \n        if scheduler:\n            scheduler.step()\n                \n        losses.append(loss.item())\n        targets_all.extend(targets.cpu().numpy())\n        outputs_all.extend(torch.sigmoid(outputs).detach().cpu().numpy())\n\n        score = np.mean(targets_all == np.argmax(outputs_all, axis=1))\n        desc = f\"Training epoch {epoch}/{args.epochs} - loss:{loss:0.4f}, accuracy: {score:0.4f}\"\n        t.set_description(desc)\n        \n    return np.mean(losses), score","metadata":{"execution":{"iopub.status.busy":"2022-08-01T08:37:49.141159Z","iopub.execute_input":"2022-08-01T08:37:49.141844Z","iopub.status.idle":"2022-08-01T08:37:49.153526Z","shell.execute_reply.started":"2022-08-01T08:37:49.141807Z","shell.execute_reply":"2022-08-01T08:37:49.152709Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"def test_classification(loader, model):\n    targets_all = []\n    outputs_all = []\n    \n    model.eval()\n    t = tqdm(loader, desc=\"Classification\")\n    \n    for i, sample in enumerate(t):\n        images = sample['image'].to(args.device)\n        targets = sample['target'].to(args.device)\n        \n        _, outputs = model.embed_and_classify(images)\n        \n        targets_all.extend(targets.cpu().numpy())\n        outputs_all.extend(torch.sigmoid(outputs).detach().cpu().numpy())\n        \n    \n    # repeat targets to N_MATCHES for easy calculation of MAP@5\n    y = np.repeat([targets_all], repeats=N_MATCHES, axis=0).T\n    # sort predictions and get top 5\n    preds = np.argsort(-np.array(outputs_all), axis=1)[:, :N_MATCHES]\n    # check if any of top 5 predictions are correct and calculate mean accuracy\n    acc_top_5 = (preds == y).any(axis=1).mean()\n    # calculate prediction accuracy\n    acc_top_1 = np.mean(targets_all == np.argmax(outputs_all, axis=1))\n\n    print(f\"Classification accuracy: {acc_top_1:0.4f}, MAP@5: {acc_top_5:0.4f}\")","metadata":{"execution":{"iopub.status.busy":"2022-08-01T08:37:49.156705Z","iopub.execute_input":"2022-08-01T08:37:49.157319Z","iopub.status.idle":"2022-08-01T08:37:49.167585Z","shell.execute_reply.started":"2022-08-01T08:37:49.157286Z","shell.execute_reply":"2022-08-01T08:37:49.166608Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# find 5 most similar images from different hotels and return their hotel_id_code\ndef find_matches(query, base_embeds, base_targets, k=N_MATCHES):\n    distance_df = pd.DataFrame(index=np.arange(len(base_targets)), data={\"hotel_id_code\": base_targets})\n    # calculate cosine distance of query embeds to all base embeds\n    distance_df[\"distance\"] = cosine_similarity([query], base_embeds)[0]\n    # sort by distance and hotel_id\n    distance_df = distance_df.sort_values(by=[\"distance\", \"hotel_id_code\"], ascending=False).reset_index(drop=True)\n    # return first 5 different hotel_id_codes\n    return distance_df[\"hotel_id_code\"].unique()[:N_MATCHES]\n    \n\ndef test_similarity(args, base_loader, test_loader, model):\n    base_embeds, base_targets = generate_embeddings(base_loader, model, \"Generate base embeddings\")\n    test_embeds, test_targets = generate_embeddings(test_loader, model, \"Generate test embeddings\")\n    \n    preds = []\n    for query_embeds in tqdm(test_embeds, desc=\"Similarity - match finding\"):\n        tmp = find_matches(query_embeds, base_embeds, base_targets)\n        preds.extend([tmp])\n        \n    preds = np.array(preds)\n    test_targets_N = np.repeat([test_targets], repeats=N_MATCHES, axis=0).T\n    # check if any of top 5 predictions are correct and calculate mean accuracy\n    acc_top_5 = (preds == test_targets_N).any(axis=1).mean()\n    # calculate prediction accuracy\n    acc_top_1 = np.mean(test_targets == preds[:, 0])\n    print(f\"Similarity accuracy: {acc_top_1:0.4f}, MAP@5: {acc_top_5:0.4f}\")","metadata":{"execution":{"iopub.status.busy":"2022-08-01T08:37:49.169080Z","iopub.execute_input":"2022-08-01T08:37:49.169448Z","iopub.status.idle":"2022-08-01T08:37:49.182093Z","shell.execute_reply.started":"2022-08-01T08:37:49.169400Z","shell.execute_reply":"2022-08-01T08:37:49.181079Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"data_df = pd.read_csv(DATA_FOLDER + \"train.csv\")\n# encode hotel ids\ndata_df[\"hotel_id_code\"] = data_df[\"hotel_id\"].astype('category').cat.codes.values.astype(np.int64)","metadata":{"execution":{"iopub.status.busy":"2022-08-01T08:37:49.184389Z","iopub.execute_input":"2022-08-01T08:37:49.185270Z","iopub.status.idle":"2022-08-01T08:37:49.234185Z","shell.execute_reply.started":"2022-08-01T08:37:49.185234Z","shell.execute_reply":"2022-08-01T08:37:49.233269Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# save hotel_id encoding for later decoding\nhotel_id_code_df = data_df.drop(columns=[\"image_id\"]).drop_duplicates().reset_index(drop=True)\nhotel_id_code_df.to_csv(OUTPUT_FOLDER + 'hotel_id_code_mapping.csv', index=False)\n# hotel_id_code_map = hotel_id_code_df.set_index('hotel_id_code').to_dict()[\"hotel_id\"]","metadata":{"execution":{"iopub.status.busy":"2022-08-01T08:37:49.235670Z","iopub.execute_input":"2022-08-01T08:37:49.236323Z","iopub.status.idle":"2022-08-01T08:37:49.254773Z","shell.execute_reply.started":"2022-08-01T08:37:49.236276Z","shell.execute_reply":"2022-08-01T08:37:49.253775Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"def show_images(ds, title_text, n_images=5):\n    fig, ax = plt.subplots(1,5, figsize=(22,8))\n    \n    ax[0].set_ylabel(title_text)\n    \n    for i in range(5):\n        d = ds.__getitem__(i)\n        ax[i].imshow(d[\"image\"].T)","metadata":{"execution":{"iopub.status.busy":"2022-08-01T08:37:49.256481Z","iopub.execute_input":"2022-08-01T08:37:49.256864Z","iopub.status.idle":"2022-08-01T08:37:49.262937Z","shell.execute_reply.started":"2022-08-01T08:37:49.256828Z","shell.execute_reply":"2022-08-01T08:37:49.261840Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"train_dataset = HotelTrainDataset(data_df, base_transform, data_path=IMAGE_FOLDER)\nshow_images(train_dataset, 'No augmentations')\n\ntrain_dataset = HotelTrainDataset(data_df, train_transform, data_path=IMAGE_FOLDER)\nshow_images(train_dataset, 'Train augmentations')","metadata":{"execution":{"iopub.status.busy":"2022-08-01T08:37:49.264944Z","iopub.execute_input":"2022-08-01T08:37:49.265344Z","iopub.status.idle":"2022-08-01T08:37:50.710897Z","shell.execute_reply.started":"2022-08-01T08:37:49.265306Z","shell.execute_reply":"2022-08-01T08:37:50.709962Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"test_image = np.array(pil_image.open('../input/hotel-id-to-combat-human-trafficking-2022-fgvc9/test_images/abc.jpg')).astype(np.uint8)\nplt.figure(figsize=(6,6))\nplt.imshow(test_image)","metadata":{"execution":{"iopub.status.busy":"2022-08-01T08:37:50.712510Z","iopub.execute_input":"2022-08-01T08:37:50.713178Z","iopub.status.idle":"2022-08-01T08:37:51.030365Z","shell.execute_reply.started":"2022-08-01T08:37:50.713129Z","shell.execute_reply":"2022-08-01T08:37:51.029293Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"def train_and_validate(args, data_df):\n    model_name = f\"embedding-model-{args.backbone_name}-{IMG_SIZE}x{IMG_SIZE}\"\n    print(model_name)\n\n    seed_everything(seed=SEED)\n\n    # split data into train and validation set\n    hotel_image_count = data_df.groupby(\"hotel_id\")[\"image_id\"].count()\n    # hotels that have more images than samples for validation\n    valid_hotels = hotel_image_count[hotel_image_count > args.val_samples]\n    # data that can be split into train and val set\n    valid_data = data_df[data_df[\"hotel_id\"].isin(valid_hotels.index)]\n    # if hotel had less than required val_samples it will be only in the train set\n    valid_df = valid_data.groupby(\"hotel_id\").sample(args.val_samples, random_state=SEED)\n    train_df = data_df[~data_df[\"image_id\"].isin(valid_df[\"image_id\"])]\n    \n\n    train_dataset = HotelTrainDataset(train_df, train_transform, data_path=IMAGE_FOLDER)\n    train_loader  = DataLoader(train_dataset, num_workers=args.num_workers, batch_size=args.batch_size, shuffle=True, drop_last=True)\n    valid_dataset = HotelTrainDataset(valid_df, val_transform, data_path=IMAGE_FOLDER)\n    valid_loader  = DataLoader(valid_dataset, num_workers=args.num_workers, batch_size=args.batch_size, shuffle=False)\n    # base dataset for image similarity search\n    base_dataset  = HotelTrainDataset(train_df, base_transform, data_path=IMAGE_FOLDER)\n    base_loader   = DataLoader(base_dataset, num_workers=args.num_workers, batch_size=args.batch_size*4, shuffle=False)\n\n    model = EmbeddingModel(args.n_classes, args.embedding_size ,args.backbone_name)\n    model = model.to(args.device)\n\n    criterion = nn.CrossEntropyLoss()\n    optimizer = torch.optim.AdamW(model.parameters(), lr=args.lr)\n\n    scheduler = torch.optim.lr_scheduler.OneCycleLR(\n                    optimizer,\n                    max_lr=args.lr,\n                    epochs=args.epochs,\n                    steps_per_epoch=len(train_loader),\n                    div_factor=10,\n                    final_div_factor=1,\n                    pct_start=0.1,\n                    anneal_strategy=\"cos\",\n                )\n    \n    start_epoch = 1\n    \n    for epoch in range(start_epoch, args.epochs+1):\n        train_loss, train_score = train_epoch(args, model, train_loader, criterion, optimizer, scheduler, epoch)\n        save_checkpoint(model, scheduler, optimizer, epoch, model_name, train_loss, train_score)\n        test_classification(valid_loader, model)\n\n    test_similarity(args, base_loader, valid_loader, model)\n    \n    # generate embeddings for all train images and save them for inference\n    base_dataset   = HotelTrainDataset(data_df, base_transform, data_path=IMAGE_FOLDER)\n    base_loader    = DataLoader(base_dataset, num_workers=args.num_workers, batch_size=args.batch_size*4, shuffle=False)\n    base_embeds, _ = generate_embeddings(base_loader, model, \"Generate embeddings for all images\")\n    data_df[\"embeddings\"] = list(base_embeds)\n    data_df.to_pickle(f\"{OUTPUT_FOLDER}{model_name}_image-embeddings.pkl\")","metadata":{"execution":{"iopub.status.busy":"2022-08-01T08:37:51.031894Z","iopub.execute_input":"2022-08-01T08:37:51.032467Z","iopub.status.idle":"2022-08-01T08:37:51.050503Z","shell.execute_reply.started":"2022-08-01T08:37:51.032429Z","shell.execute_reply":"2022-08-01T08:37:51.049630Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"!mkdir -p /root/.cache/torch/hub/checkpoints\n!cp ../input/efficientnet-b0/efficientnet_b0_ra-3dd342df.pth /root/.cache/torch/hub/checkpoints/efficientnet_b0_ra-3dd342df.pth\n# !cp ../input/efficientnet-b2/efficientnet_b2_ra-bcdf34b7.pth /root/.cache/torch/hub/checkpoints/efficientnet_b2_ra-bcdf34b7.pth\n# !cp ../input/swinv2-base-256/swinv2_base_patch4_window8_256.pth /root/.cache/torch/hub/checkpoints/swinv2_base_patch4_window8_256.pth\n# !cp ../input/resnest101e/resnest101-22405ba7.pth /root/.cache/torch/hub/checkpoints/resnest101-22405ba7.pth\n# !cp ../input/swinv2base256/swinv2_base_patch4_window16_256.pth /root/.cache/torch/hub/checkpoints/swinv2_base_patch4_window16_256.pth\n# !cp ../input/resnet50/resnet50_a1_0-14fe96d1.pth /root/.cache/torch/hub/checkpoints/resnet50_a1_0-14fe96d1.pth\n# !cp ../input/resnet34/resnet34-43635321.pth /root/.cache/torch/hub/checkpoints/resnet34-43635321.pth\n","metadata":{"execution":{"iopub.status.busy":"2022-08-01T08:37:51.053997Z","iopub.execute_input":"2022-08-01T08:37:51.054276Z","iopub.status.idle":"2022-08-01T08:37:52.827120Z","shell.execute_reply.started":"2022-08-01T08:37:51.054251Z","shell.execute_reply":"2022-08-01T08:37:52.825802Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"%%time \n\nclass args:\n    epochs = 10\n    lr = 1e-3\n    batch_size = 64\n    num_workers = 0\n    val_samples = 1\n    embedding_size = 128\n    backbone_name = \"efficientnet_b0\"\n    n_classes = data_df[\"hotel_id_code\"].nunique()\n    device = ('cuda' if torch.cuda.is_available() else 'cpu')\n\ntrain_and_validate(args, data_df)","metadata":{"execution":{"iopub.status.busy":"2022-08-01T08:37:52.830989Z","iopub.execute_input":"2022-08-01T08:37:52.831324Z","iopub.status.idle":"2022-08-01T09:48:27.039428Z","shell.execute_reply.started":"2022-08-01T08:37:52.831293Z","shell.execute_reply":"2022-08-01T09:48:27.038448Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"","metadata":{},"execution_count":null,"outputs":[]}]}