Skip to content

Commit 11672d2

Browse files
authored
Merge branch 'main' into references/simplify_clipping
2 parents ba2f991 + 22ff44f commit 11672d2

Some content is hidden

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

63 files changed

+1064
-146
lines changed

android/build.gradle

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ allprojects {
1515
androidSupportAppCompatV7Version = "28.0.0"
1616
fbjniJavaOnlyVersion = "0.0.3"
1717
soLoaderNativeLoaderVersion = "0.8.0"
18-
pytorchAndroidVersion = "1.10.0-SNAPSHOT"
18+
pytorchAndroidVersion = "1.11.0-SNAPSHOT"
1919
}
2020

2121
repositories {

docs/source/models.rst

Lines changed: 0 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -323,10 +323,6 @@ Inception v3
323323

324324
inception_v3
325325

326-
.. note ::
327-
This requires `scipy` to be installed
328-
329-
330326
GoogLeNet
331327
------------
332328

@@ -336,10 +332,6 @@ GoogLeNet
336332

337333
googlenet
338334

339-
.. note ::
340-
This requires `scipy` to be installed
341-
342-
343335
ShuffleNet v2
344336
-------------
345337

gallery/assets/person1.jpg

68.5 KB
Loading
-187 KB
Binary file not shown.
Loading

gallery/plot_visualization_utils.py

Lines changed: 109 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,10 +4,10 @@
44
=======================
55
66
This example illustrates some of the utilities that torchvision offers for
7-
visualizing images, bounding boxes, and segmentation masks.
7+
visualizing images, bounding boxes, segmentation masks and keypoints.
88
"""
99

10-
# sphinx_gallery_thumbnail_path = "../../gallery/assets/visualization_utils_thumbnail.png"
10+
# sphinx_gallery_thumbnail_path = "../../gallery/assets/visualization_utils_thumbnail2.png"
1111

1212
import torch
1313
import numpy as np
@@ -366,3 +366,110 @@ def show(imgs):
366366
# The two 'people' masks in the first image where not selected because they have
367367
# a lower score than the score threshold. Similarly in the second image, the
368368
# instance with class 15 (which corresponds to 'bench') was not selected.
369+
370+
#####################################
371+
# Visualizing keypoints
372+
# ------------------------------
373+
# The :func:`~torchvision.utils.draw_keypoints` function can be used to
374+
# draw keypoints on images. We will see how to use it with
375+
# torchvision's KeypointRCNN loaded with :func:`~torchvision.models.detection.keypointrcnn_resnet50_fpn`.
376+
# We will first have a look at output of the model.
377+
#
378+
# Note that the keypoint detection model does not need normalized images.
379+
#
380+
381+
from torchvision.models.detection import keypointrcnn_resnet50_fpn
382+
from torchvision.io import read_image
383+
384+
person_int = read_image(str(Path("assets") / "person1.jpg"))
385+
person_float = convert_image_dtype(person_int, dtype=torch.float)
386+
387+
model = keypointrcnn_resnet50_fpn(pretrained=True, progress=False)
388+
model = model.eval()
389+
390+
outputs = model([person_float])
391+
print(outputs)
392+
393+
#####################################
394+
# As we see the output contains a list of dictionaries.
395+
# The output list is of length batch_size.
396+
# We currently have just a single image so length of list is 1.
397+
# Each entry in the list corresponds to an input image,
398+
# and it is a dict with keys `boxes`, `labels`, `scores`, `keypoints` and `keypoint_scores`.
399+
# Each value associated to those keys has `num_instances` elements in it.
400+
# In our case above there are 2 instances detected in the image.
401+
402+
kpts = outputs[0]['keypoints']
403+
scores = outputs[0]['scores']
404+
405+
print(kpts)
406+
print(scores)
407+
408+
#####################################
409+
# The KeypointRCNN model detects there are two instances in the image.
410+
# If you plot the boxes by using :func:`~draw_bounding_boxes`
411+
# you would recognize they are the person and the surfboard.
412+
# If we look at the scores, we will realize that the model is much more confident about the person than surfboard.
413+
# We could now set a threshold confidence and plot instances which we are confident enough.
414+
# Let us set a threshold of 0.75 and filter out the keypoints corresponding to the person.
415+
416+
detect_threshold = 0.75
417+
idx = torch.where(scores > detect_threshold)
418+
keypoints = kpts[idx]
419+
420+
print(keypoints)
421+
422+
#####################################
423+
# Great, now we have the keypoints corresponding to the person.
424+
# Each keypoint is represented by x, y coordinates and the visibility.
425+
# We can now use the :func:`~torchvision.utils.draw_keypoints` function to draw keypoints.
426+
# Note that the utility expects uint8 images.
427+
428+
from torchvision.utils import draw_keypoints
429+
430+
res = draw_keypoints(person_int, keypoints, colors="blue", radius=3)
431+
show(res)
432+
433+
#####################################
434+
# As we see the keypoints appear as colored circles over the image.
435+
# The coco keypoints for a person are ordered and represent the following list.\
436+
437+
coco_keypoints = [
438+
"nose", "left_eye", "right_eye", "left_ear", "right_ear",
439+
"left_shoulder", "right_shoulder", "left_elbow", "right_elbow",
440+
"left_wrist", "right_wrist", "left_hip", "right_hip",
441+
"left_knee", "right_knee", "left_ankle", "right_ankle",
442+
]
443+
444+
#####################################
445+
# What if we are interested in joining the keypoints?
446+
# This is especially useful in creating pose detection or action recognition.
447+
# We can join the keypoints easily using the `connectivity` parameter.
448+
# A close observation would reveal that we would need to join the points in below
449+
# order to construct human skeleton.
450+
#
451+
# nose -> left_eye -> left_ear. (0, 1), (1, 3)
452+
#
453+
# nose -> right_eye -> right_ear. (0, 2), (2, 4)
454+
#
455+
# nose -> left_shoulder -> left_elbow -> left_wrist. (0, 5), (5, 7), (7, 9)
456+
#
457+
# nose -> right_shoulder -> right_elbow -> right_wrist. (0, 6), (6, 8), (8, 10)
458+
#
459+
# left_shoulder -> left_hip -> left_knee -> left_ankle. (5, 11), (11, 13), (13, 15)
460+
#
461+
# right_shoulder -> right_hip -> right_knee -> right_ankle. (6, 12), (12, 14), (14, 16)
462+
#
463+
# We will create a list containing these keypoint ids to be connected.
464+
465+
connect_skeleton = [
466+
(0, 1), (0, 2), (1, 3), (2, 4), (0, 5), (0, 6), (5, 7), (6, 8),
467+
(7, 9), (8, 10), (5, 11), (6, 12), (11, 13), (12, 14), (13, 15), (14, 16)
468+
]
469+
470+
#####################################
471+
# We pass the above list to the connectivity parameter to connect the keypoints.
472+
#
473+
474+
res = draw_keypoints(person_int, keypoints, connectivity=connect_skeleton, colors="blue", radius=4, width=3)
475+
show(res)

packaging/windows/internal/cuda_install.bat

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -167,7 +167,7 @@ if not exist "%SRC_DIR%\temp_build\%CUDA_INSTALL_EXE%" (
167167
curl -k -L "https://ossci-windows.s3.amazonaws.com/%CUDA_INSTALL_EXE%" --output "%SRC_DIR%\temp_build\%CUDA_INSTALL_EXE%"
168168
if errorlevel 1 exit /b 1
169169
set "CUDA_SETUP_FILE=%SRC_DIR%\temp_build\%CUDA_INSTALL_EXE%"
170-
set "ARGS=thrust_11.3 nvcc_11.3 cuobjdump_11.3 nvprune_11.3 nvprof_11.3 cupti_11.3 cublas_11.3 cublas_dev_11.3 cudart_11.3 cufft_11.3 cufft_dev_11.3 curand_11.3 curand_dev_11.3 cusolver_11.3 cusolver_dev_11.3 cusparse_11.3 cusparse_dev_11.3 npp_11.3 npp_dev_11.3 nvrtc_11.3 nvrtc_dev_11.3 nvml_dev_11.3"
170+
set "ARGS=thrust_11.3 nvcc_11.3 cuobjdump_11.3 nvprune_11.3 nvprof_11.3 cupti_11.3 cublas_11.3 cublas_dev_11.3 cudart_11.3 cufft_11.3 cufft_dev_11.3 curand_11.3 curand_dev_11.3 cusolver_11.3 cusolver_dev_11.3 cusparse_11.3 cusparse_dev_11.3 npp_11.3 npp_dev_11.3 nvjpeg_11.3 nvjpeg_dev_11.3 nvrtc_11.3 nvrtc_dev_11.3 nvml_dev_11.3"
171171

172172
)
173173

references/classification/train.py

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -325,6 +325,8 @@ def main(args):
325325
args.start_epoch = checkpoint["epoch"] + 1
326326
if model_ema:
327327
model_ema.load_state_dict(checkpoint["model_ema"])
328+
if scaler:
329+
scaler.load_state_dict(checkpoint["scaler"])
328330

329331
if args.test_only:
330332
# We disable the cudnn benchmarking because it can noticeably affect the accuracy
@@ -356,6 +358,8 @@ def main(args):
356358
}
357359
if model_ema:
358360
checkpoint["model_ema"] = model_ema.state_dict()
361+
if scaler:
362+
checkpoint["scaler"] = scaler.state_dict()
359363
utils.save_on_master(checkpoint, os.path.join(args.output_dir, f"model_{epoch}.pth"))
360364
utils.save_on_master(checkpoint, os.path.join(args.output_dir, "checkpoint.pth"))
361365

test/test_ops.py

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -479,7 +479,9 @@ def _create_tensors_with_iou(self, N, iou_thresh):
479479
return boxes, scores
480480

481481
@pytest.mark.parametrize("iou", (0.2, 0.5, 0.8))
482-
def test_nms_ref(self, iou):
482+
@pytest.mark.parametrize("seed", range(10))
483+
def test_nms_ref(self, iou, seed):
484+
torch.random.manual_seed(seed)
483485
err_msg = "NMS incompatible between CPU and reference implementation for IoU={}"
484486
boxes, scores = self._create_tensors_with_iou(1000, iou)
485487
keep_ref = self._reference_nms(boxes, scores, iou)

test/test_prototype_datasets_api.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22

33
import pytest
44
from torchvision.prototype import datasets
5-
from torchvision.prototype.datasets.utils._internal import FrozenMapping, FrozenBunch
5+
from torchvision.prototype.utils._internal import FrozenMapping, FrozenBunch
66

77

88
def make_minimal_dataset_info(name="name", type=datasets.utils.DatasetType.RAW, categories=None, **kwargs):

0 commit comments

Comments
 (0)