Skip to content

Commit b8a1eac

Browse files
committed
Merge branch 'main' into datasets/video-decoding
2 parents cb79fbc + f40c8df commit b8a1eac

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

73 files changed

+2429
-1651
lines changed

.circleci/config.yml

Lines changed: 642 additions & 414 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

.circleci/config.yml.in

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -848,7 +848,7 @@ jobs:
848848
executor:
849849
name: windows-gpu
850850
environment:
851-
CUDA_VERSION: "11.1"
851+
CUDA_VERSION: "11.3"
852852
PYTHON_VERSION: << parameters.python_version >>
853853
steps:
854854
- checkout

.circleci/regenerate.py

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@
2121
from jinja2 import select_autoescape
2222

2323

24-
PYTHON_VERSIONS = ["3.7", "3.8", "3.9"]
24+
PYTHON_VERSIONS = ["3.7", "3.8", "3.9", "3.10"]
2525

2626
RC_PATTERN = r"/v[0-9]+(\.[0-9]+)*-rc[0-9]+/"
2727

@@ -32,8 +32,8 @@ def build_workflows(prefix="", filter_branch=None, upload=False, indentation=6,
3232
for os_type in ["linux", "macos", "win"]:
3333
python_versions = PYTHON_VERSIONS
3434
cu_versions_dict = {
35-
"linux": ["cpu", "cu102", "cu111", "cu113", "cu115", "rocm4.3.1", "rocm4.5.2"],
36-
"win": ["cpu", "cu111", "cu113", "cu115"],
35+
"linux": ["cpu", "cu102", "cu113", "cu115", "rocm4.3.1", "rocm4.5.2"],
36+
"win": ["cpu", "cu113", "cu115"],
3737
"macos": ["cpu"],
3838
}
3939
cu_versions = cu_versions_dict[os_type]

.circleci/unittest/windows/scripts/environment.yml

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,10 +9,11 @@ dependencies:
99
- libpng
1010
- jpeg
1111
- ca-certificates
12-
- h5py
12+
- hdf5
1313
- pip:
1414
- future
1515
- pillow >=5.3.0, !=8.3.*
1616
- scipy
1717
- av
1818
- dataclasses
19+
- h5py

.circleci/unittest/windows/scripts/install.sh

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,7 @@ else
2828
fi
2929

3030
printf "Installing PyTorch with %s\n" "${cudatoolkit}"
31-
conda install -y -c "pytorch-${UPLOAD_CHANNEL}" -c conda-forge "pytorch-${UPLOAD_CHANNEL}"::pytorch[build="*${version}*"] "${cudatoolkit}" pytest
31+
conda install -y -c "pytorch-${UPLOAD_CHANNEL}" -c nvidia "pytorch-${UPLOAD_CHANNEL}"::pytorch[build="*${version}*"] "${cudatoolkit}" pytest
3232

3333
torch_cuda=$(python -c "import torch; print(torch.cuda.is_available())")
3434
echo torch.cuda.is_available is $torch_cuda

.pre-commit-config.yaml

Lines changed: 1 addition & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -10,15 +10,8 @@ repos:
1010
args: [--fix=lf]
1111
- id: end-of-file-fixer
1212

13-
# - repo: https://github.com/asottile/pyupgrade
14-
# rev: v2.29.0
15-
# hooks:
16-
# - id: pyupgrade
17-
# args: [--py37-plus]
18-
# name: Upgrade code
19-
2013
- repo: https://github.com/omnilib/ufmt
21-
rev: v1.3.0
14+
rev: v1.3.2
2215
hooks:
2316
- id: ufmt
2417
additional_dependencies:

docs/source/ops.rst

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,8 @@ Operators
2020
box_iou
2121
clip_boxes_to_image
2222
deform_conv2d
23+
drop_block2d
24+
drop_block3d
2325
generalized_box_iou
2426
generalized_box_iou_loss
2527
masks_to_boxes
@@ -45,5 +47,8 @@ Operators
4547
FeaturePyramidNetwork
4648
StochasticDepth
4749
FrozenBatchNorm2d
48-
ConvNormActivation
50+
Conv2dNormActivation
51+
Conv3dNormActivation
4952
SqueezeExcitation
53+
DropBlock2d
54+
DropBlock3d

docs/source/transforms.rst

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -198,6 +198,7 @@ The new transform can be used standalone or mixed-and-matched with existing tran
198198
AutoAugment
199199
RandAugment
200200
TrivialAugmentWide
201+
AugMix
201202

202203
.. _functional_transforms:
203204

gallery/plot_transforms.py

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -263,6 +263,14 @@ def plot(imgs, with_orig=True, row_title=None, **imshow_kwargs):
263263
imgs = [augmenter(orig_img) for _ in range(4)]
264264
plot(imgs)
265265

266+
####################################
267+
# AugMix
268+
# ~~~~~~
269+
# The :class:`~torchvision.transforms.AugMix` transform automatically augments the data.
270+
augmenter = T.AugMix()
271+
imgs = [augmenter(orig_img) for _ in range(4)]
272+
plot(imgs)
273+
266274
####################################
267275
# Randomly-applied transforms
268276
# ---------------------------

packaging/pkg_helpers.bash

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -205,6 +205,7 @@ setup_wheel_python() {
205205
3.7) python_abi=cp37-cp37m ;;
206206
3.8) python_abi=cp38-cp38 ;;
207207
3.9) python_abi=cp39-cp39 ;;
208+
3.10) python_abi=cp310-cp310 ;;
208209
*)
209210
echo "Unrecognized PYTHON_VERSION=$PYTHON_VERSION"
210211
exit 1

references/classification/presets.py

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,8 @@ def __init__(
2222
trans.append(autoaugment.RandAugment(interpolation=interpolation))
2323
elif auto_augment_policy == "ta_wide":
2424
trans.append(autoaugment.TrivialAugmentWide(interpolation=interpolation))
25+
elif auto_augment_policy == "augmix":
26+
trans.append(autoaugment.AugMix(interpolation=interpolation))
2527
else:
2628
aa_policy = autoaugment.AutoAugmentPolicy(auto_augment_policy)
2729
trans.append(autoaugment.AutoAugment(policy=aa_policy, interpolation=interpolation))

references/classification/utils.py

Lines changed: 2 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -166,17 +166,7 @@ def __init__(self, model, decay, device="cpu"):
166166
def ema_avg(avg_model_param, model_param, num_averaged):
167167
return decay * avg_model_param + (1 - decay) * model_param
168168

169-
super().__init__(model, device, ema_avg)
170-
171-
def update_parameters(self, model):
172-
for p_swa, p_model in zip(self.module.state_dict().values(), model.state_dict().values()):
173-
device = p_swa.device
174-
p_model_ = p_model.detach().to(device)
175-
if self.n_averaged == 0:
176-
p_swa.detach().copy_(p_model_)
177-
else:
178-
p_swa.detach().copy_(self.avg_fn(p_swa.detach(), p_model_, self.n_averaged.to(device)))
179-
self.n_averaged += 1
169+
super().__init__(model, device, ema_avg, use_buffers=True)
180170

181171

182172
def accuracy(output, target, topk=(1,)):
@@ -274,6 +264,7 @@ def init_distributed_mode(args):
274264
torch.distributed.init_process_group(
275265
backend=args.dist_backend, init_method=args.dist_url, world_size=args.world_size, rank=args.rank
276266
)
267+
torch.distributed.barrier()
277268
setup_for_distributed(args.rank == 0)
278269

279270

references/detection/transforms.py

Lines changed: 53 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44
import torchvision
55
from torch import nn, Tensor
66
from torchvision.transforms import functional as F
7-
from torchvision.transforms import transforms as T
7+
from torchvision.transforms import transforms as T, InterpolationMode
88

99

1010
def _flip_coco_person_keypoints(kps, width):
@@ -282,3 +282,55 @@ def forward(
282282
image = F.to_pil_image(image)
283283

284284
return image, target
285+
286+
287+
class ScaleJitter(nn.Module):
288+
"""Randomly resizes the image and its bounding boxes within the specified scale range.
289+
The class implements the Scale Jitter augmentation as described in the paper
290+
`"Simple Copy-Paste is a Strong Data Augmentation Method for Instance Segmentation" <https://arxiv.org/abs/2012.07177>`_.
291+
292+
Args:
293+
target_size (tuple of ints): The target size for the transform provided in (height, weight) format.
294+
scale_range (tuple of ints): scaling factor interval, e.g (a, b), then scale is randomly sampled from the
295+
range a <= scale <= b.
296+
interpolation (InterpolationMode): Desired interpolation enum defined by
297+
:class:`torchvision.transforms.InterpolationMode`. Default is ``InterpolationMode.BILINEAR``.
298+
"""
299+
300+
def __init__(
301+
self,
302+
target_size: Tuple[int, int],
303+
scale_range: Tuple[float, float] = (0.1, 2.0),
304+
interpolation: InterpolationMode = InterpolationMode.BILINEAR,
305+
):
306+
super().__init__()
307+
self.target_size = target_size
308+
self.scale_range = scale_range
309+
self.interpolation = interpolation
310+
311+
def forward(
312+
self, image: Tensor, target: Optional[Dict[str, Tensor]] = None
313+
) -> Tuple[Tensor, Optional[Dict[str, Tensor]]]:
314+
if isinstance(image, torch.Tensor):
315+
if image.ndimension() not in {2, 3}:
316+
raise ValueError(f"image should be 2/3 dimensional. Got {image.ndimension()} dimensions.")
317+
elif image.ndimension() == 2:
318+
image = image.unsqueeze(0)
319+
320+
orig_width, orig_height = F.get_image_size(image)
321+
322+
r = self.scale_range[0] + torch.rand(1) * (self.scale_range[1] - self.scale_range[0])
323+
new_width = int(self.target_size[1] * r)
324+
new_height = int(self.target_size[0] * r)
325+
326+
image = F.resize(image, [new_height, new_width], interpolation=self.interpolation)
327+
328+
if target is not None:
329+
target["boxes"][:, 0::2] *= new_width / orig_width
330+
target["boxes"][:, 1::2] *= new_height / orig_height
331+
if "masks" in target:
332+
target["masks"] = F.resize(
333+
target["masks"], [new_height, new_width], interpolation=InterpolationMode.NEAREST
334+
)
335+
336+
return image, target

references/optical_flow/utils.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -267,6 +267,7 @@ def setup_ddp(args):
267267
world_size=args.world_size,
268268
init_method=args.dist_url,
269269
)
270+
torch.distributed.barrier()
270271

271272

272273
def reduce_across_processes(val):

references/segmentation/utils.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -291,4 +291,5 @@ def init_distributed_mode(args):
291291
torch.distributed.init_process_group(
292292
backend=args.dist_backend, init_method=args.dist_url, world_size=args.world_size, rank=args.rank
293293
)
294+
torch.distributed.barrier()
294295
setup_for_distributed(args.rank == 0)

references/video_classification/utils.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -250,4 +250,5 @@ def init_distributed_mode(args):
250250
torch.distributed.init_process_group(
251251
backend=args.dist_backend, init_method=args.dist_url, world_size=args.world_size, rank=args.rank
252252
)
253+
torch.distributed.barrier()
253254
setup_for_distributed(args.rank == 0)

scripts/release_notes/classify_prs.py

Lines changed: 19 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,18 @@
11
# In[1]:
22

3-
3+
# imports and set configuration
44
import pandas as pd
5+
from retrieve_prs_data import run
56

7+
exclude_prototype = True
8+
data_filename = "10.0_to_11.0-rc2.json"
9+
previous_release = "v10.0"
10+
current_release = "v11.0-rc2"
611

712
# In[2]:
813

914

10-
df = pd.read_json("10.0_to_11.0-rc2.json").T
15+
df = pd.read_json(data_filename).T
1116
df.tail()
1217

1318

@@ -76,6 +81,8 @@
7681
def format_prs(mod_df):
7782
out = []
7883
for idx, row in mod_df.iterrows():
84+
if exclude_prototype and row["prototype"]:
85+
continue
7986
modules = idx
8087
# Put "documentation" and "tests" first for sorting to be dece
8188
for last_module in ("documentation", "tests"):
@@ -119,3 +126,13 @@ def format_prs(mod_df):
119126
# Missing PRs are these ones... classify them manually
120127
missing_prs = pd.concat([mod_df, included_prs]).drop_duplicates(subset="pr_number", keep=False)
121128
print(format_prs(missing_prs))
129+
130+
# In[12]:
131+
132+
# Generate list of contributors
133+
print()
134+
print("## Contributors")
135+
136+
command_to_run = f"{{ git shortlog -s {previous_release}..{current_release} | cut -f2- & git log -s {previous_release}..{current_release} | grep Co-authored | cut -f2- -d: | cut -f1 -d\\< | sed 's/^ *//;s/ *$//' ; }} | sort --ignore-case | uniq | tr '\\n' ';' | sed 's/;/, /g;s/, $//' | fold -s"
137+
rc, output, err = run(command_to_run)
138+
print(output)

test/test_ops.py

Lines changed: 93 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22
import os
33
from abc import ABC, abstractmethod
44
from functools import lru_cache
5+
from itertools import product
56
from typing import Callable, List, Tuple
67

78
import numpy as np
@@ -57,6 +58,16 @@ def forward(self, a):
5758
self.layer(a)
5859

5960

61+
class DropBlockWrapper(nn.Module):
62+
def __init__(self, obj):
63+
super().__init__()
64+
self.layer = obj
65+
self.n_inputs = 1
66+
67+
def forward(self, a):
68+
self.layer(a)
69+
70+
6071
class RoIOpTester(ABC):
6172
dtype = torch.float64
6273

@@ -1357,5 +1368,87 @@ def test_split_normalization_params(self, norm_layer):
13571368
assert len(params[1]) == 82
13581369

13591370

1371+
class TestDropBlock:
1372+
@pytest.mark.parametrize("seed", range(10))
1373+
@pytest.mark.parametrize("dim", [2, 3])
1374+
@pytest.mark.parametrize("p", [0, 0.5])
1375+
@pytest.mark.parametrize("block_size", [5, 11])
1376+
@pytest.mark.parametrize("inplace", [True, False])
1377+
def test_drop_block(self, seed, dim, p, block_size, inplace):
1378+
torch.manual_seed(seed)
1379+
batch_size = 5
1380+
channels = 3
1381+
height = 11
1382+
width = height
1383+
depth = height
1384+
if dim == 2:
1385+
x = torch.ones(size=(batch_size, channels, height, width))
1386+
layer = ops.DropBlock2d(p=p, block_size=block_size, inplace=inplace)
1387+
feature_size = height * width
1388+
elif dim == 3:
1389+
x = torch.ones(size=(batch_size, channels, depth, height, width))
1390+
layer = ops.DropBlock3d(p=p, block_size=block_size, inplace=inplace)
1391+
feature_size = depth * height * width
1392+
layer.__repr__()
1393+
1394+
out = layer(x)
1395+
if p == 0:
1396+
assert out.equal(x)
1397+
if block_size == height:
1398+
for b, c in product(range(batch_size), range(channels)):
1399+
assert out[b, c].count_nonzero() in (0, feature_size)
1400+
1401+
@pytest.mark.parametrize("seed", range(10))
1402+
@pytest.mark.parametrize("dim", [2, 3])
1403+
@pytest.mark.parametrize("p", [0.1, 0.2])
1404+
@pytest.mark.parametrize("block_size", [3])
1405+
@pytest.mark.parametrize("inplace", [False])
1406+
def test_drop_block_random(self, seed, dim, p, block_size, inplace):
1407+
torch.manual_seed(seed)
1408+
batch_size = 5
1409+
channels = 3
1410+
height = 11
1411+
width = height
1412+
depth = height
1413+
if dim == 2:
1414+
x = torch.ones(size=(batch_size, channels, height, width))
1415+
layer = ops.DropBlock2d(p=p, block_size=block_size, inplace=inplace)
1416+
elif dim == 3:
1417+
x = torch.ones(size=(batch_size, channels, depth, height, width))
1418+
layer = ops.DropBlock3d(p=p, block_size=block_size, inplace=inplace)
1419+
1420+
trials = 250
1421+
num_samples = 0
1422+
counts = 0
1423+
cell_numel = torch.tensor(x.shape).prod()
1424+
for _ in range(trials):
1425+
with torch.no_grad():
1426+
out = layer(x)
1427+
non_zero_count = out.nonzero().size(0)
1428+
counts += cell_numel - non_zero_count
1429+
num_samples += cell_numel
1430+
1431+
assert abs(p - counts / num_samples) / p < 0.15
1432+
1433+
def make_obj(self, dim, p, block_size, inplace, wrap=False):
1434+
if dim == 2:
1435+
obj = ops.DropBlock2d(p, block_size, inplace)
1436+
elif dim == 3:
1437+
obj = ops.DropBlock3d(p, block_size, inplace)
1438+
return DropBlockWrapper(obj) if wrap else obj
1439+
1440+
@pytest.mark.parametrize("dim", (2, 3))
1441+
@pytest.mark.parametrize("p", [0, 1])
1442+
@pytest.mark.parametrize("block_size", [5, 7])
1443+
@pytest.mark.parametrize("inplace", [True, False])
1444+
def test_is_leaf_node(self, dim, p, block_size, inplace):
1445+
op_obj = self.make_obj(dim, p, block_size, inplace, wrap=True)
1446+
graph_node_names = get_graph_node_names(op_obj)
1447+
1448+
assert len(graph_node_names) == 2
1449+
assert len(graph_node_names[0]) == len(graph_node_names[1])
1450+
assert len(graph_node_names[0]) == 1 + op_obj.n_inputs
1451+
1452+
13601453
if __name__ == "__main__":
13611454
pytest.main([__file__])

0 commit comments

Comments
 (0)