Skip to content
This repository has been archived by the owner on Jul 2, 2021. It is now read-only.

FPN - Add min/max size params for pre-processing. #830

Merged
merged 8 commits into from
Mar 12, 2019

Conversation

23pointsNorth
Copy link
Contributor

Allow for the min_size, max_size parameter to be set when creating an FPN network.
It is following the Faster-RCNN template.

@yuyu2172
Copy link
Member

Thanks. Can you set the default values for FasterRCNN so that the tests won't fail?

@@ -26,6 +26,9 @@ class FasterRCNN(chainer.Chain):
head (Link): A link that has the same interface as
:class:`~chainercv.links.model.fpn.Head`.
Please refer to the documentation found there.
min_size (int): A preprocessing paramter for :meth:`prepare`. Please
refer to a docstring found for :meth:`prepare`.
Copy link
Member

Choose a reason for hiding this comment

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

How about this?

Please refer to :meth:`prepare`.

docstring will be confusing when it rendered by sphinx.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

This was done in the same style as the faster-rcnn docs with regards to the param.

Copy link
Member

Choose a reason for hiding this comment

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

I see.

n_fg_class (int): The number of classes excluding the background.
pretrained_model (string): The weight file to be loaded.
n_fg_class (int): The number of classes excluding the background.
pretrained_model (string): The weight file to be loaded.
Copy link
Member

Choose a reason for hiding this comment

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

Why did you change the indentation?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

The rest of the code is indented with 4 space.
These lines were with 3. I am happy to revert if comments don't follow this requirement.

Copy link
Member

Choose a reason for hiding this comment

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

This was my mistake. Thank you for fixing!

n_fg_class (int): The number of classes excluding the background.
pretrained_model (string): The weight file to be loaded.
This can take :obj:`'coco'`, `filepath` or :obj:`None`.
The default value is :obj:`None`.
Copy link
Member

Choose a reason for hiding this comment

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

ditto.

@@ -19,7 +19,8 @@ class FasterRCNNFPNResNet(FasterRCNN):
A subclass of this class should have :obj:`_base` and :obj:`_models`.
"""

def __init__(self, n_fg_class=None, pretrained_model=None):
def __init__(self, n_fg_class=None, pretrained_model=None,
min_size=800, max_size=1333):
Copy link
Member

Choose a reason for hiding this comment

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

min_size and max_size are not used.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

That was a versioning mistake. It will be added on L39.

@Hakuyume
Copy link
Member

Thanks. Can you set the default values for FasterRCNN so that the tests won't fail?

Perhaps, we can modify the tests to pass those parameters explicitly. In that case, we can remove the default value from FasterRCNN.

@Hakuyume
Copy link
Member

@23pointsNorth
Copy link
Contributor Author

23pointsNorth commented Mar 12, 2019

I am not sure how you expect the testing to look like. If we inspect the other place preprare is used, i.e. https://github.com/chainer/chainercv/blob/master/tests/links_tests/model_tests/faster_rcnn_tests/test_faster_rcnn.py#L81 only the input param is checked against.

I can alter the tests to include a value for min/max, such that we can remove the default in the class (but I think it may be unnecessary, Edit based on:

that also has default params in the class)

@Hakuyume
Copy link
Member

I am not sure how you expect the testing to look like. If we inspect the other place preprare is used, i.e. https://github.com/chainer/chainercv/blob/master/tests/links_tests/model_tests/faster_rcnn_tests/test_faster_rcnn.py#L81 only the input param is checked against.

The test in faster_rcnn_tests checks the effect of min_size/max_size because it uses values that are different from the default values ((200, 400) vs (600, 1000)). On the other hand, the test in fpn_tests uses the default value. So the test cannot detect an error even if FasterRCNN ignores those parameters. At least we should use different values for the test. It would be better to check both default params and other params (with testing.parameterize).

I can alter the tests to include a value for min/max, such that we can remove the default in the class (but I think it may be unnecessary, Edit based on:

I'm sorry for my confusing comment. It is OK to keep the default values. I just mentioned the side-effect.

@23pointsNorth
Copy link
Contributor Author

@Hakuyume I attempted to add extra tests. I changed them to follow the ones in test_faster_rcnn in regards to in_shape, expected_shape.

The paramterize tag becomes a bit clunky, because in our tests we want to make the permutations of 3*n_fg_class, 2*(min_size, max_size, in_shape, expected shape). I don't know if I can give 2 dict and the testing can do the permutations of them.

{'n_fg_class': 20},
{'n_fg_class': 1, 'min_size': 200, 'max_size': 400,
'in_shape': (3, 200, 50), 'expected_shape': (3, 400, 100)},
{'n_fg_class': 1, 'min_size': 800, 'max_size': 133,
Copy link
Member

Choose a reason for hiding this comment

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

133 is typo of 1333?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Yes, a typo.

self.assertEqual(out.shape, self.expected_shape)

def test_prepare_cpu(self):
self.check_prepare()
Copy link
Member

Choose a reason for hiding this comment

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

We do not need to make _cpu/_gpu because prepare is not related cupy.

@Hakuyume
Copy link
Member

You can use testing.product_dict.

@testing.parameterize(*testing.product_dict(
    [
        {'n_fg_class': 1},
        {'n_fg_class': 5},
        {'n_fg_class': 20},
    ],
    [
        {
            'in_shape': (3, 480, 640),
            'min_size': 800, 'max_size': 1333,
            'expected_shape': (3, 800, 1088),
        },
        {
            'in_shape': (3, 200, 50),
            'min_size': 200, 'max_size': 400,
            'expected_shape': (3, 400, 100),
        },
    ],
))
class TestFasterRCNN(unittest.TestCase):

{'n_fg_class': 1, 'min_size': 200, 'max_size': 400,
'in_shape': (3, 200, 50), 'expected_shape': (3, 400, 100)},
{'n_fg_class': 1, 'min_size': 800, 'max_size': 133,
'in_shape': (3, 480, 640), 'expected_shape': (3, 800, 1088)},
Copy link
Member

Choose a reason for hiding this comment

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

prepare can accept a batch of images of different shapes.
How about 'in_sizes': [(480, 640), (320, 320)], 'expected_size': (800, 1088) ? (I omit 3 because it is not parameterized)

@23pointsNorth
Copy link
Contributor Author

23pointsNorth commented Mar 12, 2019

I think I've incorporated all of the requests. A general unexpected behaviour I found based on the tests i.e.
https://travis-ci.org/chainer/chainercv/jobs/505234966#L847
If the max_size is the parameter based on which the size is calculated, and if it is not divisible by stride, based on line
https://github.com/chainer/chainercv/blob/master/chainercv/links/model/fpn/faster_rcnn.py#L165
we'll get a resulting image size that is larger than max_size (i.e. max_size of 400 -> final image size 416).

This I think is ok in general, but should be documented somewhere.

@Hakuyume
Copy link
Member

If the max_size is the parameter based on which the size is calculated, and if it is not divisible by stride, based on line
https://github.com/chainer/chainercv/blob/master/chainercv/links/model/fpn/faster_rcnn.py#L165
we'll get a resulting image size that is larger than max_size (i.e. max_size of 400 -> final image size 416).

Actually, this is an expected behavior (same as the Detecton's implementation).
But I agree with you that it is confusing because the output can exceed max_size.

This I think is ok in general, but should be documented somewhere.

How about adding a note here?

max_size (int): A preprocessing paramter for :meth:`prepare`.

For example,

max_size (int): A preprocessing paramter for :meth:`prepare`. 
        Note that the result of :meth:`prepare` can exceed this size
        because of alignment.

Copy link
Member

@Hakuyume Hakuyume left a comment

Choose a reason for hiding this comment

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

LGTM. Thank you!

@Hakuyume Hakuyume merged commit 975964d into chainer:master Mar 12, 2019
@knorth55 knorth55 added this to the 0.13 milestone May 14, 2019
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants