We are currently solving the following issue within our repository. Here is the issue text:
--- BEGIN ISSUE ---
Select subset of classes to sample from
## 🚀 Feature

When loading a dataset with `ImageFolder` provide an optional argument to select a subset of classes.

## Motivation

I deal with large (1000+) multi-class datasets upon which I train image classifiers. However, I usually don't want to train for all the classes at the same time.
## Pitch

I'd like to change `find_classes` function
https://github.com/pytorch/vision/blob/20a771e5143c6867eee63868c38a5bcc272a35e7/torchvision/datasets/folder.py#L61

to 

```python
classes = sorted(entry.name for entry in os.scandir(directory) 
                 if entry.is_dir() and (entry.name in allowed_classes or not allowed_classes))
```

where `allowed_classes: Optional[str] = []` is an empty list by default but it can given to `ImageFolder` at initialisation time (it has to be propagated back to `DatasetFolder` where `find_classes` is used).

## Alternatives

I tried to

1) manually create a new folder structure with only the relevant classes. This gets messy quite fast as I have now multiple versions of the same folders
2) resort to a custom dataloader filtering loaded samples after initialisation (obviously this is very slow as soon as the number of images increases)

## Additional context

Here I found a discussion on the same topic.

https://discuss.pytorch.org/t/how-to-sample-images-belonging-to-particular-classes/43776/8


cc @pmeier

--- END ISSUE ---

Below are some code segments, each from a relevant file. One or more of these files may contain bugs.
--- BEGIN FILES ---
Path: `torchvision/datasets/folder.py`
Content:
```
1 from .vision import VisionDataset
2 
3 from PIL import Image
4 
5 import os
6 import os.path
7 from typing import Any, Callable, cast, Dict, List, Optional, Tuple
8 
9 
10 def has_file_allowed_extension(filename: str, extensions: Tuple[str, ...]) -> bool:
11     """Checks if a file is an allowed extension.
12 
13     Args:
14         filename (string): path to a file
15         extensions (tuple of strings): extensions to consider (lowercase)
16 
17     Returns:
18         bool: True if the filename ends with one of given extensions
19     """
20     return filename.lower().endswith(extensions)
21 
22 
23 def is_image_file(filename: str) -> bool:
24     """Checks if a file is an allowed image extension.
25 
26     Args:
27         filename (string): path to a file
28 
29     Returns:
30         bool: True if the filename ends with a known image extension
31     """
32     return has_file_allowed_extension(filename, IMG_EXTENSIONS)
33 
34 
35 def find_classes(directory: str) -> Tuple[List[str], Dict[str, int]]:
36     """Finds the class folders in a dataset structured as follows:
37 
38     .. code::
39 
40         directory/
41         ├── class_x
42         │   ├── xxx.ext
43         │   ├── xxy.ext
44         │   └── ...
45         │       └── xxz.ext
46         └── class_y
47             ├── 123.ext
48             ├── nsdf3.ext
49             └── ...
50                 └── asd932_.ext
51 
52     Args:
53         directory (str): Root directory path.
54 
55     Raises:
56         FileNotFoundError: If ``directory`` has no class folders.
57 
58     Returns:
59         (Tuple[List[str], Dict[str, int]]): List of all classes and dictionary mapping each class to an index.
60     """
61     classes = sorted(entry.name for entry in os.scandir(directory) if entry.is_dir())
62     if not classes:
63         raise FileNotFoundError(f"Couldn't find any class folder in {directory}.")
64 
65     class_to_idx = {cls_name: i for i, cls_name in enumerate(classes)}
66     return classes, class_to_idx
67 
68 
69 def make_dataset(
70     directory: str,
71     class_to_idx: Optional[Dict[str, int]] = None,
72     extensions: Optional[Tuple[str, ...]] = None,
73     is_valid_file: Optional[Callable[[str], bool]] = None,
74 ) -> List[Tuple[str, int]]:
75     """Generates a list of samples of a form (path_to_sample, class).
76 
77     Args:
78         directory (str): root dataset directory
79         class_to_idx (Optional[Dict[str, int]]): Dictionary mapping class name to class index. If omitted, is generated
80             by :func:`find_classes`.
81         extensions (optional): A list of allowed extensions.
82             Either extensions or is_valid_file should be passed. Defaults to None.
83         is_valid_file (optional): A function that takes path of a file
84             and checks if the file is a valid file
85             (used to check of corrupt files) both extensions and
86             is_valid_file should not be passed. Defaults to None.
87 
88     Raises:
89         ValueError: In case ``class_to_idx`` is empty.
90         ValueError: In case ``extensions`` and ``is_valid_file`` are None or both are not None.
91         FileNotFoundError: In case no valid file was found for any class.
92 
93     Returns:
94         List[Tuple[str, int]]: samples of a form (path_to_sample, class)
95     """
96     directory = os.path.expanduser(directory)
97 
98     if class_to_idx is None:
99         _, class_to_idx = find_classes(directory)
100     elif not class_to_idx:
101         raise ValueError("'class_to_index' must have at least one entry to collect any samples.")
102 
103     both_none = extensions is None and is_valid_file is None
104     both_something = extensions is not None and is_valid_file is not None
105     if both_none or both_something:
106         raise ValueError("Both extensions and is_valid_file cannot be None or not None at the same time")
107 
108     if extensions is not None:
109 
110         def is_valid_file(x: str) -> bool:
111             return has_file_allowed_extension(x, cast(Tuple[str, ...], extensions))
112 
113     is_valid_file = cast(Callable[[str], bool], is_valid_file)
114 
115     instances = []
116     available_classes = set()
117     for target_class in sorted(class_to_idx.keys()):
118         class_index = class_to_idx[target_class]
119         target_dir = os.path.join(directory, target_class)
120         if not os.path.isdir(target_dir):
121             continue
122         for root, _, fnames in sorted(os.walk(target_dir, followlinks=True)):
123             for fname in sorted(fnames):
124                 path = os.path.join(root, fname)
125                 if is_valid_file(path):
126                     item = path, class_index
127                     instances.append(item)
128 
129                     if target_class not in available_classes:
130                         available_classes.add(target_class)
131 
132     empty_classes = set(class_to_idx.keys()) - available_classes
133     if empty_classes:
134         msg = f"Found no valid file for the classes {', '.join(sorted(empty_classes))}. "
135         if extensions is not None:
136             msg += f"Supported extensions are: {', '.join(extensions)}"
137         raise FileNotFoundError(msg)
138 
139     return instances
140 
141 
142 class DatasetFolder(VisionDataset):
143     """A generic data loader where the samples are arranged in this way: ::
144 
145         root/class_x/xxx.ext
146         root/class_x/xxy.ext
147         root/class_x/[...]/xxz.ext
148 
149         root/class_y/123.ext
150         root/class_y/nsdf3.ext
151         root/class_y/[...]/asd932_.ext
152 
153     Args:
154         root (string): Root directory path.
155         loader (callable): A function to load a sample given its path.
156         extensions (tuple[string]): A list of allowed extensions.
157             both extensions and is_valid_file should not be passed.
158         transform (callable, optional): A function/transform that takes in
159             a sample and returns a transformed version.
160             E.g, ``transforms.RandomCrop`` for images.
161         target_transform (callable, optional): A function/transform that takes
162             in the target and transforms it.
163         is_valid_file (callable, optional): A function that takes path of a file
164             and check if the file is a valid file (used to check of corrupt files)
165             both extensions and is_valid_file should not be passed.
166 
167      Attributes:
168         classes (list): List of the class names sorted alphabetically.
169         class_to_idx (dict): Dict with items (class_name, class_index).
170         samples (list): List of (sample path, class_index) tuples
171         targets (list): The class_index value for each image in the dataset
172     """
173 
174     def __init__(
175             self,
176             root: str,
177             loader: Callable[[str], Any],
178             extensions: Optional[Tuple[str, ...]] = None,
179             transform: Optional[Callable] = None,
180             target_transform: Optional[Callable] = None,
181             is_valid_file: Optional[Callable[[str], bool]] = None,
182     ) -> None:
183         super(DatasetFolder, self).__init__(root, transform=transform,
184                                             target_transform=target_transform)
185         classes, class_to_idx = self._find_classes(self.root)
186         samples = self.make_dataset(self.root, class_to_idx, extensions, is_valid_file)
187 
188         self.loader = loader
189         self.extensions = extensions
190 
191         self.classes = classes
192         self.class_to_idx = class_to_idx
193         self.samples = samples
194         self.targets = [s[1] for s in samples]
195 
196     @staticmethod
197     def make_dataset(
198         directory: str,
199         class_to_idx: Dict[str, int],
200         extensions: Optional[Tuple[str, ...]] = None,
201         is_valid_file: Optional[Callable[[str], bool]] = None,
202     ) -> List[Tuple[str, int]]:
203         return make_dataset(directory, class_to_idx, extensions=extensions, is_valid_file=is_valid_file)
204 
205     @staticmethod
206     def _find_classes(dir: str) -> Tuple[List[str], Dict[str, int]]:
207         return find_classes(dir)
208 
209     def __getitem__(self, index: int) -> Tuple[Any, Any]:
210         """
211         Args:
212             index (int): Index
213 
214         Returns:
215             tuple: (sample, target) where target is class_index of the target class.
216         """
217         path, target = self.samples[index]
218         sample = self.loader(path)
219         if self.transform is not None:
220             sample = self.transform(sample)
221         if self.target_transform is not None:
222             target = self.target_transform(target)
223 
224         return sample, target
225 
226     def __len__(self) -> int:
227         return len(self.samples)
228 
229 
230 IMG_EXTENSIONS = ('.jpg', '.jpeg', '.png', '.ppm', '.bmp', '.pgm', '.tif', '.tiff', '.webp')
231 
232 
233 def pil_loader(path: str) -> Image.Image:
234     # open path as file to avoid ResourceWarning (https://github.com/python-pillow/Pillow/issues/835)
235     with open(path, 'rb') as f:
236         img = Image.open(f)
237         return img.convert('RGB')
238 
239 
240 # TODO: specify the return type
241 def accimage_loader(path: str) -> Any:
242     import accimage
243     try:
244         return accimage.Image(path)
245     except IOError:
246         # Potentially a decoding problem, fall back to PIL.Image
247         return pil_loader(path)
248 
249 
250 def default_loader(path: str) -> Any:
251     from torchvision import get_image_backend
252     if get_image_backend() == 'accimage':
253         return accimage_loader(path)
254     else:
255         return pil_loader(path)
256 
257 
258 class ImageFolder(DatasetFolder):
259     """A generic data loader where the images are arranged in this way: ::
260 
261         root/dog/xxx.png
262         root/dog/xxy.png
263         root/dog/[...]/xxz.png
264 
265         root/cat/123.png
266         root/cat/nsdf3.png
267         root/cat/[...]/asd932_.png
268 
269     Args:
270         root (string): Root directory path.
271         transform (callable, optional): A function/transform that  takes in an PIL image
272             and returns a transformed version. E.g, ``transforms.RandomCrop``
273         target_transform (callable, optional): A function/transform that takes in the
274             target and transforms it.
275         loader (callable, optional): A function to load an image given its path.
276         is_valid_file (callable, optional): A function that takes path of an Image file
277             and check if the file is a valid file (used to check of corrupt files)
278 
279      Attributes:
280         classes (list): List of the class names sorted alphabetically.
281         class_to_idx (dict): Dict with items (class_name, class_index).
282         imgs (list): List of (image path, class_index) tuples
283     """
284 
285     def __init__(
286             self,
287             root: str,
288             transform: Optional[Callable] = None,
289             target_transform: Optional[Callable] = None,
290             loader: Callable[[str], Any] = default_loader,
291             is_valid_file: Optional[Callable[[str], bool]] = None,
292     ):
293         super(ImageFolder, self).__init__(root, loader, IMG_EXTENSIONS if is_valid_file is None else None,
294                                           transform=transform,
295                                           target_transform=target_transform,
296                                           is_valid_file=is_valid_file)
297         self.imgs = self.samples
298
```
--- END FILES ---

Please first localize the bug based on the issue statement, and then generate a patch according to the `git diff` format fenced by three backticks.

Here is an example:

```diff
diff --git a/examples/server_async.py b/examples/server_async.py
--- a/examples/server_async.py
+++ b/examples/server_async.py
@@ -313,4 +313,4 @@
 
 
 if __name__ == "__main__":
-    asyncio.run(run_async_server("."), debug=True)
+    asyncio.run(run_async_server(), debug=True)
diff --git a/examples/server_sync.py b/examples/server_sync.py
--- a/examples/server_sync.py
+++ b/examples/server_sync.py
@@ -313,5 +313,5 @@
 
 
 if __name__ == "__main__":
-    server = run_sync_server(".")
+    server = run_sync_server()
     server.shutdown()

```

diff --git a/torchvision/datasets/folder.py b/torchvision/datasets/folder.py
--- a/torchvision/datasets/folder.py
+++ b/torchvision/datasets/folder.py
@@ -182,7 +182,7 @@
     ) -> None:
         super(DatasetFolder, self).__init__(root, transform=transform,
                                             target_transform=target_transform)
-        classes, class_to_idx = self._find_classes(self.root)
+        classes, class_to_idx = self.find_classes(self.root)
         samples = self.make_dataset(self.root, class_to_idx, extensions, is_valid_file)
 
         self.loader = loader
@@ -202,8 +202,12 @@
     ) -> List[Tuple[str, int]]:
         return make_dataset(directory, class_to_idx, extensions=extensions, is_valid_file=is_valid_file)
 
-    @staticmethod
-    def _find_classes(dir: str) -> Tuple[List[str], Dict[str, int]]:
+    def find_classes(self, dir: str) -> Tuple[List[str], Dict[str, int]]:
+        """Same as :func:`find_classes`.
+
+        This method can be overridden to only consider
+        a subset of classes, or to adapt to a different dataset directory structure.
+        """
         return find_classes(dir)
 
     def __getitem__(self, index: int) -> Tuple[Any, Any]:

{"golden_diff": "diff --git a/torchvision/datasets/folder.py b/torchvision/datasets/folder.py\n--- a/torchvision/datasets/folder.py\n+++ b/torchvision/datasets/folder.py\n@@ -182,7 +182,7 @@\n     ) -> None:\n         super(DatasetFolder, self).__init__(root, transform=transform,\n                                             target_transform=target_transform)\n-        classes, class_to_idx = self._find_classes(self.root)\n+        classes, class_to_idx = self.find_classes(self.root)\n         samples = self.make_dataset(self.root, class_to_idx, extensions, is_valid_file)\n \n         self.loader = loader\n@@ -202,8 +202,12 @@\n     ) -> List[Tuple[str, int]]:\n         return make_dataset(directory, class_to_idx, extensions=extensions, is_valid_file=is_valid_file)\n \n-    @staticmethod\n-    def _find_classes(dir: str) -> Tuple[List[str], Dict[str, int]]:\n+    def find_classes(self, dir: str) -> Tuple[List[str], Dict[str, int]]:\n+        \"\"\"Same as :func:`find_classes`.\n+\n+        This method can be overridden to only consider\n+        a subset of classes, or to adapt to a different dataset directory structure.\n+        \"\"\"\n         return find_classes(dir)\n \n     def __getitem__(self, index: int) -> Tuple[Any, Any]:\n", "issue": "Select subset of classes to sample from\n## \ud83d\ude80 Feature\r\n\r\nWhen loading a dataset with `ImageFolder` provide an optional argument to select a subset of classes.\r\n\r\n## Motivation\r\n\r\nI deal with large (1000+) multi-class datasets upon which I train image classifiers. However, I usually don't want to train for all the classes at the same time.\r\n## Pitch\r\n\r\nI'd like to change `find_classes` function\r\nhttps://github.com/pytorch/vision/blob/20a771e5143c6867eee63868c38a5bcc272a35e7/torchvision/datasets/folder.py#L61\r\n\r\nto \r\n\r\n```python\r\nclasses = sorted(entry.name for entry in os.scandir(directory) \r\n                 if entry.is_dir() and (entry.name in allowed_classes or not allowed_classes))\r\n```\r\n\r\nwhere `allowed_classes: Optional[str] = []` is an empty list by default but it can given to `ImageFolder` at initialisation time (it has to be propagated back to `DatasetFolder` where `find_classes` is used).\r\n\r\n## Alternatives\r\n\r\nI tried to\r\n\r\n1) manually create a new folder structure with only the relevant classes. This gets messy quite fast as I have now multiple versions of the same folders\r\n2) resort to a custom dataloader filtering loaded samples after initialisation (obviously this is very slow as soon as the number of images increases)\r\n\r\n## Additional context\r\n\r\nHere I found a discussion on the same topic.\r\n\r\nhttps://discuss.pytorch.org/t/how-to-sample-images-belonging-to-particular-classes/43776/8\r\n\n\ncc @pmeier\n", "before_files": [{"content": "from .vision import VisionDataset\n\nfrom PIL import Image\n\nimport os\nimport os.path\nfrom typing import Any, Callable, cast, Dict, List, Optional, Tuple\n\n\ndef has_file_allowed_extension(filename: str, extensions: Tuple[str, ...]) -> bool:\n    \"\"\"Checks if a file is an allowed extension.\n\n    Args:\n        filename (string): path to a file\n        extensions (tuple of strings): extensions to consider (lowercase)\n\n    Returns:\n        bool: True if the filename ends with one of given extensions\n    \"\"\"\n    return filename.lower().endswith(extensions)\n\n\ndef is_image_file(filename: str) -> bool:\n    \"\"\"Checks if a file is an allowed image extension.\n\n    Args:\n        filename (string): path to a file\n\n    Returns:\n        bool: True if the filename ends with a known image extension\n    \"\"\"\n    return has_file_allowed_extension(filename, IMG_EXTENSIONS)\n\n\ndef find_classes(directory: str) -> Tuple[List[str], Dict[str, int]]:\n    \"\"\"Finds the class folders in a dataset structured as follows:\n\n    .. code::\n\n        directory/\n        \u251c\u2500\u2500 class_x\n        \u2502   \u251c\u2500\u2500 xxx.ext\n        \u2502   \u251c\u2500\u2500 xxy.ext\n        \u2502   \u2514\u2500\u2500 ...\n        \u2502       \u2514\u2500\u2500 xxz.ext\n        \u2514\u2500\u2500 class_y\n            \u251c\u2500\u2500 123.ext\n            \u251c\u2500\u2500 nsdf3.ext\n            \u2514\u2500\u2500 ...\n                \u2514\u2500\u2500 asd932_.ext\n\n    Args:\n        directory (str): Root directory path.\n\n    Raises:\n        FileNotFoundError: If ``directory`` has no class folders.\n\n    Returns:\n        (Tuple[List[str], Dict[str, int]]): List of all classes and dictionary mapping each class to an index.\n    \"\"\"\n    classes = sorted(entry.name for entry in os.scandir(directory) if entry.is_dir())\n    if not classes:\n        raise FileNotFoundError(f\"Couldn't find any class folder in {directory}.\")\n\n    class_to_idx = {cls_name: i for i, cls_name in enumerate(classes)}\n    return classes, class_to_idx\n\n\ndef make_dataset(\n    directory: str,\n    class_to_idx: Optional[Dict[str, int]] = None,\n    extensions: Optional[Tuple[str, ...]] = None,\n    is_valid_file: Optional[Callable[[str], bool]] = None,\n) -> List[Tuple[str, int]]:\n    \"\"\"Generates a list of samples of a form (path_to_sample, class).\n\n    Args:\n        directory (str): root dataset directory\n        class_to_idx (Optional[Dict[str, int]]): Dictionary mapping class name to class index. If omitted, is generated\n            by :func:`find_classes`.\n        extensions (optional): A list of allowed extensions.\n            Either extensions or is_valid_file should be passed. Defaults to None.\n        is_valid_file (optional): A function that takes path of a file\n            and checks if the file is a valid file\n            (used to check of corrupt files) both extensions and\n            is_valid_file should not be passed. Defaults to None.\n\n    Raises:\n        ValueError: In case ``class_to_idx`` is empty.\n        ValueError: In case ``extensions`` and ``is_valid_file`` are None or both are not None.\n        FileNotFoundError: In case no valid file was found for any class.\n\n    Returns:\n        List[Tuple[str, int]]: samples of a form (path_to_sample, class)\n    \"\"\"\n    directory = os.path.expanduser(directory)\n\n    if class_to_idx is None:\n        _, class_to_idx = find_classes(directory)\n    elif not class_to_idx:\n        raise ValueError(\"'class_to_index' must have at least one entry to collect any samples.\")\n\n    both_none = extensions is None and is_valid_file is None\n    both_something = extensions is not None and is_valid_file is not None\n    if both_none or both_something:\n        raise ValueError(\"Both extensions and is_valid_file cannot be None or not None at the same time\")\n\n    if extensions is not None:\n\n        def is_valid_file(x: str) -> bool:\n            return has_file_allowed_extension(x, cast(Tuple[str, ...], extensions))\n\n    is_valid_file = cast(Callable[[str], bool], is_valid_file)\n\n    instances = []\n    available_classes = set()\n    for target_class in sorted(class_to_idx.keys()):\n        class_index = class_to_idx[target_class]\n        target_dir = os.path.join(directory, target_class)\n        if not os.path.isdir(target_dir):\n            continue\n        for root, _, fnames in sorted(os.walk(target_dir, followlinks=True)):\n            for fname in sorted(fnames):\n                path = os.path.join(root, fname)\n                if is_valid_file(path):\n                    item = path, class_index\n                    instances.append(item)\n\n                    if target_class not in available_classes:\n                        available_classes.add(target_class)\n\n    empty_classes = set(class_to_idx.keys()) - available_classes\n    if empty_classes:\n        msg = f\"Found no valid file for the classes {', '.join(sorted(empty_classes))}. \"\n        if extensions is not None:\n            msg += f\"Supported extensions are: {', '.join(extensions)}\"\n        raise FileNotFoundError(msg)\n\n    return instances\n\n\nclass DatasetFolder(VisionDataset):\n    \"\"\"A generic data loader where the samples are arranged in this way: ::\n\n        root/class_x/xxx.ext\n        root/class_x/xxy.ext\n        root/class_x/[...]/xxz.ext\n\n        root/class_y/123.ext\n        root/class_y/nsdf3.ext\n        root/class_y/[...]/asd932_.ext\n\n    Args:\n        root (string): Root directory path.\n        loader (callable): A function to load a sample given its path.\n        extensions (tuple[string]): A list of allowed extensions.\n            both extensions and is_valid_file should not be passed.\n        transform (callable, optional): A function/transform that takes in\n            a sample and returns a transformed version.\n            E.g, ``transforms.RandomCrop`` for images.\n        target_transform (callable, optional): A function/transform that takes\n            in the target and transforms it.\n        is_valid_file (callable, optional): A function that takes path of a file\n            and check if the file is a valid file (used to check of corrupt files)\n            both extensions and is_valid_file should not be passed.\n\n     Attributes:\n        classes (list): List of the class names sorted alphabetically.\n        class_to_idx (dict): Dict with items (class_name, class_index).\n        samples (list): List of (sample path, class_index) tuples\n        targets (list): The class_index value for each image in the dataset\n    \"\"\"\n\n    def __init__(\n            self,\n            root: str,\n            loader: Callable[[str], Any],\n            extensions: Optional[Tuple[str, ...]] = None,\n            transform: Optional[Callable] = None,\n            target_transform: Optional[Callable] = None,\n            is_valid_file: Optional[Callable[[str], bool]] = None,\n    ) -> None:\n        super(DatasetFolder, self).__init__(root, transform=transform,\n                                            target_transform=target_transform)\n        classes, class_to_idx = self._find_classes(self.root)\n        samples = self.make_dataset(self.root, class_to_idx, extensions, is_valid_file)\n\n        self.loader = loader\n        self.extensions = extensions\n\n        self.classes = classes\n        self.class_to_idx = class_to_idx\n        self.samples = samples\n        self.targets = [s[1] for s in samples]\n\n    @staticmethod\n    def make_dataset(\n        directory: str,\n        class_to_idx: Dict[str, int],\n        extensions: Optional[Tuple[str, ...]] = None,\n        is_valid_file: Optional[Callable[[str], bool]] = None,\n    ) -> List[Tuple[str, int]]:\n        return make_dataset(directory, class_to_idx, extensions=extensions, is_valid_file=is_valid_file)\n\n    @staticmethod\n    def _find_classes(dir: str) -> Tuple[List[str], Dict[str, int]]:\n        return find_classes(dir)\n\n    def __getitem__(self, index: int) -> Tuple[Any, Any]:\n        \"\"\"\n        Args:\n            index (int): Index\n\n        Returns:\n            tuple: (sample, target) where target is class_index of the target class.\n        \"\"\"\n        path, target = self.samples[index]\n        sample = self.loader(path)\n        if self.transform is not None:\n            sample = self.transform(sample)\n        if self.target_transform is not None:\n            target = self.target_transform(target)\n\n        return sample, target\n\n    def __len__(self) -> int:\n        return len(self.samples)\n\n\nIMG_EXTENSIONS = ('.jpg', '.jpeg', '.png', '.ppm', '.bmp', '.pgm', '.tif', '.tiff', '.webp')\n\n\ndef pil_loader(path: str) -> Image.Image:\n    # open path as file to avoid ResourceWarning (https://github.com/python-pillow/Pillow/issues/835)\n    with open(path, 'rb') as f:\n        img = Image.open(f)\n        return img.convert('RGB')\n\n\n# TODO: specify the return type\ndef accimage_loader(path: str) -> Any:\n    import accimage\n    try:\n        return accimage.Image(path)\n    except IOError:\n        # Potentially a decoding problem, fall back to PIL.Image\n        return pil_loader(path)\n\n\ndef default_loader(path: str) -> Any:\n    from torchvision import get_image_backend\n    if get_image_backend() == 'accimage':\n        return accimage_loader(path)\n    else:\n        return pil_loader(path)\n\n\nclass ImageFolder(DatasetFolder):\n    \"\"\"A generic data loader where the images are arranged in this way: ::\n\n        root/dog/xxx.png\n        root/dog/xxy.png\n        root/dog/[...]/xxz.png\n\n        root/cat/123.png\n        root/cat/nsdf3.png\n        root/cat/[...]/asd932_.png\n\n    Args:\n        root (string): Root directory path.\n        transform (callable, optional): A function/transform that  takes in an PIL image\n            and returns a transformed version. E.g, ``transforms.RandomCrop``\n        target_transform (callable, optional): A function/transform that takes in the\n            target and transforms it.\n        loader (callable, optional): A function to load an image given its path.\n        is_valid_file (callable, optional): A function that takes path of an Image file\n            and check if the file is a valid file (used to check of corrupt files)\n\n     Attributes:\n        classes (list): List of the class names sorted alphabetically.\n        class_to_idx (dict): Dict with items (class_name, class_index).\n        imgs (list): List of (image path, class_index) tuples\n    \"\"\"\n\n    def __init__(\n            self,\n            root: str,\n            transform: Optional[Callable] = None,\n            target_transform: Optional[Callable] = None,\n            loader: Callable[[str], Any] = default_loader,\n            is_valid_file: Optional[Callable[[str], bool]] = None,\n    ):\n        super(ImageFolder, self).__init__(root, loader, IMG_EXTENSIONS if is_valid_file is None else None,\n                                          transform=transform,\n                                          target_transform=target_transform,\n                                          is_valid_file=is_valid_file)\n        self.imgs = self.samples\n", "path": "torchvision/datasets/folder.py"}], "after_files": [{"content": "from .vision import VisionDataset\n\nfrom PIL import Image\n\nimport os\nimport os.path\nfrom typing import Any, Callable, cast, Dict, List, Optional, Tuple\n\n\ndef has_file_allowed_extension(filename: str, extensions: Tuple[str, ...]) -> bool:\n    \"\"\"Checks if a file is an allowed extension.\n\n    Args:\n        filename (string): path to a file\n        extensions (tuple of strings): extensions to consider (lowercase)\n\n    Returns:\n        bool: True if the filename ends with one of given extensions\n    \"\"\"\n    return filename.lower().endswith(extensions)\n\n\ndef is_image_file(filename: str) -> bool:\n    \"\"\"Checks if a file is an allowed image extension.\n\n    Args:\n        filename (string): path to a file\n\n    Returns:\n        bool: True if the filename ends with a known image extension\n    \"\"\"\n    return has_file_allowed_extension(filename, IMG_EXTENSIONS)\n\n\ndef find_classes(directory: str) -> Tuple[List[str], Dict[str, int]]:\n    \"\"\"Finds the class folders in a dataset structured as follows:\n\n    .. code::\n\n        directory/\n        \u251c\u2500\u2500 class_x\n        \u2502   \u251c\u2500\u2500 xxx.ext\n        \u2502   \u251c\u2500\u2500 xxy.ext\n        \u2502   \u2514\u2500\u2500 ...\n        \u2502       \u2514\u2500\u2500 xxz.ext\n        \u2514\u2500\u2500 class_y\n            \u251c\u2500\u2500 123.ext\n            \u251c\u2500\u2500 nsdf3.ext\n            \u2514\u2500\u2500 ...\n                \u2514\u2500\u2500 asd932_.ext\n\n    Args:\n        directory (str): Root directory path.\n\n    Raises:\n        FileNotFoundError: If ``directory`` has no class folders.\n\n    Returns:\n        (Tuple[List[str], Dict[str, int]]): List of all classes and dictionary mapping each class to an index.\n    \"\"\"\n    classes = sorted(entry.name for entry in os.scandir(directory) if entry.is_dir())\n    if not classes:\n        raise FileNotFoundError(f\"Couldn't find any class folder in {directory}.\")\n\n    class_to_idx = {cls_name: i for i, cls_name in enumerate(classes)}\n    return classes, class_to_idx\n\n\ndef make_dataset(\n    directory: str,\n    class_to_idx: Optional[Dict[str, int]] = None,\n    extensions: Optional[Tuple[str, ...]] = None,\n    is_valid_file: Optional[Callable[[str], bool]] = None,\n) -> List[Tuple[str, int]]:\n    \"\"\"Generates a list of samples of a form (path_to_sample, class).\n\n    Args:\n        directory (str): root dataset directory\n        class_to_idx (Optional[Dict[str, int]]): Dictionary mapping class name to class index. If omitted, is generated\n            by :func:`find_classes`.\n        extensions (optional): A list of allowed extensions.\n            Either extensions or is_valid_file should be passed. Defaults to None.\n        is_valid_file (optional): A function that takes path of a file\n            and checks if the file is a valid file\n            (used to check of corrupt files) both extensions and\n            is_valid_file should not be passed. Defaults to None.\n\n    Raises:\n        ValueError: In case ``class_to_idx`` is empty.\n        ValueError: In case ``extensions`` and ``is_valid_file`` are None or both are not None.\n        FileNotFoundError: In case no valid file was found for any class.\n\n    Returns:\n        List[Tuple[str, int]]: samples of a form (path_to_sample, class)\n    \"\"\"\n    directory = os.path.expanduser(directory)\n\n    if class_to_idx is None:\n        _, class_to_idx = find_classes(directory)\n    elif not class_to_idx:\n        raise ValueError(\"'class_to_index' must have at least one entry to collect any samples.\")\n\n    both_none = extensions is None and is_valid_file is None\n    both_something = extensions is not None and is_valid_file is not None\n    if both_none or both_something:\n        raise ValueError(\"Both extensions and is_valid_file cannot be None or not None at the same time\")\n\n    if extensions is not None:\n\n        def is_valid_file(x: str) -> bool:\n            return has_file_allowed_extension(x, cast(Tuple[str, ...], extensions))\n\n    is_valid_file = cast(Callable[[str], bool], is_valid_file)\n\n    instances = []\n    available_classes = set()\n    for target_class in sorted(class_to_idx.keys()):\n        class_index = class_to_idx[target_class]\n        target_dir = os.path.join(directory, target_class)\n        if not os.path.isdir(target_dir):\n            continue\n        for root, _, fnames in sorted(os.walk(target_dir, followlinks=True)):\n            for fname in sorted(fnames):\n                path = os.path.join(root, fname)\n                if is_valid_file(path):\n                    item = path, class_index\n                    instances.append(item)\n\n                    if target_class not in available_classes:\n                        available_classes.add(target_class)\n\n    empty_classes = set(class_to_idx.keys()) - available_classes\n    if empty_classes:\n        msg = f\"Found no valid file for the classes {', '.join(sorted(empty_classes))}. \"\n        if extensions is not None:\n            msg += f\"Supported extensions are: {', '.join(extensions)}\"\n        raise FileNotFoundError(msg)\n\n    return instances\n\n\nclass DatasetFolder(VisionDataset):\n    \"\"\"A generic data loader where the samples are arranged in this way: ::\n\n        root/class_x/xxx.ext\n        root/class_x/xxy.ext\n        root/class_x/[...]/xxz.ext\n\n        root/class_y/123.ext\n        root/class_y/nsdf3.ext\n        root/class_y/[...]/asd932_.ext\n\n    Args:\n        root (string): Root directory path.\n        loader (callable): A function to load a sample given its path.\n        extensions (tuple[string]): A list of allowed extensions.\n            both extensions and is_valid_file should not be passed.\n        transform (callable, optional): A function/transform that takes in\n            a sample and returns a transformed version.\n            E.g, ``transforms.RandomCrop`` for images.\n        target_transform (callable, optional): A function/transform that takes\n            in the target and transforms it.\n        is_valid_file (callable, optional): A function that takes path of a file\n            and check if the file is a valid file (used to check of corrupt files)\n            both extensions and is_valid_file should not be passed.\n\n     Attributes:\n        classes (list): List of the class names sorted alphabetically.\n        class_to_idx (dict): Dict with items (class_name, class_index).\n        samples (list): List of (sample path, class_index) tuples\n        targets (list): The class_index value for each image in the dataset\n    \"\"\"\n\n    def __init__(\n            self,\n            root: str,\n            loader: Callable[[str], Any],\n            extensions: Optional[Tuple[str, ...]] = None,\n            transform: Optional[Callable] = None,\n            target_transform: Optional[Callable] = None,\n            is_valid_file: Optional[Callable[[str], bool]] = None,\n    ) -> None:\n        super(DatasetFolder, self).__init__(root, transform=transform,\n                                            target_transform=target_transform)\n        classes, class_to_idx = self.find_classes(self.root)\n        samples = self.make_dataset(self.root, class_to_idx, extensions, is_valid_file)\n\n        self.loader = loader\n        self.extensions = extensions\n\n        self.classes = classes\n        self.class_to_idx = class_to_idx\n        self.samples = samples\n        self.targets = [s[1] for s in samples]\n\n    @staticmethod\n    def make_dataset(\n        directory: str,\n        class_to_idx: Dict[str, int],\n        extensions: Optional[Tuple[str, ...]] = None,\n        is_valid_file: Optional[Callable[[str], bool]] = None,\n    ) -> List[Tuple[str, int]]:\n        return make_dataset(directory, class_to_idx, extensions=extensions, is_valid_file=is_valid_file)\n\n    def find_classes(self, dir: str) -> Tuple[List[str], Dict[str, int]]:\n        \"\"\"Same as :func:`find_classes`.\n\n        This method can be overridden to only consider\n        a subset of classes, or to adapt to a different dataset directory structure.\n        \"\"\"\n        return find_classes(dir)\n\n    def __getitem__(self, index: int) -> Tuple[Any, Any]:\n        \"\"\"\n        Args:\n            index (int): Index\n\n        Returns:\n            tuple: (sample, target) where target is class_index of the target class.\n        \"\"\"\n        path, target = self.samples[index]\n        sample = self.loader(path)\n        if self.transform is not None:\n            sample = self.transform(sample)\n        if self.target_transform is not None:\n            target = self.target_transform(target)\n\n        return sample, target\n\n    def __len__(self) -> int:\n        return len(self.samples)\n\n\nIMG_EXTENSIONS = ('.jpg', '.jpeg', '.png', '.ppm', '.bmp', '.pgm', '.tif', '.tiff', '.webp')\n\n\ndef pil_loader(path: str) -> Image.Image:\n    # open path as file to avoid ResourceWarning (https://github.com/python-pillow/Pillow/issues/835)\n    with open(path, 'rb') as f:\n        img = Image.open(f)\n        return img.convert('RGB')\n\n\n# TODO: specify the return type\ndef accimage_loader(path: str) -> Any:\n    import accimage\n    try:\n        return accimage.Image(path)\n    except IOError:\n        # Potentially a decoding problem, fall back to PIL.Image\n        return pil_loader(path)\n\n\ndef default_loader(path: str) -> Any:\n    from torchvision import get_image_backend\n    if get_image_backend() == 'accimage':\n        return accimage_loader(path)\n    else:\n        return pil_loader(path)\n\n\nclass ImageFolder(DatasetFolder):\n    \"\"\"A generic data loader where the images are arranged in this way: ::\n\n        root/dog/xxx.png\n        root/dog/xxy.png\n        root/dog/[...]/xxz.png\n\n        root/cat/123.png\n        root/cat/nsdf3.png\n        root/cat/[...]/asd932_.png\n\n    Args:\n        root (string): Root directory path.\n        transform (callable, optional): A function/transform that  takes in an PIL image\n            and returns a transformed version. E.g, ``transforms.RandomCrop``\n        target_transform (callable, optional): A function/transform that takes in the\n            target and transforms it.\n        loader (callable, optional): A function to load an image given its path.\n        is_valid_file (callable, optional): A function that takes path of an Image file\n            and check if the file is a valid file (used to check of corrupt files)\n\n     Attributes:\n        classes (list): List of the class names sorted alphabetically.\n        class_to_idx (dict): Dict with items (class_name, class_index).\n        imgs (list): List of (image path, class_index) tuples\n    \"\"\"\n\n    def __init__(\n            self,\n            root: str,\n            transform: Optional[Callable] = None,\n            target_transform: Optional[Callable] = None,\n            loader: Callable[[str], Any] = default_loader,\n            is_valid_file: Optional[Callable[[str], bool]] = None,\n    ):\n        super(ImageFolder, self).__init__(root, loader, IMG_EXTENSIONS if is_valid_file is None else None,\n                                          transform=transform,\n                                          target_transform=target_transform,\n                                          is_valid_file=is_valid_file)\n        self.imgs = self.samples\n", "path": "torchvision/datasets/folder.py"}]}