diff --git a/NEWS.md b/NEWS.md index 121d368c..5177adc4 100644 --- a/NEWS.md +++ b/NEWS.md @@ -2,6 +2,7 @@ ## New features +* Added segmentation article on `model_fcn_resnet50()` with two images (@DerrickUnleashed, #281). * Added collection dataset catalog with `search_collection()`, `get_collection_catalog()`, and `list_collection_datasets()` functions for discovering and exploring collections (#271, @ANAMASGARD). * Added `target_transform_coco_masks()` and `target_transform_trimap_masks()` transformation functions for explicit segmentation mask generation (@ANAMASGARD). @@ -12,6 +13,7 @@ ## New datasets +* Added `vggface2_dataset()` for loading the VGGFace2 dataset (@DerrickUnleashed, #238). * Added `moth` dataset to `rf100_biology_collection()` and `currency` and `wine_label` to `rf100_document_collection()` (#274). ## Bug fixes and improvements @@ -33,7 +35,6 @@ to non-vectorized `transform_` operations (#264) and `rf100_underwater_collection()` . Those are collection of datasets from RoboFlow 100 under the same thematic, for a total of 35 datasets (@koshtiakanksha, @cregouby, #239). * Added `rf100_peixos_segmentation_dataset()`. (@koshtiakanksha, @cregouby, #250). -* Added `vggface2_dataset()` for loading the VGGFace2 dataset (@DerrickUnleashed, #238). ## New models diff --git a/R/dataset-vggface2.R b/R/dataset-vggface2.R index ce725792..64f6e053 100644 --- a/R/dataset-vggface2.R +++ b/R/dataset-vggface2.R @@ -32,7 +32,7 @@ #' ds$classes[item$y] # list(name=..., gender=...) #' } #' -#' @family segmentation_dataset +#' @family classification_dataset #' @export vggface2_dataset <- torch::dataset( name = "vggface2", diff --git a/R/vision_utils.R b/R/vision_utils.R index 801ab697..b4515cd4 100644 --- a/R/vision_utils.R +++ b/R/vision_utils.R @@ -346,7 +346,7 @@ draw_segmentation_masks.torch_tensor <- function(x, if (masks$dtype != torch::torch_bool() && masks$dtype != torch::torch_float() ) { type_error("`masks` is expected to be of dtype torch_bool() or torch_float()") } - if (any(masks$shape[2:3] != img_to_draw$shape[2:3])) { + if (any(masks$shape[-2:-1] != img_to_draw$shape[-2:-1])) { value_error("`masks` and `image` must have the same height and width") } # if mask is a model inference output, we need to convert float mask to boolean mask diff --git a/_pkgdown.yml b/_pkgdown.yml index b3621d56..f0513dc5 100644 --- a/_pkgdown.yml +++ b/_pkgdown.yml @@ -27,6 +27,8 @@ navbar: href: articles/examples/style-transfer.html - text: texture-nca href: articles/examples/texture-nca.html + - text: fcnresnet + href: articles/examples/fcnresnet.html reference: - title: Transforms diff --git a/man/caltech_dataset.Rd b/man/caltech_dataset.Rd index 14642918..365b565d 100644 --- a/man/caltech_dataset.Rd +++ b/man/caltech_dataset.Rd @@ -86,6 +86,7 @@ Other classification_dataset: \code{\link{oxfordiiitpet_dataset}()}, \code{\link{places365_dataset}()}, \code{\link{tiny_imagenet_dataset}()}, +\code{\link{vggface2_dataset}()}, \code{\link{whoi_plankton_dataset}()}, \code{\link{whoi_small_coralnet_dataset}()} } diff --git a/man/cifar_datasets.Rd b/man/cifar_datasets.Rd index 72494b8e..be28853a 100644 --- a/man/cifar_datasets.Rd +++ b/man/cifar_datasets.Rd @@ -74,6 +74,7 @@ Other classification_dataset: \code{\link{oxfordiiitpet_dataset}()}, \code{\link{places365_dataset}()}, \code{\link{tiny_imagenet_dataset}()}, +\code{\link{vggface2_dataset}()}, \code{\link{whoi_plankton_dataset}()}, \code{\link{whoi_small_coralnet_dataset}()} } diff --git a/man/eurosat_dataset.Rd b/man/eurosat_dataset.Rd index 1e3b04fd..4192ef8f 100644 --- a/man/eurosat_dataset.Rd +++ b/man/eurosat_dataset.Rd @@ -90,6 +90,7 @@ Other classification_dataset: \code{\link{oxfordiiitpet_dataset}()}, \code{\link{places365_dataset}()}, \code{\link{tiny_imagenet_dataset}()}, +\code{\link{vggface2_dataset}()}, \code{\link{whoi_plankton_dataset}()}, \code{\link{whoi_small_coralnet_dataset}()} } diff --git a/man/fer_dataset.Rd b/man/fer_dataset.Rd index 6877592f..ce8d8d1d 100644 --- a/man/fer_dataset.Rd +++ b/man/fer_dataset.Rd @@ -67,6 +67,7 @@ Other classification_dataset: \code{\link{oxfordiiitpet_dataset}()}, \code{\link{places365_dataset}()}, \code{\link{tiny_imagenet_dataset}()}, +\code{\link{vggface2_dataset}()}, \code{\link{whoi_plankton_dataset}()}, \code{\link{whoi_small_coralnet_dataset}()} } diff --git a/man/fgvc_aircraft_dataset.Rd b/man/fgvc_aircraft_dataset.Rd index 79ff977f..d2bc4b2c 100644 --- a/man/fgvc_aircraft_dataset.Rd +++ b/man/fgvc_aircraft_dataset.Rd @@ -107,6 +107,7 @@ Other classification_dataset: \code{\link{oxfordiiitpet_dataset}()}, \code{\link{places365_dataset}()}, \code{\link{tiny_imagenet_dataset}()}, +\code{\link{vggface2_dataset}()}, \code{\link{whoi_plankton_dataset}()}, \code{\link{whoi_small_coralnet_dataset}()} } diff --git a/man/flowers102_dataset.Rd b/man/flowers102_dataset.Rd index 0894f193..dd2f9faa 100644 --- a/man/flowers102_dataset.Rd +++ b/man/flowers102_dataset.Rd @@ -80,6 +80,7 @@ Other classification_dataset: \code{\link{oxfordiiitpet_dataset}()}, \code{\link{places365_dataset}()}, \code{\link{tiny_imagenet_dataset}()}, +\code{\link{vggface2_dataset}()}, \code{\link{whoi_plankton_dataset}()}, \code{\link{whoi_small_coralnet_dataset}()} } diff --git a/man/image_folder_dataset.Rd b/man/image_folder_dataset.Rd index ee8bca36..18585829 100644 --- a/man/image_folder_dataset.Rd +++ b/man/image_folder_dataset.Rd @@ -59,6 +59,7 @@ Other classification_dataset: \code{\link{oxfordiiitpet_dataset}()}, \code{\link{places365_dataset}()}, \code{\link{tiny_imagenet_dataset}()}, +\code{\link{vggface2_dataset}()}, \code{\link{whoi_plankton_dataset}()}, \code{\link{whoi_small_coralnet_dataset}()} } diff --git a/man/lfw_dataset.Rd b/man/lfw_dataset.Rd index 84b1036d..a5a93873 100644 --- a/man/lfw_dataset.Rd +++ b/man/lfw_dataset.Rd @@ -123,6 +123,7 @@ Other classification_dataset: \code{\link{oxfordiiitpet_dataset}()}, \code{\link{places365_dataset}()}, \code{\link{tiny_imagenet_dataset}()}, +\code{\link{vggface2_dataset}()}, \code{\link{whoi_plankton_dataset}()}, \code{\link{whoi_small_coralnet_dataset}()} } diff --git a/man/mnist_dataset.Rd b/man/mnist_dataset.Rd index ff21937e..6c87e21f 100644 --- a/man/mnist_dataset.Rd +++ b/man/mnist_dataset.Rd @@ -158,6 +158,7 @@ Other classification_dataset: \code{\link{oxfordiiitpet_dataset}()}, \code{\link{places365_dataset}()}, \code{\link{tiny_imagenet_dataset}()}, +\code{\link{vggface2_dataset}()}, \code{\link{whoi_plankton_dataset}()}, \code{\link{whoi_small_coralnet_dataset}()} } diff --git a/man/oxfordiiitpet_dataset.Rd b/man/oxfordiiitpet_dataset.Rd index 26c2206f..6f992168 100644 --- a/man/oxfordiiitpet_dataset.Rd +++ b/man/oxfordiiitpet_dataset.Rd @@ -89,6 +89,7 @@ Other classification_dataset: \code{\link{mnist_dataset}()}, \code{\link{places365_dataset}()}, \code{\link{tiny_imagenet_dataset}()}, +\code{\link{vggface2_dataset}()}, \code{\link{whoi_plankton_dataset}()}, \code{\link{whoi_small_coralnet_dataset}()} } diff --git a/man/oxfordiiitpet_segmentation_dataset.Rd b/man/oxfordiiitpet_segmentation_dataset.Rd index 8a479a7b..bba73d07 100644 --- a/man/oxfordiiitpet_segmentation_dataset.Rd +++ b/man/oxfordiiitpet_segmentation_dataset.Rd @@ -78,7 +78,6 @@ tensor_image_browse(overlay) \seealso{ Other segmentation_dataset: \code{\link{pascal_voc_datasets}}, -\code{\link{rf100_peixos_segmentation_dataset}()}, -\code{\link{vggface2_dataset}()} +\code{\link{rf100_peixos_segmentation_dataset}()} } \concept{segmentation_dataset} diff --git a/man/pascal_voc_datasets.Rd b/man/pascal_voc_datasets.Rd index 91d6859e..24c198e4 100644 --- a/man/pascal_voc_datasets.Rd +++ b/man/pascal_voc_datasets.Rd @@ -129,8 +129,7 @@ tensor_image_browse(boxed_img) \seealso{ Other segmentation_dataset: \code{\link{oxfordiiitpet_segmentation_dataset}()}, -\code{\link{rf100_peixos_segmentation_dataset}()}, -\code{\link{vggface2_dataset}()} +\code{\link{rf100_peixos_segmentation_dataset}()} Other detection_dataset: \code{\link{coco_detection_dataset}()}, diff --git a/man/places365_dataset.Rd b/man/places365_dataset.Rd index 4b6787a3..00990d1c 100644 --- a/man/places365_dataset.Rd +++ b/man/places365_dataset.Rd @@ -110,6 +110,7 @@ Other classification_dataset: \code{\link{mnist_dataset}()}, \code{\link{oxfordiiitpet_dataset}()}, \code{\link{tiny_imagenet_dataset}()}, +\code{\link{vggface2_dataset}()}, \code{\link{whoi_plankton_dataset}()}, \code{\link{whoi_small_coralnet_dataset}()} } diff --git a/man/rf100_peixos_segmentation_dataset.Rd b/man/rf100_peixos_segmentation_dataset.Rd index a38622f9..9fd991b1 100644 --- a/man/rf100_peixos_segmentation_dataset.Rd +++ b/man/rf100_peixos_segmentation_dataset.Rd @@ -60,7 +60,6 @@ tensor_image_browse(overlay) \seealso{ Other segmentation_dataset: \code{\link{oxfordiiitpet_segmentation_dataset}()}, -\code{\link{pascal_voc_datasets}}, -\code{\link{vggface2_dataset}()} +\code{\link{pascal_voc_datasets}} } \concept{segmentation_dataset} diff --git a/man/tiny_imagenet_dataset.Rd b/man/tiny_imagenet_dataset.Rd index 35234258..d8fb7acc 100644 --- a/man/tiny_imagenet_dataset.Rd +++ b/man/tiny_imagenet_dataset.Rd @@ -31,6 +31,7 @@ Other classification_dataset: \code{\link{mnist_dataset}()}, \code{\link{oxfordiiitpet_dataset}()}, \code{\link{places365_dataset}()}, +\code{\link{vggface2_dataset}()}, \code{\link{whoi_plankton_dataset}()}, \code{\link{whoi_small_coralnet_dataset}()} } diff --git a/man/vggface2_dataset.Rd b/man/vggface2_dataset.Rd index 5af4efa7..d84d77cc 100644 --- a/man/vggface2_dataset.Rd +++ b/man/vggface2_dataset.Rd @@ -60,9 +60,20 @@ ds$classes[item$y] # list(name=..., gender=...) } \seealso{ -Other segmentation_dataset: -\code{\link{oxfordiiitpet_segmentation_dataset}()}, -\code{\link{pascal_voc_datasets}}, -\code{\link{rf100_peixos_segmentation_dataset}()} +Other classification_dataset: +\code{\link{caltech_dataset}}, +\code{\link{cifar10_dataset}()}, +\code{\link{eurosat_dataset}()}, +\code{\link{fer_dataset}()}, +\code{\link{fgvc_aircraft_dataset}()}, +\code{\link{flowers102_dataset}()}, +\code{\link{image_folder_dataset}()}, +\code{\link{lfw_dataset}}, +\code{\link{mnist_dataset}()}, +\code{\link{oxfordiiitpet_dataset}()}, +\code{\link{places365_dataset}()}, +\code{\link{tiny_imagenet_dataset}()}, +\code{\link{whoi_plankton_dataset}()}, +\code{\link{whoi_small_coralnet_dataset}()} } -\concept{segmentation_dataset} +\concept{classification_dataset} diff --git a/man/whoi_plankton_dataset.Rd b/man/whoi_plankton_dataset.Rd index fc42ca4f..30ced205 100644 --- a/man/whoi_plankton_dataset.Rd +++ b/man/whoi_plankton_dataset.Rd @@ -89,6 +89,7 @@ Other classification_dataset: \code{\link{oxfordiiitpet_dataset}()}, \code{\link{places365_dataset}()}, \code{\link{tiny_imagenet_dataset}()}, +\code{\link{vggface2_dataset}()}, \code{\link{whoi_small_coralnet_dataset}()} } \concept{classification_dataset} diff --git a/man/whoi_small_coralnet_dataset.Rd b/man/whoi_small_coralnet_dataset.Rd index bb691430..4a7adc0b 100644 --- a/man/whoi_small_coralnet_dataset.Rd +++ b/man/whoi_small_coralnet_dataset.Rd @@ -40,6 +40,7 @@ Other classification_dataset: \code{\link{oxfordiiitpet_dataset}()}, \code{\link{places365_dataset}()}, \code{\link{tiny_imagenet_dataset}()}, +\code{\link{vggface2_dataset}()}, \code{\link{whoi_plankton_dataset}()} } \concept{classification_dataset} diff --git a/tests/testthat/test-dataset-coco.R b/tests/testthat/test-dataset-coco.R index 9257a27b..cbb20b58 100644 --- a/tests/testthat/test-dataset-coco.R +++ b/tests/testthat/test-dataset-coco.R @@ -16,7 +16,7 @@ test_that("coco_detection_dataset handles missing files gracefully", { }) test_that("coco_detection_dataset loads a single example correctly", { - skip_if(Sys.getenv("TEST_LARGE_DATASETS", unset = 0) < 1, + skip_if(Sys.getenv("TEST_LARGE_DATASETS", unset = 0) != 1, "Skipping test: set TEST_LARGE_DATASETS=1 to enable tests requiring large downloads.") ds <- coco_detection_dataset(root = tmp, train = FALSE, year = "2017", download = TRUE) @@ -47,7 +47,7 @@ test_that("coco_detection_dataset loads a single example correctly", { }) test_that("coco_ dataset loads a single segmentation example correctly", { - skip_if(Sys.getenv("TEST_LARGE_DATASETS", unset = 0) < 1, + skip_if(Sys.getenv("TEST_LARGE_DATASETS", unset = 0) != 1, "Skipping test: set TEST_LARGE_DATASETS=1 to enable tests requiring large downloads.") ds <- coco_detection_dataset(root = tmp, train = FALSE, year = "2017", download = TRUE, @@ -71,7 +71,7 @@ test_that("coco_ dataset loads a single segmentation example correctly", { }) test_that("coco_detection_dataset batches correctly using dataloader", { - skip_if(Sys.getenv("TEST_LARGE_DATASETS", unset = 0) < 1, + skip_if(Sys.getenv("TEST_LARGE_DATASETS", unset = 0) != 1, "Skipping test: set TEST_LARGE_DATASETS=1 to enable tests requiring large downloads.") @@ -99,8 +99,8 @@ test_that("coco_caption_dataset handles missing files gracefully", { }) test_that("coco_caption_dataset loads a single example correctly", { - skip_if(Sys.getenv("TEST_LARGE_DATASETS", unset = 0) < 2, - "Skipping test: set TEST_LARGE_DATASETS=2 to enable tests requiring huge downloads.") + skip_if(Sys.getenv("TEST_HUGE_DATASETS", unset = 0) != 1, + "Skipping test: set TEST_HUGE_DATASETS=1 to enable tests requiring huge downloads.") ds <- coco_caption_dataset(root = tmp, train = FALSE, download = TRUE) @@ -120,8 +120,8 @@ test_that("coco_caption_dataset loads a single example correctly", { }) test_that("coco_caption_dataset batches correctly using dataloader", { - skip_if(Sys.getenv("TEST_LARGE_DATASETS", unset = 0) < 2, - "Skipping test: set TEST_LARGE_DATASETS=2 to enable tests requiring huge downloads.") + skip_if(Sys.getenv("TEST_HUGE_DATASETS", unset = 0) != 1, + "Skipping test: set TEST_HUGE_DATASETS=1 to enable tests requiring huge downloads.") ds <- coco_caption_dataset(root = tmp, train = FALSE, download = TRUE) diff --git a/vignettes/examples/fcnresnet.R b/vignettes/examples/fcnresnet.R new file mode 100644 index 00000000..ae456f74 --- /dev/null +++ b/vignettes/examples/fcnresnet.R @@ -0,0 +1,69 @@ +# Loading Images --------------------------------------------------- +library(torchvision) +library(torch) + +url1 <- "https://raw.githubusercontent.com/pytorch/vision/main/gallery/assets/dog1.jpg" +url2 <- "https://raw.githubusercontent.com/pytorch/vision/main/gallery/assets/dog2.jpg" + +dog1 <- magick_loader(url1) |> transform_to_tensor() +dog2 <- magick_loader(url2) |> transform_to_tensor() + + +# Visualizing a grid of images ------------------------------------- + + +dogs <- torch_stack(list(dog1, dog2)) +grid <- vision_make_grid(dogs, scale = TRUE, num_rows = 2) +tensor_image_browse(grid) + + +# Preprocessing the data ------------------------------------- + + +norm_mean <- c(0.485, 0.456, 0.406) +norm_std <- c(0.229, 0.224, 0.225) + +dog1_prep <- dog1 |> + transform_resize(c(520,520)) |> + transform_normalize(mean = norm_mean, std = norm_std) +dog2_prep <- dog2 |> + transform_resize(c(520,520)) |> + transform_normalize(mean = norm_mean, std = norm_std) + +# make batch (2,3,520,520) +dog_batch <- torch_stack(list(dog1_prep, dog2_prep)) + + +# Loading Model ------------------------------------- + + +model <- model_fcn_resnet50(pretrained = TRUE) +model$eval() + +# run model +output <- model(dog_batch) + + +# Processing the Output ------------------------------ + +mask <- output$out +mask$shape +mask$dtype + +# Visualizing the Output ------------------------------ + + +segmented1 <- draw_segmentation_masks( + dog1 |> transform_resize(c(520,520)), + masks = mask[1,, ], + alpha = 0.5 +) + +segmented2 <- draw_segmentation_masks( + dog2 |> transform_resize(c(520,520)), + masks = mask[2,, ], + alpha = 0.5 +) + +tensor_image_browse(segmented1) +tensor_image_browse(segmented2) diff --git a/vignettes/examples/fcnresnet.Rmd b/vignettes/examples/fcnresnet.Rmd new file mode 100644 index 00000000..237fde8d --- /dev/null +++ b/vignettes/examples/fcnresnet.Rmd @@ -0,0 +1,9 @@ +--- +title: "fcnresnet" +type: docs +--- + +```{r, echo = FALSE} +knitr::opts_chunk$set(eval = TRUE) +knitr::spin_child(paste0(rmarkdown::metadata$title, ".R")) +```