{"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\nimport matplotlib.pyplot as plt\nfrom collections import Counter\nfrom fastai.vision.all import *\nimport albumentations\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":"2021-06-22T07:58:54.266083Z","iopub.execute_input":"2021-06-22T07:58:54.266490Z","iopub.status.idle":"2021-06-22T07:58:58.948058Z","shell.execute_reply.started":"2021-06-22T07:58:54.266458Z","shell.execute_reply":"2021-06-22T07:58:58.946985Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"path='/kaggle/input/expertclass2/'","metadata":{"execution":{"iopub.status.busy":"2021-06-22T07:58:58.949982Z","iopub.execute_input":"2021-06-22T07:58:58.950418Z","iopub.status.idle":"2021-06-22T07:58:58.955740Z","shell.execute_reply.started":"2021-06-22T07:58:58.950374Z","shell.execute_reply":"2021-06-22T07:58:58.954204Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"%%time\ntrain_df = pd.read_csv(\"/kaggle/input/expertclass2/train_data.csv\", sep=',')\ntrain_df = pd.concat([train_df['emotion'],train_df['pixels'].str.split(' ', expand=True)], axis=1)\ntest_df = pd.read_csv(\"/kaggle/input/expertclass2/test_data.csv\", sep=',')\ntest_df = pd.concat([test_df['pixels'].str.split(' ', expand=True)], axis=1)","metadata":{"execution":{"iopub.status.busy":"2021-06-22T07:58:58.958460Z","iopub.execute_input":"2021-06-22T07:58:58.959262Z","iopub.status.idle":"2021-06-22T08:00:01.805872Z","shell.execute_reply.started":"2021-06-22T07:58:58.959215Z","shell.execute_reply":"2021-06-22T08:00:01.803855Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"submission_df = pd.read_csv(\"/kaggle/input/expertclass2/example_submission.csv\", sep=',')","metadata":{"execution":{"iopub.status.busy":"2021-06-22T08:00:01.807930Z","iopub.execute_input":"2021-06-22T08:00:01.808375Z","iopub.status.idle":"2021-06-22T08:00:01.833252Z","shell.execute_reply.started":"2021-06-22T08:00:01.808315Z","shell.execute_reply":"2021-06-22T08:00:01.832207Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"train_df = train_df.astype(np.uint8)\ntrain_df.head(1)","metadata":{"execution":{"iopub.status.busy":"2021-06-22T08:00:01.834433Z","iopub.execute_input":"2021-06-22T08:00:01.834777Z","iopub.status.idle":"2021-06-22T08:00:32.229657Z","shell.execute_reply.started":"2021-06-22T08:00:01.834746Z","shell.execute_reply":"2021-06-22T08:00:32.228557Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"test_df = test_df.astype(np.uint8)\ntest_df.head(1)","metadata":{"execution":{"iopub.status.busy":"2021-06-22T08:00:32.231170Z","iopub.execute_input":"2021-06-22T08:00:32.231669Z","iopub.status.idle":"2021-06-22T08:00:36.929715Z","shell.execute_reply.started":"2021-06-22T08:00:32.231633Z","shell.execute_reply":"2021-06-22T08:00:36.928605Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"print(f'Train_df shape : {train_df.shape}')\nprint(f'Test_df shape  : {test_df.shape}')","metadata":{"execution":{"iopub.status.busy":"2021-06-22T08:00:36.931579Z","iopub.execute_input":"2021-06-22T08:00:36.932211Z","iopub.status.idle":"2021-06-22T08:00:36.944878Z","shell.execute_reply.started":"2021-06-22T08:00:36.932151Z","shell.execute_reply":"2021-06-22T08:00:36.943255Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"def split_df(df):\n    '''return a tuple (X, y) \n    \n        X : the training inputs which is in (samples, height, width, channel) shape\n        y : the label which is flatten\n    '''\n    if 'emotion' in df.columns:\n        y = df['emotion'].values.flatten()\n        X = df.drop('emotion', axis=1).values\n    else:\n        X = df.values\n        y = None\n        \n    X = X.reshape(X.shape[0], 48, 48)\n#     X = np.stack((X,) * 3, axis=-1)\n    return (X,y)\n\nclass AlbumentationsTransform(RandTransform):\n    \"A transform handler for multiple `Albumentation` transforms\"\n    split_idx,order=None,2\n    def __init__(self, train_aug, valid_aug): store_attr()\n    \n    def before_call(self, b, split_idx):\n        self.idx = split_idx\n    \n    def encodes(self, img: PILImage):\n        if self.idx == 0:\n            aug_img = self.train_aug(image=np.array(img))['image']\n        else:\n            aug_img = self.valid_aug(image=np.array(img))['image']\n        return PILImage.create(aug_img)\n            \ndef get_train_aug(): return albumentations.Compose([\n            albumentations.Transpose(p=0.2),\n            albumentations.VerticalFlip(p=0.2),\n            albumentations.ShiftScaleRotate(p=0.2),\n            albumentations.CoarseDropout(p=0.5),\n            albumentations.Cutout(p=0.5)\n])\n\ndef get_valid_aug(): return albumentations.Compose([\n    albumentations.Resize(224,224)\n], p=1.)\nitem_tfms = [Resize(224)]#, AlbumentationsTransform(get_train_aug(), get_valid_aug())]","metadata":{"execution":{"iopub.status.busy":"2021-06-22T08:00:36.949035Z","iopub.execute_input":"2021-06-22T08:00:36.949852Z","iopub.status.idle":"2021-06-22T08:00:36.963237Z","shell.execute_reply.started":"2021-06-22T08:00:36.949806Z","shell.execute_reply":"2021-06-22T08:00:36.961649Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"X_train, y_train = split_df(train_df)\nX_test, _   = split_df(test_df)\n# X_train = np.stack((X_train,) * 3, axis=-1)\n# X_test  = np.stack((X_test,) * 3, axis=-1)","metadata":{"execution":{"iopub.status.busy":"2021-06-22T08:00:36.965642Z","iopub.execute_input":"2021-06-22T08:00:36.966140Z","iopub.status.idle":"2021-06-22T08:00:37.035871Z","shell.execute_reply.started":"2021-06-22T08:00:36.966094Z","shell.execute_reply":"2021-06-22T08:00:37.034759Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"print(f'Train set shape : {X_train.shape, y_train.shape}')\nprint(f'Test  set shape  : {X_test.shape}')","metadata":{"execution":{"iopub.status.busy":"2021-06-22T08:00:37.037375Z","iopub.execute_input":"2021-06-22T08:00:37.037808Z","iopub.status.idle":"2021-06-22T08:00:37.045491Z","shell.execute_reply.started":"2021-06-22T08:00:37.037757Z","shell.execute_reply":"2021-06-22T08:00:37.043879Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"emotions = ['Angry', 'Disgust', 'Fear', 'Happy', 'Sad', 'Surprise', 'Neutral']","metadata":{"execution":{"iopub.status.busy":"2021-06-22T08:00:37.047308Z","iopub.execute_input":"2021-06-22T08:00:37.047781Z","iopub.status.idle":"2021-06-22T08:00:37.060088Z","shell.execute_reply.started":"2021-06-22T08:00:37.047734Z","shell.execute_reply":"2021-06-22T08:00:37.058706Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"index = 3\nplt.imshow(X_train[index,], cmap='gray')\nplt.title(emotions[y_train[index]]);","metadata":{"execution":{"iopub.status.busy":"2021-06-22T08:00:37.061850Z","iopub.execute_input":"2021-06-22T08:00:37.062463Z","iopub.status.idle":"2021-06-22T08:00:37.354477Z","shell.execute_reply.started":"2021-06-22T08:00:37.062421Z","shell.execute_reply":"2021-06-22T08:00:37.352687Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# Thanks to nghiaho12 (http://nghiaho.com/?p=2741)\n\ndef make_dataloaders_from_numpy_data(image, label):\n    def pass_index(idx):\n        return idx\n\n    def get_x(i):\n        # NOTE: This is a grayscale image that appears to just work with a network expecting RGB.\n        # I suspect this is due to tensor broadcasting rules.\n        return image[i]\n\n    def get_y(i):\n        return label[i]\n\n    dblock = DataBlock(\n        blocks=(ImageBlock, CategoryBlock),\n        get_items=pass_index,\n#         item_tfms=Resize(224),\n        batch_tfms=aug_transforms(size=224),\n        get_x=get_x,\n        get_y=get_y)\n\n    # pass in a list of index\n    num_images = image.shape[0]\n    dls = dblock.dataloaders(list(range(num_images)), valid_pct=0.2, seed=42)\n\n    return dls\n\ndls = make_dataloaders_from_numpy_data(X_train, y_train)\n\n# sanity check\ndls.train.show_batch(max_n=9, cmap='gray')","metadata":{"execution":{"iopub.status.busy":"2021-06-22T08:00:37.359422Z","iopub.execute_input":"2021-06-22T08:00:37.359877Z","iopub.status.idle":"2021-06-22T08:00:47.465833Z","shell.execute_reply.started":"2021-06-22T08:00:37.359820Z","shell.execute_reply":"2021-06-22T08:00:47.464626Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"model = cnn_learner(dls, models.resnet101, metrics=accuracy)\nmodel.fine_tune(10)","metadata":{"execution":{"iopub.status.busy":"2021-06-22T08:00:47.467174Z","iopub.execute_input":"2021-06-22T08:00:47.467595Z","iopub.status.idle":"2021-06-22T08:50:42.862790Z","shell.execute_reply.started":"2021-06-22T08:00:47.467535Z","shell.execute_reply":"2021-06-22T08:50:42.861639Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"model.lr_find()","metadata":{"execution":{"iopub.status.busy":"2021-06-22T09:00:54.486871Z","iopub.execute_input":"2021-06-22T09:00:54.487291Z","iopub.status.idle":"2021-06-22T09:01:51.056879Z","shell.execute_reply.started":"2021-06-22T09:00:54.487251Z","shell.execute_reply":"2021-06-22T09:01:51.055619Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# model.unfreeze()\n# model.fine_tune(20, base_lr=1e-4,cbs=[EarlyStoppingCallback(patience=5, monitor='accuracy')])\n# #model.fit_one_cycle(20, cbs=[EarlyStoppingCallback(patience=5, monitor='accuracy')])","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"model.save('model_resnet101')","metadata":{"execution":{"iopub.status.busy":"2021-06-22T09:02:58.927091Z","iopub.execute_input":"2021-06-22T09:02:58.927489Z","iopub.status.idle":"2021-06-22T09:03:00.034658Z","shell.execute_reply.started":"2021-06-22T09:02:58.927454Z","shell.execute_reply":"2021-06-22T09:03:00.033618Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"model.show_results(cmap='gray')","metadata":{"execution":{"iopub.status.busy":"2021-06-22T09:03:01.412934Z","iopub.execute_input":"2021-06-22T09:03:01.413346Z","iopub.status.idle":"2021-06-22T09:03:02.378322Z","shell.execute_reply.started":"2021-06-22T09:03:01.413309Z","shell.execute_reply":"2021-06-22T09:03:02.376943Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"class_interp = ClassificationInterpretation.from_learner(model)","metadata":{"execution":{"iopub.status.busy":"2021-06-22T09:03:02.714454Z","iopub.execute_input":"2021-06-22T09:03:02.714819Z","iopub.status.idle":"2021-06-22T09:03:27.564373Z","shell.execute_reply.started":"2021-06-22T09:03:02.714788Z","shell.execute_reply":"2021-06-22T09:03:27.563102Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"class_interp.plot_top_losses(9, figsize=(15,10), cmap='gray')","metadata":{"execution":{"iopub.status.busy":"2021-06-22T09:03:27.566782Z","iopub.execute_input":"2021-06-22T09:03:27.567314Z","iopub.status.idle":"2021-06-22T09:03:28.307942Z","shell.execute_reply.started":"2021-06-22T09:03:27.567259Z","shell.execute_reply":"2021-06-22T09:03:28.306570Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"class_interp.plot_confusion_matrix()","metadata":{"execution":{"iopub.status.busy":"2021-06-22T09:03:28.310674Z","iopub.execute_input":"2021-06-22T09:03:28.311111Z","iopub.status.idle":"2021-06-22T09:03:28.775866Z","shell.execute_reply.started":"2021-06-22T09:03:28.311067Z","shell.execute_reply":"2021-06-22T09:03:28.774841Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"predictions, *_ = model.get_preds(dl=dls.test_dl(X_test))\nlabels = np.argmax(predictions, 1)\nCounter(labels.cpu().detach().numpy())","metadata":{"execution":{"iopub.status.busy":"2021-06-22T09:03:28.778863Z","iopub.execute_input":"2021-06-22T09:03:28.779694Z","iopub.status.idle":"2021-06-22T09:03:48.497984Z","shell.execute_reply.started":"2021-06-22T09:03:28.779646Z","shell.execute_reply":"2021-06-22T09:03:48.496909Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"tta, *_ = model.tta(dl=dls.test_dl(X_test), use_max=True)\nlabels_tta = np.argmax(tta, 1)\nCounter(labels_tta.cpu().detach().numpy())","metadata":{"execution":{"iopub.status.busy":"2021-06-22T09:03:48.501837Z","iopub.execute_input":"2021-06-22T09:03:48.502141Z","iopub.status.idle":"2021-06-22T09:05:33.818029Z","shell.execute_reply.started":"2021-06-22T09:03:48.502108Z","shell.execute_reply":"2021-06-22T09:05:33.816764Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"submission_df['Emotion'] = labels_tta\nsubmission_df.to_csv(\"submission.csv\", index=False)\nsubmission_df","metadata":{"execution":{"iopub.status.busy":"2021-06-22T09:05:33.820168Z","iopub.execute_input":"2021-06-22T09:05:33.820701Z","iopub.status.idle":"2021-06-22T09:05:34.195582Z","shell.execute_reply.started":"2021-06-22T09:05:33.820653Z","shell.execute_reply":"2021-06-22T09:05:34.194504Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"","metadata":{},"execution_count":null,"outputs":[]}]}