{"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":"markdown","source":"## Dogs v Cats","metadata":{"_uuid":"4c0d29a7ea3a3d5fc93fcc1c71da0bb9a636f038"}},{"cell_type":"code","source":"%reload_ext autoreload\n%autoreload 2\n%matplotlib inline\n\nfrom fastai.imports import *\n\nfrom fastai.transforms import *\nfrom fastai.conv_learner import *\nfrom fastai.model import *\nfrom fastai.dataset import *\nfrom fastai.sgdr import *","metadata":{"_uuid":"a5d0a595e160469fa1462fbcabcd9e07e8440b57","execution":{"iopub.status.busy":"2021-08-12T10:19:50.850179Z","iopub.execute_input":"2021-08-12T10:19:50.850553Z","iopub.status.idle":"2021-08-12T10:19:50.938965Z","shell.execute_reply.started":"2021-08-12T10:19:50.850501Z","shell.execute_reply":"2021-08-12T10:19:50.938124Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"import os\nos.makedirs('../inputs')\n!ls ..","metadata":{"execution":{"iopub.status.busy":"2021-08-12T09:20:47.287824Z","iopub.execute_input":"2021-08-12T09:20:47.28814Z","iopub.status.idle":"2021-08-12T09:20:48.01069Z","shell.execute_reply.started":"2021-08-12T09:20:47.288073Z","shell.execute_reply":"2021-08-12T09:20:48.009753Z"}}},{"cell_type":"markdown","source":"os.chdir(\"/kaggle/inputs/\")\n!ls ..","metadata":{"execution":{"iopub.status.busy":"2021-08-12T09:20:51.405587Z","iopub.execute_input":"2021-08-12T09:20:51.405971Z","iopub.status.idle":"2021-08-12T09:20:52.168889Z","shell.execute_reply.started":"2021-08-12T09:20:51.405907Z","shell.execute_reply":"2021-08-12T09:20:52.167986Z"}}},{"cell_type":"code","source":"print(os.listdir(\"../input\"))","metadata":{"execution":{"iopub.status.busy":"2021-08-12T09:20:58.091558Z","iopub.execute_input":"2021-08-12T09:20:58.091868Z","iopub.status.idle":"2021-08-12T09:20:58.127671Z","shell.execute_reply.started":"2021-08-12T09:20:58.091811Z","shell.execute_reply":"2021-08-12T09:20:58.126716Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"PATH = \"/kaggle/input\"\nTMP_PATH = \"/kaggle/working/tmp/\"\nMODEL_PATH = \"/kaggle/working/models/\"\nsz = 224\narch = resnet34\nbs = 64","metadata":{"_uuid":"60760adc3fed9076804aa12ae27c9b479efcfc8a","execution":{"iopub.status.busy":"2021-08-12T10:19:55.747781Z","iopub.execute_input":"2021-08-12T10:19:55.748108Z","iopub.status.idle":"2021-08-12T10:19:55.799672Z","shell.execute_reply.started":"2021-08-12T10:19:55.748055Z","shell.execute_reply":"2021-08-12T10:19:55.799032Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"print(os.listdir(f'{PATH}'))","metadata":{"execution":{"iopub.status.busy":"2021-08-12T09:21:07.229577Z","iopub.execute_input":"2021-08-12T09:21:07.229872Z","iopub.status.idle":"2021-08-12T09:21:07.259651Z","shell.execute_reply.started":"2021-08-12T09:21:07.229815Z","shell.execute_reply":"2021-08-12T09:21:07.258737Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"from os import walk\nfor (dirpath, dirnames, filenames) in walk(\"../input\"):\n    print(\"Directory path: \", dirpath)\n    print(\"Folder name: \", dirnames)\n    print(\"File name: \", filenames)","metadata":{"execution":{"iopub.status.busy":"2021-08-12T09:21:10.743913Z","iopub.execute_input":"2021-08-12T09:21:10.744214Z","iopub.status.idle":"2021-08-12T09:21:10.776403Z","shell.execute_reply.started":"2021-08-12T09:21:10.744161Z","shell.execute_reply":"2021-08-12T09:21:10.775446Z"}}},{"cell_type":"code","source":"base_dir = \"../input\"\ntrain_dir = os.path.join(base_dir, \"train.zip\")\ntest_dir = os.path.join(base_dir, \"test.zip\")\n\nimport zipfile\nwith zipfile.ZipFile(train_dir,\"r\") as z: z.extractall()\n\nwith zipfile.ZipFile(test_dir,\"r\") as z: z.extractall()","metadata":{"execution":{"iopub.status.busy":"2021-08-12T10:21:13.052177Z","iopub.execute_input":"2021-08-12T10:21:13.052465Z","iopub.status.idle":"2021-08-12T10:21:31.752584Z","shell.execute_reply.started":"2021-08-12T10:21:13.052408Z","shell.execute_reply":"2021-08-12T10:21:31.751912Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"os.listdir(\"./train\")","metadata":{"execution":{"iopub.status.busy":"2021-08-12T10:32:15.311259Z","iopub.execute_input":"2021-08-12T10:32:15.311599Z","iopub.status.idle":"2021-08-12T10:32:15.385722Z","shell.execute_reply.started":"2021-08-12T10:32:15.311544Z","shell.execute_reply":"2021-08-12T10:32:15.384956Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"import os\ncwd = os.getcwd()\nprint(cwd)","metadata":{"execution":{"iopub.status.busy":"2021-08-12T10:33:44.799411Z","iopub.execute_input":"2021-08-12T10:33:44.799678Z","iopub.status.idle":"2021-08-12T10:33:44.849067Z","shell.execute_reply.started":"2021-08-12T10:33:44.799628Z","shell.execute_reply":"2021-08-12T10:33:44.848139Z"}}},{"cell_type":"code","source":"os.listdir(\"./test\")","metadata":{"execution":{"iopub.status.busy":"2021-08-12T10:21:52.430407Z","iopub.execute_input":"2021-08-12T10:21:52.430703Z","iopub.status.idle":"2021-08-12T10:21:52.501676Z","shell.execute_reply.started":"2021-08-12T10:21:52.430652Z","shell.execute_reply":"2021-08-12T10:21:52.500774Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"m = arch(True)","metadata":{"_uuid":"3ac1577547c4681c1ab48e12a20468b657eeb2cb","execution":{"iopub.status.busy":"2021-08-12T10:22:46.888534Z","iopub.execute_input":"2021-08-12T10:22:46.888819Z","iopub.status.idle":"2021-08-12T10:22:55.890507Z","shell.execute_reply.started":"2021-08-12T10:22:46.888769Z","shell.execute_reply":"2021-08-12T10:22:55.889814Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"m","metadata":{"_uuid":"8efca7b5c8073e214aa8753bd0ab4be7bca585cf","execution":{"iopub.status.busy":"2021-08-12T10:22:58.355151Z","iopub.execute_input":"2021-08-12T10:22:58.355538Z","iopub.status.idle":"2021-08-12T10:22:58.434268Z","shell.execute_reply.started":"2021-08-12T10:22:58.355469Z","shell.execute_reply":"2021-08-12T10:22:58.429065Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"m = nn.Sequential(*children(m)[:-2], \n                  nn.Conv2d(512, 2, 3, padding=1), \n                  nn.AdaptiveAvgPool2d(1), Flatten(), \n                  nn.LogSoftmax())","metadata":{"_uuid":"41f9ff4fbbf0e162d0e0d515d750acc5a1b16415","execution":{"iopub.status.busy":"2021-08-12T10:23:05.427149Z","iopub.execute_input":"2021-08-12T10:23:05.427438Z","iopub.status.idle":"2021-08-12T10:23:05.477316Z","shell.execute_reply.started":"2021-08-12T10:23:05.427387Z","shell.execute_reply":"2021-08-12T10:23:05.476671Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"#fnames = np.array([f'train/{f}' for f in sorted(os.listdir(f'{PATH}/'))])\nfnames = np.array([f'train/{f}' for f in sorted(os.listdir('./train'))])\nlabels = np.array([(0 if 'cat' in fname else 1) for fname in fnames])","metadata":{"_uuid":"24e585ee0921697ca7895629d19a6f7ae8373d3b","execution":{"iopub.status.busy":"2021-08-12T10:43:35.956311Z","iopub.execute_input":"2021-08-12T10:43:35.956645Z","iopub.status.idle":"2021-08-12T10:43:36.062512Z","shell.execute_reply.started":"2021-08-12T10:43:35.956594Z","shell.execute_reply":"2021-08-12T10:43:36.06179Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"tfms = tfms_from_model(arch, sz, aug_tfms=transforms_side_on, max_zoom=1.1)\ndata = ImageClassifierData.from_names_and_array(\n    path='./', \n    fnames=fnames, \n    y=labels, \n    classes=['dogs', 'cats'], \n    test_name='test', \n    tfms=tfms,\n    bs=bs\n)","metadata":{"_uuid":"2027cb854d03795c912b0c69606d95f40b6236f7","execution":{"iopub.status.busy":"2021-08-12T10:46:23.413797Z","iopub.execute_input":"2021-08-12T10:46:23.414109Z","iopub.status.idle":"2021-08-12T10:46:23.809149Z","shell.execute_reply.started":"2021-08-12T10:46:23.414056Z","shell.execute_reply":"2021-08-12T10:46:23.808481Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"tfms = tfms_from_model(arch, sz, aug_tfms=transforms_side_on, max_zoom=1.1)\ndata = ImageClassifierData.from_names_and_array(\n    path=PATH, \n    fnames=fnames, \n    y=labels, \n    classes=['dogs', 'cats'], \n    test_name='test', \n    tfms=tfms,\n    bs=bs\n)","metadata":{}},{"cell_type":"code","source":"learn = ConvLearner.from_model_data(m, data, tmp_name=TMP_PATH, models_name=MODEL_PATH)","metadata":{"_uuid":"64fc5ff0d6341418daa146e1b89b172782f92f89","execution":{"iopub.status.busy":"2021-08-12T10:46:39.164941Z","iopub.execute_input":"2021-08-12T10:46:39.165224Z","iopub.status.idle":"2021-08-12T10:46:42.11654Z","shell.execute_reply.started":"2021-08-12T10:46:39.165175Z","shell.execute_reply":"2021-08-12T10:46:42.115858Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"learn.freeze_to(-4)","metadata":{"_uuid":"4fee3be982915812100795b09251910964079a98","execution":{"iopub.status.busy":"2021-08-12T10:46:56.282859Z","iopub.execute_input":"2021-08-12T10:46:56.283151Z","iopub.status.idle":"2021-08-12T10:46:56.332851Z","shell.execute_reply.started":"2021-08-12T10:46:56.283101Z","shell.execute_reply":"2021-08-12T10:46:56.33211Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"m[-1].trainable","metadata":{"_uuid":"066abc53d6ced93228b277563ea763bcffc7637a","execution":{"iopub.status.busy":"2021-08-12T10:47:02.586422Z","iopub.execute_input":"2021-08-12T10:47:02.586695Z","iopub.status.idle":"2021-08-12T10:47:02.637757Z","shell.execute_reply.started":"2021-08-12T10:47:02.586646Z","shell.execute_reply":"2021-08-12T10:47:02.636803Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"m[-4].trainable","metadata":{"_uuid":"7b083e31ab8e25ae49ba1ed7a4bd13f2ceb01c70","execution":{"iopub.status.busy":"2021-08-12T10:47:08.468728Z","iopub.execute_input":"2021-08-12T10:47:08.469012Z","iopub.status.idle":"2021-08-12T10:47:08.51866Z","shell.execute_reply.started":"2021-08-12T10:47:08.468959Z","shell.execute_reply":"2021-08-12T10:47:08.517832Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"learn.fit(0.01, 1)","metadata":{"_uuid":"65e26bad6cf57de132cdf553722bb629f29b89bb","execution":{"iopub.status.busy":"2021-08-12T10:47:12.451131Z","iopub.execute_input":"2021-08-12T10:47:12.451425Z","iopub.status.idle":"2021-08-12T10:50:09.921014Z","shell.execute_reply.started":"2021-08-12T10:47:12.451353Z","shell.execute_reply":"2021-08-12T10:50:09.920182Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"learn.fit(0.01, 1, cycle_len=1)","metadata":{"_uuid":"0a27b67e0a86924f9015ceb6bd41b36fda36bcbf","execution":{"iopub.status.busy":"2021-08-12T11:17:17.562296Z","iopub.execute_input":"2021-08-12T11:17:17.562515Z","iopub.status.idle":"2021-08-12T11:17:17.689897Z","shell.execute_reply.started":"2021-08-12T11:17:17.562468Z","shell.execute_reply":"2021-08-12T11:17:17.688729Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"## Class Activation Maps (CAM)","metadata":{"_uuid":"e38f9c0a0bb03a61564efeb05bdb1373c926a2cb"}},{"cell_type":"code","source":"class SaveFeatures():\n    features=None\n    def __init__(self, m): self.hook = m.register_forward_hook(self.hook_fn)\n    def hook_fn(self, module, input, output): self.features = output\n    def remove(self): self.hook.remove()","metadata":{"_uuid":"9206bc21499d5e4377f837ac7885422f107fe946","trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"x,y = next(iter(data.val_dl))","metadata":{"_uuid":"b1df9f2c0e084141ed920327c0dde6d682896d94","trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"x,y = x[None,1], y[None,1]\nvx = Variable(x.cuda(), requires_grad=True)","metadata":{"_uuid":"97958ce8c998ac39eef73d23f4b99002b977a62c","trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"dx = data.val_ds.denorm(x)[0]\nplt.imshow(dx);","metadata":{"_uuid":"41bfb7d13c04c132b5894ac5ee456671c16bace5","trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"sfs = [SaveFeatures(o) for o in [m[-7], m[-6], m[-5], m[-4]]]","metadata":{"_uuid":"4850479db9102efec638678092b6f583890df2b0","trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"%time py = m(Variable(x.cuda()))","metadata":{"_uuid":"0b19e6d0548feb4a1b4c2a84cf26b7b4d1be161e","trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"for o in sfs: o.remove()","metadata":{"_uuid":"f9fbc8351c0cb19d147a4a0f6c124c132c926a7a","trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"[o.features.size() for o in sfs]","metadata":{"_uuid":"b5be218e068b0c67d0387a71bdb30776ea3be2cf","trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"py = np.exp(to_np(py)[0]); py","metadata":{"_uuid":"112e38b10f97f7e5a1c8f7af5bf2c83c23e867e6","trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"feat = np.maximum(0,to_np(sfs[3].features[0]))\nfeat.shape","metadata":{"_uuid":"fa4717f9f752e381a3d2531d6d53c0dcb5f28d8f","trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"f2=np.dot(np.rollaxis(feat,0,3), py)\nf2-=f2.min()\nf2/=f2.max()\nf2","metadata":{"_uuid":"597d99c9ffb87757bebbcff58fbf414786fda041","trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"plt.imshow(dx)\nplt.imshow(scale_min(f2, dx.shape[0]), alpha=0.5, cmap='hot');","metadata":{"_uuid":"d2f030b906c0df7aaa7a05a5470d000b6073428c","trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"## Model","metadata":{"heading_collapsed":true,"_uuid":"1dae4246659089e592cbaf54a1b3bf713a3e21a5"}},{"cell_type":"code","source":"learn.unfreeze()\nlearn.bn_freeze(True)","metadata":{"hidden":true,"_uuid":"da9f1a0cf45ac298587985443611e40ba2220f67","trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# 12 layer groups call for 12 lrs\nlr=np.array([[1e-6]*4,[1e-4]*4,[1e-2]*4]).flatten()","metadata":{"hidden":true,"_uuid":"64afdce6a2a04fa9ea8ee6a53cf77e9b6dd0be81","trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"learn.fit(lr, 2, cycle_len=1)","metadata":{"hidden":true,"_uuid":"9da31851aa4e209922cdb1a64f45de54e802554a","trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"log_preds,y = learn.TTA()\npreds = np.mean(np.exp(log_preds),0)\naccuracy_np(preds,y)","metadata":{"hidden":true,"_uuid":"7be5b9ddb73ad2951a02a5db2175baf8bf172fda","trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"learn.fit(lr, 2, cycle_len=1)","metadata":{"hidden":true,"_uuid":"09266fc79077dfeee17a8a9c347a1c2dcd72f9ac","trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"log_preds,y = learn.TTA()\npreds = np.mean(np.exp(log_preds),0)\naccuracy_np(preds,y)","metadata":{"hidden":true,"_uuid":"2d945ab8d38682ea50ced36240a7665442e1665e","trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"","metadata":{"hidden":true,"_uuid":"be29ab1a37820f77b1444576a127f14b0cf656f8"},"execution_count":null,"outputs":[]}]}