{"cells":[{"metadata":{"_uuid":"4c0d29a7ea3a3d5fc93fcc1c71da0bb9a636f038"},"cell_type":"markdown","source":"## Dogs v Cats"},{"metadata":{"_uuid":"a5d0a595e160469fa1462fbcabcd9e07e8440b57","trusted":true,"collapsed":true},"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 *","execution_count":null,"outputs":[]},{"metadata":{"_uuid":"60760adc3fed9076804aa12ae27c9b479efcfc8a","trusted":true,"collapsed":true},"cell_type":"code","source":"PATH = \"../input/\"\nTMP_PATH = \"/kaggle/working/tmp/\"\nMODEL_PATH = \"/kaggle/working/models/\"\nsz = 224\narch = resnet34\nbs = 64","execution_count":null,"outputs":[]},{"metadata":{"_uuid":"3ac1577547c4681c1ab48e12a20468b657eeb2cb","trusted":true,"collapsed":true},"cell_type":"code","source":"m = arch(True)","execution_count":null,"outputs":[]},{"metadata":{"_uuid":"8efca7b5c8073e214aa8753bd0ab4be7bca585cf","trusted":true,"collapsed":true},"cell_type":"code","source":"m","execution_count":null,"outputs":[]},{"metadata":{"scrolled":false,"_uuid":"41f9ff4fbbf0e162d0e0d515d750acc5a1b16415","trusted":true,"collapsed":true},"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())","execution_count":null,"outputs":[]},{"metadata":{"trusted":true,"_uuid":"24e585ee0921697ca7895629d19a6f7ae8373d3b","collapsed":true},"cell_type":"code","source":"fnames = np.array([f'train/{f}' for f in sorted(os.listdir(f'{PATH}train'))])\nlabels = np.array([(0 if 'cat' in fname else 1) for fname in fnames])","execution_count":null,"outputs":[]},{"metadata":{"_uuid":"2027cb854d03795c912b0c69606d95f40b6236f7","trusted":true,"collapsed":true},"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=PATH, \n    fnames=fnames, \n    y=labels, \n    classes=['dogs', 'cats'], \n    test_name='test', \n    tfms=tfms,\n    bs=bs\n)","execution_count":null,"outputs":[]},{"metadata":{"_uuid":"64fc5ff0d6341418daa146e1b89b172782f92f89","trusted":true,"collapsed":true},"cell_type":"code","source":"learn = ConvLearner.from_model_data(m, data, tmp_name=TMP_PATH, models_name=MODEL_PATH)","execution_count":null,"outputs":[]},{"metadata":{"collapsed":true,"_uuid":"4fee3be982915812100795b09251910964079a98","trusted":true},"cell_type":"code","source":"learn.freeze_to(-4)","execution_count":null,"outputs":[]},{"metadata":{"_uuid":"066abc53d6ced93228b277563ea763bcffc7637a","trusted":true,"collapsed":true},"cell_type":"code","source":"m[-1].trainable","execution_count":null,"outputs":[]},{"metadata":{"_uuid":"7b083e31ab8e25ae49ba1ed7a4bd13f2ceb01c70","trusted":true,"collapsed":true},"cell_type":"code","source":"m[-4].trainable","execution_count":null,"outputs":[]},{"metadata":{"scrolled":false,"_uuid":"65e26bad6cf57de132cdf553722bb629f29b89bb","trusted":true,"collapsed":true},"cell_type":"code","source":"learn.fit(0.01, 1)","execution_count":null,"outputs":[]},{"metadata":{"scrolled":false,"_uuid":"0a27b67e0a86924f9015ceb6bd41b36fda36bcbf","trusted":true,"collapsed":true},"cell_type":"code","source":"learn.fit(0.01, 1, cycle_len=1)","execution_count":null,"outputs":[]},{"metadata":{"_uuid":"e38f9c0a0bb03a61564efeb05bdb1373c926a2cb"},"cell_type":"markdown","source":"## Class Activation Maps (CAM)"},{"metadata":{"_uuid":"9206bc21499d5e4377f837ac7885422f107fe946","trusted":true,"collapsed":true},"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()","execution_count":null,"outputs":[]},{"metadata":{"_uuid":"b1df9f2c0e084141ed920327c0dde6d682896d94","trusted":true,"collapsed":true},"cell_type":"code","source":"x,y = next(iter(data.val_dl))","execution_count":null,"outputs":[]},{"metadata":{"_uuid":"97958ce8c998ac39eef73d23f4b99002b977a62c","trusted":true,"collapsed":true},"cell_type":"code","source":"x,y = x[None,1], y[None,1]\nvx = Variable(x.cuda(), requires_grad=True)","execution_count":null,"outputs":[]},{"metadata":{"_uuid":"41bfb7d13c04c132b5894ac5ee456671c16bace5","trusted":true,"collapsed":true},"cell_type":"code","source":"dx = data.val_ds.denorm(x)[0]\nplt.imshow(dx);","execution_count":null,"outputs":[]},{"metadata":{"_uuid":"4850479db9102efec638678092b6f583890df2b0","trusted":true,"collapsed":true},"cell_type":"code","source":"sfs = [SaveFeatures(o) for o in [m[-7], m[-6], m[-5], m[-4]]]","execution_count":null,"outputs":[]},{"metadata":{"scrolled":false,"_uuid":"0b19e6d0548feb4a1b4c2a84cf26b7b4d1be161e","trusted":true,"collapsed":true},"cell_type":"code","source":"%time py = m(Variable(x.cuda()))","execution_count":null,"outputs":[]},{"metadata":{"_uuid":"f9fbc8351c0cb19d147a4a0f6c124c132c926a7a","trusted":true,"collapsed":true},"cell_type":"code","source":"for o in sfs: o.remove()","execution_count":null,"outputs":[]},{"metadata":{"_uuid":"b5be218e068b0c67d0387a71bdb30776ea3be2cf","trusted":true,"collapsed":true},"cell_type":"code","source":"[o.features.size() for o in sfs]","execution_count":null,"outputs":[]},{"metadata":{"_uuid":"112e38b10f97f7e5a1c8f7af5bf2c83c23e867e6","trusted":true,"collapsed":true},"cell_type":"code","source":"py = np.exp(to_np(py)[0]); py","execution_count":null,"outputs":[]},{"metadata":{"_uuid":"fa4717f9f752e381a3d2531d6d53c0dcb5f28d8f","trusted":true,"collapsed":true},"cell_type":"code","source":"feat = np.maximum(0,to_np(sfs[3].features[0]))\nfeat.shape","execution_count":null,"outputs":[]},{"metadata":{"_uuid":"597d99c9ffb87757bebbcff58fbf414786fda041","trusted":true,"collapsed":true},"cell_type":"code","source":"f2=np.dot(np.rollaxis(feat,0,3), py)\nf2-=f2.min()\nf2/=f2.max()\nf2","execution_count":null,"outputs":[]},{"metadata":{"_uuid":"d2f030b906c0df7aaa7a05a5470d000b6073428c","trusted":true,"collapsed":true},"cell_type":"code","source":"plt.imshow(dx)\nplt.imshow(scale_min(f2, dx.shape[0]), alpha=0.5, cmap='hot');","execution_count":null,"outputs":[]},{"metadata":{"collapsed":true,"heading_collapsed":true,"_uuid":"1dae4246659089e592cbaf54a1b3bf713a3e21a5"},"cell_type":"markdown","source":"## Model"},{"metadata":{"collapsed":true,"hidden":true,"_uuid":"da9f1a0cf45ac298587985443611e40ba2220f67","trusted":true},"cell_type":"code","source":"learn.unfreeze()\nlearn.bn_freeze(True)","execution_count":null,"outputs":[]},{"metadata":{"collapsed":true,"hidden":true,"_uuid":"64afdce6a2a04fa9ea8ee6a53cf77e9b6dd0be81","trusted":true},"cell_type":"code","source":"# 12 layer groups call for 12 lrs\nlr=np.array([[1e-6]*4,[1e-4]*4,[1e-2]*4]).flatten()","execution_count":null,"outputs":[]},{"metadata":{"hidden":true,"scrolled":false,"_uuid":"9da31851aa4e209922cdb1a64f45de54e802554a","trusted":true,"collapsed":true},"cell_type":"code","source":"learn.fit(lr, 2, cycle_len=1)","execution_count":null,"outputs":[]},{"metadata":{"hidden":true,"_uuid":"7be5b9ddb73ad2951a02a5db2175baf8bf172fda","trusted":true,"collapsed":true},"cell_type":"code","source":"log_preds,y = learn.TTA()\npreds = np.mean(np.exp(log_preds),0)\naccuracy_np(preds,y)","execution_count":null,"outputs":[]},{"metadata":{"hidden":true,"scrolled":false,"_uuid":"09266fc79077dfeee17a8a9c347a1c2dcd72f9ac","trusted":true,"collapsed":true},"cell_type":"code","source":"learn.fit(lr, 2, cycle_len=1)","execution_count":null,"outputs":[]},{"metadata":{"hidden":true,"_uuid":"2d945ab8d38682ea50ced36240a7665442e1665e","trusted":true,"collapsed":true},"cell_type":"code","source":"log_preds,y = learn.TTA()\npreds = np.mean(np.exp(log_preds),0)\naccuracy_np(preds,y)","execution_count":null,"outputs":[]},{"metadata":{"collapsed":true,"hidden":true,"_uuid":"be29ab1a37820f77b1444576a127f14b0cf656f8","trusted":false},"cell_type":"code","source":"","execution_count":null,"outputs":[]}],"metadata":{"kernelspec":{"display_name":"Python 3","language":"python","name":"python3"},"language_info":{"name":"python","version":"3.6.4","mimetype":"text/x-python","codemirror_mode":{"name":"ipython","version":3},"pygments_lexer":"ipython3","nbconvert_exporter":"python","file_extension":".py"},"toc":{"colors":{"hover_highlight":"#DAA520","navigate_num":"#000000","navigate_text":"#333333","running_highlight":"#FF0000","selected_highlight":"#FFD700","sidebar_border":"#EEEEEE","wrapper_background":"#FFFFFF"},"moveMenuLeft":true,"nav_menu":{"height":"286px","width":"252px"},"navigate_menu":true,"number_sections":true,"sideBar":true,"threshold":4,"toc_cell":false,"toc_section_display":"block","toc_window_display":false,"widenNotebook":false}},"nbformat":4,"nbformat_minor":1}