Commit bf491463 authored by limm's avatar limm
Browse files

add v0.19.1 release

parent e17f5ea2
.. _tv_tensors:
TVTensors
==========
.. currentmodule:: torchvision.tv_tensors
TVTensors are :class:`torch.Tensor` subclasses which the v2 :ref:`transforms
<transforms>` use under the hood to dispatch their inputs to the appropriate
lower-level kernels. Most users do not need to manipulate TVTensors directly.
Refer to
:ref:`sphx_glr_auto_examples_transforms_plot_transforms_getting_started.py` for
an introduction to TVTensors, or
:ref:`sphx_glr_auto_examples_transforms_plot_tv_tensors.py` for more advanced
info.
.. autosummary::
:toctree: generated/
:template: class.rst
Image
Video
BoundingBoxFormat
BoundingBoxes
Mask
TVTensor
set_return_type
wrap
torchvision.utils .. _utils:
=================
.. currentmodule:: torchvision.utils Utils
=====
.. autofunction:: make_grid The ``torchvision.utils`` module contains various utilities, mostly :ref:`for
visualization <sphx_glr_auto_examples_others_plot_visualization_utils.py>`.
.. autofunction:: save_image .. currentmodule:: torchvision.utils
.. autofunction:: draw_bounding_boxes .. autosummary::
:toctree: generated/
:template: function.rst
.. autofunction:: draw_segmentation_masks draw_bounding_boxes
draw_segmentation_masks
draw_keypoints
flow_to_image
make_grid
save_image
cmake_minimum_required(VERSION 3.10)
project(run_model)
option(USE_TORCHVISION "Whether to link to torchvision" OFF)
find_package(Torch REQUIRED)
if(USE_TORCHVISION)
find_package(TorchVision REQUIRED)
endif()
add_executable(run_model run_model.cpp)
target_link_libraries(run_model "${TORCH_LIBRARIES}")
if(USE_TORCHVISION)
target_link_libraries(run_model TorchVision::TorchVision)
endif()
set_property(TARGET run_model PROPERTY CXX_STANDARD 17)
Using torchvision models in C++
===============================
This is a minimal example of getting TorchVision models to work in C++ with
Torchscript. The model is first scripted in Python and exported to a file, and
then loaded in C++. For a similar tutorial, see [this
tutorial](https://pytorch.org/tutorials/advanced/cpp_export.html).
In order to successfully compile this example, make sure you have ``LibTorch``
installed. You can either:
- Install PyTorch normally
- Or download the LibTorch C++ distribution.
In both cases refer [here](https://pytorch.org/get-started/locally/) the
corresponding install or download instructions.
Some torchvision models only depend on PyTorch operators, and can be used in C++
without depending on the torchvision lib. Other models rely on torchvision's C++
operators like NMS, RoiAlign (typically the detection models) and those need to
be linked against the torchvision lib.
We'll first see the simpler case of running a model without the torchvision lib
dependency.
Running a model that doesn't need torchvision lib
-------------------------------------------------
Create a ``build`` directory inside the current one.
```bash
mkdir build
cd build
```
Then run `python ../trace_model.py` which should create a `resnet18.pt` file in
the build directory. This is the scripted model that will be used in the C++
code.
We can now start building with CMake. We have to tell CMake where it can find
the necessary PyTorch resources. If you installed PyTorch normally, you can do:
```bash
TORCH_PATH=$(python -c "import pathlib, torch; print(pathlib.Path(torch.__path__[0]))")
Torch_DIR="${TORCH_PATH}/share/cmake/Torch" # there should be .cmake files in there
cmake .. -DTorch_DIR=$Torch_DIR
```
If instead you downloaded the LibTorch somewhere, you can do:
```bash
cmake .. -DCMAKE_PREFIX_PATH=/path/to/libtorch
```
Then `cmake --build .` and you should now be able to run
```bash
./run_model resnet18.pt
```
If you try to run the model with a model that depends on the torchvision lib, like
`./run_model fasterrcnn_resnet50_fpn.pt`, you should get a runtime error. This is
because the executable wasn't linked against the torchvision lib.
Running a model that needs torchvision lib
------------------------------------------
First, we need to build the torchvision lib. To build the torchvision lib go to
the root of the torchvision project and run:
```bash
mkdir build
cd build
cmake .. -DCMAKE_PREFIX_PATH=/path/to/libtorch # or -DTorch_DIR= if you installed PyTorch normally, see above
cmake --build .
cmake --install .
```
You may want to pass `-DCMAKE_INSTALL_PREFIX=/path/to/libtorchvision` for
cmake to copy/install the files to a specific location (e.g. `$CONDA_PREFIX`).
**DISCLAIMER**: the `libtorchvision` library includes the torchvision
custom ops as well as most of the C++ torchvision APIs. Those APIs do not come
with any backward-compatibility guarantees and may change from one version to
the next. Only the Python APIs are stable and with backward-compatibility
guarantees. So, if you need stability within a C++ environment, your best bet is
to export the Python APIs via torchscript.
Now that libtorchvision is built and installed we can tell our project to use
and link to it via the `-DUSE_TORCHVISION` flag. We also need to tell CMake
where to find it, just like we did with LibTorch, e.g.:
```bash
cmake .. -DTorch_DIR=$Torch_DIR -DTorchVision_DIR=path/to/libtorchvision -DUSE_TORCHVISION=ON
cmake --build .
```
Now the `run_model` executable should be able to run the
`fasterrcnn_resnet50_fpn.pt` file.
cmake_minimum_required(VERSION 3.10)
project(hello-world)
# The first thing do is to tell cmake to find the TorchVision library.
# The package pulls in all the necessary torch libraries,
# so there is no need to also add `find_package(Torch)` here.
find_package(TorchVision REQUIRED)
add_executable(hello-world main.cpp)
# We now need to link the TorchVision library to our executable.
# We can do that by using the TorchVision::TorchVision target,
# which also adds all the necessary torch dependencies.
target_compile_features(hello-world PUBLIC cxx_range_for)
target_link_libraries(hello-world TorchVision::TorchVision)
set_property(TARGET hello-world PROPERTY CXX_STANDARD 14)
Hello World!
============
This is a minimal example of getting TorchVision to work in C++ with CMake.
In order to successfully compile this example, make sure you have both ``LibTorch`` and
``TorchVision`` installed.
Once both dependencies are sorted, we can start the CMake fun:
1) Create a ``build`` directory inside the current one.
2) from within the ``build`` directory, run the following commands:
- | ``cmake -DCMAKE_PREFIX_PATH="<PATH_TO_LIBTORCH>;<PATH_TO_TORCHVISION>" ..``
| where ``<PATH_TO_LIBTORCH>`` and ``<PATH_TO_TORCHVISION>`` are the paths to the libtorch and torchvision installations.
- ``cmake --build .``
| That's it!
| You should now have a ``hello-world`` executable in your ``build`` folder.
Running it will output a (fairly long) tensor of random values to your terminal.
\ No newline at end of file
#include <iostream>
#include <torch/torch.h>
#include <torchvision/vision.h>
#include <torchvision/models/resnet.h>
int main()
{
auto model = vision::models::ResNet18();
model->eval();
// Create a random input tensor and run it through the model.
auto in = torch::rand({1, 3, 10, 10});
auto out = model->forward(in);
std::cout << out.sizes();
if (torch::cuda::is_available()) {
// Move model and inputs to GPU
model->to(torch::kCUDA);
auto gpu_in = in.to(torch::kCUDA);
auto gpu_out = model->forward(gpu_in);
std::cout << gpu_out.sizes();
}
}
#include <torch/script.h> #include <torch/script.h>
#include <torch/torch.h> #include <torch/torch.h>
#include <torchvision/vision.h> #include <cstring>
#include <torchvision/ops/nms.h> #include <iostream>
#ifdef _WIN32
#include <torchvision/vision.h>
#endif // _WIN32
int main() { int main(int argc, const char* argv[]) {
if (argc != 2) {
std::cout << "Usage: run_model <path_to_scripted_model>\n";
return -1;
}
torch::DeviceType device_type; torch::DeviceType device_type;
device_type = torch::kCPU; device_type = torch::kCPU;
torch::jit::script::Module module; torch::jit::script::Module model;
try { try {
std::cout << "Loading model\n"; std::cout << "Loading model\n";
// Deserialize the ScriptModule from a file using torch::jit::load(). // Deserialize the ScriptModule from a file using torch::jit::load().
module = torch::jit::load("fasterrcnn_resnet50_fpn.pt"); model = torch::jit::load(argv[1]);
std::cout << "Model loaded\n"; std::cout << "Model loaded\n";
} catch (const torch::Error& e) { } catch (const torch::Error& e) {
std::cout << "error loading the model\n"; std::cout << "error loading the model.\n";
return -1; return -1;
} catch (const std::exception& e) { } catch (const std::exception& e) {
std::cout << "Other error: " << e.what() << "\n"; std::cout << "Other error: " << e.what() << "\n";
...@@ -25,34 +32,36 @@ int main() { ...@@ -25,34 +32,36 @@ int main() {
// TorchScript models require a List[IValue] as input // TorchScript models require a List[IValue] as input
std::vector<torch::jit::IValue> inputs; std::vector<torch::jit::IValue> inputs;
if (std::strstr(argv[1], "fasterrcnn") != NULL) {
// Faster RCNN accepts a List[Tensor] as main input // Faster RCNN accepts a List[Tensor] as main input
std::vector<torch::Tensor> images; std::vector<torch::Tensor> images;
images.push_back(torch::rand({3, 256, 275})); images.push_back(torch::rand({3, 256, 275}));
images.push_back(torch::rand({3, 256, 275})); images.push_back(torch::rand({3, 256, 275}));
inputs.push_back(images); inputs.push_back(images);
auto output = module.forward(inputs); } else {
inputs.push_back(torch::rand({1, 3, 10, 10}));
std::cout << "ok\n"; }
std::cout << "output" << output << "\n"; auto out = model.forward(inputs);
std::cout << out << "\n";
if (torch::cuda::is_available()) { if (torch::cuda::is_available()) {
// Move traced model to GPU // Move model and inputs to GPU
module.to(torch::kCUDA); model.to(torch::kCUDA);
// Add GPU inputs // Add GPU inputs
images.clear();
inputs.clear(); inputs.clear();
torch::TensorOptions options = torch::TensorOptions{torch::kCUDA}; torch::TensorOptions options = torch::TensorOptions{torch::kCUDA};
if (std::strstr(argv[1], "fasterrcnn") != NULL) {
// Faster RCNN accepts a List[Tensor] as main input
std::vector<torch::Tensor> images;
images.push_back(torch::rand({3, 256, 275}, options)); images.push_back(torch::rand({3, 256, 275}, options));
images.push_back(torch::rand({3, 256, 275}, options)); images.push_back(torch::rand({3, 256, 275}, options));
inputs.push_back(images); inputs.push_back(images);
auto output = module.forward(inputs); } else {
inputs.push_back(torch::rand({1, 3, 10, 10}, options));
}
std::cout << "ok\n"; auto gpu_out = model.forward(inputs);
std::cout << "output" << output << "\n"; std::cout << gpu_out << "\n";
} }
return 0;
} }
import torch
from torchvision import models
for model, name in (
(models.resnet18(weights=None), "resnet18"),
(models.detection.fasterrcnn_resnet50_fpn(weights=None, weights_backbone=None), "fasterrcnn_resnet50_fpn"),
):
model.eval()
traced_model = torch.jit.script(model)
traced_model.save(f"{name}.pt")
# Python examples # Python examples
- [![Open In Colab](https://colab.research.google.com/assets/colab-badge.svg)](https://colab.research.google.com/github/pytorch/vision/blob/master/examples/python/tensor_transforms.ipynb) The examples in this directory have been moved online in our [gallery
[Examples of Tensor Images transformations](https://github.com/pytorch/vision/blob/master/examples/python/tensor_transforms.ipynb) page](https://pytorch.org/vision/stable/auto_examples/index.html).
- [![Open In Colab](https://colab.research.google.com/assets/colab-badge.svg)](https://colab.research.google.com/github/pytorch/vision/blob/master/examples/python/video_api.ipynb)
[Example of VideoAPI](https://github.com/pytorch/vision/blob/master/examples/python/video_api.ipynb)
- [![Open In Colab](https://colab.research.google.com/assets/colab-badge.svg)](https://colab.research.google.com/github/pytorch/vision/blob/master/examples/python/visualization_utils.ipynb)
[Example of Visualization Utils](https://github.com/pytorch/vision/blob/master/examples/python/visualization_utils.ipynb)
Prior to v0.8.0, transforms in torchvision have traditionally been PIL-centric and presented multiple limitations due to
that. Now, since v0.8.0, transforms implementations are Tensor and PIL compatible and we can achieve the following new
features:
- transform multi-band torch tensor images (with more than 3-4 channels)
- torchscript transforms together with your model for deployment
- support for GPU acceleration
- batched transformation such as for videos
- read and decode data directly as torch tensor with torchscript support (for PNG and JPEG image formats)
Furthermore, previously we used to provide a very high-level API for video decoding which left little control to the user. We're now expanding that API (and replacing it in the future) with a lower-level API that allows the user a frame-based access to a video.
Torchvision also provides utilities to visualize results. You can make grid of images, plot bounding boxes as well as segmentation masks. Thse utilities work standalone as well as with torchvision models for detection and segmentation.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
Example gallery .. _gallery:
===============
Below is a gallery of examples Examples and tutorials
\ No newline at end of file ======================
../../astronaut.jpg
\ No newline at end of file
../../dog2.jpg
\ No newline at end of file
{"images": [{"file_name": "000000000001.jpg", "height": 512, "width": 512, "id": 1}, {"file_name": "000000000002.jpg", "height": 500, "width": 500, "id": 2}], "annotations": [{"segmentation": [[40.0, 511.0, 26.0, 487.0, 28.0, 438.0, 17.0, 397.0, 24.0, 346.0, 38.0, 306.0, 61.0, 250.0, 111.0, 206.0, 111.0, 187.0, 120.0, 183.0, 136.0, 159.0, 159.0, 150.0, 181.0, 148.0, 182.0, 132.0, 175.0, 132.0, 168.0, 120.0, 154.0, 102.0, 153.0, 62.0, 188.0, 35.0, 191.0, 29.0, 208.0, 20.0, 210.0, 22.0, 227.0, 16.0, 240.0, 16.0, 276.0, 31.0, 285.0, 39.0, 301.0, 88.0, 297.0, 108.0, 281.0, 128.0, 273.0, 138.0, 266.0, 138.0, 264.0, 153.0, 257.0, 162.0, 256.0, 174.0, 284.0, 197.0, 300.0, 221.0, 303.0, 236.0, 337.0, 258.0, 357.0, 306.0, 361.0, 351.0, 358.0, 511.0]], "iscrowd": 0, "image_id": 1, "bbox": [17.0, 16.0, 344.0, 495.0], "category_id": 1, "id": 1}, {"segmentation": [[0.0, 411.0, 43.0, 401.0, 99.0, 395.0, 105.0, 351.0, 124.0, 326.0, 181.0, 294.0, 227.0, 280.0, 245.0, 262.0, 259.0, 234.0, 262.0, 207.0, 271.0, 140.0, 283.0, 139.0, 301.0, 162.0, 309.0, 181.0, 341.0, 175.0, 362.0, 139.0, 369.0, 139.0, 377.0, 163.0, 378.0, 203.0, 381.0, 212.0, 380.0, 220.0, 382.0, 242.0, 404.0, 264.0, 392.0, 293.0, 384.0, 295.0, 385.0, 316.0, 399.0, 343.0, 391.0, 448.0, 452.0, 475.0, 457.0, 494.0, 436.0, 498.0, 402.0, 491.0, 369.0, 488.0, 366.0, 496.0, 319.0, 496.0, 302.0, 485.0, 226.0, 469.0, 128.0, 456.0, 74.0, 458.0, 29.0, 439.0, 0.0, 445.0]], "iscrowd": 0, "image_id": 2, "bbox": [0.0, 139.0, 457.0, 359.0], "category_id": 18, "id": 2}]}
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment