From e0ceb9456e9a1176d31504b9526be5e10473e3ce Mon Sep 17 00:00:00 2001 From: Francisco Massa Date: Fri, 26 Oct 2018 08:55:09 +0200 Subject: [PATCH] Add support for Python 2 (#11) * Add missing __init__.py files * Add packages * Rename logging.py to logger.py Import rules from Python2 makes this a bad idea * Make import_file py2 compatible * list does not have .copy() in py2 * math.log2 does not exist in py2 * Miscellaneous fixes for py2 * Address comments --- .gitignore | 2 +- maskrcnn_benchmark/__init__.py | 1 + maskrcnn_benchmark/data/build.py | 4 ++- maskrcnn_benchmark/engine/__init__.py | 1 + maskrcnn_benchmark/modeling/poolers.py | 7 ++-- maskrcnn_benchmark/structures/image_list.py | 2 ++ maskrcnn_benchmark/utils/c2_model_loading.py | 5 ++- maskrcnn_benchmark/utils/imports.py | 35 ++++++++++++------- .../utils/{logging.py => logger.py} | 0 setup.py | 2 +- tools/test_net.py | 2 +- tools/train_net.py | 2 +- 12 files changed, 40 insertions(+), 23 deletions(-) create mode 100644 maskrcnn_benchmark/__init__.py create mode 100644 maskrcnn_benchmark/engine/__init__.py rename maskrcnn_benchmark/utils/{logging.py => logger.py} (100%) diff --git a/.gitignore b/.gitignore index 47c883260..223e87a19 100644 --- a/.gitignore +++ b/.gitignore @@ -3,7 +3,7 @@ __pycache__ _ext *.pyc *.so -maskrcnn-benchmark.egg-info/ +maskrcnn_benchmark.egg-info/ build/ dist/ diff --git a/maskrcnn_benchmark/__init__.py b/maskrcnn_benchmark/__init__.py new file mode 100644 index 000000000..5c7f19c6c --- /dev/null +++ b/maskrcnn_benchmark/__init__.py @@ -0,0 +1 @@ +# Copyright (c) Facebook, Inc. and its affiliates. All Rights Reserved. diff --git a/maskrcnn_benchmark/data/build.py b/maskrcnn_benchmark/data/build.py index 86d3829e2..b1cfcc05f 100644 --- a/maskrcnn_benchmark/data/build.py +++ b/maskrcnn_benchmark/data/build.py @@ -1,5 +1,6 @@ # Copyright (c) Facebook, Inc. and its affiliates. All Rights Reserved. import bisect +import copy import logging import torch.utils.data @@ -63,7 +64,8 @@ def make_data_sampler(dataset, shuffle, distributed): def _quantize(x, bins): - bins = sorted(bins.copy()) + bins = copy.copy(bins) + bins = sorted(bins) quantized = list(map(lambda y: bisect.bisect_right(bins, y), x)) return quantized diff --git a/maskrcnn_benchmark/engine/__init__.py b/maskrcnn_benchmark/engine/__init__.py new file mode 100644 index 000000000..5c7f19c6c --- /dev/null +++ b/maskrcnn_benchmark/engine/__init__.py @@ -0,0 +1 @@ +# Copyright (c) Facebook, Inc. and its affiliates. All Rights Reserved. diff --git a/maskrcnn_benchmark/modeling/poolers.py b/maskrcnn_benchmark/modeling/poolers.py index 0c3fb086b..bf0f4b8a6 100644 --- a/maskrcnn_benchmark/modeling/poolers.py +++ b/maskrcnn_benchmark/modeling/poolers.py @@ -1,5 +1,4 @@ # Copyright (c) Facebook, Inc. and its affiliates. All Rights Reserved. -import math import torch import torch.nn.functional as F from torch import nn @@ -57,7 +56,7 @@ def __init__(self, output_size, scales, sampling_ratio): """ Arguments: output_size (list[tuple[int]] or list[int]): output size for the pooled region - scales (list[flaot]): scales for each Pooler + scales (list[float]): scales for each Pooler sampling_ratio (int): sampling ratio for ROIAlign """ super(Pooler, self).__init__() @@ -72,8 +71,8 @@ def __init__(self, output_size, scales, sampling_ratio): self.output_size = output_size # get the levels in the feature map by leveraging the fact that the network always # downsamples by a factor of 2 at each level. - lvl_min = -math.log2(scales[0]) - lvl_max = -math.log2(scales[-1]) + lvl_min = -torch.log2(torch.tensor(scales[0], dtype=torch.float32)).item() + lvl_max = -torch.log2(torch.tensor(scales[-1], dtype=torch.float32)).item() self.map_levels = LevelMapper(lvl_min, lvl_max) def convert_to_roi_format(self, boxes): diff --git a/maskrcnn_benchmark/structures/image_list.py b/maskrcnn_benchmark/structures/image_list.py index c45c1f039..9a70418fb 100644 --- a/maskrcnn_benchmark/structures/image_list.py +++ b/maskrcnn_benchmark/structures/image_list.py @@ -1,4 +1,6 @@ # Copyright (c) Facebook, Inc. and its affiliates. All Rights Reserved. +from __future__ import division + import torch diff --git a/maskrcnn_benchmark/utils/c2_model_loading.py b/maskrcnn_benchmark/utils/c2_model_loading.py index 3057a04fb..df3711be0 100644 --- a/maskrcnn_benchmark/utils/c2_model_loading.py +++ b/maskrcnn_benchmark/utils/c2_model_loading.py @@ -119,7 +119,10 @@ def _rename_weights_for_resnet(weights, stage_names): def _load_c2_pickled_weights(file_path): with open(file_path, "rb") as f: - data = pickle.load(f, encoding="latin1") + if torch._six.PY3: + data = pickle.load(f, encoding="latin1") + else: + data = pickle.load(f) if "blobs" in data: weights = data["blobs"] else: diff --git a/maskrcnn_benchmark/utils/imports.py b/maskrcnn_benchmark/utils/imports.py index 4b3cfa661..53e27e2bc 100644 --- a/maskrcnn_benchmark/utils/imports.py +++ b/maskrcnn_benchmark/utils/imports.py @@ -1,14 +1,23 @@ # Copyright (c) Facebook, Inc. and its affiliates. All Rights Reserved. -import importlib -import importlib.util -import sys - - -# from https://stackoverflow.com/questions/67631/how-to-import-a-module-given-the-full-path?utm_medium=organic&utm_source=google_rich_qa&utm_campaign=google_rich_qa -def import_file(module_name, file_path, make_importable=False): - spec = importlib.util.spec_from_file_location(module_name, file_path) - module = importlib.util.module_from_spec(spec) - spec.loader.exec_module(module) - if make_importable: - sys.modules[module_name] = module - return module +import torch + +if torch._six.PY3: + import importlib + import importlib.util + import sys + + + # from https://stackoverflow.com/questions/67631/how-to-import-a-module-given-the-full-path?utm_medium=organic&utm_source=google_rich_qa&utm_campaign=google_rich_qa + def import_file(module_name, file_path, make_importable=False): + spec = importlib.util.spec_from_file_location(module_name, file_path) + module = importlib.util.module_from_spec(spec) + spec.loader.exec_module(module) + if make_importable: + sys.modules[module_name] = module + return module +else: + import imp + + def import_file(module_name, file_path, make_importable=None): + module = imp.load_source(module_name, file_path) + return module diff --git a/maskrcnn_benchmark/utils/logging.py b/maskrcnn_benchmark/utils/logger.py similarity index 100% rename from maskrcnn_benchmark/utils/logging.py rename to maskrcnn_benchmark/utils/logger.py diff --git a/setup.py b/setup.py index c0216cdc6..3503372cf 100644 --- a/setup.py +++ b/setup.py @@ -62,7 +62,7 @@ def get_extensions(): author="fmassa", url="https://github.com/facebookresearch/maskrnn-benchmark", description="object detection in pytorch", - # packages=find_packages(exclude=("configs", "examples", "test",)), + packages=find_packages(exclude=("configs", "tests",)), # install_requires=requirements, ext_modules=get_extensions(), cmdclass={"build_ext": torch.utils.cpp_extension.BuildExtension}, diff --git a/tools/test_net.py b/tools/test_net.py index 1a6f61e58..bf01a739b 100644 --- a/tools/test_net.py +++ b/tools/test_net.py @@ -14,7 +14,7 @@ from maskrcnn_benchmark.utils.checkpoint import DetectronCheckpointer from maskrcnn_benchmark.utils.collect_env import collect_env_info from maskrcnn_benchmark.utils.comm import synchronize -from maskrcnn_benchmark.utils.logging import setup_logger +from maskrcnn_benchmark.utils.logger import setup_logger from maskrcnn_benchmark.utils.miscellaneous import mkdir diff --git a/tools/train_net.py b/tools/train_net.py index 1c0025f82..3cce63915 100644 --- a/tools/train_net.py +++ b/tools/train_net.py @@ -22,7 +22,7 @@ from maskrcnn_benchmark.utils.collect_env import collect_env_info from maskrcnn_benchmark.utils.comm import synchronize from maskrcnn_benchmark.utils.imports import import_file -from maskrcnn_benchmark.utils.logging import setup_logger +from maskrcnn_benchmark.utils.logger import setup_logger from maskrcnn_benchmark.utils.miscellaneous import mkdir