Repository: Lightning-AI/torchmetrics

Issue:
Pearson Correlation Coefficient raises error when 2D tensor but single task
## 🐛 Bug

I have a regression based modelling repository where the predictions can be multi-output or single-output based on configuration. My network outputs `[n_samples, n_tasks]` where `n_task` varies according to the task. If `n_task` is 1 then trying, `torchmetrics.functional.pearson_corrcoef(predictions, targets)` gives the error,

```bash
ValueError: Expected argument `num_outputs` to match the second dimension of input, but got 1 and 1
```

Changing the output shape for a single task specifically just so as to fit the metric function does not seem like a good solution. I think a simple change should be able to fix it.
My current workout around,
```python
import torchmetrics.functional as Fm

# predictions are [n, 1] for single task/output
Fm.pearson_corrcoef(predictions, targets) if predictions.shape[1] > 1 else Fm.pearson_corrcoef(predictions[:, 0], targets[:, 0])
```

There are other metrics that handle this,
```python
        metrics = {
            "mse": Fm.mean_squared_error(predictions, targets, squared=True),
            "rmse": Fm.mean_squared_error(predictions, targets, squared=False),
            "mae": Fm.mean_absolute_error(predictions, targets),
            "r2": Fm.r2_score(predictions, targets, multioutput="raw_values"),
            "mape": Fm.mean_absolute_percentage_error(predictions, targets),
            # TODO: Raise issue on torchmetrics
            "pcc": (
                Fm.pearson_corrcoef(predictions, targets) if predictions.shape[1] > 1 else
                Fm.pearson_corrcoef(predictions[:, 0], targets[:, 0])
            ),
        }
```


<!-- A clear and concise description of what the bug is. -->

### To Reproduce

Steps to reproduce the behavior...

<!-- If you have a code sample, error messages, stack traces, please provide it here as well -->

<details>
  <summary>Code sample</summary>

<!-- Ideally attach a minimal code sample to reproduce the decried issue.
Minimal means having the shortest code but still preserving the bug. -->

</details>

### Expected behavior

<!-- A clear and concise description of what you expected to happen. -->

### Environment

- TorchMetrics version (and how you installed TM, e.g. `conda`, `pip`, build from source):
- Python & PyTorch Version (e.g., 1.0):
- Any other relevant information such as OS (e.g., Linux):

### Additional context

<!-- Add any other context about the problem here. -->



Discussion:
Hi! thanks for your contribution!, great first issue!

Resolving patch:
diff --git a/src/torchmetrics/functional/regression/utils.py b/src/torchmetrics/functional/regression/utils.py
--- a/src/torchmetrics/functional/regression/utils.py
+++ b/src/torchmetrics/functional/regression/utils.py
@@ -21,7 +21,9 @@ def _check_data_shape_to_num_outputs(preds: Tensor, target: Tensor, num_outputs:
             f"Expected both predictions and target to be either 1- or 2-dimensional tensors,"
             f" but got {target.ndim} and {preds.ndim}."
         )
-    if (num_outputs == 1 and preds.ndim != 1) or (num_outputs > 1 and num_outputs != preds.shape[1]):
+    cond1 = num_outputs == 1 and not (preds.ndim == 1 or preds.shape[1] == 1)
+    cond2 = num_outputs > 1 and num_outputs != preds.shape[1]
+    if cond1 or cond2:
         raise ValueError(
             f"Expected argument `num_outputs` to match the second dimension of input, but got {num_outputs}"
             f" and {preds.shape[1]}."


Test patch:
diff --git a/tests/unittests/regression/test_pearson.py b/tests/unittests/regression/test_pearson.py
--- a/tests/unittests/regression/test_pearson.py
+++ b/tests/unittests/regression/test_pearson.py
@@ -129,6 +129,12 @@ def test_error_on_different_shape():
         metric(torch.randn(100, 5), torch.randn(100, 5))
 
 
+def test_1d_input_allowed():
+    """Check that both input of the form [N,] and [N,1] is allowed with default num_outputs argument."""
+    assert isinstance(pearson_corrcoef(torch.randn(10, 1), torch.randn(10, 1)), torch.Tensor)
+    assert isinstance(pearson_corrcoef(torch.randn(10), torch.randn(10)), torch.Tensor)
+
+
 @pytest.mark.parametrize("shapes", [(5,), (1, 5), (2, 5)])
 def test_final_aggregation_function(shapes):
     """Test that final aggregation function can take various shapes of input."""