Skip to content

Commit bb947de

Browse files
author
Tete Xiao
authored
Merge pull request #9 from CSAILVision/pytorch1.0
PyTorch1.0
2 parents 7dc43e0 + ac5f459 commit bb947de

40 files changed

+32140
-444
lines changed

README.md

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -22,10 +22,12 @@ The human visual system is able to extract a remarkable amount of semantic infor
2222

2323
- Dynamic scales of input for training with multiple GPUs.
2424

25+
- Support state-of-the-art PyTorch 1.0
26+
2527
## Environment
2628
The code is developed under the following configurations.
2729
- Hardware: 2-8 GPUs (with at least 12G GPU memories) (change ```[--num_gpus NUM_GPUS]``` accordingly)
28-
- Software: Ubuntu 16.04.3 LTS, CUDA>=8.0, ***Python>=3.5***, ***PyTorch>=0.4.0***
30+
- Software: Ubuntu 16.04.3 LTS, CUDA>=8.0, ***Python>=3.5***, ***PyTorch>=0.4.0 (PyTorch 1.0 supported)***
2931
- Library: opencv, scipy, colormath, tqdm, PyTorch compiled with cffi
3032

3133
*Warning:* We don't support the outdated Python 2 anymore. PyTorch 0.4.0 or higher is required to run the code.
@@ -40,7 +42,7 @@ We have released the UPerNet with state-of-the-art performance proposed in our p
4042

4143
You can use our pretrained models in PyTorch to segment input image. The usage is as follows:
4244

43-
1. Compile Precise RoI Pooling operator. It requires PyTorch>=0.4 (compiled with ```cffi```) and only supports CUDA (CPU mode is not implemented). To compile the essential components:
45+
1. If you're using PyTorch>=1.0 and on branch master or PyTorch 1.0, skip this step. If you're using 0.4<=PyTorch<1.0, please compile Precise RoI Pooling operator first. (**Please check out to pytorch0.4 branch!!!**) It requires PyTorch compiled with ```cffi``` and only supports CUDA (CPU mode is not implemented). To compile the essential components:
4446

4547
```bash
4648
cd lib/nn/prroi_pool

broden_dataset_utils/adeseg.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -27,13 +27,13 @@ def __init__(self, directory, version):
2727
version = ''
2828
self.root = directory
2929
self.version = version
30-
mat = loadmat(self.expand(self.version, 'index*.mat'), squeeze_me=True)
30+
mat = loadmat(os.path.join('./meta_file/ade20k', 'index_ade20k.mat'), squeeze_me=True)
3131
index = mat['index']
3232
Ade20kIndex = namedtuple('Ade20kIndex', index.dtype.names)
3333
self.index = Ade20kIndex(
3434
**{name: index[name][()] for name in index.dtype.names})
3535
# Here we use adechallenger scene label instead of ade20k.
36-
with open("./meta_file/scene_categories.txt", 'r') as f:
36+
with open("./meta_file/ade20k/scene_categories.txt", 'r') as f:
3737
lines = f.readlines()
3838
self.index_scene_adecha = []
3939
for i, l in enumerate(lines):

broden_dataset_utils/dtdseg.py

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -11,8 +11,7 @@ class DtdSegmentation(AbstractSegmentation):
1111
def __init__(self, directory):
1212
directory = os.path.expanduser(directory)
1313
self.directory = directory
14-
with open(os.path.join(directory, 'labels',
15-
'labels_joint_anno.txt')) as f:
14+
with open(os.path.join('./meta_file/dtd/', 'labels_joint_anno.txt')) as f:
1615
self.dtd_meta = [line.split(None, 1) for line in f.readlines()]
1716
# do not include '-' in texture names. No unlabeled sample in data.
1817
self.textures = sorted(list(set(sum(

broden_dataset_utils/joint_dataset.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -46,7 +46,7 @@ def __init__(self):
4646
self.data_sets = OrderedDict(ade20k=ade, pascal=pascal, os=opensurface)
4747

4848
""" use multi source dataset """
49-
self.broden_dataset_info = "./meta_file"
49+
self.broden_dataset_info = "./meta_file/joint_dataset"
5050
self.record_list = {"train": [], "validation": []}
5151
self.record_list['train'].append(get_records(
5252
os.path.join(self.broden_dataset_info, "broden_ade20k_pascal_train.json")))

broden_dataset_utils/osseg.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -14,15 +14,15 @@ def __init__(self, directory):
1414
self.directory = directory
1515
# Process material labels: open label-substance-colors.csv
1616
subst_name_map = {}
17-
with open(os.path.join(directory, 'label-substance-colors.csv')) as f:
17+
with open(os.path.join('./meta_file/opensurfaces', 'label-substance-colors.csv')) as f:
1818
for row in DictReader(f):
1919
subst_name_map[row['substance_name']] = int(row['red_color'])
2020
# NOTE: substance names should be normalized.
2121
self.substance_names = ['-'] * (1 + max(subst_name_map.values()))
2222
for k, v in list(subst_name_map.items()):
2323
self.substance_names[v] = k
2424
# Now load the metadata about images from photos.csv
25-
with open(os.path.join(directory, 'photos.csv')) as f:
25+
with open(os.path.join('./meta_file/opensurfaces/', 'photos.csv')) as f:
2626
self.image_meta = list(DictReader(f))
2727
scenes = set(row['scene_category_name'] for row in self.image_meta)
2828

broden_dataset_utils/pascalseg.py

Lines changed: 12 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11

22
import os
33
import re
4+
import warnings
45

56
import numpy
67
from scipy.io import loadmat
@@ -13,7 +14,7 @@ class PascalSegmentation(AbstractSegmentation):
1314
Implements AbstractSegmentation for the pascal PARTS dataset.
1415
"""
1516

16-
def __init__(self, directory, collapse_adjectives=None, version=None):
17+
def __init__(self, directory, collapse_adjectives=None, version='VOC2010'):
1718
directory = os.path.expanduser(directory)
1819
# Default to the latest version present in the directory
1920
if version is None:
@@ -35,19 +36,24 @@ def __init__(self, directory, collapse_adjectives=None, version=None):
3536
self.collapse_adjectives = collapse_adjectives
3637
# Load the parts coding metadata from part2ind.m
3738
codes = load_part2ind(
38-
os.path.join(directory, self.partdir, 'part2ind.m'))
39+
os.path.join('./meta_file/pascal/', 'part2ind.m'))
3940
# Normalized names
4041
self.codes = normalize_all_readable(codes, collapse_adjectives)
4142
self.part_object_names, self.part_names, self.part_key = normalize_part_key(self.codes)
4243
# Load the PASCAL context segmentation labels
4344
self.object_names = load_context_labels(
44-
os.path.join(directory, self.contextdir, 'labels.txt'))
45+
os.path.join('./meta_file/pascal/', 'context_labels.txt'))
4546
self.unknown_label = self.object_names.index('unknown')
4647
self.object_names[self.unknown_label] = '-' # normalize unknown
4748
# Assume every mat file in the relevant directory is a segmentation.
48-
self.segs = sorted([n for n in os.listdir(
49-
os.path.join(directory, self.partdir, 'Annotations_Part'))
50-
if n.endswith('.mat')])
49+
try:
50+
self.segs = sorted([n for n in os.listdir(
51+
os.path.join(directory, self.partdir, 'Annotations_Part'))
52+
if n.endswith('.mat')])
53+
except OSError:
54+
message = 'Error when searching for pascal part annotations, please check your dataset.' \
55+
+ ' With this error you may only use testing scripts. Training will fail unless you resolve this warning.'
56+
warnings.warn(message)
5157

5258
def all_names(self, category, j):
5359
if category == 'object':

lib/nn/prroi_pool/.gitignore

Lines changed: 106 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,106 @@
1-
*.o
2-
/_prroi_pooling
1+
# Byte-compiled / optimized / DLL files
2+
__pycache__/
3+
*.py[cod]
4+
*$py.class
5+
6+
.vim-template*
7+
8+
# C extensions
9+
*.so
10+
11+
# Distribution / packaging
12+
.Python
13+
build/
14+
develop-eggs/
15+
dist/
16+
downloads/
17+
eggs/
18+
.eggs/
19+
lib/
20+
lib64/
21+
parts/
22+
sdist/
23+
var/
24+
wheels/
25+
*.egg-info/
26+
.installed.cfg
27+
*.egg
28+
MANIFEST
29+
30+
# PyInstaller
31+
# Usually these files are written by a python script from a template
32+
# before PyInstaller builds the exe, so as to inject date/other infos into it.
33+
*.manifest
34+
*.spec
35+
36+
# Installer logs
37+
pip-log.txt
38+
pip-delete-this-directory.txt
39+
40+
# Unit test / coverage reports
41+
htmlcov/
42+
.tox/
43+
.coverage
44+
.coverage.*
45+
.cache
46+
nosetests.xml
47+
coverage.xml
48+
*.cover
49+
.hypothesis/
50+
.pytest_cache/
51+
52+
# Translations
53+
*.mo
54+
*.pot
55+
56+
# Django stuff:
57+
*.log
58+
local_settings.py
59+
db.sqlite3
60+
61+
# Flask stuff:
62+
instance/
63+
.webassets-cache
64+
65+
# Scrapy stuff:
66+
.scrapy
67+
68+
# Sphinx documentation
69+
docs/_build/
70+
71+
# PyBuilder
72+
target/
73+
74+
# Jupyter Notebook
75+
.ipynb_checkpoints
76+
77+
# pyenv
78+
.python-version
79+
80+
# celery beat schedule file
81+
celerybeat-schedule
82+
83+
# SageMath parsed files
84+
*.sage.py
85+
86+
# Environments
87+
.env
88+
.venv
89+
env/
90+
venv/
91+
ENV/
92+
env.bak/
93+
venv.bak/
94+
95+
# Spyder project settings
96+
.spyderproject
97+
.spyproject
98+
99+
# Rope project settings
100+
.ropeproject
101+
102+
# mkdocs documentation
103+
/site
104+
105+
# mypy
106+
.mypy_cache/

lib/nn/prroi_pool/README.md

Lines changed: 66 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,66 @@
1+
# PreciseRoIPooling
2+
This repo implements the **Precise RoI Pooling** (PrRoI Pooling), proposed in the paper **Acquisition of Localization Confidence for Accurate Object Detection** published at ECCV 2018 (Oral Presentation).
3+
4+
**Acquisition of Localization Confidence for Accurate Object Detection**
5+
6+
_Borui Jiang*, Ruixuan Luo*, Jiayuan Mao*, Tete Xiao, Yuning Jiang_ (* indicates equal contribution.)
7+
8+
https://arxiv.org/abs/1807.11590
9+
10+
## Brief
11+
12+
In short, Precise RoI Pooling is an integration-based (bilinear interpolation) average pooling method for RoI Pooling. It avoids any quantization and has a continuous gradient on bounding box coordinates. It is:
13+
14+
- different from the original RoI Pooling proposed in [Fast R-CNN](https://arxiv.org/abs/1504.08083). PrRoI Pooling uses average pooling instead of max pooling for each bin and has a continuous gradient on bounding box coordinates. That is, one can take the derivatives of some loss function w.r.t the coordinates of each RoI and optimize the RoI coordinates.
15+
- different from the RoI Align proposed in [Mask R-CNN](https://arxiv.org/abs/1703.06870). PrRoI Pooling uses a full integration-based average pooling instead of sampling a constant number of points. This makes the gradient w.r.t. the coordinates continuous.
16+
17+
For a better illustration, we illustrate RoI Pooling, RoI Align and PrRoI Pooing in the following figure. More details including the gradient computation can be found in our paper.
18+
19+
<center><img src="./_assets/prroi_visualization.png" width="80%"></center>
20+
21+
## Implementation
22+
23+
PrRoI Pooling was originally implemented by [Tete Xiao](http://tetexiao.com/) based on MegBrain, an (internal) deep learning framework built by Megvii Inc. It was later adapted into open-source deep learning frameworks. Currently, we only support PyTorch. Unfortunately, we don't have any specific plan for the adaptation into other frameworks such as TensorFlow, but any contributions (pull requests) will be more than welcome.
24+
25+
## Usage (PyTorch 1.0)
26+
27+
In the directory `pytorch/`, we provide a PyTorch-based implementation of PrRoI Pooling. It requires PyTorch 1.0+ and only supports CUDA (CPU mode is not implemented).
28+
Since we use PyTorch JIT for cxx/cuda code compilation, to use the module in your code, simply do:
29+
30+
```
31+
from prroi_pool import PrRoIPool2D
32+
33+
avg_pool = PrRoIPool2D(window_height, window_width, spatial_scale)
34+
roi_features = avg_pool(features, rois)
35+
36+
# for those who want to use the "functional"
37+
38+
from prroi_pool.functional import prroi_pool2d
39+
roi_features = prroi_pool2d(features, rois, window_height, window_width, spatial_scale)
40+
```
41+
42+
43+
## Usage (PyTorch 0.4)
44+
45+
**!!! Please first checkout to the branch pytorch0.4.**
46+
47+
In the directory `pytorch/`, we provide a PyTorch-based implementation of PrRoI Pooling. It requires PyTorch 0.4 and only supports CUDA (CPU mode is not implemented).
48+
To use the PrRoI Pooling module, first goto `pytorch/prroi_pool` and execute `./travis.sh` to compile the essential components (you may need `nvcc` for this step). To use the module in your code, simply do:
49+
50+
```
51+
from prroi_pool import PrRoIPool2D
52+
53+
avg_pool = PrRoIPool2D(window_height, window_width, spatial_scale)
54+
roi_features = avg_pool(features, rois)
55+
56+
# for those who want to use the "functional"
57+
58+
from prroi_pool.functional import prroi_pool2d
59+
roi_features = prroi_pool2d(features, rois, window_height, window_width, spatial_scale)
60+
```
61+
62+
Here,
63+
64+
- RoI is an `m * 5` float tensor of format `(batch_index, x0, y0, x1, y1)`, following the convention in the original Caffe implementation of RoI Pooling, although in some frameworks the batch indices are provided by an integer tensor.
65+
- `spatial_scale` is multiplied to the RoIs. For example, if your feature maps are down-sampled by a factor of 16 (w.r.t. the input image), you should use a spatial scale of `1/16`.
66+
- The coordinates for RoI follows the [L, R) convension. That is, `(0, 0, 4, 4)` denotes a box of size `4x4`.

lib/nn/prroi_pool/build.py

Lines changed: 0 additions & 50 deletions
This file was deleted.

0 commit comments

Comments
 (0)