Skip to content

Instantly share code, notes, and snippets.

@Vijayabhaskar96
Created February 22, 2020 15:51
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save Vijayabhaskar96/d60b7b2bdef8a8391a0e9c6e0448dafe to your computer and use it in GitHub Desktop.
Save Vijayabhaskar96/d60b7b2bdef8a8391a0e9c6e0448dafe to your computer and use it in GitHub Desktop.
bengali ai.ipynb
Display the source blob
Display the rendered blob
Raw
{
"nbformat": 4,
"nbformat_minor": 0,
"metadata": {
"colab": {
"name": "bengali ai.ipynb",
"provenance": [],
"collapsed_sections": [],
"machine_shape": "hm",
"include_colab_link": true
},
"kernelspec": {
"name": "python3",
"display_name": "Python 3"
},
"accelerator": "GPU"
},
"cells": [
{
"cell_type": "markdown",
"metadata": {
"id": "view-in-github",
"colab_type": "text"
},
"source": [
"<a href=\"https://colab.research.google.com/gist/Vijayabhaskar96/d60b7b2bdef8a8391a0e9c6e0448dafe/bengali-ai.ipynb\" target=\"_parent\"><img src=\"https://colab.research.google.com/assets/colab-badge.svg\" alt=\"Open In Colab\"/></a>"
]
},
{
"cell_type": "code",
"metadata": {
"id": "2w9qcg_8uV7d",
"colab_type": "code",
"colab": {}
},
"source": [
"import os\n",
"os.environ['KAGGLE_USERNAME']=\"\"\n",
"os.environ['KAGGLE_KEY']=\"\""
],
"execution_count": 0,
"outputs": []
},
{
"cell_type": "code",
"metadata": {
"id": "9Q_KXhhzxAmI",
"colab_type": "code",
"colab": {}
},
"source": [
"from fastprogress import master_bar, progress_bar\n",
"import pdb"
],
"execution_count": 0,
"outputs": []
},
{
"cell_type": "code",
"metadata": {
"id": "ZiY0lmXCR9hm",
"colab_type": "code",
"colab": {}
},
"source": [
"import pandas as pd\n",
"import cv2\n",
"import numpy as np\n",
"import matplotlib.pyplot as plt\n",
"import shutil"
],
"execution_count": 0,
"outputs": []
},
{
"cell_type": "code",
"metadata": {
"id": "yaLXCYhcusNS",
"colab_type": "code",
"colab": {}
},
"source": [
"!kaggle competitions download -c bengaliai-cv19"
],
"execution_count": 0,
"outputs": []
},
{
"cell_type": "code",
"metadata": {
"id": "8zC56uVzuvpt",
"colab_type": "code",
"colab": {}
},
"source": [
"files_list = os.listdir(\".\")"
],
"execution_count": 0,
"outputs": []
},
{
"cell_type": "code",
"metadata": {
"id": "3EEyulVpoxlw",
"colab_type": "code",
"colab": {}
},
"source": [
"for file in progress_bar(files_list):\n",
" if file.endswith(\".zip\"):\n",
" !unzip {file}"
],
"execution_count": 0,
"outputs": []
},
{
"cell_type": "markdown",
"metadata": {
"id": "evyvxdDBt5JF",
"colab_type": "text"
},
"source": [
"## Create Dataset (I've uploaded the cropped dataset to kaggle, so no need to run this)"
]
},
{
"cell_type": "code",
"metadata": {
"id": "iXtLVDr7h3vl",
"colab_type": "code",
"colab": {}
},
"source": [
"data0 = pd.read_parquet(\"train_image_data_0.parquet\")"
],
"execution_count": 0,
"outputs": []
},
{
"cell_type": "code",
"metadata": {
"id": "ne-cLHvPSsgO",
"colab_type": "code",
"colab": {}
},
"source": [
"data0.iloc[0][1:].values"
],
"execution_count": 0,
"outputs": []
},
{
"cell_type": "code",
"metadata": {
"id": "oYjZ1AxzpQJ2",
"colab_type": "code",
"colab": {}
},
"source": [
"data0_head = data0.iloc[1420][1:].values\n",
"im = data0_head.reshape(137,236).astype(np.uint8)\n",
"plt.imshow(im,cmap=\"binary\")"
],
"execution_count": 0,
"outputs": []
},
{
"cell_type": "code",
"metadata": {
"id": "vULZOHE8S3uY",
"colab_type": "code",
"colab": {}
},
"source": [
"# im = data0_head.reshape(137,236).astype(np.uint8)\n",
"ret, thresh1 = cv2.threshold(im.copy(),230,255,cv2.THRESH_BINARY_INV)\n",
"contours, hierarchy = cv2.findContours(thresh1,cv2.RETR_EXTERNAL,cv2.CHAIN_APPROX_SIMPLE)\n",
"new_im = im.copy()\n",
"cnt_list=[]\n",
"for cnt in contours:\n",
" x,y,w,h = cv2.boundingRect(cnt)\n",
" # cv2.rectangle(new_im,(x,y),(x+w,y+h),(0,255,0),3)\n",
" cnt_list.append([x,y,x+w,y+h])\n",
"(x, y), (x2, y2) = np.array(cnt_list)[:,:2].min(axis=0), np.array(cnt_list)[:,2:].max(axis=0)\n",
"cv2.rectangle(new_im,(x,y),(x2,y2),(0,255,0),3)\n",
" # print(\"Area\",w*h)\n",
"plt.imshow(new_im,cmap=\"binary\")"
],
"execution_count": 0,
"outputs": []
},
{
"cell_type": "code",
"metadata": {
"id": "XIqVdQgcpPUK",
"colab_type": "code",
"colab": {}
},
"source": [
"cropped_im = im[y:y2,x:x2].copy()\n",
"plt.imshow(cropped_im,cmap=\"binary\")"
],
"execution_count": 0,
"outputs": []
},
{
"cell_type": "code",
"metadata": {
"id": "jkRaGiyuWuZZ",
"colab_type": "code",
"colab": {}
},
"source": [
"default_pad=5\n",
"pad_locations=[(default_pad, default_pad), (default_pad, default_pad)]\n",
"pad_pos = np.argmin(cropped_im.shape)\n",
"pad_length = abs(cropped_im.shape[0]-cropped_im.shape[1])//2\n",
"pad_locations[pad_pos] = (default_pad+pad_length,default_pad+pad_length)\n",
"padded_img = np.pad(cropped_im,pad_width=pad_locations,constant_values=(255,255))"
],
"execution_count": 0,
"outputs": []
},
{
"cell_type": "code",
"metadata": {
"id": "7XHrgb-miRfP",
"colab_type": "code",
"colab": {}
},
"source": [
"plt.imshow(padded_img,cmap=\"binary\")"
],
"execution_count": 0,
"outputs": []
},
{
"cell_type": "code",
"metadata": {
"id": "TTFtLBi2vzRx",
"colab_type": "code",
"colab": {}
},
"source": [
"plt.imshow(cv2.resize(padded_img,(90,90)),cmap=\"binary\")"
],
"execution_count": 0,
"outputs": []
},
{
"cell_type": "code",
"metadata": {
"id": "g5X9WhdOv1UU",
"colab_type": "code",
"colab": {}
},
"source": [
"mb = master_bar(range(0,4))\n",
"default_pad=5\n",
"for s in [\"train\",\"test\"]:\n",
" try:\n",
" os.makedirs(f\"./images/{s}\")\n",
" except:\n",
" pass\n",
" for i in mb:\n",
" df = pd.read_parquet(f\"./{s}_image_data_{i}.parquet\")\n",
" for j in progress_bar(range(df.shape[0])):\n",
" data0_head = df.iloc[j][1:].values\n",
" im = data0_head.reshape(137,236).astype(np.uint8)\n",
" ret, thresh1 = cv2.threshold(im.copy(),230,255,cv2.THRESH_BINARY_INV)\n",
" contours, hierarchy = cv2.findContours(thresh1,cv2.RETR_EXTERNAL,cv2.CHAIN_APPROX_SIMPLE)\n",
" new_im = im.copy()\n",
" cnt_list=[]\n",
" for cnt in contours:\n",
" x,y,w,h = cv2.boundingRect(cnt)\n",
" # cv2.rectangle(new_im,(x,y),(x+w,y+h),(0,255,0),3)\n",
" cnt_list.append([x,y,x+w,y+h])\n",
" (x, y), (x2, y2) = np.array(cnt_list)[:,:2].min(axis=0), np.array(cnt_list)[:,2:].max(axis=0)\n",
" cropped_im = im[y:y2,x:x2].copy()\n",
" pad_locations=[(default_pad, default_pad), (default_pad, default_pad)]\n",
" pad_pos = np.argmin(cropped_im.shape)\n",
" pad_length = abs(cropped_im.shape[0]-cropped_im.shape[1])//2\n",
" pad_locations[pad_pos] = (default_pad+pad_length,default_pad+pad_length)\n",
" padded_img = np.pad(cropped_im,pad_width=pad_locations,constant_values=(255,255))\n",
" resized_img = cv2.resize(padded_img,(90,90))\n",
" cv2.imwrite(f\"./images/{s}/{df.iloc[j][0]}.png\",resized_img)"
],
"execution_count": 0,
"outputs": []
},
{
"cell_type": "markdown",
"metadata": {
"id": "7KuSEpq-t9_v",
"colab_type": "text"
},
"source": [
"## Code"
]
},
{
"cell_type": "code",
"metadata": {
"id": "deKmpEKPuQXq",
"colab_type": "code",
"colab": {}
},
"source": [
"!kaggle datasets download -d vijayabhaskar96/bengali-ai-cropped-90x90-dataset"
],
"execution_count": 0,
"outputs": []
},
{
"cell_type": "code",
"metadata": {
"id": "TjJYdcAh0mTY",
"colab_type": "code",
"colab": {}
},
"source": [
"!unzip bengali-ai-cropped-90x90-dataset.zip"
],
"execution_count": 0,
"outputs": []
},
{
"cell_type": "code",
"metadata": {
"id": "PAjC3kAfwXRH",
"colab_type": "code",
"colab": {}
},
"source": [
"from fastai.vision import *"
],
"execution_count": 0,
"outputs": []
},
{
"cell_type": "code",
"metadata": {
"id": "HQRd6Pi2yyTi",
"colab_type": "code",
"colab": {}
},
"source": [
"traindf = pd.read_csv(\"./train.csv\")\n",
"testdf = pd.read_csv(\"./test.csv\")"
],
"execution_count": 0,
"outputs": []
},
{
"cell_type": "code",
"metadata": {
"id": "J1RYocIvyzIy",
"colab_type": "code",
"colab": {}
},
"source": [
"src=ImageList.from_df(traindf,\"./images/train\",cols=\"image_id\",suffix=\".png\").split_by_rand_pct(seed=42).label_from_df(cols=[\"grapheme_root\",\"vowel_diacritic\",\"consonant_diacritic\"])\n",
"data=src.transform(get_transforms(),size=90).databunch(bs=256).normalize(imagenet_stats)\n",
"test_data=ImageList.from_df(testdf,\"./images/test\",cols=\"image_id\",suffix=\".png\")\n",
"data.add_test(test_data)\n",
"data"
],
"execution_count": 0,
"outputs": []
},
{
"cell_type": "code",
"metadata": {
"id": "i-vEYfqOzjbl",
"colab_type": "code",
"colab": {}
},
"source": [
"class Loss_combine(nn.Module):\n",
" def __init__(self):\n",
" super().__init__()\n",
" \n",
" def forward(self, input, target):\n",
" x = input\n",
" y = target.long()\n",
" # pdb.set_trace()\n",
" return 2.0*F.cross_entropy(x[:,:168],y[:,0]) + \\\n",
" F.cross_entropy(x[:,168:168+11],y[:,1]) + \\\n",
" F.cross_entropy(x[:,168+11:],y[:,2]) \n",
"\n",
"class Metric_idx(Callback):\n",
" def __init__(self, idx,n_classes, average='macro'):\n",
" super().__init__()\n",
" self.idx = idx\n",
" self.n_classes = n_classes\n",
" self.average = average\n",
" self.cm = None\n",
" self.eps = 1e-9\n",
" \n",
" def on_epoch_begin(self, **kwargs):\n",
" self.tp = 0\n",
" self.fp = 0\n",
" self.cm = None\n",
" \n",
" def on_batch_end(self, last_output:Tensor, last_target:Tensor, **kwargs):\n",
" if self.idx == 0:\n",
" last_output = last_output[:,:168]\n",
" elif self.idx == 1:\n",
" last_output = last_output[:,168:168+11]\n",
" elif self.idx == 2:\n",
" last_output = last_output[:,168+11:]\n",
" last_target = last_target[:,self.idx]\n",
" preds = last_output.argmax(-1).view(-1).cpu()\n",
" targs = last_target.long().cpu()\n",
" # pdb.set_trace()\n",
" if self.n_classes == 0:\n",
" self.n_classes = last_output.shape[-1]\n",
" self.x = torch.arange(0, self.n_classes)\n",
" else:\n",
" self.x = torch.arange(0, self.n_classes)\n",
" cm = ((preds==self.x[:, None]) & (targs==self.x[:, None, None])) \\\n",
" .sum(dim=2, dtype=torch.float32)\n",
" if self.cm is None: self.cm = cm\n",
" else: self.cm += cm\n",
"\n",
" def _weights(self, avg:str):\n",
" if self.n_classes != 2 and avg == \"binary\":\n",
" avg = self.average = \"macro\"\n",
" warn(\"average=`binary` was selected for a non binary case. \\\n",
" Value for average has now been set to `macro` instead.\")\n",
" if avg == \"binary\":\n",
" if self.pos_label not in (0, 1):\n",
" self.pos_label = 1\n",
" warn(\"Invalid value for pos_label. It has now been set to 1.\")\n",
" if self.pos_label == 1: return Tensor([0,1])\n",
" else: return Tensor([1,0])\n",
" elif avg == \"micro\": return self.cm.sum(dim=0) / self.cm.sum()\n",
" elif avg == \"macro\": return torch.ones((self.n_classes,)) / self.n_classes\n",
" elif avg == \"weighted\": return self.cm.sum(dim=1) / self.cm.sum()\n",
" \n",
" def _recall(self):\n",
" rec = torch.diag(self.cm) / (self.cm.sum(dim=1) + self.eps)\n",
" if self.average is None: return rec\n",
" else:\n",
" if self.average == \"micro\": weights = self._weights(avg=\"weighted\")\n",
" else: weights = self._weights(avg=self.average)\n",
" return (rec * weights).sum()\n",
" \n",
" def on_epoch_end(self, last_metrics, **kwargs): \n",
" return add_metrics(last_metrics, self._recall())\n",
" \n",
"# Metric_grapheme = partial(Metric_idx,0)\n",
"# Metric_vowel = partial(Metric_idx,1)\n",
"# Metric_consonant = partial(Metric_idx,2)\n",
"\n",
"class Metric_tot(Callback):\n",
" def __init__(self):\n",
" super().__init__()\n",
" self.grapheme = Metric_idx(0,168)\n",
" self.vowel = Metric_idx(1,11)\n",
" self.consonant = Metric_idx(2,7)\n",
" \n",
" def on_epoch_begin(self, **kwargs):\n",
" self.grapheme.on_epoch_begin(**kwargs)\n",
" self.vowel.on_epoch_begin(**kwargs)\n",
" self.consonant.on_epoch_begin(**kwargs)\n",
" \n",
" def on_batch_end(self, last_output:Tensor, last_target:Tensor, **kwargs):\n",
" self.grapheme.on_batch_end(last_output, last_target, **kwargs)\n",
" self.vowel.on_batch_end(last_output, last_target, **kwargs)\n",
" self.consonant.on_batch_end(last_output, last_target, **kwargs)\n",
" \n",
" def on_epoch_end(self, last_metrics, **kwargs): \n",
" return add_metrics(last_metrics, 0.5*self.grapheme._recall() +\n",
" 0.25*self.vowel._recall() + 0.25*self.consonant._recall())"
],
"execution_count": 0,
"outputs": []
},
{
"cell_type": "code",
"metadata": {
"id": "RHzvo3CHcdEO",
"colab_type": "code",
"colab": {}
},
"source": [
"traindf.grapheme_root.nunique(),traindf.vowel_diacritic.nunique(),traindf.consonant_diacritic.nunique()"
],
"execution_count": 0,
"outputs": []
},
{
"cell_type": "code",
"metadata": {
"id": "Wx5q3IJ6CmeG",
"colab_type": "code",
"colab": {}
},
"source": [
"def create_head(nf:int, nc:int, lin_ftrs:Optional[Collection[int]]=None, ps:Floats=0.5,\n",
" concat_pool:bool=True, bn_final:bool=False):\n",
" \"Model head that takes `nf` features, runs through `lin_ftrs`, and about `nc` classes.\"\n",
" lin_ftrs = [nf, 512, nc] if lin_ftrs is None else [nf] + lin_ftrs + [nc]\n",
" ps = listify(ps)\n",
" if len(ps) == 1: ps = [ps[0]/2] * (len(lin_ftrs)-2) + ps\n",
" actns = [nn.ReLU(inplace=True)] * (len(lin_ftrs)-2) + [None]\n",
" pool = AdaptiveConcatPool2d() if concat_pool else nn.AdaptiveAvgPool2d(1)\n",
" layers = [pool, Flatten()]\n",
" for ni,no,p,actn in zip(lin_ftrs[:-1], lin_ftrs[1:], ps, actns):\n",
" layers += bn_drop_lin(ni, no, True, p, actn)\n",
" if bn_final: layers.append(nn.BatchNorm1d(lin_ftrs[-1], momentum=0.01))\n",
" return nn.Sequential(*layers)"
],
"execution_count": 0,
"outputs": []
},
{
"cell_type": "code",
"metadata": {
"id": "s0RMcPfIv6mz",
"colab_type": "code",
"colab": {}
},
"source": [
"learn = cnn_learner(data,models.resnet34,loss_func=Loss_combine(),custom_head=create_head(nf=1024,nc=186),metrics=[Metric_tot()])"
],
"execution_count": 0,
"outputs": []
},
{
"cell_type": "code",
"metadata": {
"id": "8FZNlgkoybLv",
"colab_type": "code",
"colab": {}
},
"source": [
"learn.lr_find(num_it=500,stop_div=False)"
],
"execution_count": 0,
"outputs": []
},
{
"cell_type": "code",
"metadata": {
"id": "6DfFdCzuylii",
"colab_type": "code",
"colab": {}
},
"source": [
"learn.recorder.plot()"
],
"execution_count": 0,
"outputs": []
},
{
"cell_type": "code",
"metadata": {
"id": "g8Ya2aGKyt5-",
"colab_type": "code",
"colab": {}
},
"source": [
"learn.freeze()\n",
"learn.fit_one_cycle(2,max_lr=1e-1/2)"
],
"execution_count": 0,
"outputs": []
},
{
"cell_type": "code",
"metadata": {
"id": "QSFreOyAiDCt",
"colab_type": "code",
"colab": {}
},
"source": [
"learn.unfreeze()\n",
"learn.fit_one_cycle(20,max_lr=slice(1e-3/2,1e-2/2))"
],
"execution_count": 0,
"outputs": []
},
{
"cell_type": "code",
"metadata": {
"id": "v6t9c4W70cU4",
"colab_type": "code",
"colab": {}
},
"source": [
"learn.save(\"unfreeze1\")"
],
"execution_count": 0,
"outputs": []
},
{
"cell_type": "code",
"metadata": {
"id": "RpDxH89A3STU",
"colab_type": "code",
"colab": {}
},
"source": [
"test_preds=learn.TTA(ds_type=DatasetType.Test)"
],
"execution_count": 0,
"outputs": []
},
{
"cell_type": "code",
"metadata": {
"id": "GOnQdQ9j815V",
"colab_type": "code",
"colab": {}
},
"source": [
"test_preds=test_preds[0].numpy()"
],
"execution_count": 0,
"outputs": []
},
{
"cell_type": "code",
"metadata": {
"id": "tJEQ6g8o32l5",
"colab_type": "code",
"colab": {}
},
"source": [
"grapheme,vowel,consonant = test_preds[:,:168], test_preds[:,168:168+11], test_preds[:,168+11:]"
],
"execution_count": 0,
"outputs": []
},
{
"cell_type": "code",
"metadata": {
"id": "pxjDwO0u-QgK",
"colab_type": "code",
"colab": {}
},
"source": [
"finaldf=testdf.copy()"
],
"execution_count": 0,
"outputs": []
},
{
"cell_type": "code",
"metadata": {
"id": "eEUL68vW9Xqi",
"colab_type": "code",
"colab": {}
},
"source": [
"finaldf=finaldf.drop(labels=[\"image_id\",\"component\"],axis=1)"
],
"execution_count": 0,
"outputs": []
},
{
"cell_type": "code",
"metadata": {
"id": "Wr3auYQJ_8AH",
"colab_type": "code",
"colab": {}
},
"source": [
"finaldf[\"target\"]=-1"
],
"execution_count": 0,
"outputs": []
},
{
"cell_type": "code",
"metadata": {
"id": "hkVe4hdXAh83",
"colab_type": "code",
"colab": {}
},
"source": [
"for i in range(0,36,3):\n",
" print(learn.data.test_ds.items[i])\n",
" finaldf[\"target\"][i] = np.argmax(consonant,axis=1)[i]\n",
" finaldf[\"target\"][i+1] = np.argmax(grapheme,axis=1)[i]\n",
" finaldf[\"target\"][i+2] = np.argmax(vowel,axis=1)[i]"
],
"execution_count": 0,
"outputs": []
},
{
"cell_type": "code",
"metadata": {
"id": "mB4wPmWsAu7s",
"colab_type": "code",
"colab": {}
},
"source": [
"finaldf.to_csv(\"./submission.csv\",index=False)"
],
"execution_count": 0,
"outputs": []
},
{
"cell_type": "code",
"metadata": {
"id": "s0vucqkGD3VR",
"colab_type": "code",
"colab": {}
},
"source": [
""
],
"execution_count": 0,
"outputs": []
}
]
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment