{"cells":[{"metadata":{},"cell_type":"markdown","source":"# Simple pytorch inference\nYou can use this simple notebook as your starter code for submitting your results.\nYou can train your model locally or at Kaggle and upload the weights as a dataset.\n\n### References\n- [Image Dataset](http://www.kaggle.com/dataset/a318f9ccd11aea9ede828487914dbbcb76776b72aeb4ef85b51709cfbbe004d3) for training\n- [Weights for my baseline models](https://www.kaggle.com/pestipeti/bengali-ai-model-weights)\n- [Pretrained weights](https://www.kaggle.com/pytorch/resnet18)\n- [Training kernel](https://www.kaggle.com/pestipeti/simple-pytorch-training)\n- [EDA Kernel](https://www.kaggle.com/pestipeti/bengali-quick-eda)"},{"metadata":{"_uuid":"d629ff2d2480ee46fbb7e2d37f6b5fab8052498a","_cell_guid":"79c7e3d0-c299-4dcb-8224-4455121ee9b0","trusted":true},"cell_type":"code","source":"import pandas as pd\nimport numpy as np\nimport torch\nimport torch.nn.functional as F\nimport torchvision\n\nfrom tqdm import tqdm\nfrom torch.utils.data import Dataset\nfrom albumentations import Compose\nfrom albumentations.pytorch import ToTensorV2\n\nINPUT_PATH = '/kaggle/input/bengaliai-cv19'","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"# ======================\n# Params\nBATCH_SIZE = 32\nN_WORKERS = 4\nN_EPOCHS = 5\n\nHEIGHT = 137\nWIDTH = 236\nTARGET_SIZE = 256\n\n# My weights dataset for this compeititon; feel free to vote the dataste ;)\n# https://www.kaggle.com/pestipeti/bengali-ai-model-weights\nWEIGHTS_FILE = '/kaggle/input/bengali-ai-model-weights/baseline_weights.pth'","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"def make_square(img, target_size=256):\n    img = img[0:-1, :]\n    height, width = img.shape\n\n    x = target_size\n    y = target_size\n\n    square = np.ones((x, y), np.uint8) * 255\n    square[(y - height) // 2:y - (y - height) // 2, (x - width) // 2:x - (x - width) // 2] = img\n\n    return square\n\nclass BengaliParquetDataset(Dataset):\n\n    def __init__(self, parquet_file, transform=None):\n\n        self.data = pd.read_parquet(parquet_file)\n        self.transform = transform\n\n    def __len__(self):\n        return len(self.data)\n\n    def __getitem__(self, idx):\n        tmp = self.data.iloc[idx, 1:].values.reshape(HEIGHT, WIDTH)\n        img = np.zeros((TARGET_SIZE, TARGET_SIZE, 3))\n        img[..., 0] = make_square(tmp, target_size=TARGET_SIZE)\n        img[..., 1] = img[..., 0]\n        img[..., 2] = img[..., 0]\n\n        image_id = self.data.iloc[idx, 0]\n\n        if self.transform:\n            transformed = self.transform(image=img)\n            img = transformed['image']\n\n        return {\n            'image_id': image_id,\n            'image': img\n        }\n\n","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"class BengaliModel(torch.nn.Module):\n\n    def __init__(self):\n        super().__init__()\n        self.backbone = torchvision.models.resnet18(pretrained=False)\n\n        in_features = self.backbone.fc.in_features\n\n        self.fc_graph = torch.nn.Linear(in_features, 168)\n        self.fc_vowel = torch.nn.Linear(in_features, 11)\n        self.fc_conso = torch.nn.Linear(in_features, 7)\n\n    def forward(self, x):\n\n        x = self.backbone.conv1(x)\n        x = self.backbone.bn1(x)\n        x = self.backbone.relu(x)\n        x = self.backbone.maxpool(x)\n\n        x = self.backbone.layer1(x)\n        x = self.backbone.layer2(x)\n        x = self.backbone.layer3(x)\n        x = self.backbone.layer4(x)\n\n        x = self.backbone.avgpool(x)\n        x = torch.flatten(x, 1)\n\n        fc_graph = self.fc_graph(x)\n        fc_vowel = self.fc_vowel(x)\n        fc_conso = self.fc_conso(x)\n\n        return fc_graph, fc_vowel, fc_conso\n","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"test_df = pd.read_csv(INPUT_PATH + '/test.csv')\nsubmission_df = pd.read_csv(INPUT_PATH + '/sample_submission.csv')\n\ntransform_test = Compose([\n    ToTensorV2()\n])\n\ndevice = torch.device(\"cuda:0\")\nmodel = BengaliModel()\nmodel.load_state_dict(torch.load(WEIGHTS_FILE))\nmodel.to(device)\n\nresults = []","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"for i in range(4):\n    parq = INPUT_PATH + '/test_image_data_{}.parquet'.format(i)\n    test_dataset = BengaliParquetDataset(\n        parquet_file=parq,\n        transform=transform_test\n    )\n    data_loader_test = torch.utils.data.DataLoader(\n        test_dataset,\n        batch_size=BATCH_SIZE,\n        num_workers=N_WORKERS,\n        shuffle=False\n    )\n\n    print('Parquet {}'.format(i))\n\n    model.eval()\n\n    tk0 = tqdm(data_loader_test, desc=\"Iteration\")\n\n    for step, batch in enumerate(tk0):\n        inputs = batch[\"image\"]\n        image_ids = batch[\"image_id\"]\n        inputs = inputs.to(device, dtype=torch.float)\n\n        out_graph, out_vowel, out_conso = model(inputs)\n        out_graph = F.softmax(out_graph, dim=1).data.cpu().numpy().argmax(axis=1)\n        out_vowel = F.softmax(out_vowel, dim=1).data.cpu().numpy().argmax(axis=1)\n        out_conso = F.softmax(out_conso, dim=1).data.cpu().numpy().argmax(axis=1)\n\n        for idx, image_id in enumerate(image_ids):\n            results.append(out_conso[idx])\n            results.append(out_graph[idx])\n            results.append(out_vowel[idx])","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"submission_df['target'] = results\nsubmission_df.to_csv('./submission.csv', index=False)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"","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":1}