-
Notifications
You must be signed in to change notification settings - Fork 547
Optim-wip: Add model linearization, and expanded weights spatial positions #574
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from 12 commits
6892f3c
336c62f
dba1e48
83bc5b8
94fe929
690fc79
caf0cc7
620f1ee
7515fd2
2e86d98
752186a
4116ecd
f1f73b0
ebaacbd
891fd97
18a9d8c
49bee39
70bd89c
899ee6f
bf5b991
9a59014
790066b
441b751
7212dd8
7071396
c141bd7
4237205
58a8c3b
4d3c686
2570eed
f447533
d472a91
88a88ed
908bec0
075ac59
73175c0
537fe79
0a8b6e2
866faac
ba07685
130513b
fae868b
b9cbf02
4d85d13
83921ed
f45b208
bc7fa97
162e47a
2fc46d0
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1,5 +1,5 @@ | ||
| import math | ||
| from typing import List, Tuple, Union | ||
| from typing import Any, List, Optional, Tuple, Union | ||
|
|
||
| import torch | ||
| import torch.nn as nn | ||
|
|
@@ -70,8 +70,12 @@ class ReluLayer(nn.Module): | |
| Basic Hookable & Replaceable ReLU layer. | ||
| """ | ||
|
|
||
| def __init__(self, inplace: bool = True) -> None: | ||
| super(ReluLayer, self).__init__() | ||
| self.inplace = inplace | ||
|
|
||
| def forward(self, input: torch.Tensor) -> torch.Tensor: | ||
| return F.relu(input, inplace=True) | ||
| return F.relu(input, inplace=self.inplace) | ||
|
|
||
|
|
||
| def replace_layers(model, old_layer=ReluLayer, new_layer=RedirectedReluLayer) -> None: | ||
|
|
@@ -168,3 +172,70 @@ def collect_activations( | |
| catch_activ = ActivationFetcher(model, targets) | ||
| activ_out = catch_activ(model_input) | ||
| return activ_out | ||
|
|
||
|
|
||
| def max2avg_pool2d(model, value: Optional[Any] = float("-inf")) -> None: | ||
ProGamerGov marked this conversation as resolved.
Outdated
Show resolved
Hide resolved
|
||
| """ | ||
| Replace all nonlinear MaxPool2d layers with their linear AvgPool2d equivalents. | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. It looks like here we also do replacement of layers but don't use
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Yeah I had to make a separate function because the
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Okay, I think I've figured out to replace layers while attempting to copy over any parameters that are shared!
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. @NarineK Let me know what you think of the new |
||
| This allows us to ignore nonlinear values when calculating expanded weights. | ||
|
|
||
| Args: | ||
| model (nn.Module): A PyTorch model instance. | ||
| value (Any): Used to return any padding that's meant to be ignored by | ||
| pooling layers back to zero. | ||
| """ | ||
|
|
||
| class AvgPool2dLayer(torch.nn.Module): | ||
| def __init__( | ||
| self, | ||
| kernel_size: Union[int, Tuple[int, ...]] = 2, | ||
| stride: Optional[Union[int, Tuple[int, ...]]] = 2, | ||
| padding: Union[int, Tuple[int, ...]] = 0, | ||
| ceil_mode: bool = False, | ||
| value: Optional[Any] = None, | ||
| ) -> None: | ||
| super().__init__() | ||
| self.avgpool = torch.nn.AvgPool2d( | ||
| kernel_size=kernel_size, | ||
| stride=stride, | ||
| padding=padding, | ||
| ceil_mode=ceil_mode, | ||
| ) | ||
| self.value = value | ||
|
|
||
| def forward(self, x: torch.Tensor) -> torch.Tensor: | ||
| x = self.avgpool(x) | ||
| if self.value is not None: | ||
| x[x == self.value] = 0.0 | ||
| return x | ||
|
|
||
| for name, child in model._modules.items(): | ||
| if isinstance(child, torch.nn.MaxPool2d): | ||
| new_layer = AvgPool2dLayer( | ||
| kernel_size=child.kernel_size, | ||
| stride=child.stride, | ||
| padding=child.padding, | ||
| ceil_mode=child.ceil_mode, | ||
| value=value, | ||
| ) | ||
| setattr(model, name, new_layer) | ||
| elif child is not None: | ||
| max2avg_pool2d(child) | ||
|
|
||
|
|
||
| def ignore_layer(model, layer) -> None: | ||
|
||
| """ | ||
| Replace target layers with layers that do nothing. | ||
| This is useful for removing the nonlinear ReLU | ||
| layers when creating expanded weights. | ||
|
|
||
| Args: | ||
| model (nn.Module): A PyTorch model instance. | ||
| layer (nn.Module): A layer class type. | ||
| """ | ||
|
|
||
| class IgnoreLayer(torch.nn.Module): | ||
| def forward(self, x: torch.Tensor) -> torch.Tensor: | ||
| return x | ||
|
|
||
| replace_layers(model, layer, IgnoreLayer) | ||
Uh oh!
There was an error while loading. Please reload this page.