{"cells":[{"metadata":{"_uuid":"8f2839f25d086af736a60e9eeb907d3b93b6e0e5","_cell_guid":"b1076dfc-b9ad-4769-8c92-a6c4dae69d19","trusted":true},"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 in \n\nimport numpy as np # linear algebra\nimport pandas as pd # data processing, CSV file I/O (e.g. pd.read_csv)\nimport matplotlib.pyplot as plt\n# Input data files are available in the \"../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# Any results you write to the current directory are saved as output.","execution_count":null,"outputs":[]},{"metadata":{"_uuid":"d629ff2d2480ee46fbb7e2d37f6b5fab8052498a","_cell_guid":"79c7e3d0-c299-4dcb-8224-4455121ee9b0","trusted":true},"cell_type":"code","source":"DATA_PATH = '../input/bengaliai-cv19/'\n","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"train_labels = pd.read_csv(DATA_PATH + 'train.csv')\ntest_labels = pd.read_csv(DATA_PATH + 'test.csv')\nclass_map = pd.read_csv(DATA_PATH + 'class_map.csv')\nsample_submission = pd.read_csv(DATA_PATH + 'sample_submission.csv')","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"train_labels.head()","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"for col in train_labels:\n    print(col , '----> unique values = ' , train_labels[col].unique().shape[0])","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"for col in class_map:\n    print(col , '----> unique values = ' , class_map[col].unique().shape[0])","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"import matplotlib.pyplot as plt\nimport numpy as np","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"def by_cat(CC,GG):\n    con=train_labels[CC].unique()\n    all_cols=train_labels.drop(['image_id',CC,GG],axis=1).columns\n    fig,ax=plt.subplots(len(con),len(all_cols),figsize=(20,15))\n    for i in range(len(con)):\n        temp=train_labels[train_labels[CC]==con[i]].groupby(GG).count()\n        for c in range(len(all_cols)):\n            if all_cols[c] in temp:\n                ax[i,c].bar(temp.index,temp[all_cols[c]])\n                ax[i,c].set_title(str(all_cols[c]) + ' ' + str(con[i]))\n    plt.tight_layout()\n    plt.show()\n    \n\n   \n\n    \n    ","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"by_cat('consonant_diacritic','vowel_diacritic')\n","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"by_cat('consonant_diacritic','grapheme_root')\n","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"len(train_labels)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"train_df_0 = pd.read_parquet(DATA_PATH + 'train_image_data_0.parquet')\ntrain_df_0.head()","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"import matplotlib.pyplot as plt\nimport numpy as np\n\nH,W = (137,236)\n \ndef plot_img(val):\n    img = val.reshape(H, W)\n    plt.imshow(img.astype(float), cmap='gray')\n    plt.show()\n    return img.astype(float)\n\ndef crop_img(img_,th):\n    arr=np.argwhere(img>th)\n    x=arr[:,0]\n    y=arr[:,1]  \n    fRow = min(x)\n    lRow = max(x)\n    fCol = min(y)\n    lCol = max(y)\n    return img[fRow:lRow,fCol:lCol]\n\n\ndef setup_img(val,th):\n    val=val/val.max()\n    img = val.reshape(H, W)\n    img=1-img\n    img[img<th]=0\n    return img.astype(float)\n\ndef apply_th(img,th):\n    img[img<th]=0\n    img[img>=th]=1\n    return img\n    ","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"fig,ax=plt.subplots(1,3,figsize=(10,10))\n\n\nimg=setup_img(train_df_0.iloc[2].values[1:],0.1)\nax[0].imshow(img,cmap='gray')\nax[0].set_title('orginal invert')\n\ncorped_img=crop_img(img,0.5)\nax[1].imshow(corped_img,cmap='gray')\nax[1].set_title('croped img')\n\n\nth_img=apply_th(corped_img,0.3)\nax[2].imshow(th_img,cmap='gray')\nax[2].set_title('threshold')\n\nplt.show()","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"#let see the avg img size ","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"HH=[]\nWW=[]\nfor i in range (0,100):\n    img=setup_img(train_df_0.iloc[i].values[1:],0.1)\n    corped_img=crop_img(img,0.5)\n    HH.append(corped_img.shape[0])\n    WW.append(corped_img.shape[1])","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"from scipy import stats","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"np.mean(HH),np.mean(WW)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"stats.mode(HH),stats.mode(WW)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"# LETS TRY 80 X 110","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"import cv2","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"#corped_img\nimg_resized= cv2.resize(corped_img, dsize=(80, 110), interpolation=cv2.INTER_CUBIC      )\nplt.imshow(img_resized,cmap='gray')","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"#th_img\nimg_resized= cv2.resize(th_img, dsize=(80, 110), interpolation=cv2.INTER_CUBIC)\nplt.imshow(img_resized,cmap='gray')","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"for i in range(10):\n    fig,ax=plt.subplots(1,2,figsize=(10,10))\n    img1=PreprocessImg.get_img(train_df_0.iloc[i].values[1:],True,True)\n    img2=PreprocessImg.get_img(train_df_0.iloc[i].values[1:],True,False)\n\n    ax[0].imshow(img1,cmap='gray')\n    ax[1].imshow(img2,cmap='gray')\n    plt.show()","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"import pandas  as pd\nimport cv2\nfrom  tqdm import tqdm\n\ndef crop_and_resize_images(df, resized_df, resize_size = 80):\n    cropped_imgs = {}\n    for img_id in tqdm(range(df.shape[0])):\n        img = resized_df[img_id]\n        _, thresh = cv2.threshold(img, 30, 255, cv2.THRESH_BINARY_INV + cv2.THRESH_OTSU)\n        contours, _ = cv2.findContours(thresh,cv2.RETR_LIST,cv2.CHAIN_APPROX_SIMPLE)[-2:]\n        \n        idx = 0 \n        ls_xmin = []\n        ls_ymin = []\n        ls_xmax = []\n        ls_ymax = []\n        for cnt in contours:\n            idx += 1\n            x,y,w,h = cv2.boundingRect(cnt)\n            ls_xmin.append(x)\n            ls_ymin.append(y)\n            ls_xmax.append(x + w)\n            ls_ymax.append(y + h)\n        xmin = min(ls_xmin)\n        ymin = min(ls_ymin)\n        xmax = max(ls_xmax)\n        ymax = max(ls_ymax)\n\n        roi = img[ymin:ymax,xmin:xmax]\n        resized_roi = cv2.resize(roi, (resize_size, resize_size))\n        resized_roi=resized_roi/255\n        cropped_imgs[df.image_id[img_id]] = resized_roi.reshape(-1)\n        \n    resized = pd.DataFrame(cropped_imgs).T.reset_index()\n    resized.columns = resized.columns.astype(str)\n    resized.rename(columns={'index':'image_id'},inplace=True)\n    return resized #out_df","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"TRAIN=['train_image_data_0.parquet','train_image_data_1.parquet','train_image_data_2.parquet','train_image_data_3.parquet']\nDATA_PATH = '../input/bengaliai-cv19/'\nHEIGHT = 137\nWIDTH = 236\n\nfor i,dName in enumerate(TRAIN):\n    df = pd.read_parquet(DATA_PATH + dName )\n    resized = df.iloc[:, 1:].values.reshape(-1, HEIGHT, WIDTH)\n    name = '80x80_train_{}.feather'.format(i)\n    cropped_df = crop_and_resize_images(df,resized)\n    cropped_df.to_feather(name)\n    del df,resized,cropped_df\n\n    \n    ","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"'''\ngrapheme_root ----> unique values =  168\nvowel_diacritic ----> unique values =  11\nconsonant_diacritic ----> unique values =  7\n'''","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"import cv2\n#shape=(80,80)\nH,W = (137,236)\nth=0.3\nclass PreprocessImg():\n    def get_img(val,shape,apply_th=False,resize=True):\n        img_=PreprocessImg.setup_img(val)\n        img_=PreprocessImg.crop_img(img_,th)\n        if apply_th:\n            img_=PreprocessImg.apply_th(img_,th)\n        if resize:\n            img_= cv2.resize(img_, dsize=shape, interpolation=cv2.INTER_CUBIC)\n        return img_\n        \n    def crop_img(img,th):\n        arr=np.argwhere(img>=th)\n        x=arr[:,0]\n        y=arr[:,1]  \n        fRow = min(x)\n        lRow = max(x)\n        fCol = min(y)\n        lCol = max(y)\n        return img[fRow:lRow,fCol:lCol]\n\n    def setup_img(val):\n        val=val/val.max()\n        img = val.reshape(H, W)\n        img=1-img\n        return img.astype(float)\n    \n    def apply_th(img,th):\n        img[img<th]=0\n        img[img>=th]=1\n        return img","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"def one_hot_encoding(c):\n    arr=np.zeros((168))\n    arr[c]=1\n    return arr\n\ndef x_y(x,y):\n    y_arr=np.zeros((25,168),dtype=np.float32)\n    for c in range(25):\n        y_arr[c] = one_hot_encoding(y[c])\n        \n    x_arr=np.zeros((x.shape[0],80,80,1),dtype=np.float32)\n    for c in range((x.shape[0])):\n        im=PreprocessImg.get_img(x[c],True,True)\n        x_arr[c] = np.reshape(im,(80,80,1))\n    return x_arr,y_arr","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"import pandas as pd\nimport numpy as np\nimport time    \nimport cv2\nfrom tensorflow.keras.utils import Sequence\n\nTRAIN_RANGE=200840\nTEST_RANGE=12\nBATCH_SIZE=25\nCLASS_=168\nIMAGE_SIZE=(80,80)\nDATA_PATH = '../input/bengaliai-cv19/'\nTRAIN=['train_image_data_0.parquet','train_image_data_1.parquet','train_image_data_2.parquet','train_image_data_3.parquet']\nTEST=['test_image_data_0.parquet','test_image_data_1.parquet','test_image_data_2.parquet','test_image_data_3.parquet',]\n\n\nclass batch():\n\n    def __init__(self,batch_size,to_fit=True):\n        self.batch_size=batch_size\n        self.pre=0\n        self.to_fit=to_fit\n        if to_fit:\n            self.data=pd.read_parquet(DATA_PATH + TRAIN[0])\n            self.lis_of_file=TRAIN\n            self.LABLES=pd.read_csv(DATA_PATH +  'train.csv')\n        else:\n            self.data=pd.read_parquet(DATA_PATH + TEST[0])\n            self.lis_of_file=TEST\n            \n        self.len=len(self.data)\n        \n        self.index=0\n\n    def set_next_df(self):\n        if self.index + 1 < len(self.lis_of_file):\n            self.data=pd.read_parquet(DATA_PATH + self.lis_of_file[self.index + 1])\n            self.index += 1\n        else:\n            self.data=pd.read_parquet(DATA_PATH + self.lis_of_file[0])\n            self.index = 0\n        self.pre=0\n        self.len=len(self.data)\n\n\n    def next_batch(self,get_as_array=True):\n        if self.pre +  self.batch_size > self.len:\n            if self.pre < self.len:\n                x=self.data.iloc[self.pre  : ]\n                len_of_x= len(x)\n                self.set_next_df()\n                x=x.append(self.data.iloc[self.pre : self.batch_size - len_of_x ] , ignore_index=True)\n                self.pre = self.batch_size - len_of_x\n                y=self.get_y(x)\n                if get_as_array:\n                    return self.get_asArray(x,y)\n                return x,y\n            else:\n                    self.set_next_df\n        x=self.data.iloc[self.pre  :  self.pre +  self.batch_size]\n        y=self.get_y(x)\n        self.pre+=self.batch_size\n        if get_as_array:\n            return self.get_asArray(x,y)\n        return x,y\n\n    def get_y(self,data):\n        if  self.to_fit == False:\n            return []\n        l=len(data)\n        d=data['image_id'].iloc[0]\n        index=self.LABLES[self.LABLES['image_id']==d].index[0]\n        if index + l > TRAIN_RANGE:\n            y=self.LABLES.iloc[index:]\n            len_of_y= len(y)\n            y=y.append(self.LABLES[0: l - len_of_y ])\n            return y\n        y=self.LABLES.iloc[index:index+l]\n        return y\n    \n    def get_asArray(self,x,y):\n        y_val=[]\n        if self.to_fit == True :\n            y_val=y.drop(['image_id','grapheme','vowel_diacritic','consonant_diacritic'],axis=1).values\n        x_val=x.drop('image_id',axis=1).values\n        #y_val=y.drop(['image_id','grapheme'],axis=1).values\n        return x_val,y_val\n\n\nclass DataGenerator(Sequence):\n    \"\"\"Generates data for Keras\n    Sequence based data generator. Suitable for building data generator for training and prediction.\n    \"\"\"\n    def __init__(self,to_fit=True, batch_size=25, dim=(80, 80), n_classes=168,final_=True):\n     \n        self.to_fit = to_fit\n        self.batch_size = batch_size\n        self.dim = dim\n        self.n_classes = n_classes\n        self.b=batch(batch_size = batch_size , to_fit = to_fit)\n        self.final_=final_\n        #self.on_epoch_end()\n\n    def __len__(self):\n        \n        return int(np.floor(TRAIN_RANGE / self.batch_size))\n\n    def __getitem__(self, index):\n        \n       \n        X,y=self.b.next_batch()\n        if  self.final_: \n            X,y=self.FinalXY(X,y)\n\n        if self.to_fit:\n            return X, y\n        else:\n            return X\n        \n    def one_hot_encoding(self,c):\n        arr=np.zeros((CLASS_))\n        arr[c]=1\n        return arr\n\n    def FinalXY(self,x,y):\n        y_arr=[]\n        if self.to_fit:\n            y_arr=np.zeros((self.batch_size,CLASS_),dtype=np.float32)\n            for c in range(self.batch_size):\n                y_arr[c] = self.one_hot_encoding(y[c])\n            \n        x_arr=np.zeros((x.shape[0],IMAGE_SIZE[0],IMAGE_SIZE[1],1),dtype=np.float32)\n        for c in range((BATCH_SIZE)):\n            im=PreprocessImg.get_img(x[c],IMAGE_SIZE,True,True)\n            x_arr[c] = np.reshape(im,(IMAGE_SIZE[0],IMAGE_SIZE[1],1))\n            \n        return x_arr,y_arr","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"\n\nfrom tensorflow.keras.models import Sequential\nfrom tensorflow.keras.layers import Dense , Activation , Dropout , Flatten ,Conv2D , MaxPool2D ,BatchNormalization \nfrom tensorflow.keras import optimizers\n","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"def setup_model(input_shape):\n    model = Sequential()\n    model.add(Conv2D(64,(3,3),input_shape=input_shape,activation='relu',padding='same'))\n    model.add(Conv2D(64,(3,3),activation='relu',padding='same'))\n    model.add(BatchNormalization())\n    model.add(MaxPool2D(pool_size=(2,2)))\n    model.add(Dropout(0.2))\n\n    model.add(Conv2D(128,(3,3),activation='relu',padding='same'))\n    model.add(Conv2D(64,(3,3),activation='relu',padding='same'))\n    model.add(Conv2D(32,(3,3),activation='relu',padding='same'))\n    model.add(Dropout(0.2))\n\n    model.add(BatchNormalization())\n    model.add(MaxPool2D(pool_size=(2,2)))\n    model.add(Dropout(0.2))\n\n    model.add(Conv2D(128,(3,3),activation='relu',padding='same'))\n    model.add(Conv2D(64,(3,3),activation='relu',padding='same'))\n    model.add(Conv2D(32,(3,3),activation='relu',padding='same'))\n    model.add(BatchNormalization())\n    model.add(MaxPool2D(pool_size=(2,2)))\n    model.add(Dropout(0.2))\n\n    model.add(Conv2D(128,(3,3),activation='relu',padding='same'))\n    model.add(Conv2D(64,(3,3),activation='relu',padding='same'))\n    model.add(Conv2D(32,(3,3),activation='relu',padding='same'))\n    model.add(BatchNormalization())\n    model.add(MaxPool2D(pool_size=(2,2)))\n    model.add(Dropout(0.2))\n\n    model.add(Flatten())\n    model.add(Dense(256))\n    model.add(Dense(128))\n    model.add(Dense(64))\n\n    #model.add(Activation('relu'))\n    model.add(Dropout(0.2))\n    model.add(Dense(168,activation='softmax'))\n\n    model.compile(loss='categorical_crossentropy', metrics=['accuracy'],optimizer='adam')\n    print(model.summary())\n    return model","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"model=setup_model((80,80,1))","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"mname='Mbangi'","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"import keras\nclass CustomSaver(keras.callbacks.Callback):\n    def on_epoch_end(self, epoch, logs={}):\n        if epoch % 10 == 0 : \n            self.model.save(\"{}_{}.hd5\".format(mname,epoch))","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"Gen = DataGenerator(to_fit=True, batch_size=BATCH_SIZE, dim=(80, 80), n_classes=168,final_=True)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"saver = CustomSaver()","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"hist=model.fit_generator(generator=Gen,epochs=20,verbose=1,shuffle=True,callbacks=[saver])","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"BATCH_SIZE","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}