We are currently solving the following issue within our repository. Here is the issue text:
--- BEGIN ISSUE ---
AL detection scorer fails for object detection
## Error
![image](https://user-images.githubusercontent.com/1522766/116398967-ad9f7980-a828-11eb-8583-135e29b8e7b4.png)
## Reproduction:
`np.partition([[1.]],-2, axis=1)` yields `ValueError: kth(=-1) out of bounds (1)`
## Possible cause of error:
https://github.com/lightly-ai/lightly/blob/b064ab7f077867ab1fe4ca1a3977090701856c26/lightly/active_learning/utils/object_detection_output.py#L1[…]27
tries to do a one-hot-encoding without knowing the number of classes. Thus if max(labels) is only 1, only one class is encoded and the probability vector only has a length of 1. Thus partitioning it into 2 fails.

## Possible Solutions:
### 1. Prevent the error cause
Create the class_probabilities vector correctly with a given number of classes.
### 2. Handle the error (MUST DO, We all agree on it)
In the ScorerClassification handle the case where there is only a single class
### 3. General solution
The class_probabilities do not make sense at all if the ObjectDetectionOutput is created from scores. Thus we could also not create the `class_probabilities` in this case and not compute any classification scores if the `class_probabilities` are unset.

Solution 1 and 3 are exclusive, solution 2 can be combined with the other solutions.

## How to work on this issue
- First write a unittest reproducing the error by using ClassificationScorer.calculate_scores()
- Next fix this unittest with solution 2.
- Do not work on Solution 3 yet (another issue)

--- END ISSUE ---

Below are some code segments, each from a relevant file. One or more of these files may contain bugs.
--- BEGIN FILES ---
Path: `lightly/active_learning/scorers/classification.py`
Content:
```
1 from typing import *
2 
3 import numpy as np
4 
5 from lightly.active_learning.scorers.scorer import Scorer
6 
7 
8 def _entropy(probs: np.ndarray, axis: int = 1) -> np.ndarray:
9     """Computes the entropy of a probability matrix over one array
10 
11     Args:
12         probs:
13             A probability matrix of shape (N, M)
14         axis:
15             The axis the compute the probability over, the output does not have this axis anymore
16 
17     Exammple:
18         if probs.shape = (N, C) and axis = 1 then entropies.shape = (N, )
19 
20     Returns:
21         The entropy of the prediction vectors, shape: probs.shape, but without the specified axis
22     """
23     zeros = np.zeros_like(probs)
24     log_probs = np.log2(probs, out=zeros, where=probs > 0)
25     entropies = -1 * np.sum(probs * log_probs, axis=axis)
26     return entropies
27 
28 def _margin_largest_secondlargest(probs: np.ndarray) -> np.ndarray:
29     """Computes the margin of a probability matrix
30 
31         Args:
32             probs:
33                 A probability matrix of shape (N, M)
34 
35         Exammple:
36             if probs.shape = (N, C) then margins.shape = (N, )
37 
38         Returns:
39             The margin of the prediction vectors
40         """
41     sorted_probs = np.partition(probs, -2, axis=1)
42     margins = sorted_probs[:, -1] - sorted_probs[:, -2]
43     return margins
44 
45 
46 class ScorerClassification(Scorer):
47     """Class to compute active learning scores from the model_output of a classification task.
48 
49     Currently supports the following scorers:
50 
51         The following three uncertainty scores are taken from
52         http://burrsettles.com/pub/settles.activelearning.pdf, Section 3.1, page 12f
53         and also explained in https://towardsdatascience.com/uncertainty-sampling-cheatsheet-ec57bc067c0b
54         They all have in common, that the score is highest if all classes have the
55         same confidence and are 0 if the model assigns 100% probability to a single class.
56         The differ in the number of class confidences they take into account.
57 
58         `uncertainty_least_confidence`:
59             This score is 1 - the highest confidence prediction. It is high
60             when the confidence about the most probable class is low.
61 
62         `uncertainty_margin`
63             This score is 1- the margin between the highest conficence
64             and second highest confidence prediction. It is high when the model
65             cannot decide between the two most probable classes.
66 
67         `uncertainty_entropy`:
68             This scorer computes the entropy of the prediction. The confidences
69              for all classes are considered to compute the entropy of a sample.
70 
71     Attributes:
72         model_output:
73             Predictions of shape N x C where N is the number of unlabeled samples
74             and C is the number of classes in the classification task. Must be
75             normalized such that the sum over each row is 1.
76             The order of the predictions must be the one specified by
77             ActiveLearningAgent.unlabeled_set.
78 
79     Examples:
80         >>> # example with three unlabeled samples
81         >>> al_agent.unlabeled_set
82         >>> > ['img0.jpg', 'img1.jpg', 'img2.jpg']
83         >>> predictions = np.array(
84         >>>     [
85         >>>          [0.1, 0.9], # predictions for img0.jpg
86         >>>          [0.3, 0.7], # predictions for img1.jpg
87         >>>          [0.8, 0.2], # predictions for img2.jpg
88         >>>     ] 
89         >>> )
90         >>> np.sum(predictions, axis=1)
91         >>> > array([1., 1., 1.])
92         >>> scorer = ScorerClassification(predictions)
93 
94     """
95     def __init__(self, model_output: Union[np.ndarray, List[List[float]]]):
96         if isinstance(model_output, List):
97             model_output = np.array(model_output)
98         super(ScorerClassification, self).__init__(model_output)
99 
100     @classmethod
101     def score_names(cls) -> List[str]:
102         """Returns the names of the calculated active learning scores
103         """
104         score_names = list(cls(model_output=[[0.5, 0.5]]).calculate_scores().keys())
105         return score_names
106 
107     def calculate_scores(self, normalize_to_0_1: bool = True) -> Dict[str, np.ndarray]:
108         """Calculates and returns the active learning scores.
109 
110         Args:
111             normalize_to_0_1:
112                 If this is true, each score is normalized to have a
113                 theoretical minimum of 0 and a theoretical maximum of 1.
114 
115         Returns:
116             A dictionary mapping from the score name (as string)
117             to the scores (as a single-dimensional numpy array).
118         """
119         if len(self.model_output) == 0:
120             return {score_name: [] for score_name in self.score_names()}
121 
122         scores_with_names = [
123             self._get_scores_uncertainty_least_confidence(),
124             self._get_scores_uncertainty_margin(),
125             self._get_scores_uncertainty_entropy()
126         ]
127 
128         scores = dict()
129         for score, score_name in scores_with_names:
130             score = np.nan_to_num(score)
131             scores[score_name] = score
132 
133         if normalize_to_0_1:
134             scores = self.normalize_scores_0_1(scores)
135 
136         return scores
137 
138     def normalize_scores_0_1(self, scores: Dict[str, np.ndarray]) -> Dict[str, np.ndarray]:
139         num_classes = self.model_output.shape[1]
140         model_output_very_sure = np.zeros(shape=(1,num_classes))
141         model_output_very_sure[0, 0] = 1
142         model_output_very_unsure = np.ones_like(model_output_very_sure)/num_classes
143 
144         scores_minimum = ScorerClassification(model_output_very_sure).calculate_scores(normalize_to_0_1=False)
145         scores_maximum = ScorerClassification(model_output_very_unsure).calculate_scores(normalize_to_0_1=False)
146 
147         for score_name in scores.keys():
148             interp_xp = [float(scores_minimum[score_name]), float(scores_maximum[score_name])]
149             interp_fp = [0, 1]
150             scores[score_name] = np.interp(scores[score_name], interp_xp, interp_fp)
151 
152         return scores
153 
154     def _get_scores_uncertainty_least_confidence(self):
155         scores = 1 - np.max(self.model_output, axis=1)
156         return scores, "uncertainty_least_confidence"
157 
158     def _get_scores_uncertainty_margin(self):
159         scores = 1 - _margin_largest_secondlargest(self.model_output)
160         return scores, "uncertainty_margin"
161 
162     def _get_scores_uncertainty_entropy(self):
163         scores = _entropy(self.model_output, axis=1)
164         return scores, "uncertainty_entropy"
165
```
--- 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/lightly/active_learning/scorers/classification.py b/lightly/active_learning/scorers/classification.py
--- a/lightly/active_learning/scorers/classification.py
+++ b/lightly/active_learning/scorers/classification.py
@@ -1,3 +1,4 @@
+import warnings
 from typing import *
 
 import numpy as np
@@ -93,9 +94,25 @@
 
     """
     def __init__(self, model_output: Union[np.ndarray, List[List[float]]]):
-        if isinstance(model_output, List):
+        if not isinstance(model_output, np.ndarray):
             model_output = np.array(model_output)
-        super(ScorerClassification, self).__init__(model_output)
+
+        validated_model_output = self.ensure_valid_model_output(model_output)
+
+        super(ScorerClassification, self).__init__(validated_model_output)
+
+    def ensure_valid_model_output(self, model_output: np.ndarray) -> np.ndarray:
+        if len(model_output) == 0:
+            return model_output
+        if len(model_output.shape) != 2:
+            raise ValueError("ScorerClassification model_output must be a 2-dimensional array")
+        if model_output.shape[1] == 0:
+            raise ValueError("ScorerClassification model_output must not have an empty dimension 1")
+        if model_output.shape[1] == 1:
+            # assuming a binary classification problem with
+            # the model_output denoting the probability of the first class
+            model_output = np.concatenate([model_output, 1-model_output], axis=1)
+        return model_output
 
     @classmethod
     def score_names(cls) -> List[str]:

{"golden_diff": "diff --git a/lightly/active_learning/scorers/classification.py b/lightly/active_learning/scorers/classification.py\n--- a/lightly/active_learning/scorers/classification.py\n+++ b/lightly/active_learning/scorers/classification.py\n@@ -1,3 +1,4 @@\n+import warnings\n from typing import *\n \n import numpy as np\n@@ -93,9 +94,25 @@\n \n     \"\"\"\n     def __init__(self, model_output: Union[np.ndarray, List[List[float]]]):\n-        if isinstance(model_output, List):\n+        if not isinstance(model_output, np.ndarray):\n             model_output = np.array(model_output)\n-        super(ScorerClassification, self).__init__(model_output)\n+\n+        validated_model_output = self.ensure_valid_model_output(model_output)\n+\n+        super(ScorerClassification, self).__init__(validated_model_output)\n+\n+    def ensure_valid_model_output(self, model_output: np.ndarray) -> np.ndarray:\n+        if len(model_output) == 0:\n+            return model_output\n+        if len(model_output.shape) != 2:\n+            raise ValueError(\"ScorerClassification model_output must be a 2-dimensional array\")\n+        if model_output.shape[1] == 0:\n+            raise ValueError(\"ScorerClassification model_output must not have an empty dimension 1\")\n+        if model_output.shape[1] == 1:\n+            # assuming a binary classification problem with\n+            # the model_output denoting the probability of the first class\n+            model_output = np.concatenate([model_output, 1-model_output], axis=1)\n+        return model_output\n \n     @classmethod\n     def score_names(cls) -> List[str]:\n", "issue": "AL detection scorer fails for object detection\n## Error\r\n![image](https://user-images.githubusercontent.com/1522766/116398967-ad9f7980-a828-11eb-8583-135e29b8e7b4.png)\r\n## Reproduction:\r\n`np.partition([[1.]],-2, axis=1)` yields `ValueError: kth(=-1) out of bounds (1)`\r\n## Possible cause of error:\r\nhttps://github.com/lightly-ai/lightly/blob/b064ab7f077867ab1fe4ca1a3977090701856c26/lightly/active_learning/utils/object_detection_output.py#L1[\u2026]27\r\ntries to do a one-hot-encoding without knowing the number of classes. Thus if max(labels) is only 1, only one class is encoded and the probability vector only has a length of 1. Thus partitioning it into 2 fails.\r\n\r\n## Possible Solutions:\r\n### 1. Prevent the error cause\r\nCreate the class_probabilities vector correctly with a given number of classes.\r\n### 2. Handle the error (MUST DO, We all agree on it)\r\nIn the ScorerClassification handle the case where there is only a single class\r\n### 3. General solution\r\nThe class_probabilities do not make sense at all if the ObjectDetectionOutput is created from scores. Thus we could also not create the `class_probabilities` in this case and not compute any classification scores if the `class_probabilities` are unset.\r\n\r\nSolution 1 and 3 are exclusive, solution 2 can be combined with the other solutions.\r\n\r\n## How to work on this issue\r\n- First write a unittest reproducing the error by using ClassificationScorer.calculate_scores()\r\n- Next fix this unittest with solution 2.\r\n- Do not work on Solution 3 yet (another issue)\n", "before_files": [{"content": "from typing import *\n\nimport numpy as np\n\nfrom lightly.active_learning.scorers.scorer import Scorer\n\n\ndef _entropy(probs: np.ndarray, axis: int = 1) -> np.ndarray:\n    \"\"\"Computes the entropy of a probability matrix over one array\n\n    Args:\n        probs:\n            A probability matrix of shape (N, M)\n        axis:\n            The axis the compute the probability over, the output does not have this axis anymore\n\n    Exammple:\n        if probs.shape = (N, C) and axis = 1 then entropies.shape = (N, )\n\n    Returns:\n        The entropy of the prediction vectors, shape: probs.shape, but without the specified axis\n    \"\"\"\n    zeros = np.zeros_like(probs)\n    log_probs = np.log2(probs, out=zeros, where=probs > 0)\n    entropies = -1 * np.sum(probs * log_probs, axis=axis)\n    return entropies\n\ndef _margin_largest_secondlargest(probs: np.ndarray) -> np.ndarray:\n    \"\"\"Computes the margin of a probability matrix\n\n        Args:\n            probs:\n                A probability matrix of shape (N, M)\n\n        Exammple:\n            if probs.shape = (N, C) then margins.shape = (N, )\n\n        Returns:\n            The margin of the prediction vectors\n        \"\"\"\n    sorted_probs = np.partition(probs, -2, axis=1)\n    margins = sorted_probs[:, -1] - sorted_probs[:, -2]\n    return margins\n\n\nclass ScorerClassification(Scorer):\n    \"\"\"Class to compute active learning scores from the model_output of a classification task.\n\n    Currently supports the following scorers:\n\n        The following three uncertainty scores are taken from\n        http://burrsettles.com/pub/settles.activelearning.pdf, Section 3.1, page 12f\n        and also explained in https://towardsdatascience.com/uncertainty-sampling-cheatsheet-ec57bc067c0b\n        They all have in common, that the score is highest if all classes have the\n        same confidence and are 0 if the model assigns 100% probability to a single class.\n        The differ in the number of class confidences they take into account.\n\n        `uncertainty_least_confidence`:\n            This score is 1 - the highest confidence prediction. It is high\n            when the confidence about the most probable class is low.\n\n        `uncertainty_margin`\n            This score is 1- the margin between the highest conficence\n            and second highest confidence prediction. It is high when the model\n            cannot decide between the two most probable classes.\n\n        `uncertainty_entropy`:\n            This scorer computes the entropy of the prediction. The confidences\n             for all classes are considered to compute the entropy of a sample.\n\n    Attributes:\n        model_output:\n            Predictions of shape N x C where N is the number of unlabeled samples\n            and C is the number of classes in the classification task. Must be\n            normalized such that the sum over each row is 1.\n            The order of the predictions must be the one specified by\n            ActiveLearningAgent.unlabeled_set.\n\n    Examples:\n        >>> # example with three unlabeled samples\n        >>> al_agent.unlabeled_set\n        >>> > ['img0.jpg', 'img1.jpg', 'img2.jpg']\n        >>> predictions = np.array(\n        >>>     [\n        >>>          [0.1, 0.9], # predictions for img0.jpg\n        >>>          [0.3, 0.7], # predictions for img1.jpg\n        >>>          [0.8, 0.2], # predictions for img2.jpg\n        >>>     ] \n        >>> )\n        >>> np.sum(predictions, axis=1)\n        >>> > array([1., 1., 1.])\n        >>> scorer = ScorerClassification(predictions)\n\n    \"\"\"\n    def __init__(self, model_output: Union[np.ndarray, List[List[float]]]):\n        if isinstance(model_output, List):\n            model_output = np.array(model_output)\n        super(ScorerClassification, self).__init__(model_output)\n\n    @classmethod\n    def score_names(cls) -> List[str]:\n        \"\"\"Returns the names of the calculated active learning scores\n        \"\"\"\n        score_names = list(cls(model_output=[[0.5, 0.5]]).calculate_scores().keys())\n        return score_names\n\n    def calculate_scores(self, normalize_to_0_1: bool = True) -> Dict[str, np.ndarray]:\n        \"\"\"Calculates and returns the active learning scores.\n\n        Args:\n            normalize_to_0_1:\n                If this is true, each score is normalized to have a\n                theoretical minimum of 0 and a theoretical maximum of 1.\n\n        Returns:\n            A dictionary mapping from the score name (as string)\n            to the scores (as a single-dimensional numpy array).\n        \"\"\"\n        if len(self.model_output) == 0:\n            return {score_name: [] for score_name in self.score_names()}\n\n        scores_with_names = [\n            self._get_scores_uncertainty_least_confidence(),\n            self._get_scores_uncertainty_margin(),\n            self._get_scores_uncertainty_entropy()\n        ]\n\n        scores = dict()\n        for score, score_name in scores_with_names:\n            score = np.nan_to_num(score)\n            scores[score_name] = score\n\n        if normalize_to_0_1:\n            scores = self.normalize_scores_0_1(scores)\n\n        return scores\n\n    def normalize_scores_0_1(self, scores: Dict[str, np.ndarray]) -> Dict[str, np.ndarray]:\n        num_classes = self.model_output.shape[1]\n        model_output_very_sure = np.zeros(shape=(1,num_classes))\n        model_output_very_sure[0, 0] = 1\n        model_output_very_unsure = np.ones_like(model_output_very_sure)/num_classes\n\n        scores_minimum = ScorerClassification(model_output_very_sure).calculate_scores(normalize_to_0_1=False)\n        scores_maximum = ScorerClassification(model_output_very_unsure).calculate_scores(normalize_to_0_1=False)\n\n        for score_name in scores.keys():\n            interp_xp = [float(scores_minimum[score_name]), float(scores_maximum[score_name])]\n            interp_fp = [0, 1]\n            scores[score_name] = np.interp(scores[score_name], interp_xp, interp_fp)\n\n        return scores\n\n    def _get_scores_uncertainty_least_confidence(self):\n        scores = 1 - np.max(self.model_output, axis=1)\n        return scores, \"uncertainty_least_confidence\"\n\n    def _get_scores_uncertainty_margin(self):\n        scores = 1 - _margin_largest_secondlargest(self.model_output)\n        return scores, \"uncertainty_margin\"\n\n    def _get_scores_uncertainty_entropy(self):\n        scores = _entropy(self.model_output, axis=1)\n        return scores, \"uncertainty_entropy\"\n", "path": "lightly/active_learning/scorers/classification.py"}], "after_files": [{"content": "import warnings\nfrom typing import *\n\nimport numpy as np\n\nfrom lightly.active_learning.scorers.scorer import Scorer\n\n\ndef _entropy(probs: np.ndarray, axis: int = 1) -> np.ndarray:\n    \"\"\"Computes the entropy of a probability matrix over one array\n\n    Args:\n        probs:\n            A probability matrix of shape (N, M)\n        axis:\n            The axis the compute the probability over, the output does not have this axis anymore\n\n    Exammple:\n        if probs.shape = (N, C) and axis = 1 then entropies.shape = (N, )\n\n    Returns:\n        The entropy of the prediction vectors, shape: probs.shape, but without the specified axis\n    \"\"\"\n    zeros = np.zeros_like(probs)\n    log_probs = np.log2(probs, out=zeros, where=probs > 0)\n    entropies = -1 * np.sum(probs * log_probs, axis=axis)\n    return entropies\n\ndef _margin_largest_secondlargest(probs: np.ndarray) -> np.ndarray:\n    \"\"\"Computes the margin of a probability matrix\n\n        Args:\n            probs:\n                A probability matrix of shape (N, M)\n\n        Exammple:\n            if probs.shape = (N, C) then margins.shape = (N, )\n\n        Returns:\n            The margin of the prediction vectors\n        \"\"\"\n    sorted_probs = np.partition(probs, -2, axis=1)\n    margins = sorted_probs[:, -1] - sorted_probs[:, -2]\n    return margins\n\n\nclass ScorerClassification(Scorer):\n    \"\"\"Class to compute active learning scores from the model_output of a classification task.\n\n    Currently supports the following scorers:\n\n        The following three uncertainty scores are taken from\n        http://burrsettles.com/pub/settles.activelearning.pdf, Section 3.1, page 12f\n        and also explained in https://towardsdatascience.com/uncertainty-sampling-cheatsheet-ec57bc067c0b\n        They all have in common, that the score is highest if all classes have the\n        same confidence and are 0 if the model assigns 100% probability to a single class.\n        The differ in the number of class confidences they take into account.\n\n        `uncertainty_least_confidence`:\n            This score is 1 - the highest confidence prediction. It is high\n            when the confidence about the most probable class is low.\n\n        `uncertainty_margin`\n            This score is 1- the margin between the highest conficence\n            and second highest confidence prediction. It is high when the model\n            cannot decide between the two most probable classes.\n\n        `uncertainty_entropy`:\n            This scorer computes the entropy of the prediction. The confidences\n             for all classes are considered to compute the entropy of a sample.\n\n    Attributes:\n        model_output:\n            Predictions of shape N x C where N is the number of unlabeled samples\n            and C is the number of classes in the classification task. Must be\n            normalized such that the sum over each row is 1.\n            The order of the predictions must be the one specified by\n            ActiveLearningAgent.unlabeled_set.\n\n    Examples:\n        >>> # example with three unlabeled samples\n        >>> al_agent.unlabeled_set\n        >>> > ['img0.jpg', 'img1.jpg', 'img2.jpg']\n        >>> predictions = np.array(\n        >>>     [\n        >>>          [0.1, 0.9], # predictions for img0.jpg\n        >>>          [0.3, 0.7], # predictions for img1.jpg\n        >>>          [0.8, 0.2], # predictions for img2.jpg\n        >>>     ] \n        >>> )\n        >>> np.sum(predictions, axis=1)\n        >>> > array([1., 1., 1.])\n        >>> scorer = ScorerClassification(predictions)\n\n    \"\"\"\n    def __init__(self, model_output: Union[np.ndarray, List[List[float]]]):\n        if not isinstance(model_output, np.ndarray):\n            model_output = np.array(model_output)\n\n        validated_model_output = self.ensure_valid_model_output(model_output)\n\n        super(ScorerClassification, self).__init__(validated_model_output)\n\n    def ensure_valid_model_output(self, model_output: np.ndarray) -> np.ndarray:\n        if len(model_output) == 0:\n            return model_output\n        if len(model_output.shape) != 2:\n            raise ValueError(\"ScorerClassification model_output must be a 2-dimensional array\")\n        if model_output.shape[1] == 0:\n            raise ValueError(\"ScorerClassification model_output must not have an empty dimension 1\")\n        if model_output.shape[1] == 1:\n            # assuming a binary classification problem with\n            # the model_output denoting the probability of the first class\n            model_output = np.concatenate([model_output, 1-model_output], axis=1)\n        return model_output\n\n    @classmethod\n    def score_names(cls) -> List[str]:\n        \"\"\"Returns the names of the calculated active learning scores\n        \"\"\"\n        score_names = list(cls(model_output=[[0.5, 0.5]]).calculate_scores().keys())\n        return score_names\n\n    def calculate_scores(self, normalize_to_0_1: bool = True) -> Dict[str, np.ndarray]:\n        \"\"\"Calculates and returns the active learning scores.\n\n        Args:\n            normalize_to_0_1:\n                If this is true, each score is normalized to have a\n                theoretical minimum of 0 and a theoretical maximum of 1.\n\n        Returns:\n            A dictionary mapping from the score name (as string)\n            to the scores (as a single-dimensional numpy array).\n        \"\"\"\n        if len(self.model_output) == 0:\n            return {score_name: [] for score_name in self.score_names()}\n\n        scores_with_names = [\n            self._get_scores_uncertainty_least_confidence(),\n            self._get_scores_uncertainty_margin(),\n            self._get_scores_uncertainty_entropy()\n        ]\n\n        scores = dict()\n        for score, score_name in scores_with_names:\n            score = np.nan_to_num(score)\n            scores[score_name] = score\n\n        if normalize_to_0_1:\n            scores = self.normalize_scores_0_1(scores)\n\n        return scores\n\n    def normalize_scores_0_1(self, scores: Dict[str, np.ndarray]) -> Dict[str, np.ndarray]:\n        num_classes = self.model_output.shape[1]\n        model_output_very_sure = np.zeros(shape=(1,num_classes))\n        model_output_very_sure[0, 0] = 1\n        model_output_very_unsure = np.ones_like(model_output_very_sure)/num_classes\n\n        scores_minimum = ScorerClassification(model_output_very_sure).calculate_scores(normalize_to_0_1=False)\n        scores_maximum = ScorerClassification(model_output_very_unsure).calculate_scores(normalize_to_0_1=False)\n\n        for score_name in scores.keys():\n            interp_xp = [float(scores_minimum[score_name]), float(scores_maximum[score_name])]\n            interp_fp = [0, 1]\n            scores[score_name] = np.interp(scores[score_name], interp_xp, interp_fp)\n\n        return scores\n\n    def _get_scores_uncertainty_least_confidence(self):\n        scores = 1 - np.max(self.model_output, axis=1)\n        return scores, \"uncertainty_least_confidence\"\n\n    def _get_scores_uncertainty_margin(self):\n        scores = 1 - _margin_largest_secondlargest(self.model_output)\n        return scores, \"uncertainty_margin\"\n\n    def _get_scores_uncertainty_entropy(self):\n        scores = _entropy(self.model_output, axis=1)\n        return scores, \"uncertainty_entropy\"\n", "path": "lightly/active_learning/scorers/classification.py"}]}