We are currently solving the following issue within our repository. Here is the issue text:
--- BEGIN ISSUE ---
Add `_filter_kwargs` in `ClasswiseWrapper` metric wrapper
As the `ClasswiseWrapper` accepts agnostic `*args, **kwargs` arguments, its not handy to use it in a `MetricColletion`, as tailored input arguments for other metrics get passed in the metrics.

It would be great, just like in `MetricColletion`, to add the `_filter_kwargs` for the metric 

--- END ISSUE ---

Below are some code segments, each from a relevant file. One or more of these files may contain bugs.
--- BEGIN FILES ---
Path: `src/torchmetrics/wrappers/classwise.py`
Content:
```
1 # Copyright The Lightning team.
2 #
3 # Licensed under the Apache License, Version 2.0 (the "License");
4 # you may not use this file except in compliance with the License.
5 # You may obtain a copy of the License at
6 #
7 #     http://www.apache.org/licenses/LICENSE-2.0
8 #
9 # Unless required by applicable law or agreed to in writing, software
10 # distributed under the License is distributed on an "AS IS" BASIS,
11 # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 # See the License for the specific language governing permissions and
13 # limitations under the License.
14 import typing
15 from typing import Any, Dict, List, Optional, Sequence, Union
16 
17 from torch import Tensor
18 
19 from torchmetrics.metric import Metric
20 from torchmetrics.utilities.imports import _MATPLOTLIB_AVAILABLE
21 from torchmetrics.utilities.plot import _AX_TYPE, _PLOT_OUT_TYPE
22 from torchmetrics.wrappers.abstract import WrapperMetric
23 
24 if typing.TYPE_CHECKING:
25     from torch.nn import Module
26 
27 if not _MATPLOTLIB_AVAILABLE:
28     __doctest_skip__ = ["ClasswiseWrapper.plot"]
29 
30 
31 class ClasswiseWrapper(WrapperMetric):
32     """Wrapper metric for altering the output of classification metrics.
33 
34     This metric works together with classification metrics that returns multiple values (one value per class) such that
35     label information can be automatically included in the output.
36 
37     Args:
38         metric: base metric that should be wrapped. It is assumed that the metric outputs a single
39             tensor that is split along the first dimension.
40         labels: list of strings indicating the different classes.
41         prefix: string that is prepended to the metric names.
42         postfix: string that is appended to the metric names.
43 
44     Example::
45         Basic example where the output of a metric is unwrapped into a dictionary with the class index as keys:
46 
47         >>> import torch
48         >>> _ = torch.manual_seed(42)
49         >>> from torchmetrics.wrappers import ClasswiseWrapper
50         >>> from torchmetrics.classification import MulticlassAccuracy
51         >>> metric = ClasswiseWrapper(MulticlassAccuracy(num_classes=3, average=None))
52         >>> preds = torch.randn(10, 3).softmax(dim=-1)
53         >>> target = torch.randint(3, (10,))
54         >>> metric(preds, target)  # doctest: +NORMALIZE_WHITESPACE
55         {'multiclassaccuracy_0': tensor(0.5000),
56         'multiclassaccuracy_1': tensor(0.7500),
57         'multiclassaccuracy_2': tensor(0.)}
58 
59     Example::
60         Using custom name via prefix and postfix:
61 
62         >>> import torch
63         >>> _ = torch.manual_seed(42)
64         >>> from torchmetrics.wrappers import ClasswiseWrapper
65         >>> from torchmetrics.classification import MulticlassAccuracy
66         >>> metric_pre = ClasswiseWrapper(MulticlassAccuracy(num_classes=3, average=None), prefix="acc-")
67         >>> metric_post = ClasswiseWrapper(MulticlassAccuracy(num_classes=3, average=None), postfix="-acc")
68         >>> preds = torch.randn(10, 3).softmax(dim=-1)
69         >>> target = torch.randint(3, (10,))
70         >>> metric_pre(preds, target)  # doctest: +NORMALIZE_WHITESPACE
71         {'acc-0': tensor(0.5000),
72          'acc-1': tensor(0.7500),
73          'acc-2': tensor(0.)}
74         >>> metric_post(preds, target)  # doctest: +NORMALIZE_WHITESPACE
75         {'0-acc': tensor(0.5000),
76          '1-acc': tensor(0.7500),
77          '2-acc': tensor(0.)}
78 
79     Example::
80         Providing labels as a list of strings:
81 
82         >>> from torchmetrics.wrappers import ClasswiseWrapper
83         >>> from torchmetrics.classification import MulticlassAccuracy
84         >>> metric = ClasswiseWrapper(
85         ...    MulticlassAccuracy(num_classes=3, average=None),
86         ...    labels=["horse", "fish", "dog"]
87         ... )
88         >>> preds = torch.randn(10, 3).softmax(dim=-1)
89         >>> target = torch.randint(3, (10,))
90         >>> metric(preds, target)  # doctest: +NORMALIZE_WHITESPACE
91         {'multiclassaccuracy_horse': tensor(0.3333),
92         'multiclassaccuracy_fish': tensor(0.6667),
93         'multiclassaccuracy_dog': tensor(0.)}
94 
95     Example::
96         Classwise can also be used in combination with :class:`~torchmetrics.MetricCollection`. In this case, everything
97         will be flattened into a single dictionary:
98 
99         >>> from torchmetrics import MetricCollection
100         >>> from torchmetrics.wrappers import ClasswiseWrapper
101         >>> from torchmetrics.classification import MulticlassAccuracy, MulticlassRecall
102         >>> labels = ["horse", "fish", "dog"]
103         >>> metric = MetricCollection(
104         ...     {'multiclassaccuracy': ClasswiseWrapper(MulticlassAccuracy(num_classes=3, average=None), labels),
105         ...     'multiclassrecall': ClasswiseWrapper(MulticlassRecall(num_classes=3, average=None), labels)}
106         ... )
107         >>> preds = torch.randn(10, 3).softmax(dim=-1)
108         >>> target = torch.randint(3, (10,))
109         >>> metric(preds, target)  # doctest: +NORMALIZE_WHITESPACE
110         {'multiclassaccuracy_horse': tensor(0.),
111          'multiclassaccuracy_fish': tensor(0.3333),
112          'multiclassaccuracy_dog': tensor(0.4000),
113          'multiclassrecall_horse': tensor(0.),
114          'multiclassrecall_fish': tensor(0.3333),
115          'multiclassrecall_dog': tensor(0.4000)}
116 
117     """
118 
119     def __init__(
120         self,
121         metric: Metric,
122         labels: Optional[List[str]] = None,
123         prefix: Optional[str] = None,
124         postfix: Optional[str] = None,
125     ) -> None:
126         super().__init__()
127         if not isinstance(metric, Metric):
128             raise ValueError(f"Expected argument `metric` to be an instance of `torchmetrics.Metric` but got {metric}")
129         self.metric = metric
130 
131         if labels is not None and not (isinstance(labels, list) and all(isinstance(lab, str) for lab in labels)):
132             raise ValueError(f"Expected argument `labels` to either be `None` or a list of strings but got {labels}")
133         self.labels = labels
134 
135         if prefix is not None and not isinstance(prefix, str):
136             raise ValueError(f"Expected argument `prefix` to either be `None` or a string but got {prefix}")
137         self._prefix = prefix
138 
139         if postfix is not None and not isinstance(postfix, str):
140             raise ValueError(f"Expected argument `postfix` to either be `None` or a string but got {postfix}")
141         self._postfix = postfix
142 
143         self._update_count = 1
144 
145     def _convert(self, x: Tensor) -> Dict[str, Any]:
146         # Will set the class name as prefix if neither prefix nor postfix is given
147         if not self._prefix and not self._postfix:
148             prefix = f"{self.metric.__class__.__name__.lower()}_"
149             postfix = ""
150         else:
151             prefix = self._prefix or ""
152             postfix = self._postfix or ""
153         if self.labels is None:
154             return {f"{prefix}{i}{postfix}": val for i, val in enumerate(x)}
155         return {f"{prefix}{lab}{postfix}": val for lab, val in zip(self.labels, x)}
156 
157     def forward(self, *args: Any, **kwargs: Any) -> Any:
158         """Calculate on batch and accumulate to global state."""
159         return self._convert(self.metric(*args, **kwargs))
160 
161     def update(self, *args: Any, **kwargs: Any) -> None:
162         """Update state."""
163         self.metric.update(*args, **kwargs)
164 
165     def compute(self) -> Dict[str, Tensor]:
166         """Compute metric."""
167         return self._convert(self.metric.compute())
168 
169     def reset(self) -> None:
170         """Reset metric."""
171         self.metric.reset()
172 
173     def plot(
174         self, val: Optional[Union[Tensor, Sequence[Tensor]]] = None, ax: Optional[_AX_TYPE] = None
175     ) -> _PLOT_OUT_TYPE:
176         """Plot a single or multiple values from the metric.
177 
178         Args:
179             val: Either a single result from calling `metric.forward` or `metric.compute` or a list of these results.
180                 If no value is provided, will automatically call `metric.compute` and plot that result.
181             ax: An matplotlib axis object. If provided will add plot to that axis
182 
183         Returns:
184             Figure and Axes object
185 
186         Raises:
187             ModuleNotFoundError:
188                 If `matplotlib` is not installed
189 
190         .. plot::
191             :scale: 75
192 
193             >>> # Example plotting a single value
194             >>> import torch
195             >>> from torchmetrics.wrappers import ClasswiseWrapper
196             >>> from torchmetrics.classification import MulticlassAccuracy
197             >>> metric = ClasswiseWrapper(MulticlassAccuracy(num_classes=3, average=None))
198             >>> metric.update(torch.randint(3, (20,)), torch.randint(3, (20,)))
199             >>> fig_, ax_ = metric.plot()
200 
201         .. plot::
202             :scale: 75
203 
204             >>> # Example plotting multiple values
205             >>> import torch
206             >>> from torchmetrics.wrappers import ClasswiseWrapper
207             >>> from torchmetrics.classification import MulticlassAccuracy
208             >>> metric = ClasswiseWrapper(MulticlassAccuracy(num_classes=3, average=None))
209             >>> values = [ ]
210             >>> for _ in range(3):
211             ...     values.append(metric(torch.randint(3, (20,)), torch.randint(3, (20,))))
212             >>> fig_, ax_ = metric.plot(values)
213 
214         """
215         return self._plot(val, ax)
216 
217     def __getattr__(self, name: str) -> Union[Tensor, "Module"]:
218         """Get attribute from classwise wrapper."""
219         if name == "metric" or (name in self.__dict__ and name not in self.metric.__dict__):
220             # we need this to prevent from infinite getattribute loop.
221             return super().__getattr__(name)
222 
223         return getattr(self.metric, name)
224 
225     def __setattr__(self, name: str, value: Any) -> None:
226         """Set attribute to classwise wrapper."""
227         if hasattr(self, "metric") and name in self.metric._defaults:
228             setattr(self.metric, name, value)
229         else:
230             super().__setattr__(name, value)
231             if name == "metric":
232                 self._defaults = self.metric._defaults
233                 self._persistent = self.metric._persistent
234                 self._reductions = self.metric._reductions
235
```
--- 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/src/torchmetrics/wrappers/classwise.py b/src/torchmetrics/wrappers/classwise.py
--- a/src/torchmetrics/wrappers/classwise.py
+++ b/src/torchmetrics/wrappers/classwise.py
@@ -142,7 +142,12 @@
 
         self._update_count = 1
 
-    def _convert(self, x: Tensor) -> Dict[str, Any]:
+    def _filter_kwargs(self, **kwargs: Any) -> Dict[str, Any]:
+        """Filter kwargs for the metric."""
+        return self.metric._filter_kwargs(**kwargs)
+
+    def _convert_output(self, x: Tensor) -> Dict[str, Any]:
+        """Convert output to dictionary with labels as keys."""
         # Will set the class name as prefix if neither prefix nor postfix is given
         if not self._prefix and not self._postfix:
             prefix = f"{self.metric.__class__.__name__.lower()}_"
@@ -156,7 +161,7 @@
 
     def forward(self, *args: Any, **kwargs: Any) -> Any:
         """Calculate on batch and accumulate to global state."""
-        return self._convert(self.metric(*args, **kwargs))
+        return self._convert_output(self.metric(*args, **kwargs))
 
     def update(self, *args: Any, **kwargs: Any) -> None:
         """Update state."""
@@ -164,7 +169,7 @@
 
     def compute(self) -> Dict[str, Tensor]:
         """Compute metric."""
-        return self._convert(self.metric.compute())
+        return self._convert_output(self.metric.compute())
 
     def reset(self) -> None:
         """Reset metric."""

{"golden_diff": "diff --git a/src/torchmetrics/wrappers/classwise.py b/src/torchmetrics/wrappers/classwise.py\n--- a/src/torchmetrics/wrappers/classwise.py\n+++ b/src/torchmetrics/wrappers/classwise.py\n@@ -142,7 +142,12 @@\n \n         self._update_count = 1\n \n-    def _convert(self, x: Tensor) -> Dict[str, Any]:\n+    def _filter_kwargs(self, **kwargs: Any) -> Dict[str, Any]:\n+        \"\"\"Filter kwargs for the metric.\"\"\"\n+        return self.metric._filter_kwargs(**kwargs)\n+\n+    def _convert_output(self, x: Tensor) -> Dict[str, Any]:\n+        \"\"\"Convert output to dictionary with labels as keys.\"\"\"\n         # Will set the class name as prefix if neither prefix nor postfix is given\n         if not self._prefix and not self._postfix:\n             prefix = f\"{self.metric.__class__.__name__.lower()}_\"\n@@ -156,7 +161,7 @@\n \n     def forward(self, *args: Any, **kwargs: Any) -> Any:\n         \"\"\"Calculate on batch and accumulate to global state.\"\"\"\n-        return self._convert(self.metric(*args, **kwargs))\n+        return self._convert_output(self.metric(*args, **kwargs))\n \n     def update(self, *args: Any, **kwargs: Any) -> None:\n         \"\"\"Update state.\"\"\"\n@@ -164,7 +169,7 @@\n \n     def compute(self) -> Dict[str, Tensor]:\n         \"\"\"Compute metric.\"\"\"\n-        return self._convert(self.metric.compute())\n+        return self._convert_output(self.metric.compute())\n \n     def reset(self) -> None:\n         \"\"\"Reset metric.\"\"\"\n", "issue": "Add `_filter_kwargs` in `ClasswiseWrapper` metric wrapper\nAs the `ClasswiseWrapper` accepts agnostic `*args, **kwargs` arguments, its not handy to use it in a `MetricColletion`, as tailored input arguments for other metrics get passed in the metrics.\r\n\r\nIt would be great, just like in `MetricColletion`, to add the `_filter_kwargs` for the metric \n", "before_files": [{"content": "# Copyright The Lightning team.\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\");\n# you may not use this file except in compliance with the License.\n# You may obtain a copy of the License at\n#\n#     http://www.apache.org/licenses/LICENSE-2.0\n#\n# Unless required by applicable law or agreed to in writing, software\n# distributed under the License is distributed on an \"AS IS\" BASIS,\n# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n# See the License for the specific language governing permissions and\n# limitations under the License.\nimport typing\nfrom typing import Any, Dict, List, Optional, Sequence, Union\n\nfrom torch import Tensor\n\nfrom torchmetrics.metric import Metric\nfrom torchmetrics.utilities.imports import _MATPLOTLIB_AVAILABLE\nfrom torchmetrics.utilities.plot import _AX_TYPE, _PLOT_OUT_TYPE\nfrom torchmetrics.wrappers.abstract import WrapperMetric\n\nif typing.TYPE_CHECKING:\n    from torch.nn import Module\n\nif not _MATPLOTLIB_AVAILABLE:\n    __doctest_skip__ = [\"ClasswiseWrapper.plot\"]\n\n\nclass ClasswiseWrapper(WrapperMetric):\n    \"\"\"Wrapper metric for altering the output of classification metrics.\n\n    This metric works together with classification metrics that returns multiple values (one value per class) such that\n    label information can be automatically included in the output.\n\n    Args:\n        metric: base metric that should be wrapped. It is assumed that the metric outputs a single\n            tensor that is split along the first dimension.\n        labels: list of strings indicating the different classes.\n        prefix: string that is prepended to the metric names.\n        postfix: string that is appended to the metric names.\n\n    Example::\n        Basic example where the output of a metric is unwrapped into a dictionary with the class index as keys:\n\n        >>> import torch\n        >>> _ = torch.manual_seed(42)\n        >>> from torchmetrics.wrappers import ClasswiseWrapper\n        >>> from torchmetrics.classification import MulticlassAccuracy\n        >>> metric = ClasswiseWrapper(MulticlassAccuracy(num_classes=3, average=None))\n        >>> preds = torch.randn(10, 3).softmax(dim=-1)\n        >>> target = torch.randint(3, (10,))\n        >>> metric(preds, target)  # doctest: +NORMALIZE_WHITESPACE\n        {'multiclassaccuracy_0': tensor(0.5000),\n        'multiclassaccuracy_1': tensor(0.7500),\n        'multiclassaccuracy_2': tensor(0.)}\n\n    Example::\n        Using custom name via prefix and postfix:\n\n        >>> import torch\n        >>> _ = torch.manual_seed(42)\n        >>> from torchmetrics.wrappers import ClasswiseWrapper\n        >>> from torchmetrics.classification import MulticlassAccuracy\n        >>> metric_pre = ClasswiseWrapper(MulticlassAccuracy(num_classes=3, average=None), prefix=\"acc-\")\n        >>> metric_post = ClasswiseWrapper(MulticlassAccuracy(num_classes=3, average=None), postfix=\"-acc\")\n        >>> preds = torch.randn(10, 3).softmax(dim=-1)\n        >>> target = torch.randint(3, (10,))\n        >>> metric_pre(preds, target)  # doctest: +NORMALIZE_WHITESPACE\n        {'acc-0': tensor(0.5000),\n         'acc-1': tensor(0.7500),\n         'acc-2': tensor(0.)}\n        >>> metric_post(preds, target)  # doctest: +NORMALIZE_WHITESPACE\n        {'0-acc': tensor(0.5000),\n         '1-acc': tensor(0.7500),\n         '2-acc': tensor(0.)}\n\n    Example::\n        Providing labels as a list of strings:\n\n        >>> from torchmetrics.wrappers import ClasswiseWrapper\n        >>> from torchmetrics.classification import MulticlassAccuracy\n        >>> metric = ClasswiseWrapper(\n        ...    MulticlassAccuracy(num_classes=3, average=None),\n        ...    labels=[\"horse\", \"fish\", \"dog\"]\n        ... )\n        >>> preds = torch.randn(10, 3).softmax(dim=-1)\n        >>> target = torch.randint(3, (10,))\n        >>> metric(preds, target)  # doctest: +NORMALIZE_WHITESPACE\n        {'multiclassaccuracy_horse': tensor(0.3333),\n        'multiclassaccuracy_fish': tensor(0.6667),\n        'multiclassaccuracy_dog': tensor(0.)}\n\n    Example::\n        Classwise can also be used in combination with :class:`~torchmetrics.MetricCollection`. In this case, everything\n        will be flattened into a single dictionary:\n\n        >>> from torchmetrics import MetricCollection\n        >>> from torchmetrics.wrappers import ClasswiseWrapper\n        >>> from torchmetrics.classification import MulticlassAccuracy, MulticlassRecall\n        >>> labels = [\"horse\", \"fish\", \"dog\"]\n        >>> metric = MetricCollection(\n        ...     {'multiclassaccuracy': ClasswiseWrapper(MulticlassAccuracy(num_classes=3, average=None), labels),\n        ...     'multiclassrecall': ClasswiseWrapper(MulticlassRecall(num_classes=3, average=None), labels)}\n        ... )\n        >>> preds = torch.randn(10, 3).softmax(dim=-1)\n        >>> target = torch.randint(3, (10,))\n        >>> metric(preds, target)  # doctest: +NORMALIZE_WHITESPACE\n        {'multiclassaccuracy_horse': tensor(0.),\n         'multiclassaccuracy_fish': tensor(0.3333),\n         'multiclassaccuracy_dog': tensor(0.4000),\n         'multiclassrecall_horse': tensor(0.),\n         'multiclassrecall_fish': tensor(0.3333),\n         'multiclassrecall_dog': tensor(0.4000)}\n\n    \"\"\"\n\n    def __init__(\n        self,\n        metric: Metric,\n        labels: Optional[List[str]] = None,\n        prefix: Optional[str] = None,\n        postfix: Optional[str] = None,\n    ) -> None:\n        super().__init__()\n        if not isinstance(metric, Metric):\n            raise ValueError(f\"Expected argument `metric` to be an instance of `torchmetrics.Metric` but got {metric}\")\n        self.metric = metric\n\n        if labels is not None and not (isinstance(labels, list) and all(isinstance(lab, str) for lab in labels)):\n            raise ValueError(f\"Expected argument `labels` to either be `None` or a list of strings but got {labels}\")\n        self.labels = labels\n\n        if prefix is not None and not isinstance(prefix, str):\n            raise ValueError(f\"Expected argument `prefix` to either be `None` or a string but got {prefix}\")\n        self._prefix = prefix\n\n        if postfix is not None and not isinstance(postfix, str):\n            raise ValueError(f\"Expected argument `postfix` to either be `None` or a string but got {postfix}\")\n        self._postfix = postfix\n\n        self._update_count = 1\n\n    def _convert(self, x: Tensor) -> Dict[str, Any]:\n        # Will set the class name as prefix if neither prefix nor postfix is given\n        if not self._prefix and not self._postfix:\n            prefix = f\"{self.metric.__class__.__name__.lower()}_\"\n            postfix = \"\"\n        else:\n            prefix = self._prefix or \"\"\n            postfix = self._postfix or \"\"\n        if self.labels is None:\n            return {f\"{prefix}{i}{postfix}\": val for i, val in enumerate(x)}\n        return {f\"{prefix}{lab}{postfix}\": val for lab, val in zip(self.labels, x)}\n\n    def forward(self, *args: Any, **kwargs: Any) -> Any:\n        \"\"\"Calculate on batch and accumulate to global state.\"\"\"\n        return self._convert(self.metric(*args, **kwargs))\n\n    def update(self, *args: Any, **kwargs: Any) -> None:\n        \"\"\"Update state.\"\"\"\n        self.metric.update(*args, **kwargs)\n\n    def compute(self) -> Dict[str, Tensor]:\n        \"\"\"Compute metric.\"\"\"\n        return self._convert(self.metric.compute())\n\n    def reset(self) -> None:\n        \"\"\"Reset metric.\"\"\"\n        self.metric.reset()\n\n    def plot(\n        self, val: Optional[Union[Tensor, Sequence[Tensor]]] = None, ax: Optional[_AX_TYPE] = None\n    ) -> _PLOT_OUT_TYPE:\n        \"\"\"Plot a single or multiple values from the metric.\n\n        Args:\n            val: Either a single result from calling `metric.forward` or `metric.compute` or a list of these results.\n                If no value is provided, will automatically call `metric.compute` and plot that result.\n            ax: An matplotlib axis object. If provided will add plot to that axis\n\n        Returns:\n            Figure and Axes object\n\n        Raises:\n            ModuleNotFoundError:\n                If `matplotlib` is not installed\n\n        .. plot::\n            :scale: 75\n\n            >>> # Example plotting a single value\n            >>> import torch\n            >>> from torchmetrics.wrappers import ClasswiseWrapper\n            >>> from torchmetrics.classification import MulticlassAccuracy\n            >>> metric = ClasswiseWrapper(MulticlassAccuracy(num_classes=3, average=None))\n            >>> metric.update(torch.randint(3, (20,)), torch.randint(3, (20,)))\n            >>> fig_, ax_ = metric.plot()\n\n        .. plot::\n            :scale: 75\n\n            >>> # Example plotting multiple values\n            >>> import torch\n            >>> from torchmetrics.wrappers import ClasswiseWrapper\n            >>> from torchmetrics.classification import MulticlassAccuracy\n            >>> metric = ClasswiseWrapper(MulticlassAccuracy(num_classes=3, average=None))\n            >>> values = [ ]\n            >>> for _ in range(3):\n            ...     values.append(metric(torch.randint(3, (20,)), torch.randint(3, (20,))))\n            >>> fig_, ax_ = metric.plot(values)\n\n        \"\"\"\n        return self._plot(val, ax)\n\n    def __getattr__(self, name: str) -> Union[Tensor, \"Module\"]:\n        \"\"\"Get attribute from classwise wrapper.\"\"\"\n        if name == \"metric\" or (name in self.__dict__ and name not in self.metric.__dict__):\n            # we need this to prevent from infinite getattribute loop.\n            return super().__getattr__(name)\n\n        return getattr(self.metric, name)\n\n    def __setattr__(self, name: str, value: Any) -> None:\n        \"\"\"Set attribute to classwise wrapper.\"\"\"\n        if hasattr(self, \"metric\") and name in self.metric._defaults:\n            setattr(self.metric, name, value)\n        else:\n            super().__setattr__(name, value)\n            if name == \"metric\":\n                self._defaults = self.metric._defaults\n                self._persistent = self.metric._persistent\n                self._reductions = self.metric._reductions\n", "path": "src/torchmetrics/wrappers/classwise.py"}], "after_files": [{"content": "# Copyright The Lightning team.\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\");\n# you may not use this file except in compliance with the License.\n# You may obtain a copy of the License at\n#\n#     http://www.apache.org/licenses/LICENSE-2.0\n#\n# Unless required by applicable law or agreed to in writing, software\n# distributed under the License is distributed on an \"AS IS\" BASIS,\n# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n# See the License for the specific language governing permissions and\n# limitations under the License.\nimport typing\nfrom typing import Any, Dict, List, Optional, Sequence, Union\n\nfrom torch import Tensor\n\nfrom torchmetrics.metric import Metric\nfrom torchmetrics.utilities.imports import _MATPLOTLIB_AVAILABLE\nfrom torchmetrics.utilities.plot import _AX_TYPE, _PLOT_OUT_TYPE\nfrom torchmetrics.wrappers.abstract import WrapperMetric\n\nif typing.TYPE_CHECKING:\n    from torch.nn import Module\n\nif not _MATPLOTLIB_AVAILABLE:\n    __doctest_skip__ = [\"ClasswiseWrapper.plot\"]\n\n\nclass ClasswiseWrapper(WrapperMetric):\n    \"\"\"Wrapper metric for altering the output of classification metrics.\n\n    This metric works together with classification metrics that returns multiple values (one value per class) such that\n    label information can be automatically included in the output.\n\n    Args:\n        metric: base metric that should be wrapped. It is assumed that the metric outputs a single\n            tensor that is split along the first dimension.\n        labels: list of strings indicating the different classes.\n        prefix: string that is prepended to the metric names.\n        postfix: string that is appended to the metric names.\n\n    Example::\n        Basic example where the output of a metric is unwrapped into a dictionary with the class index as keys:\n\n        >>> import torch\n        >>> _ = torch.manual_seed(42)\n        >>> from torchmetrics.wrappers import ClasswiseWrapper\n        >>> from torchmetrics.classification import MulticlassAccuracy\n        >>> metric = ClasswiseWrapper(MulticlassAccuracy(num_classes=3, average=None))\n        >>> preds = torch.randn(10, 3).softmax(dim=-1)\n        >>> target = torch.randint(3, (10,))\n        >>> metric(preds, target)  # doctest: +NORMALIZE_WHITESPACE\n        {'multiclassaccuracy_0': tensor(0.5000),\n        'multiclassaccuracy_1': tensor(0.7500),\n        'multiclassaccuracy_2': tensor(0.)}\n\n    Example::\n        Using custom name via prefix and postfix:\n\n        >>> import torch\n        >>> _ = torch.manual_seed(42)\n        >>> from torchmetrics.wrappers import ClasswiseWrapper\n        >>> from torchmetrics.classification import MulticlassAccuracy\n        >>> metric_pre = ClasswiseWrapper(MulticlassAccuracy(num_classes=3, average=None), prefix=\"acc-\")\n        >>> metric_post = ClasswiseWrapper(MulticlassAccuracy(num_classes=3, average=None), postfix=\"-acc\")\n        >>> preds = torch.randn(10, 3).softmax(dim=-1)\n        >>> target = torch.randint(3, (10,))\n        >>> metric_pre(preds, target)  # doctest: +NORMALIZE_WHITESPACE\n        {'acc-0': tensor(0.5000),\n         'acc-1': tensor(0.7500),\n         'acc-2': tensor(0.)}\n        >>> metric_post(preds, target)  # doctest: +NORMALIZE_WHITESPACE\n        {'0-acc': tensor(0.5000),\n         '1-acc': tensor(0.7500),\n         '2-acc': tensor(0.)}\n\n    Example::\n        Providing labels as a list of strings:\n\n        >>> from torchmetrics.wrappers import ClasswiseWrapper\n        >>> from torchmetrics.classification import MulticlassAccuracy\n        >>> metric = ClasswiseWrapper(\n        ...    MulticlassAccuracy(num_classes=3, average=None),\n        ...    labels=[\"horse\", \"fish\", \"dog\"]\n        ... )\n        >>> preds = torch.randn(10, 3).softmax(dim=-1)\n        >>> target = torch.randint(3, (10,))\n        >>> metric(preds, target)  # doctest: +NORMALIZE_WHITESPACE\n        {'multiclassaccuracy_horse': tensor(0.3333),\n        'multiclassaccuracy_fish': tensor(0.6667),\n        'multiclassaccuracy_dog': tensor(0.)}\n\n    Example::\n        Classwise can also be used in combination with :class:`~torchmetrics.MetricCollection`. In this case, everything\n        will be flattened into a single dictionary:\n\n        >>> from torchmetrics import MetricCollection\n        >>> from torchmetrics.wrappers import ClasswiseWrapper\n        >>> from torchmetrics.classification import MulticlassAccuracy, MulticlassRecall\n        >>> labels = [\"horse\", \"fish\", \"dog\"]\n        >>> metric = MetricCollection(\n        ...     {'multiclassaccuracy': ClasswiseWrapper(MulticlassAccuracy(num_classes=3, average=None), labels),\n        ...     'multiclassrecall': ClasswiseWrapper(MulticlassRecall(num_classes=3, average=None), labels)}\n        ... )\n        >>> preds = torch.randn(10, 3).softmax(dim=-1)\n        >>> target = torch.randint(3, (10,))\n        >>> metric(preds, target)  # doctest: +NORMALIZE_WHITESPACE\n        {'multiclassaccuracy_horse': tensor(0.),\n         'multiclassaccuracy_fish': tensor(0.3333),\n         'multiclassaccuracy_dog': tensor(0.4000),\n         'multiclassrecall_horse': tensor(0.),\n         'multiclassrecall_fish': tensor(0.3333),\n         'multiclassrecall_dog': tensor(0.4000)}\n\n    \"\"\"\n\n    def __init__(\n        self,\n        metric: Metric,\n        labels: Optional[List[str]] = None,\n        prefix: Optional[str] = None,\n        postfix: Optional[str] = None,\n    ) -> None:\n        super().__init__()\n        if not isinstance(metric, Metric):\n            raise ValueError(f\"Expected argument `metric` to be an instance of `torchmetrics.Metric` but got {metric}\")\n        self.metric = metric\n\n        if labels is not None and not (isinstance(labels, list) and all(isinstance(lab, str) for lab in labels)):\n            raise ValueError(f\"Expected argument `labels` to either be `None` or a list of strings but got {labels}\")\n        self.labels = labels\n\n        if prefix is not None and not isinstance(prefix, str):\n            raise ValueError(f\"Expected argument `prefix` to either be `None` or a string but got {prefix}\")\n        self._prefix = prefix\n\n        if postfix is not None and not isinstance(postfix, str):\n            raise ValueError(f\"Expected argument `postfix` to either be `None` or a string but got {postfix}\")\n        self._postfix = postfix\n\n        self._update_count = 1\n\n    def _filter_kwargs(self, **kwargs: Any) -> Dict[str, Any]:\n        \"\"\"Filter kwargs for the metric.\"\"\"\n        return self.metric._filter_kwargs(**kwargs)\n\n    def _convert_output(self, x: Tensor) -> Dict[str, Any]:\n        \"\"\"Convert output to dictionary with labels as keys.\"\"\"\n        # Will set the class name as prefix if neither prefix nor postfix is given\n        if not self._prefix and not self._postfix:\n            prefix = f\"{self.metric.__class__.__name__.lower()}_\"\n            postfix = \"\"\n        else:\n            prefix = self._prefix or \"\"\n            postfix = self._postfix or \"\"\n        if self.labels is None:\n            return {f\"{prefix}{i}{postfix}\": val for i, val in enumerate(x)}\n        return {f\"{prefix}{lab}{postfix}\": val for lab, val in zip(self.labels, x)}\n\n    def forward(self, *args: Any, **kwargs: Any) -> Any:\n        \"\"\"Calculate on batch and accumulate to global state.\"\"\"\n        return self._convert_output(self.metric(*args, **kwargs))\n\n    def update(self, *args: Any, **kwargs: Any) -> None:\n        \"\"\"Update state.\"\"\"\n        self.metric.update(*args, **kwargs)\n\n    def compute(self) -> Dict[str, Tensor]:\n        \"\"\"Compute metric.\"\"\"\n        return self._convert_output(self.metric.compute())\n\n    def reset(self) -> None:\n        \"\"\"Reset metric.\"\"\"\n        self.metric.reset()\n\n    def plot(\n        self, val: Optional[Union[Tensor, Sequence[Tensor]]] = None, ax: Optional[_AX_TYPE] = None\n    ) -> _PLOT_OUT_TYPE:\n        \"\"\"Plot a single or multiple values from the metric.\n\n        Args:\n            val: Either a single result from calling `metric.forward` or `metric.compute` or a list of these results.\n                If no value is provided, will automatically call `metric.compute` and plot that result.\n            ax: An matplotlib axis object. If provided will add plot to that axis\n\n        Returns:\n            Figure and Axes object\n\n        Raises:\n            ModuleNotFoundError:\n                If `matplotlib` is not installed\n\n        .. plot::\n            :scale: 75\n\n            >>> # Example plotting a single value\n            >>> import torch\n            >>> from torchmetrics.wrappers import ClasswiseWrapper\n            >>> from torchmetrics.classification import MulticlassAccuracy\n            >>> metric = ClasswiseWrapper(MulticlassAccuracy(num_classes=3, average=None))\n            >>> metric.update(torch.randint(3, (20,)), torch.randint(3, (20,)))\n            >>> fig_, ax_ = metric.plot()\n\n        .. plot::\n            :scale: 75\n\n            >>> # Example plotting multiple values\n            >>> import torch\n            >>> from torchmetrics.wrappers import ClasswiseWrapper\n            >>> from torchmetrics.classification import MulticlassAccuracy\n            >>> metric = ClasswiseWrapper(MulticlassAccuracy(num_classes=3, average=None))\n            >>> values = [ ]\n            >>> for _ in range(3):\n            ...     values.append(metric(torch.randint(3, (20,)), torch.randint(3, (20,))))\n            >>> fig_, ax_ = metric.plot(values)\n\n        \"\"\"\n        return self._plot(val, ax)\n\n    def __getattr__(self, name: str) -> Union[Tensor, \"Module\"]:\n        \"\"\"Get attribute from classwise wrapper.\"\"\"\n        if name == \"metric\" or (name in self.__dict__ and name not in self.metric.__dict__):\n            # we need this to prevent from infinite getattribute loop.\n            return super().__getattr__(name)\n\n        return getattr(self.metric, name)\n\n    def __setattr__(self, name: str, value: Any) -> None:\n        \"\"\"Set attribute to classwise wrapper.\"\"\"\n        if hasattr(self, \"metric\") and name in self.metric._defaults:\n            setattr(self.metric, name, value)\n        else:\n            super().__setattr__(name, value)\n            if name == \"metric\":\n                self._defaults = self.metric._defaults\n                self._persistent = self.metric._persistent\n                self._reductions = self.metric._reductions\n", "path": "src/torchmetrics/wrappers/classwise.py"}]}