Last active
July 13, 2019 07:58
-
-
Save gautham20/e62b7295a27738b4f72bf3ce53284093 to your computer and use it in GitHub Desktop.
Using hooks in pytorch
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| class Hook(): | |
| def __init__(self, m:nn.Module, hook_func:HookFunc, is_forward:bool=True, detach:bool=True): | |
| self.hook_func,self.detach,self.stored = hook_func,detach,None | |
| f = m.register_forward_hook if is_forward else m.register_backward_hook | |
| self.hook = f(self.hook_fn) | |
| self.removed = False | |
| def hook_fn(self, module:nn.Module, input:Tensors, output:Tensors): | |
| if self.detach: | |
| input = (o.detach() for o in input ) if is_listy(input ) else input.detach() | |
| output = (o.detach() for o in output) if is_listy(output) else output.detach() | |
| self.stored = self.hook_func(module, input, output) | |
| def remove(self): | |
| if not self.removed: | |
| self.hook.remove() | |
| self.removed=True | |
| def __enter__(self, *args): return self | |
| def __exit__(self, *args): self.remove() | |
| def get_output(module, input_value, output): | |
| return output.flatten(1) | |
| def get_input(module, input_value, output): | |
| return list(input_value)[0] | |
| def get_named_module_from_model(model, name): | |
| for n, m in model.named_modules(): | |
| if n == name: | |
| return m | |
| return None | |
| linear_output_layer = get_named_module_from_model(model, '1.4') | |
| # getting all images in train | |
| train_valid_images_df = data_df[data_df['dataset'] != 'test'] | |
| inference_data_source = (ImageList.from_df(df=train_valid_images_df, path=images_path, cols='images') | |
| .split_none() | |
| .label_from_df(cols='category') | |
| ) | |
| inference_data = inference_data_source.transform(tmfs, size=224).databunch(bs=64).normalize(imagenet_stats) | |
| # turning off shuffle | |
| inference_dataloader = inference_data.train_dl.new(shuffle=False) | |
| import time | |
| img_repr_map = {} | |
| with Hook(linear_output_layer, get_output, True, True) as hook: | |
| start = time.time() | |
| for i, (xb, yb) in enumerate(inference_dataloader): | |
| bs = xb.shape[0] | |
| img_ids = inference_dataloader.items[i*bs: (i+1)*bs] | |
| result = model.eval()(xb) | |
| img_reprs = hook.stored.cpu().numpy() | |
| img_reprs = img_reprs.reshape(bs, -1) | |
| for img_id, img_repr in zip(img_ids, img_reprs): | |
| img_repr_map[img_id] = img_repr | |
| if(len(img_repr_map) % 12800 == 0): | |
| end = time.time() | |
| print(f'{end-start} secs for 12800 images') | |
| start = end | |
| img_repr_df = pd.DataFrame(img_repr_map.items(), columns=['img_id', 'img_repr']) | |
| img_repr_df['label'] = [inference_data.classes[x] for x in inference_data.train_ds.y.items[0:img_repr_df.shape[0]]] |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment