prompt: We are currently solving the following issue within our repository. Here is the issue text:
  --- BEGIN ISSUE ---
  Per-label accuracy does not work for multiple batches
  **Describe the bug**
  When `batch_size > 1`, `per_label_accuracy` computation fails.
  
  **To Reproduce**
  Steps to reproduce the behavior:
  1. Set `batch_size = 4` in any classification unit test
  2. See error
  
  **Expected behavior**
  The function should compute multiple batches of accuracies.
  
  **Screenshots**
  N.A.
  
  **GaNDLF Version**
  <!-- Put the output of the following command:
  python -c 'import GANDLF as g;print(g.__version__)'
  -->
  0.0.15-dev
  
  **Desktop (please complete the following information):**
  N.A.
  
  **Additional context**
  Reported by @brandon-edwards
  
  --- END ISSUE ---
  
  Below are some code segments, each from a relevant file. One or more of these files may contain bugs.
  --- BEGIN FILES ---
  Path: `GANDLF/metrics/regression.py`
  Content:
  ```
  1 """
  2 All the metrics are to be called from here
  3 """
  4 import torch
  5 from sklearn.metrics import balanced_accuracy_score
  6 import numpy as np
  7 
  8 
  9 def classification_accuracy(output, label, params):
  10     """
  11     This function computes the classification accuracy.
  12 
  13     Args:
  14         output (torch.Tensor): The output of the model.
  15         label (torch.Tensor): The ground truth labels.
  16         params (dict): The parameter dictionary containing training and data information.
  17 
  18     Returns:
  19         torch.Tensor: The classification accuracy.
  20     """
  21     if params["problem_type"] == "classification":
  22         predicted_classes = torch.argmax(output, 1)
  23     else:
  24         predicted_classes = output
  25 
  26     acc = torch.sum(predicted_classes == label.squeeze()) / len(label)
  27     return acc
  28 
  29 
  30 def balanced_acc_score(output, label, params):
  31     """
  32     This function computes the balanced accuracy.
  33 
  34     Args:
  35         output (torch.Tensor): The output of the model.
  36         label (torch.Tensor): The ground truth labels.
  37         params (dict): The parameter dictionary containing training and data information.
  38 
  39     Returns:
  40         torch.Tensor: The balanced accuracy.
  41     """
  42     if params["problem_type"] == "classification":
  43         predicted_classes = torch.argmax(output, 1)
  44     else:
  45         predicted_classes = output
  46 
  47     return torch.from_numpy(
  48         np.array(balanced_accuracy_score(predicted_classes.cpu(), label.cpu()))
  49     )
  50 
  51 
  52 def per_label_accuracy(output, label, params):
  53     """
  54     This function computes the per class accuracy.
  55 
  56     Args:
  57         output (torch.Tensor): The output of the model.
  58         label (torch.Tensor): The ground truth labels.
  59         params (dict): The parameter dictionary containing training and data information.
  60 
  61     Returns:
  62         torch.Tensor: The per class accuracy.
  63     """
  64     if params["problem_type"] == "classification":
  65         predicted_classes = np.array([0] * len(params["model"]["class_list"]))
  66         label_cpu = np.array([0] * len(params["model"]["class_list"]))
  67         predicted_classes[torch.argmax(output, 1).cpu().item()] = 1
  68         label_cpu[label.cpu().item()] = 1
  69         return torch.from_numpy((predicted_classes == label_cpu).astype(float))
  70     else:
  71         return balanced_acc_score(output, label, params)
  72
  ```
  --- 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()
  
  ```
  
golden_diff: diff --git a/GANDLF/metrics/regression.py b/GANDLF/metrics/regression.py
  --- a/GANDLF/metrics/regression.py
  +++ b/GANDLF/metrics/regression.py
  @@ -62,10 +62,14 @@
           torch.Tensor: The per class accuracy.
       """
       if params["problem_type"] == "classification":
  -        predicted_classes = np.array([0] * len(params["model"]["class_list"]))
  -        label_cpu = np.array([0] * len(params["model"]["class_list"]))
  -        predicted_classes[torch.argmax(output, 1).cpu().item()] = 1
  -        label_cpu[label.cpu().item()] = 1
  -        return torch.from_numpy((predicted_classes == label_cpu).astype(float))
  +        # ensure this works for multiple batches
  +        output_accuracy = torch.zeros(len(params["model"]["class_list"]))
  +        for output_batch, label_batch in zip(output, label):
  +            predicted_classes = torch.Tensor([0] * len(params["model"]["class_list"]))
  +            label_cpu = torch.Tensor([0] * len(params["model"]["class_list"]))
  +            predicted_classes[torch.argmax(output_batch, 0).cpu().item()] = 1
  +            label_cpu[label_batch.cpu().item()] = 1
  +            output_accuracy += (predicted_classes == label_cpu).type(torch.float)
  +        return output_accuracy / len(output)
       else:
           return balanced_acc_score(output, label, params)
  
verification_info: {"golden_diff": "diff --git a/GANDLF/metrics/regression.py b/GANDLF/metrics/regression.py\n--- a/GANDLF/metrics/regression.py\n+++ b/GANDLF/metrics/regression.py\n@@ -62,10 +62,14 @@\n         torch.Tensor: The per class accuracy.\n     \"\"\"\n     if params[\"problem_type\"] == \"classification\":\n-        predicted_classes = np.array([0] * len(params[\"model\"][\"class_list\"]))\n-        label_cpu = np.array([0] * len(params[\"model\"][\"class_list\"]))\n-        predicted_classes[torch.argmax(output, 1).cpu().item()] = 1\n-        label_cpu[label.cpu().item()] = 1\n-        return torch.from_numpy((predicted_classes == label_cpu).astype(float))\n+        # ensure this works for multiple batches\n+        output_accuracy = torch.zeros(len(params[\"model\"][\"class_list\"]))\n+        for output_batch, label_batch in zip(output, label):\n+            predicted_classes = torch.Tensor([0] * len(params[\"model\"][\"class_list\"]))\n+            label_cpu = torch.Tensor([0] * len(params[\"model\"][\"class_list\"]))\n+            predicted_classes[torch.argmax(output_batch, 0).cpu().item()] = 1\n+            label_cpu[label_batch.cpu().item()] = 1\n+            output_accuracy += (predicted_classes == label_cpu).type(torch.float)\n+        return output_accuracy / len(output)\n     else:\n         return balanced_acc_score(output, label, params)\n", "issue": "Per-label accuracy does not work for multiple batches\n**Describe the bug**\r\nWhen `batch_size > 1`, `per_label_accuracy` computation fails.\r\n\r\n**To Reproduce**\r\nSteps to reproduce the behavior:\r\n1. Set `batch_size = 4` in any classification unit test\r\n2. See error\r\n\r\n**Expected behavior**\r\nThe function should compute multiple batches of accuracies.\r\n\r\n**Screenshots**\r\nN.A.\r\n\r\n**GaNDLF Version**\r\n<!-- Put the output of the following command:\r\npython -c 'import GANDLF as g;print(g.__version__)'\r\n-->\r\n0.0.15-dev\r\n\r\n**Desktop (please complete the following information):**\r\nN.A.\r\n\r\n**Additional context**\r\nReported by @brandon-edwards\n", "before_files": [{"content": "\"\"\"\nAll the metrics are to be called from here\n\"\"\"\nimport torch\nfrom sklearn.metrics import balanced_accuracy_score\nimport numpy as np\n\n\ndef classification_accuracy(output, label, params):\n    \"\"\"\n    This function computes the classification accuracy.\n\n    Args:\n        output (torch.Tensor): The output of the model.\n        label (torch.Tensor): The ground truth labels.\n        params (dict): The parameter dictionary containing training and data information.\n\n    Returns:\n        torch.Tensor: The classification accuracy.\n    \"\"\"\n    if params[\"problem_type\"] == \"classification\":\n        predicted_classes = torch.argmax(output, 1)\n    else:\n        predicted_classes = output\n\n    acc = torch.sum(predicted_classes == label.squeeze()) / len(label)\n    return acc\n\n\ndef balanced_acc_score(output, label, params):\n    \"\"\"\n    This function computes the balanced accuracy.\n\n    Args:\n        output (torch.Tensor): The output of the model.\n        label (torch.Tensor): The ground truth labels.\n        params (dict): The parameter dictionary containing training and data information.\n\n    Returns:\n        torch.Tensor: The balanced accuracy.\n    \"\"\"\n    if params[\"problem_type\"] == \"classification\":\n        predicted_classes = torch.argmax(output, 1)\n    else:\n        predicted_classes = output\n\n    return torch.from_numpy(\n        np.array(balanced_accuracy_score(predicted_classes.cpu(), label.cpu()))\n    )\n\n\ndef per_label_accuracy(output, label, params):\n    \"\"\"\n    This function computes the per class accuracy.\n\n    Args:\n        output (torch.Tensor): The output of the model.\n        label (torch.Tensor): The ground truth labels.\n        params (dict): The parameter dictionary containing training and data information.\n\n    Returns:\n        torch.Tensor: The per class accuracy.\n    \"\"\"\n    if params[\"problem_type\"] == \"classification\":\n        predicted_classes = np.array([0] * len(params[\"model\"][\"class_list\"]))\n        label_cpu = np.array([0] * len(params[\"model\"][\"class_list\"]))\n        predicted_classes[torch.argmax(output, 1).cpu().item()] = 1\n        label_cpu[label.cpu().item()] = 1\n        return torch.from_numpy((predicted_classes == label_cpu).astype(float))\n    else:\n        return balanced_acc_score(output, label, params)\n", "path": "GANDLF/metrics/regression.py"}], "after_files": [{"content": "\"\"\"\nAll the metrics are to be called from here\n\"\"\"\nimport torch\nfrom sklearn.metrics import balanced_accuracy_score\nimport numpy as np\n\n\ndef classification_accuracy(output, label, params):\n    \"\"\"\n    This function computes the classification accuracy.\n\n    Args:\n        output (torch.Tensor): The output of the model.\n        label (torch.Tensor): The ground truth labels.\n        params (dict): The parameter dictionary containing training and data information.\n\n    Returns:\n        torch.Tensor: The classification accuracy.\n    \"\"\"\n    if params[\"problem_type\"] == \"classification\":\n        predicted_classes = torch.argmax(output, 1)\n    else:\n        predicted_classes = output\n\n    acc = torch.sum(predicted_classes == label.squeeze()) / len(label)\n    return acc\n\n\ndef balanced_acc_score(output, label, params):\n    \"\"\"\n    This function computes the balanced accuracy.\n\n    Args:\n        output (torch.Tensor): The output of the model.\n        label (torch.Tensor): The ground truth labels.\n        params (dict): The parameter dictionary containing training and data information.\n\n    Returns:\n        torch.Tensor: The balanced accuracy.\n    \"\"\"\n    if params[\"problem_type\"] == \"classification\":\n        predicted_classes = torch.argmax(output, 1)\n    else:\n        predicted_classes = output\n\n    return torch.from_numpy(\n        np.array(balanced_accuracy_score(predicted_classes.cpu(), label.cpu()))\n    )\n\n\ndef per_label_accuracy(output, label, params):\n    \"\"\"\n    This function computes the per class accuracy.\n\n    Args:\n        output (torch.Tensor): The output of the model.\n        label (torch.Tensor): The ground truth labels.\n        params (dict): The parameter dictionary containing training and data information.\n\n    Returns:\n        torch.Tensor: The per class accuracy.\n    \"\"\"\n    if params[\"problem_type\"] == \"classification\":\n        # ensure this works for multiple batches\n        output_accuracy = torch.zeros(len(params[\"model\"][\"class_list\"]))\n        for output_batch, label_batch in zip(output, label):\n            predicted_classes = torch.Tensor([0] * len(params[\"model\"][\"class_list\"]))\n            label_cpu = torch.Tensor([0] * len(params[\"model\"][\"class_list\"]))\n            predicted_classes[torch.argmax(output_batch, 0).cpu().item()] = 1\n            label_cpu[label_batch.cpu().item()] = 1\n            output_accuracy += (predicted_classes == label_cpu).type(torch.float)\n        return output_accuracy / len(output)\n    else:\n        return balanced_acc_score(output, label, params)\n", "path": "GANDLF/metrics/regression.py"}]}