Skip to content

Genet from timm #344

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

Merged
merged 8 commits into from
Jul 4, 2021
Merged

Genet from timm #344

merged 8 commits into from
Jul 4, 2021

Conversation

Vozf
Copy link
Contributor

@Vozf Vozf commented Feb 11, 2021

Some concerns listed in code comments.
I didn't test it on the real world task
Tests pass and weights are loading

requirements.txt Outdated
@@ -1,4 +1,4 @@
torchvision>=0.3.0
pretrainedmodels==0.7.4
efficientnet-pytorch==0.6.3
timm==0.3.2
git+https://github.com/rwightman/pytorch-image-models@d8e69206be253892b2956341fea09fdebfaae4e3
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

No release is out with genet yet, so we'll have to wait until release

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pip does not support such requirements
Possible solution: in encoders/init.py use try: except while loading this encoder with suggestion to install latest source timm (before timm new release)

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pip supports such requirement and pip install -r requirements.txt works fine. It is still a temporary solution as timm releases often and in my opinion it's easier to wait.

import torch.nn as nn


class GERNetEncoder(ByobNet, EncoderMixin):
Copy link
Contributor Author

@Vozf Vozf Feb 11, 2021

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This inherits from byobnet same as new repvgg so we should consider adding generic ByoBnetEncoder to comply with future timm changes https://github.com/rwightman/pytorch-image-models/blob/d8e69206be253892b2956341fea09fdebfaae4e3/timm/models/byobnet.py#L645



class GERNetEncoder(ByobNet, EncoderMixin):
def __init__(self, out_channels, depth=6, **kwargs):
Copy link
Contributor Author

@Vozf Vozf Feb 11, 2021

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

For genet I've found 6(+rgb=7) stages and most others encoders have 5, maybe I've misunderstood the concept or we should join some stages.

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

each stage should reduce spatial resolution, you may combine several stages in one

Copy link
Contributor Author

@Vozf Vozf Feb 11, 2021

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Which stages should we combine if the constant resolution stages are different for each version?
(3, 13, 48, 48, 384, 560, 1920) - s
(3, 32, 128, 192, 640, 640, 2560) - m, l
Combining different stages for different versions seems odd

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this is channels resolution, not spatial
try to print tensor shapes afrer each stage

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

suppose you have image 224 224 3
stem 112 112 13
stage_1 64 64 48
stage_2 32 32 48
stage_3 32 32 386
etc...

so, you should combine stage_2 and stage_3

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

s - [torch.Size([1, 3, 64, 64]), torch.Size([1, 13, 32, 32]), torch.Size([1, 48, 16, 16]), torch.Size([1, 48, 8, 8]), torch.Size([1, 384, 4, 4]), torch.Size([1, 560, 2, 2]), torch.Size([1, 1920, 2, 2])]
m, l - [torch.Size([1, 3, 64, 64]), torch.Size([1, 32, 32, 32]), torch.Size([1, 128, 16, 16]), torch.Size([1, 192, 8, 8]), torch.Size([1, 640, 4, 4]), torch.Size([1, 640, 2, 2]), torch.Size([1, 2560, 2, 2])]

Last 2 should be joined as I understood?

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, and out_channels should be modified:
(3, 13, 48, 48, 384, 560, 1920) ->
(3, 13, 48, 48, 384, 1920)

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

And depth to 5

@Vozf
Copy link
Contributor Author

Vozf commented Feb 11, 2021

Something wrong with cloud CI, I've checked tests locally, they pass
But if I set DEFAULT_ENCODER = "timm-gernet_s" 2 MANet tests fail
image
Here is the log for the failing test, 2nd one has the same
Not really sure what's going on there but it seems that Manet conv2d has 0 passed as parameter as result of skip_channels(13) // reduction(16) = 0

FAILED                            [ 71%]
tests/test_models.py:85 (test_aux_output[MAnet])
model_class = <class 'segmentation_models_pytorch.manet.model.MAnet'>

    @pytest.mark.parametrize("model_class", [smp.PAN, smp.FPN, smp.PSPNet, smp.Linknet, smp.Unet, smp.UnetPlusPlus, smp.MAnet])
    def test_aux_output(model_class):
        model = model_class(
>           DEFAULT_ENCODER, encoder_weights=None, aux_params=dict(classes=2)
        )

test_models.py:89: 
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 
../segmentation_models_pytorch/manet/model.py:78: in __init__
    pab_channels=decoder_pab_channels
../segmentation_models_pytorch/manet/decoder.py:170: in __init__
    for in_ch, skip_ch, out_ch in zip(in_channels, skip_channels, out_channels)
../segmentation_models_pytorch/manet/decoder.py:170: in <listcomp>
    for in_ch, skip_ch, out_ch in zip(in_channels, skip_channels, out_channels)
../segmentation_models_pytorch/manet/decoder.py:61: in __init__
    nn.Conv2d(skip_channels, skip_channels // reduction, 1),
../../../anaconda3/envs/rnd/lib/python3.6/site-packages/torch/nn/modules/conv.py:412: in __init__
    False, _pair(0), groups, bias, padding_mode)
../../../anaconda3/envs/rnd/lib/python3.6/site-packages/torch/nn/modules/conv.py:83: in __init__
    self.reset_parameters()
../../../anaconda3/envs/rnd/lib/python3.6/site-packages/torch/nn/modules/conv.py:86: in reset_parameters
    init.kaiming_uniform_(self.weight, a=math.sqrt(5))
../../../anaconda3/envs/rnd/lib/python3.6/site-packages/torch/nn/init.py:379: in kaiming_uniform_
    fan = _calculate_correct_fan(tensor, mode)
../../../anaconda3/envs/rnd/lib/python3.6/site-packages/torch/nn/init.py:348: in _calculate_correct_fan
    fan_in, fan_out = _calculate_fan_in_and_fan_out(tensor)
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 

tensor = Parameter containing:
tensor([], size=(0, 13, 1, 1), requires_grad=True)

    def _calculate_fan_in_and_fan_out(tensor):
        dimensions = tensor.dim()
        if dimensions < 2:
            raise ValueError("Fan in and fan out can not be computed for tensor with fewer than 2 dimensions")
    
        num_input_fmaps = tensor.size(1)
        num_output_fmaps = tensor.size(0)
        receptive_field_size = 1
        if tensor.dim() > 2:
>           receptive_field_size = tensor[0][0].numel()
E           IndexError: index 0 is out of bounds for dimension 0 with size 0

../../../anaconda3/envs/rnd/lib/python3.6/site-packages/torch/nn/init.py:280: IndexError

for source_name, source_url in sources.items():
pretrained_settings[model_name][source_name] = {
"url": source_url,
'input_size': [3, 224, 224] if not model_name == 'timm-gernet_l' else [3, 256, 256],
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Not sure that such if else inside builder is appropriate, but it seems better than 3 separate large configs

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

input_size is not necessery kwarg, you may remove it

@@ -16,6 +16,7 @@
from .timm_res2net import timm_res2net_encoders
from .timm_regnet import timm_regnet_encoders
from .timm_sknet import timm_sknet_encoders
from .timm_gernet import timm_gernet_encoders
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

try:
    from .timm_gernet import timm_gernet_encoders
except <Exception> as e:
    timm_gernet_encoders = {}
    <warning>

@qubvel
Copy link
Collaborator

qubvel commented Feb 11, 2021

Thanks for PR, I have left some comments about what needs to be corrected.

And also, please, add information about Encoder in following places:

  • README.md modify number of encoder in start description
  • README.md add encoder names to table
  • Add information about encoders to docs/encoders.rst

You can use misc/generate_table.py script to get number of params for encoders.

@Vozf
Copy link
Contributor Author

Vozf commented Feb 11, 2021

Still got 2 questions regarding the Manet failing test and stage combining.

@Vozf
Copy link
Contributor Author

Vozf commented Feb 11, 2021

Updated all the points. The only thing left is that manet test

@qubvel
Copy link
Collaborator

qubvel commented Feb 11, 2021

Could you patch MAnet decoder as follows and run tests:
starting from line 61:

        reduced_channels = max(1, skip_channels // reduction)
        self.SE_ll = nn.Sequential(
            nn.AdaptiveAvgPool2d(1),
            nn.Conv2d(skip_channels, reduced_channels, 1),
            nn.ReLU(inplace=True),
            nn.Conv2d(reduced_channels, skip_channels, 1),
            nn.Sigmoid(),
        )
        self.SE_hl = nn.Sequential(
            nn.AdaptiveAvgPool2d(1),
            nn.Conv2d(skip_channels, reduced_channels, 1),
            nn.ReLU(inplace=True),
            nn.Conv2d(reduced_channels, skip_channels, 1),
            nn.Sigmoid(),
        )

P.S. The problem is in stem, it has just 13 channels, and reducing it by 16 lead to 0 channels, which raises error.

@qubvel
Copy link
Collaborator

qubvel commented Feb 11, 2021

And please add here (after that line):
https://github.com/qubvel/segmentation_models.pytorch/blob/b07695f0e2da4626a0f69cc7672067b1c2530a6c/.github/workflows/tests.yml#L31

pip install -U git+https://github.com/rwightman/pytorch-image-models

to run tests with new encoder in CI

@Vozf
Copy link
Contributor Author

Vozf commented Feb 11, 2021

All passing now

@Vozf
Copy link
Contributor Author

Vozf commented Feb 12, 2021

Set training genet_s model for the night, and its val metrics are noticeably worse than efficientnet-b0(not from timm, I've faced some similar val metric issues with timm previously)
No clue why is this happening and how much expected is such behavior
image

@qubvel
Copy link
Collaborator

qubvel commented Feb 15, 2021

I will try to test it on some of my tasks, and then merge

@Vozf
Copy link
Contributor Author

Vozf commented Mar 17, 2021

timm is released

@qubvel qubvel merged commit 23a54b4 into qubvel-org:master Jul 4, 2021
@Vozf
Copy link
Contributor Author

Vozf commented Jul 4, 2021

pip install ... should probably be removed from tests as timm is already released

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants