chore: import upstream snapshot with attribution
This commit is contained in:
@@ -0,0 +1,89 @@
|
||||
"""
|
||||
Helper functions used internally for object detection tasks.
|
||||
"""
|
||||
|
||||
from typing import Any, Dict, List, Optional
|
||||
|
||||
|
||||
import numpy as np
|
||||
|
||||
from cleanlab.internal.numerics import softmax
|
||||
|
||||
|
||||
def bbox_xyxy_to_xywh(bbox: List[float]) -> Optional[List[float]]:
|
||||
"""Converts bounding box coodrinate types from x1y1,x2y2 to x,y,w,h"""
|
||||
if len(bbox) == 4:
|
||||
x1, y1, x2, y2 = bbox
|
||||
w = x2 - x1
|
||||
h = y2 - y1
|
||||
return [x1, y1, w, h]
|
||||
else:
|
||||
print("Wrong bbox shape", len(bbox))
|
||||
return None
|
||||
|
||||
|
||||
def softmin1d(scores: np.ndarray, temperature: float = 0.99, axis: int = 0) -> float:
|
||||
"""Returns softmin of passed in scores."""
|
||||
scores = np.array(scores)
|
||||
softmax_scores = softmax(x=-1 * scores, temperature=temperature, axis=axis, shift=True)
|
||||
return np.dot(softmax_scores, scores)
|
||||
|
||||
|
||||
def calculate_bounding_box_areas(rectangle_coordinates):
|
||||
"""Calculate areas of bounding boxes represented by numpy array with x1, y1, x2, y2 format"""
|
||||
widths = rectangle_coordinates[:, 2] - rectangle_coordinates[:, 0]
|
||||
heights = rectangle_coordinates[:, 3] - rectangle_coordinates[:, 1]
|
||||
return widths * heights
|
||||
|
||||
|
||||
def assert_valid_aggregation_weights(aggregation_weights: Dict[str, Any]) -> None:
|
||||
"""assert aggregation weights are in the proper format"""
|
||||
weights = np.array(list(aggregation_weights.values()))
|
||||
if (not np.isclose(np.sum(weights), 1.0)) or (np.min(weights) < 0.0):
|
||||
raise ValueError(
|
||||
f"""Aggregation weights should be non-negative and must sum to 1.0
|
||||
"""
|
||||
)
|
||||
|
||||
|
||||
def assert_valid_inputs(
|
||||
labels: List[Dict[str, Any]],
|
||||
predictions,
|
||||
method: Optional[str] = None,
|
||||
threshold: Optional[float] = None,
|
||||
):
|
||||
"""Asserts proper input format."""
|
||||
if len(labels) != len(predictions):
|
||||
raise ValueError(
|
||||
f"labels and predictions length needs to match. len(labels) == {len(labels)} while len(predictions) == {len(predictions)}."
|
||||
)
|
||||
# Typecheck labels and predictions
|
||||
if not isinstance(labels[0], dict):
|
||||
raise ValueError(
|
||||
f"Labels has to be a list of dicts. Instead it is list of {type(labels[0])}."
|
||||
)
|
||||
# check last column of predictions is probabilities ( < 1.)?
|
||||
if not isinstance(predictions[0], (list, np.ndarray)):
|
||||
raise ValueError(
|
||||
f"Prediction has to be a list or np.ndarray. Instead it is type {type(predictions[0])}."
|
||||
)
|
||||
if not predictions[0][0].shape[1] == 5:
|
||||
raise ValueError(
|
||||
f"Prediction values have to be of format [x1,y1,x2,y2,pred_prob]. Please refer to the documentation for predicted probabilities under object_detection.rank.get_label_quality_scores for details"
|
||||
)
|
||||
|
||||
valid_methods = ["objectlab"]
|
||||
if method is not None and method not in valid_methods:
|
||||
raise ValueError(
|
||||
f"""
|
||||
{method} is not a valid object detection scoring method!
|
||||
Please choose a valid scoring_method: {valid_methods}
|
||||
"""
|
||||
)
|
||||
|
||||
if threshold is not None and threshold > 1.0:
|
||||
raise ValueError(
|
||||
f"""
|
||||
Threshold is a cutoff of predicted probabilities and therefore should be <= 1.
|
||||
"""
|
||||
)
|
||||
Reference in New Issue
Block a user