{"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":"# This Python 3 environment comes with many helpful analytics libraries installed\n# It is defined by the kaggle/python Docker image: https://github.com/kaggle/docker-python\n# For example, here's several helpful packages to load\n\nimport numpy as np # linear algebra\nimport pandas as pd # data processing, CSV file I/O (e.g. pd.read_csv)\n\n# Input data files are available in the read-only \"../input/\" directory\n# For example, running this (by clicking run or pressing Shift+Enter) will list all files under the input directory\n\nimport os\nfor dirname, _, filenames in os.walk('/kaggle/input'):\n    for filename in filenames:\n        print(os.path.join(dirname, filename))\n\n# You can write up to 20GB to the current directory (/kaggle/working/) that gets preserved as output when you create a version using \"Save & Run All\" \n# You can also write temporary files to /kaggle/temp/, but they won't be saved outside of the current session","metadata":{"_uuid":"8f2839f25d086af736a60e9eeb907d3b93b6e0e5","_cell_guid":"b1076dfc-b9ad-4769-8c92-a6c4dae69d19","execution":{"iopub.status.busy":"2023-03-24T10:23:37.536200Z","iopub.execute_input":"2023-03-24T10:23:37.536993Z","iopub.status.idle":"2023-03-24T10:25:17.518192Z","shell.execute_reply.started":"2023-03-24T10:23:37.536957Z","shell.execute_reply":"2023-03-24T10:25:17.517112Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"","metadata":{},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# class config:\n#     name = 'v2' \n#     seed = 42\n#     defaults = [{'model': 'baseline'}, '_self_']\n#     class dataset:\n#         feature_data = \"/kaggle/working/feature_data.npy\",\n#         feature_labels = \"/kaggle/working/feature_labels.npy\",\n#         train_batch_size = 512,\n#         val_batch_size = 512,\n#         num_workers = 4,\n#         in_features = 5796,\n#         out_features = 250\n#     class training:\n#         epoch = 350,\n#         criterion = {'_target_': torch.nn.CrossEntropyLoss},\n#         optimizer= {  '_target_': torch.optim.Adam,\n#                     'lr': 3e-4,\n#                     'weight_decay': 1e-6},\n#         scheduler= {  '_target_': torch.optim.lr_scheduler.CosineAnnealingLR,\n#                     'T_max': 600,\n#                     'eta_min': 1e-7}\n\n\n#     device = \"cuda:0\"\n#     num_workers : 8","metadata":{"execution":{"iopub.status.busy":"2023-03-24T10:25:17.520525Z","iopub.execute_input":"2023-03-24T10:25:17.521312Z","iopub.status.idle":"2023-03-24T10:25:17.526497Z","shell.execute_reply.started":"2023-03-24T10:25:17.521264Z","shell.execute_reply":"2023-03-24T10:25:17.525620Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"# Utils\n","metadata":{}},{"cell_type":"code","source":"import os\nimport random\nimport numpy as np\nimport torch\n\ndef set_seed(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\n    torch.backends.cudnn.benchmark = False\n    \ndef get_lr(optimizer):\n    for param_group in optimizer.param_groups:\n        return param_group['lr']\n    \ndef create_checkpoint(model, optimizer, epoch, scheduler=None, scaler=None):\n    checkpoint = {\n        'model': model.state_dict(),\n        'optimizer': optimizer.state_dict(),\n        'epoch': epoch,\n    }\n    \n    if scheduler is not None:\n        checkpoint['scheduler'] = scheduler.state_dict()\n        \n    if scaler is not None:\n        checkpoint['scaler'] = scaler.state_dict()\n    return checkpoint","metadata":{"execution":{"iopub.status.busy":"2023-03-24T10:25:17.528220Z","iopub.execute_input":"2023-03-24T10:25:17.528931Z","iopub.status.idle":"2023-03-24T10:25:21.440051Z","shell.execute_reply.started":"2023-03-24T10:25:17.528896Z","shell.execute_reply":"2023-03-24T10:25:21.438931Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"# Dataset","metadata":{}},{"cell_type":"code","source":"from torch.utils.data import Dataset\n\nclass ASLData(Dataset):\n    def __init__(self, datax, datay):\n        self.datax = datax\n        self.datay = datay\n    \n    def __getitem__(self, index):\n        return self.datax[index,:], self.datay[index]\n    \n    def __len__(self):\n        return len(self.datay)","metadata":{"execution":{"iopub.status.busy":"2023-03-24T10:25:21.442944Z","iopub.execute_input":"2023-03-24T10:25:21.443580Z","iopub.status.idle":"2023-03-24T10:25:21.449568Z","shell.execute_reply.started":"2023-03-24T10:25:21.443540Z","shell.execute_reply":"2023-03-24T10:25:21.448503Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"# Convert data","metadata":{}},{"cell_type":"code","source":"import os\nimport multiprocessing as mp\nimport torch\nimport torch.nn as nn\nimport pandas as pd\nimport numpy as np\nimport json\nfrom tqdm import tqdm","metadata":{"execution":{"iopub.status.busy":"2023-03-24T10:25:21.451000Z","iopub.execute_input":"2023-03-24T10:25:21.451851Z","iopub.status.idle":"2023-03-24T10:25:21.465083Z","shell.execute_reply.started":"2023-03-24T10:25:21.451812Z","shell.execute_reply":"2023-03-24T10:25:21.464056Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"LANDMARK_FILES_DIR = \"/kaggle/input/asl-signs/train_landmark_files\"\nTRAIN_FILE = \"/kaggle/input/asl-signs/train.csv\"\nlabel_map = json.load(open(\"/kaggle/input/asl-signs/sign_to_prediction_index_map.json\", \"r\"))\n\nclass FeatureGen(nn.Module):\n    def __init__(self):\n        super(FeatureGen, self).__init__()\n        pass\n    \n    def forward(self, x):\n        face_x = x[:,:468,:].contiguous().view(-1, 468*3)\n        lefth_x = x[:,468:489,:].contiguous().view(-1, 21*3)\n        pose_x = x[:,489:522,:].contiguous().view(-1, 33*3)\n        righth_x = x[:,522:,:].contiguous().view(-1, 21*3)\n        \n        lefth_x = lefth_x[~torch.any(torch.isnan(lefth_x), dim=1),:]\n        righth_x = righth_x[~torch.any(torch.isnan(righth_x), dim=1),:]\n        \n        x1m = torch.mean(face_x, 0)\n        x2m = torch.mean(lefth_x, 0)\n        x3m = torch.mean(pose_x, 0)\n        x4m = torch.mean(righth_x, 0)\n        \n        x1s = torch.std(face_x, 0)\n        x2s = torch.std(lefth_x, 0)\n        x3s = torch.std(pose_x, 0)\n        x4s = torch.std(righth_x, 0)\n        \n        xfeat = torch.cat([x1m,x2m,x3m,x4m, x1s,x2s,x3s,x4s], axis=0)\n        xfeat = torch.where(torch.isnan(xfeat), torch.tensor(0.0, dtype=torch.float32), xfeat)\n        \n        return xfeat\n    \nfeature_converter = FeatureGen()\n\nROWS_PER_FRAME = 543\ndef load_relevant_data_subset(pq_path):\n    data_columns = ['x', 'y', 'z']\n    data = pd.read_parquet(pq_path, columns=data_columns)\n    n_frames = int(len(data) / ROWS_PER_FRAME)\n    data = data.values.reshape(n_frames, ROWS_PER_FRAME, len(data_columns))\n    return data.astype(np.float32)\n\ndef convert_row(row):\n    x = load_relevant_data_subset(os.path.join('/kaggle/input/asl-signs/', row[1].path))\n    x = feature_converter(torch.tensor(x)).cpu().numpy()\n    return x, row[1].label\n\ndef convert_and_save_data():\n    df = pd.read_csv(TRAIN_FILE)\n    df['label'] = df['sign'].map(label_map)\n    npdata = np.zeros((df.shape[0], 3258))\n    nplabels = np.zeros(df.shape[0])\n    with mp.Pool() as pool:\n        results = pool.imap(convert_row, df.iterrows(), chunksize=250)\n        for i, (x,y) in tqdm(enumerate(results), total=df.shape[0]):\n            npdata[i,:] = x\n            nplabels[i] = y\n    \n    np.save(\"feature_data.npy\", npdata)\n    np.save(\"feature_labels.npy\", nplabels)\n        \nconvert_and_save_data()","metadata":{"execution":{"iopub.status.busy":"2023-03-24T10:25:21.466679Z","iopub.execute_input":"2023-03-24T10:25:21.467119Z","iopub.status.idle":"2023-03-24T10:43:15.363963Z","shell.execute_reply.started":"2023-03-24T10:25:21.467085Z","shell.execute_reply":"2023-03-24T10:43:15.362430Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"# Loss","metadata":{}},{"cell_type":"code","source":"import torch\nimport torch.nn as nn\nimport torch.nn.functional as F\nimport math\n\n\nclass SoftmaxLoss(nn.Module):\n    def __init__(self, in_features, out_features):\n        #out_features: The number of classes in your training dataset\n        #in_features: The size of the embeddings that you pass into\n        super().__init__()\n        self.out_features = out_features\n        self.in_features = in_features\n        \n        self.W = torch.nn.Parameter(torch.Tensor(out_features, in_features))\n        \n        nn.init.xavier_normal_(self.W)\n    \n    def forward(self, embeddings, labels):\n         #embeddings: (None, in_features)\n             #labels: (None,)\n        logits = F.linear(embeddings, self.W)\n        return logits\n    \nclass ArcMarginProduct(nn.Module):\n    def __init__(\n        self,\n        in_features,\n        out_features,\n        scale=30.0,\n        margin=0.50,\n        easy_margin=False,\n        ls_eps=0.0,\n    ):\n        super(ArcMarginProduct, self).__init__()\n        self.in_features = in_features\n        self.out_features = out_features\n        self.scale = scale\n        self.margin = margin\n        self.ls_eps = ls_eps  # label smoothing\n        self.weight = nn.Parameter(torch.FloatTensor(out_features, in_features))\n        nn.init.xavier_uniform_(self.weight)\n\n        self.easy_margin = easy_margin\n        self.cos_m = math.cos(margin)\n        self.sin_m = math.sin(margin)\n        self.th = math.cos(math.pi - margin)\n        self.mm = math.sin(math.pi - margin) * margin\n\n    def forward(self, input, label):\n        # --------------------------- cos(theta) & phi(theta) ---------------------------\n        cosine = F.linear(F.normalize(input), F.normalize(self.weight))\n        sine = torch.sqrt(1.0 - torch.pow(cosine, 2))\n        phi = cosine * self.cos_m - sine * self.sin_m\n        if self.easy_margin:\n            phi = torch.where(cosine > 0, phi, cosine)\n        else:\n            phi = torch.where(cosine > self.th, phi, cosine - self.mm)\n        # --------------------------- convert label to one-hot ---------------------------\n        # one_hot = torch.zeros(cosine.size(), requires_grad=True, device='cuda')\n        one_hot = torch.zeros(cosine.size(), device=label.device)\n        one_hot.scatter_(1, label.view(-1, 1).long(), 1)\n        if self.ls_eps > 0:\n            one_hot = (1 - self.ls_eps) * one_hot + self.ls_eps / self.out_features\n        # -------------torch.where(out_i = {x_i if condition_i else y_i) -------------\n        output = (one_hot * phi) + ((1.0 - one_hot) * cosine)\n        output *= self.scale\n\n        return output","metadata":{"execution":{"iopub.status.busy":"2023-03-24T10:43:15.366008Z","iopub.execute_input":"2023-03-24T10:43:15.366806Z","iopub.status.idle":"2023-03-24T10:43:15.446430Z","shell.execute_reply.started":"2023-03-24T10:43:15.366737Z","shell.execute_reply":"2023-03-24T10:43:15.444848Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"# Model","metadata":{}},{"cell_type":"code","source":"from collections import OrderedDict\n\nclass ASLModel(nn.Module):\n    def __init__(self, p, in_features, n_class):\n        super(ASLModel, self).__init__()\n        self.dropout = nn.Dropout(p)\n        self.layer0 = nn.Linear(in_features, 1024)\n        self.layer1 = nn.Linear(1024, 512)\n        self.layer2 = nn.Linear(512, n_class)\n        \n    def forward(self, x):\n        x = self.layer0(x)\n        x = self.dropout(x)\n        x = self.layer1(x)\n        x = self.layer2(x)\n        return x\n\nclass ASLLinearModel(nn.Module):\n    def __init__(\n        self,\n        in_features: int,\n        first_out_features: int,\n        num_classes: int,\n        num_blocks: int,\n        drop_rate: float,\n        loss_fn,\n        arcface\n    ):\n        super().__init__()\n\n        blocks = []\n        out_features = first_out_features\n        for idx in range(num_blocks):\n            # if idx == num_blocks - 1:\n            #     out_features = num_classes\n\n            blocks.append(self._make_block(in_features, out_features, drop_rate))\n\n            in_features = out_features\n            out_features = out_features // 2\n        \n        self.model = nn.Sequential(*blocks)\n        self.loss_fn = loss_fn\n        self.fc_probs = nn.Linear(256, num_classes)\n        self.arcface = arcface\n\n    def _make_block(self, in_features, out_features, drop_rate):\n        return nn.Sequential(\n            nn.Linear(in_features, out_features),\n            nn.BatchNorm1d(out_features),\n            nn.ReLU(),\n            nn.Dropout(drop_rate),\n        )\n\n    def forward(self, x, y):\n        x = self.model(x)\n        if self.arcface:\n            arcface = self.loss_fn(x, y)\n            return self.fc_probs(x), arcface\n        else:\n            return self.fc_probs(x)\n        ","metadata":{"execution":{"iopub.status.busy":"2023-03-24T10:43:15.451812Z","iopub.execute_input":"2023-03-24T10:43:15.452731Z","iopub.status.idle":"2023-03-24T10:43:16.119237Z","shell.execute_reply.started":"2023-03-24T10:43:15.452679Z","shell.execute_reply":"2023-03-24T10:43:16.118125Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"# Train","metadata":{}},{"cell_type":"code","source":"!pip install hydra-core --upgrade","metadata":{"execution":{"iopub.status.busy":"2023-03-24T10:43:16.120963Z","iopub.execute_input":"2023-03-24T10:43:16.121394Z","iopub.status.idle":"2023-03-24T10:43:35.676658Z","shell.execute_reply.started":"2023-03-24T10:43:16.121356Z","shell.execute_reply":"2023-03-24T10:43:35.675504Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"from omegaconf import OmegaConf\nimport hydra\ndataset = OmegaConf.create( {'feature_data' : \"/kaggle/working/feature_data.npy\",'feature_labels' : \"/kaggle/working/feature_labels.npy\", 'train_batch_size' : 512,'val_batch_size' : 512, 'num_workers' : 4,' in_features' : 5796, 'out_features' : 250})\nprint(OmegaConf.to_yaml(dataset))\n\nmod = OmegaConf.create({'arcface':True,\n                         \"arch\": {'_target_': 'ASLLinearModel', 'in_features': 5796, 'first_out_features': 1024, 'num_classes': 250, 'num_blocks': 3,'drop_rate': 0.4},\n                         \"loss\": {'_target_': 'ArcMarginProduct', 'in_features': 256, 'out_features': 250, 'scale': 30.0, 'margin': 0.50, 'easy_margin': False, 'ls_eps': 0.0}})\nprint(OmegaConf.to_yaml(mod))\n\ntraining = OmegaConf.create({'epoch':350,\"criterion\": {\"_target_\":'torch.nn.CrossEntropyLoss'},\"optimizer\": {\"_target_\": \"torch.optim.Adam\", \"lr\": 3e-4, 'weight_decay':1e-6},\n                         'scheduler': {'_target_': 'torch.optim.lr_scheduler.CosineAnnealingLR', 'T_max': 600, 'eta_min': 1e-7}})\nprint(OmegaConf.to_yaml(training))\n","metadata":{"execution":{"iopub.status.busy":"2023-03-24T10:43:35.681359Z","iopub.execute_input":"2023-03-24T10:43:35.682314Z","iopub.status.idle":"2023-03-24T10:43:35.862925Z","shell.execute_reply.started":"2023-03-24T10:43:35.682264Z","shell.execute_reply":"2023-03-24T10:43:35.861746Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"class config:\n    name = 'v2' \n    seed = 42\n    device = \"cuda:0\"\n    num_workers = 8\n    training = training\n#     defaults = [{'model': 'baseline'}, '_self_']\n    dataset = dataset\n    model = mod\n","metadata":{"execution":{"iopub.status.busy":"2023-03-24T10:43:35.864488Z","iopub.execute_input":"2023-03-24T10:43:35.864876Z","iopub.status.idle":"2023-03-24T10:43:35.870233Z","shell.execute_reply.started":"2023-03-24T10:43:35.864840Z","shell.execute_reply":"2023-03-24T10:43:35.868916Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"cfg = config","metadata":{"execution":{"iopub.status.busy":"2023-03-24T10:43:35.872028Z","iopub.execute_input":"2023-03-24T10:43:35.872377Z","iopub.status.idle":"2023-03-24T10:43:35.882820Z","shell.execute_reply.started":"2023-03-24T10:43:35.872341Z","shell.execute_reply":"2023-03-24T10:43:35.881805Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"import logging\nimport numpy as np\nimport pandas as pd\nimport torch\nimport torch.nn as nn\nfrom torch.utils.data import DataLoader\nfrom torch.utils.tensorboard import SummaryWriter\nimport torchmetrics\n\nfrom sklearn.model_selection import train_test_split\nfrom sklearn.metrics import accuracy_score\n\nimport hydra \nfrom hydra.utils import instantiate\n# from hydra.core.hydra_config import HydraConfig\nfrom omegaconf import DictConfig, OmegaConf\n\n\ndef run_train(model, device, train_metric, train_loader, optimizer, scheduler, criterion, epoch, global_step, writer):\n    model.train()\n    train_loss = []\n    train_bar = train_loader\n    for x,y in train_bar:\n        x = x.float().to(device)\n        y = y.long().to(device)\n        logits, arcface = model(x, y)\n        arcface_loss = nn.CrossEntropyLoss()(arcface, y)\n        loss = criterion(logits, y) * 0.5 + arcface_loss * 0.5\n        train_metric.update(torch.argmax(logits, dim=1).detach().cpu(), y.detach().cpu())\n        writer.add_scalar('train/loss', loss.item(), global_step)\n        writer.add_scalar('lr', get_lr(optimizer), global_step)\n        \n        loss.backward()\n        optimizer.step()\n        optimizer.zero_grad()\n        \n        train_loss.append(loss.item())\n        scheduler.step()\n        global_step += 1\n    train_loss = np.mean(train_loss)\n    train_acc = train_metric.compute()\n    train_metric.reset()\n    writer.add_scalar('train/epoch_loss', train_loss, epoch)\n    writer.add_scalar('train/acc', train_acc, epoch)\n    log.info(f\"Epoch:{epoch} > Train Loss: {train_loss:.04f}, Train Acc: {train_acc:0.04f}\")\n    return global_step\n\ndef run_val(model, device, val_metric, val_loader, criterion, epoch, writer):\n    val_loss = []\n    model.eval()\n    with torch.no_grad():\n        for x,y in val_loader:\n            x = x.float().to(device)\n            y = y.long().to(device)\n            logits, arcface = model(x, y)\n            arcface_loss = nn.CrossEntropyLoss()(arcface, y)\n            loss = criterion(logits, y) * 0.5 + arcface_loss * 0.5\n            loss = criterion(logits, y)\n            val_metric.update(torch.argmax(logits, dim=1).detach().cpu(), y.detach().cpu())\n            val_loss.append(loss.item())\n                            \n    val_loss = np.mean(val_loss)\n    val_acc = val_metric.compute()\n    val_metric.reset()\n    writer.add_scalar('val/epoch_loss', val_loss, epoch)\n    writer.add_scalar('val/acc', val_acc, epoch)\n    log.info(f\"Epoch:{epoch} > Val Loss: {val_loss:.04f}, Val Acc: {val_acc:0.04f}\")\n    return val_loss, val_acc\n\nlog = logging.getLogger(__name__)\n# @hydra.main(config_path=\"conf\", config_name=\"config\")\n# @hydra.main(version_base=None, config_path=\"/kaggle/working/Kaggle-ASL-2023/configs\", config_name='/kaggle/working/')        \n        \ndef main(config):\n    SEED = config.seed\n    set_seed(SEED)\n    \n    datax = np.load(config.dataset.feature_data)\n    datay = np.load(config.dataset.feature_labels)\n    df = pd.read_csv('/kaggle/input/asl-signs/train.csv')\n    trainx, testx, trainy, testy = train_test_split(datax, datay, test_size=0.2, random_state=SEED, stratify=df['participant_id'].values)\n\n    train_data = ASLData(trainx, trainy)\n    valid_data = ASLData(testx, testy)\n\n    EPOCHS = config.training.epoch\n    train_loader = DataLoader(\n        train_data,\n        batch_size=config.dataset.train_batch_size, \n        num_workers=config.dataset.num_workers, \n        shuffle=True\n    )\n    val_loader = DataLoader(\n        valid_data,\n        batch_size=config.dataset.val_batch_size,\n        num_workers=config.dataset.num_workers, \n        shuffle=False\n    )\n    \n    device = config.device\n    loss_fn = ArcMarginProduct(in_features=256 ,out_features=250, scale=30.0, margin=0.50, easy_margin=False, ls_eps=0.0)\n    model = ASLLinearModel(in_features=3258, first_out_features=1024, num_classes=250, num_blocks=3,drop_rate=0.4,loss_fn=loss_fn, arcface=True).to(device)\n#     model = ASLModel(p=0.2, in_features=3258, n_class=250)\n    optimizer = torch.optim.Adam(params=model.parameters(), lr=0.0003, weight_decay=1.0e-06)\n    criterion = torch.nn.CrossEntropyLoss()\n    scheduler = torch.optim.lr_scheduler.CosineAnnealingLR(optimizer=optimizer, T_max=600, eta_min=1.0e-07)\n    best_metric = 0.0\n    \n    output_dir = os.path.join('/kaggle/working/')\n    os.makedirs(output_dir, exist_ok=True)\n    writer = SummaryWriter(str(output_dir))\n    \n    train_metric = torchmetrics.Accuracy(task=\"multiclass\", num_classes=config.dataset.out_features)\n    val_metric = torchmetrics.Accuracy(task=\"multiclass\", num_classes=config.dataset.out_features)\n    \n    global_step = 0\n    for epoch in range(EPOCHS):\n        global_step = run_train(model, device, train_metric, train_loader, optimizer, scheduler, criterion, epoch, global_step, writer)\n        val_loss, val_acc = run_val(model, device, val_metric, val_loader, criterion, epoch, writer)\n        if val_acc > best_metric:\n            log.info(f\"SAVING CHECKPOINT: val_metric {best_metric:0.04f} -> {val_acc:0.04f}\")\n            best_metric = val_acc\n            checkpoint = create_checkpoint(model, optimizer, epoch, scheduler=scheduler)\n            torch.save(\n                checkpoint,\n                f\"{output_dir}/best.pth\",\n            )\n        log.info(\"=\"*50)\n    writer.close()","metadata":{"execution":{"iopub.status.busy":"2023-03-24T10:45:34.283631Z","iopub.execute_input":"2023-03-24T10:45:34.284215Z","iopub.status.idle":"2023-03-24T10:45:34.313468Z","shell.execute_reply.started":"2023-03-24T10:45:34.284169Z","shell.execute_reply":"2023-03-24T10:45:34.312330Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"main(cfg)","metadata":{"execution":{"iopub.status.busy":"2023-03-24T10:45:36.169856Z","iopub.execute_input":"2023-03-24T10:45:36.170763Z","iopub.status.idle":"2023-03-24T11:23:12.598767Z","shell.execute_reply.started":"2023-03-24T10:45:36.170716Z","shell.execute_reply":"2023-03-24T11:23:12.592073Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"sample_input = torch.rand((50, 543, 3))\nonnx_feat_gen_path = 'feature_gen.onnx'\nfeature_converter = FeatureGen()\nfeature_converter.eval()\n\ntorch.onnx.export(\n    feature_converter,                  # PyTorch Model\n    sample_input,                    # Input tensor\n    onnx_feat_gen_path,        # Output file (eg. 'output_model.onnx')\n    opset_version=12,       # Operator support version\n    input_names=['input'],   # Input tensor name (arbitary)\n    output_names=['output'], # Output tensor name (arbitary)\n    dynamic_axes={\n        'input' : {0: 'input'}\n    }\n)","metadata":{"execution":{"iopub.status.busy":"2023-03-24T11:23:12.605356Z","iopub.execute_input":"2023-03-24T11:23:12.605770Z","iopub.status.idle":"2023-03-24T11:23:14.126825Z","shell.execute_reply.started":"2023-03-24T11:23:12.605726Z","shell.execute_reply":"2023-03-24T11:23:14.125754Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"import onnx","metadata":{"execution":{"iopub.status.busy":"2023-03-24T11:25:46.038941Z","iopub.execute_input":"2023-03-24T11:25:46.039752Z","iopub.status.idle":"2023-03-24T11:25:46.283208Z","shell.execute_reply.started":"2023-03-24T11:25:46.039713Z","shell.execute_reply":"2023-03-24T11:25:46.279799Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"onnx_model = onnx.load(onnx_feat_gen_path)\n\nonnx.checker.check_model(onnx_model)\n\n","metadata":{"execution":{"iopub.status.busy":"2023-03-24T11:29:32.847657Z","iopub.execute_input":"2023-03-24T11:29:32.848870Z","iopub.status.idle":"2023-03-24T11:29:32.857711Z","shell.execute_reply.started":"2023-03-24T11:29:32.848818Z","shell.execute_reply":"2023-03-24T11:29:32.856551Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# with open('/kaggle/working/best.pth', 'wb') as f:\n#     f.write(onnx_model)\n!zip submission.zip /kaggle/working/best.pth","metadata":{"execution":{"iopub.status.busy":"2023-03-24T11:30:56.399178Z","iopub.execute_input":"2023-03-24T11:30:56.399596Z","iopub.status.idle":"2023-03-24T11:31:00.094913Z","shell.execute_reply.started":"2023-03-24T11:30:56.399554Z","shell.execute_reply":"2023-03-24T11:31:00.093716Z"},"trusted":true},"execution_count":null,"outputs":[]}]}