Skip to content

Commit d5f4cc3

Browse files
authored
Datapoint -> TVTensor; datapoint[s] -> tv_tensor[s] (#7894)
1 parent b9447fd commit d5f4cc3

Some content is hidden

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

85 files changed

+1121
-1121
lines changed

docs/source/conf.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -88,8 +88,8 @@ def __init__(self, src_dir):
8888
"plot_transforms_e2e.py",
8989
"plot_cutmix_mixup.py",
9090
"plot_custom_transforms.py",
91-
"plot_datapoints.py",
92-
"plot_custom_datapoints.py",
91+
"plot_tv_tensors.py",
92+
"plot_custom_tv_tensors.py",
9393
]
9494

9595
def __call__(self, filename):

docs/source/index.rst

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,7 @@ architectures, and common image transformations for computer vision.
3232
:caption: Package Reference
3333

3434
transforms
35-
datapoints
35+
tv_tensors
3636
models
3737
datasets
3838
utils

docs/source/transforms.rst

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -30,12 +30,12 @@ tasks (image classification, detection, segmentation, video classification).
3030
.. code:: python
3131
3232
# Detection (re-using imports and transforms from above)
33-
from torchvision import datapoints
33+
from torchvision import tv_tensors
3434
3535
img = torch.randint(0, 256, size=(3, H, W), dtype=torch.uint8)
3636
bboxes = torch.randint(0, H // 2, size=(3, 4))
3737
bboxes[:, 2:] += bboxes[:, :2]
38-
bboxes = datapoints.BoundingBoxes(bboxes, format="XYXY", canvas_size=(H, W))
38+
bboxes = tv_tensors.BoundingBoxes(bboxes, format="XYXY", canvas_size=(H, W))
3939
4040
# The same transforms can be used!
4141
img, bboxes = transforms(img, bboxes)
@@ -183,8 +183,8 @@ Transforms are available as classes like
183183
This is very much like the :mod:`torch.nn` package which defines both classes
184184
and functional equivalents in :mod:`torch.nn.functional`.
185185

186-
The functionals support PIL images, pure tensors, or :ref:`datapoints
187-
<datapoints>`, e.g. both ``resize(image_tensor)`` and ``resize(bboxes)`` are
186+
The functionals support PIL images, pure tensors, or :ref:`tv_tensors
187+
<tv_tensors>`, e.g. both ``resize(image_tensor)`` and ``resize(bboxes)`` are
188188
valid.
189189

190190
.. note::
Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,13 @@
1-
.. _datapoints:
1+
.. _tv_tensors:
22

3-
Datapoints
3+
TVTensors
44
==========
55

6-
.. currentmodule:: torchvision.datapoints
6+
.. currentmodule:: torchvision.tv_tensors
77

8-
Datapoints are tensor subclasses which the :mod:`~torchvision.transforms.v2` v2 transforms use under the hood to
8+
TVTensors are tensor subclasses which the :mod:`~torchvision.transforms.v2` v2 transforms use under the hood to
99
dispatch their inputs to the appropriate lower-level kernels. Most users do not
10-
need to manipulate datapoints directly and can simply rely on dataset wrapping -
10+
need to manipulate tv_tensors directly and can simply rely on dataset wrapping -
1111
see e.g. :ref:`sphx_glr_auto_examples_transforms_plot_transforms_e2e.py`.
1212

1313
.. autosummary::
@@ -19,6 +19,6 @@ see e.g. :ref:`sphx_glr_auto_examples_transforms_plot_transforms_e2e.py`.
1919
BoundingBoxFormat
2020
BoundingBoxes
2121
Mask
22-
Datapoint
22+
TVTensor
2323
set_return_type
2424
wrap

gallery/transforms/helpers.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
import matplotlib.pyplot as plt
22
import torch
33
from torchvision.utils import draw_bounding_boxes, draw_segmentation_masks
4-
from torchvision import datapoints
4+
from torchvision import tv_tensors
55
from torchvision.transforms.v2 import functional as F
66

77

@@ -22,7 +22,7 @@ def plot(imgs, row_title=None, **imshow_kwargs):
2222
if isinstance(target, dict):
2323
boxes = target.get("boxes")
2424
masks = target.get("masks")
25-
elif isinstance(target, datapoints.BoundingBoxes):
25+
elif isinstance(target, tv_tensors.BoundingBoxes):
2626
boxes = target
2727
else:
2828
raise ValueError(f"Unexpected target type: {type(target)}")

gallery/transforms/plot_custom_transforms.py

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@
1313

1414
# %%
1515
import torch
16-
from torchvision import datapoints
16+
from torchvision import tv_tensors
1717
from torchvision.transforms import v2
1818

1919

@@ -62,7 +62,7 @@ def forward(self, img, bboxes, label): # we assume inputs are always structured
6262

6363
H, W = 256, 256
6464
img = torch.rand(3, H, W)
65-
bboxes = datapoints.BoundingBoxes(
65+
bboxes = tv_tensors.BoundingBoxes(
6666
torch.tensor([[0, 10, 10, 20], [50, 50, 70, 70]]),
6767
format="XYXY",
6868
canvas_size=(H, W)
@@ -74,9 +74,9 @@ def forward(self, img, bboxes, label): # we assume inputs are always structured
7474
print(f"Output image shape: {out_img.shape}\nout_bboxes = {out_bboxes}\n{out_label = }")
7575
# %%
7676
# .. note::
77-
# While working with datapoint classes in your code, make sure to
77+
# While working with tv_tensor classes in your code, make sure to
7878
# familiarize yourself with this section:
79-
# :ref:`datapoint_unwrapping_behaviour`
79+
# :ref:`tv_tensor_unwrapping_behaviour`
8080
#
8181
# Supporting arbitrary input structures
8282
# =====================================
@@ -111,7 +111,7 @@ def forward(self, img, bboxes, label): # we assume inputs are always structured
111111
# In brief, the core logic is to unpack the input into a flat list using `pytree
112112
# <https://github.com/pytorch/pytorch/blob/main/torch/utils/_pytree.py>`_, and
113113
# then transform only the entries that can be transformed (the decision is made
114-
# based on the **class** of the entries, as all datapoints are
114+
# based on the **class** of the entries, as all tv_tensors are
115115
# tensor-subclasses) plus some custom logic that is out of score here - check the
116116
# code for details. The (potentially transformed) entries are then repacked and
117117
# returned, in the same structure as the input.

gallery/transforms/plot_custom_datapoints.py renamed to gallery/transforms/plot_custom_tv_tensors.py

Lines changed: 22 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -1,62 +1,62 @@
11
"""
22
=====================================
3-
How to write your own Datapoint class
3+
How to write your own TVTensor class
44
=====================================
55
66
.. note::
7-
Try on `collab <https://colab.research.google.com/github/pytorch/vision/blob/gh-pages/main/_generated_ipynb_notebooks/plot_custom_datapoints.ipynb>`_
8-
or :ref:`go to the end <sphx_glr_download_auto_examples_transforms_plot_custom_datapoints.py>` to download the full example code.
7+
Try on `collab <https://colab.research.google.com/github/pytorch/vision/blob/gh-pages/main/_generated_ipynb_notebooks/plot_custom_tv_tensors.ipynb>`_
8+
or :ref:`go to the end <sphx_glr_download_auto_examples_transforms_plot_custom_tv_tensors.py>` to download the full example code.
99
1010
This guide is intended for advanced users and downstream library maintainers. We explain how to
11-
write your own datapoint class, and how to make it compatible with the built-in
11+
write your own tv_tensor class, and how to make it compatible with the built-in
1212
Torchvision v2 transforms. Before continuing, make sure you have read
13-
:ref:`sphx_glr_auto_examples_transforms_plot_datapoints.py`.
13+
:ref:`sphx_glr_auto_examples_transforms_plot_tv_tensors.py`.
1414
"""
1515

1616
# %%
1717
import torch
18-
from torchvision import datapoints
18+
from torchvision import tv_tensors
1919
from torchvision.transforms import v2
2020

2121
# %%
2222
# We will create a very simple class that just inherits from the base
23-
# :class:`~torchvision.datapoints.Datapoint` class. It will be enough to cover
23+
# :class:`~torchvision.tv_tensors.TVTensor` class. It will be enough to cover
2424
# what you need to know to implement your more elaborate uses-cases. If you need
2525
# to create a class that carries meta-data, take a look at how the
26-
# :class:`~torchvision.datapoints.BoundingBoxes` class is `implemented
27-
# <https://github.com/pytorch/vision/blob/main/torchvision/datapoints/_bounding_box.py>`_.
26+
# :class:`~torchvision.tv_tensors.BoundingBoxes` class is `implemented
27+
# <https://github.com/pytorch/vision/blob/main/torchvision/tv_tensors/_bounding_box.py>`_.
2828

2929

30-
class MyDatapoint(datapoints.Datapoint):
30+
class MyTVTensor(tv_tensors.TVTensor):
3131
pass
3232

3333

34-
my_dp = MyDatapoint([1, 2, 3])
34+
my_dp = MyTVTensor([1, 2, 3])
3535
my_dp
3636

3737
# %%
38-
# Now that we have defined our custom Datapoint class, we want it to be
38+
# Now that we have defined our custom TVTensor class, we want it to be
3939
# compatible with the built-in torchvision transforms, and the functional API.
4040
# For that, we need to implement a kernel which performs the core of the
4141
# transformation, and then "hook" it to the functional that we want to support
4242
# via :func:`~torchvision.transforms.v2.functional.register_kernel`.
4343
#
4444
# We illustrate this process below: we create a kernel for the "horizontal flip"
45-
# operation of our MyDatapoint class, and register it to the functional API.
45+
# operation of our MyTVTensor class, and register it to the functional API.
4646

4747
from torchvision.transforms.v2 import functional as F
4848

4949

50-
@F.register_kernel(functional="hflip", datapoint_cls=MyDatapoint)
51-
def hflip_my_datapoint(my_dp, *args, **kwargs):
50+
@F.register_kernel(functional="hflip", tv_tensor_cls=MyTVTensor)
51+
def hflip_my_tv_tensor(my_dp, *args, **kwargs):
5252
print("Flipping!")
5353
out = my_dp.flip(-1)
54-
return datapoints.wrap(out, like=my_dp)
54+
return tv_tensors.wrap(out, like=my_dp)
5555

5656

5757
# %%
58-
# To understand why :func:`~torchvision.datapoints.wrap` is used, see
59-
# :ref:`datapoint_unwrapping_behaviour`. Ignore the ``*args, **kwargs`` for now,
58+
# To understand why :func:`~torchvision.tv_tensors.wrap` is used, see
59+
# :ref:`tv_tensor_unwrapping_behaviour`. Ignore the ``*args, **kwargs`` for now,
6060
# we will explain it below in :ref:`param_forwarding`.
6161
#
6262
# .. note::
@@ -67,9 +67,9 @@ def hflip_my_datapoint(my_dp, *args, **kwargs):
6767
# ``@register_kernel(functional=F.hflip, ...)``.
6868
#
6969
# Now that we have registered our kernel, we can call the functional API on a
70-
# ``MyDatapoint`` instance:
70+
# ``MyTVTensor`` instance:
7171

72-
my_dp = MyDatapoint(torch.rand(3, 256, 256))
72+
my_dp = MyTVTensor(torch.rand(3, 256, 256))
7373
_ = F.hflip(my_dp)
7474

7575
# %%
@@ -102,10 +102,10 @@ def hflip_my_datapoint(my_dp, *args, **kwargs):
102102
# to its :func:`~torchvision.transforms.v2.functional.hflip` functional. If you
103103
# already defined and registered your own kernel as
104104

105-
def hflip_my_datapoint(my_dp): # noqa
105+
def hflip_my_tv_tensor(my_dp): # noqa
106106
print("Flipping!")
107107
out = my_dp.flip(-1)
108-
return datapoints.wrap(out, like=my_dp)
108+
return tv_tensors.wrap(out, like=my_dp)
109109

110110

111111
# %%

gallery/transforms/plot_transforms_e2e.py

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@
2323
import torch
2424
import torch.utils.data
2525

26-
from torchvision import models, datasets, datapoints
26+
from torchvision import models, datasets, tv_tensors
2727
from torchvision.transforms import v2
2828

2929
torch.manual_seed(0)
@@ -72,7 +72,7 @@
7272
# %%
7373
# We used the ``target_keys`` parameter to specify the kind of output we're
7474
# interested in. Our dataset now returns a target which is dict where the values
75-
# are :ref:`Datapoints <what_are_datapoints>` (all are :class:`torch.Tensor`
75+
# are :ref:`TVTensors <what_are_tv_tensors>` (all are :class:`torch.Tensor`
7676
# subclasses). We're dropped all unncessary keys from the previous output, but
7777
# if you need any of the original keys e.g. "image_id", you can still ask for
7878
# it.
@@ -103,7 +103,7 @@
103103
[
104104
v2.ToImage(),
105105
v2.RandomPhotometricDistort(p=1),
106-
v2.RandomZoomOut(fill={datapoints.Image: (123, 117, 104), "others": 0}),
106+
v2.RandomZoomOut(fill={tv_tensors.Image: (123, 117, 104), "others": 0}),
107107
v2.RandomIoUCrop(),
108108
v2.RandomHorizontalFlip(p=1),
109109
v2.SanitizeBoundingBoxes(),

gallery/transforms/plot_transforms_getting_started.py

Lines changed: 28 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -88,9 +88,9 @@
8888
#
8989
# Let's briefly look at a detection example with bounding boxes.
9090

91-
from torchvision import datapoints # we'll describe this a bit later, bare with us
91+
from torchvision import tv_tensors # we'll describe this a bit later, bare with us
9292

93-
boxes = datapoints.BoundingBoxes(
93+
boxes = tv_tensors.BoundingBoxes(
9494
[
9595
[15, 10, 370, 510],
9696
[275, 340, 510, 510],
@@ -111,44 +111,44 @@
111111
# %%
112112
#
113113
# The example above focuses on object detection. But if we had masks
114-
# (:class:`torchvision.datapoints.Mask`) for object segmentation or semantic
115-
# segmentation, or videos (:class:`torchvision.datapoints.Video`), we could have
114+
# (:class:`torchvision.tv_tensors.Mask`) for object segmentation or semantic
115+
# segmentation, or videos (:class:`torchvision.tv_tensors.Video`), we could have
116116
# passed them to the transforms in exactly the same way.
117117
#
118-
# By now you likely have a few questions: what are these datapoints, how do we
118+
# By now you likely have a few questions: what are these tv_tensors, how do we
119119
# use them, and what is the expected input/output of those transforms? We'll
120120
# answer these in the next sections.
121121

122122
# %%
123123
#
124-
# .. _what_are_datapoints:
124+
# .. _what_are_tv_tensors:
125125
#
126-
# What are Datapoints?
126+
# What are TVTensors?
127127
# --------------------
128128
#
129-
# Datapoints are :class:`torch.Tensor` subclasses. The available datapoints are
130-
# :class:`~torchvision.datapoints.Image`,
131-
# :class:`~torchvision.datapoints.BoundingBoxes`,
132-
# :class:`~torchvision.datapoints.Mask`, and
133-
# :class:`~torchvision.datapoints.Video`.
129+
# TVTensors are :class:`torch.Tensor` subclasses. The available tv_tensors are
130+
# :class:`~torchvision.tv_tensors.Image`,
131+
# :class:`~torchvision.tv_tensors.BoundingBoxes`,
132+
# :class:`~torchvision.tv_tensors.Mask`, and
133+
# :class:`~torchvision.tv_tensors.Video`.
134134
#
135-
# Datapoints look and feel just like regular tensors - they **are** tensors.
135+
# TVTensors look and feel just like regular tensors - they **are** tensors.
136136
# Everything that is supported on a plain :class:`torch.Tensor` like ``.sum()``
137-
# or any ``torch.*`` operator will also work on a datapoint:
137+
# or any ``torch.*`` operator will also work on a tv_tensor:
138138

139-
img_dp = datapoints.Image(torch.randint(0, 256, (3, 256, 256), dtype=torch.uint8))
139+
img_dp = tv_tensors.Image(torch.randint(0, 256, (3, 256, 256), dtype=torch.uint8))
140140

141141
print(f"{isinstance(img_dp, torch.Tensor) = }")
142142
print(f"{img_dp.dtype = }, {img_dp.shape = }, {img_dp.sum() = }")
143143

144144
# %%
145-
# These Datapoint classes are at the core of the transforms: in order to
145+
# These TVTensor classes are at the core of the transforms: in order to
146146
# transform a given input, the transforms first look at the **class** of the
147147
# object, and dispatch to the appropriate implementation accordingly.
148148
#
149-
# You don't need to know much more about datapoints at this point, but advanced
149+
# You don't need to know much more about tv_tensors at this point, but advanced
150150
# users who want to learn more can refer to
151-
# :ref:`sphx_glr_auto_examples_transforms_plot_datapoints.py`.
151+
# :ref:`sphx_glr_auto_examples_transforms_plot_tv_tensors.py`.
152152
#
153153
# What do I pass as input?
154154
# ------------------------
@@ -196,17 +196,17 @@
196196
# Pure :class:`torch.Tensor` objects are, in general, treated as images (or
197197
# as videos for video-specific transforms). Indeed, you may have noticed
198198
# that in the code above we haven't used the
199-
# :class:`~torchvision.datapoints.Image` class at all, and yet our images
199+
# :class:`~torchvision.tv_tensors.Image` class at all, and yet our images
200200
# got transformed properly. Transforms follow the following logic to
201201
# determine whether a pure Tensor should be treated as an image (or video),
202202
# or just ignored:
203203
#
204-
# * If there is an :class:`~torchvision.datapoints.Image`,
205-
# :class:`~torchvision.datapoints.Video`,
204+
# * If there is an :class:`~torchvision.tv_tensors.Image`,
205+
# :class:`~torchvision.tv_tensors.Video`,
206206
# or :class:`PIL.Image.Image` instance in the input, all other pure
207207
# tensors are passed-through.
208-
# * If there is no :class:`~torchvision.datapoints.Image` or
209-
# :class:`~torchvision.datapoints.Video` instance, only the first pure
208+
# * If there is no :class:`~torchvision.tv_tensors.Image` or
209+
# :class:`~torchvision.tv_tensors.Video` instance, only the first pure
210210
# :class:`torch.Tensor` will be transformed as image or video, while all
211211
# others will be passed-through. Here "first" means "first in a depth-wise
212212
# traversal".
@@ -234,9 +234,9 @@
234234
# Torchvision also supports datasets for object detection or segmentation like
235235
# :class:`torchvision.datasets.CocoDetection`. Those datasets predate
236236
# the existence of the :mod:`torchvision.transforms.v2` module and of the
237-
# datapoints, so they don't return datapoints out of the box.
237+
# tv_tensors, so they don't return tv_tensors out of the box.
238238
#
239-
# An easy way to force those datasets to return datapoints and to make them
239+
# An easy way to force those datasets to return tv_tensors and to make them
240240
# compatible with v2 transforms is to use the
241241
# :func:`torchvision.datasets.wrap_dataset_for_transforms_v2` function:
242242
#
@@ -246,14 +246,14 @@
246246
#
247247
# dataset = CocoDetection(..., transforms=my_transforms)
248248
# dataset = wrap_dataset_for_transforms_v2(dataset)
249-
# # Now the dataset returns datapoints!
249+
# # Now the dataset returns tv_tensors!
250250
#
251251
# Using your own datasets
252252
# ^^^^^^^^^^^^^^^^^^^^^^^
253253
#
254254
# If you have a custom dataset, then you'll need to convert your objects into
255-
# the appropriate Datapoint classes. Creating Datapoint instances is very easy,
256-
# refer to :ref:`datapoint_creation` for more details.
255+
# the appropriate TVTensor classes. Creating TVTensor instances is very easy,
256+
# refer to :ref:`tv_tensor_creation` for more details.
257257
#
258258
# There are two main places where you can implement that conversion logic:
259259
#

0 commit comments

Comments
 (0)