Skip to content
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

Add --backend and --use-v2 support to detection refs #7732

Merged
merged 7 commits into from
Jul 13, 2023

Conversation

NicolasHug
Copy link
Member

@NicolasHug NicolasHug commented Jul 11, 2023

This probably won't be an easy review as there's a bunch of renaming, sorry.

There are a few things I've intentionally left out of this PR:

  • presets support (those used with --test-only)
  • mask-rcnn support

It's also fairly likely that I broke some stuff in the process or that not everything works 100% correctly straight away. It's very hard to test everything considering we have no unit test, and the cross-product of all combinations is high. It shouldn't be too critical though, as we'll be addressing any outstanding issue in the near future as we run more training jobs.

@@ -30,42 +33,42 @@ def __init__(
backend="pil",
use_v2=False,
):
module = get_module(use_v2)
T = get_module(use_v2)
Copy link
Member Author

Choose a reason for hiding this comment

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

I just did s/module/T/ in the file to make it consistent with the detection one

@@ -293,11 +293,13 @@ def __init__(
target_size: Tuple[int, int],
scale_range: Tuple[float, float] = (0.1, 2.0),
interpolation: InterpolationMode = InterpolationMode.BILINEAR,
antialias=True,
Copy link
Member Author

Choose a reason for hiding this comment

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

Had to add antialias support because it'd be False otherwise by default for tensors. There's no BC requirements so we could just hard-code antialias=True below in the calls to resize() instead of adding a parameter here, but it doesn't change much. LMK what you prefer.

Copy link
Contributor

Choose a reason for hiding this comment

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

IDC. Unless there is some other opinion, let's keep it the way it is.

t.append(transforms)
transforms = T.Compose(t)

dataset = CocoDetection(img_folder, ann_file, transforms=transforms)
Copy link
Member Author

Choose a reason for hiding this comment

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

I wonder if we could get rid of this custom CocoDetection dataset here. Ideally we would always call wrap_dataset_for_transforms_v2 and just "unwrap" the datapoints classes into pure-tensors etc...? But we can't use it without silencing the V2 warning first :/

Not sure what to do to clean that up.

@@ -126,10 +126,6 @@ def _has_valid_annotation(anno):
return True
return False

if not isinstance(dataset, torchvision.datasets.CocoDetection):
Copy link
Member Author

Choose a reason for hiding this comment

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

Instead of removing this (seemingly useless check) I could just add the same workaround as elsewhere i.e. add

of isinstance(
        getattr(dataset, "_dataset", None), torchvision.datasets.CocoDetection
    ):

Copy link
Contributor

Choose a reason for hiding this comment

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

We still have #7239. Maybe we should go at it again?

@@ -97,7 +97,7 @@ def evaluate(model, data_loader, device):
outputs = [{k: v.to(cpu_device) for k, v in t.items()} for t in outputs]
model_time = time.time() - model_time

res = {target["image_id"].item(): output for target, output in zip(targets, outputs)}
res = {target["image_id"]: output for target, output in zip(targets, outputs)}
Copy link
Member Author

Choose a reason for hiding this comment

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

This is for consistency with the V2 wrapper which leaves image_id as an int. In our references we used to manually wrap it into a tensor (why, IDK), and I removed that as well below in coco_utils

@NicolasHug NicolasHug marked this pull request as ready for review July 11, 2023 13:38
Copy link
Contributor

@pmeier pmeier left a comment

Choose a reason for hiding this comment

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

LGTM, thanks Nicolas! I'm ok with not testing it on all configurations right now, but to make sure: you have tested it on least one and it works, correct?

@@ -126,10 +126,6 @@ def _has_valid_annotation(anno):
return True
return False

if not isinstance(dataset, torchvision.datasets.CocoDetection):
Copy link
Contributor

Choose a reason for hiding this comment

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

We still have #7239. Maybe we should go at it again?

@@ -196,12 +192,15 @@ def convert_to_coco_api(ds):


def get_coco_api_from_dataset(dataset):
# FIXME: This is... awful?
Copy link
Contributor

Choose a reason for hiding this comment

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

Yeah. Happy for you to address it here, but not required.

Copy link
Member Author

Choose a reason for hiding this comment

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

I would if I knew what to do lol. (I'm gonna leave this out for now I think)

@@ -26,7 +26,7 @@ def train_one_epoch(model, optimizer, data_loader, device, epoch, print_freq, sc

for images, targets in metric_logger.log_every(data_loader, print_freq, header):
images = list(image.to(device) for image in images)
targets = [{k: v.to(device) for k, v in t.items()} for t in targets]
targets = [{k: v.to(device) if isinstance(v, torch.Tensor) else v for k, v in t.items()} for t in targets]
Copy link
Contributor

Choose a reason for hiding this comment

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

This is for the image ID, right?

Comment on lines +45 to +46
# TODO: FixedSizeCrop below doesn't work on tensors!
reference_transforms.FixedSizeCrop(size=(1024, 1024), fill=mean),
Copy link
Contributor

Choose a reason for hiding this comment

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

In v2 we have RandomCrop that does what FixedSizedCrop does minus the clamping and sanitizing bounding boxes.

if use_v2:
transforms += [
T.ConvertBoundingBoxFormat(datapoints.BoundingBoxFormat.XYXY),
T.SanitizeBoundingBox(),
Copy link
Contributor

Choose a reason for hiding this comment

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

Do we also need ClampBoundingBox here?

Copy link
Member Author

Choose a reason for hiding this comment

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

I don't think so since we established that all transforms should clamp already (those that need to, at least)?

@@ -177,8 +185,8 @@ def main(args):
# Data loading code
print("Loading data")

dataset, num_classes = get_dataset(args.dataset, "train", get_transform(True, args), args.data_path)
dataset_test, _ = get_dataset(args.dataset, "val", get_transform(False, args), args.data_path)
dataset, num_classes = get_dataset(args.dataset, "train", get_transform(True, args), args.data_path, args.use_v2)
Copy link
Contributor

Choose a reason for hiding this comment

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

Not required here, but can we maybe use keyword args here? The call is really hard to parse.

@@ -293,11 +293,13 @@ def __init__(
target_size: Tuple[int, int],
scale_range: Tuple[float, float] = (0.1, 2.0),
interpolation: InterpolationMode = InterpolationMode.BILINEAR,
antialias=True,
Copy link
Contributor

Choose a reason for hiding this comment

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

IDC. Unless there is some other opinion, let's keep it the way it is.

@pmeier
Copy link
Contributor

pmeier commented Jul 13, 2023

Test failures are real. Maybe related to antialias? I'll have a look.

@NicolasHug
Copy link
Member Author

Thanks for the review!

Which failure are relevant? We have no tests for the reference folder and this PR doesn't touch any file outside of it.

@pmeier
Copy link
Contributor

pmeier commented Jul 13, 2023

We have no tests for the reference folder and this PR doesn't touch any file outside of it.

We do. We have v2 consistency tests that checks the transforms that we have added to our package against the stuff that we have in our references:

I've send a fix in 72da655.

@NicolasHug
Copy link
Member Author

but to make sure: you have tested it on least one and it works, correct?

Yeah, I tested it on a few combinations, but I wouldn't be surprised if there's a few edge-cases I missed. We'll find out soon enough. Thanks for the review!

@NicolasHug NicolasHug merged commit bb3aae7 into pytorch:main Jul 13, 2023
40 of 60 checks passed
@github-actions
Copy link

Hey @NicolasHug!

You merged this PR, but no labels were added. The list of valid labels is available at https://github.com/pytorch/vision/blob/main/.github/process_commit.py

@vfdev-5 vfdev-5 mentioned this pull request Aug 22, 2023
facebook-github-bot pushed a commit that referenced this pull request Aug 25, 2023
Summary: Co-authored-by: Philip Meier <github.pmeier@posteo.de>

Reviewed By: matteobettini

Differential Revision: D48642258

fbshipit-source-id: 7d99fb2ea5effde79ee59d259f902fcf145ae64c
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants