File size: 3,688 Bytes
1582553
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
f16709f
1582553
f532fdf
1582553
 
 
 
 
 
 
f16709f
1582553
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
f532fdf
1582553
 
f16709f
 
1582553
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
f16709f
fc72c3a
f16709f
1582553
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
from pathlib import Path
import numpy as np

from iSparrow.sparrow_model_base import ModelBase

# from iSparrow import utils


class Model(ModelBase):
    """
    Model Model class representing the the default birdnet model. Does currently not support custom species list or species prediction based on coordinates.

    """

    def __init__(
        self,
        model_path: str,
        num_threads: int = 1,
        sigmoid_sensitivity: float = 1.0,
        species_list_file: str = None,
        **kwargs
    ):
        """
        __init__ Create a new model instance that uses birdnet-analyzer models for bird species classification

        Args:
            model_path (str): Path to the location of the model file to be loaded
            num_threads (int, optional): Number of threads used for inference. Defaults to 1.
            sigmoid_sensitivity (float, optional): Parameter of the sigmoid function used to compute probabilities. Defaults to 1.0.

        Raises:
            AnalyzerConfigurationError: The model file 'model.tflite' doesn't exist at the given path.
            AnalyzerConfigurationError: The labels file 'labels.txt' doesn't exist at the given path.
        """

        labels_path = str(Path(model_path) / "labels.txt")

        model_path = str(Path(model_path) / "model.tflite")

        # base class loads the model and labels
        super().__init__(
            "birdnet_default",
            model_path,
            labels_path,
            num_threads=num_threads,
            **kwargs
        )

        self.sigmoid_sensitivity = sigmoid_sensitivity

        # store input and output index to not have to retrieve them each time an inference is made
        input_details = self.model.get_input_details()

        output_details = self.model.get_output_details()

        # Get input tensor index
        self.input_layer_index = input_details[0]["index"]

        # Get classification output or feature embeddings as output, depending on presence fo custom classifier
        self.output_layer_index = output_details[0]["index"]

    def load_species_list(self):
        # TODO
        pass

    def predict(self, sample: np.array) -> np.array:
        """
        predict Make inference about the bird species for the preprocessed data passed to this function as arguments.

        Args:
            data (np.array): list of preprocessed data chunks
        Returns:
            list: List of (label, inferred_probability)
        """
        data = np.array([sample], dtype="float32")

        self.model.resize_tensor_input(
            self.input_layer_index, [len(data), *data[0].shape]
        )
        self.model.allocate_tensors()

        # Make a prediction (Audio only for now)
        self.model.set_tensor(self.input_layer_index, np.array(data, dtype="float32"))
        self.model.invoke()

        prediction = self.model.get_tensor(self.output_layer_index)

        confidence = self._sigmoid(
            np.array(prediction), sigmoid_sensitivity=-self.sigmoid_sensitivity
        )

        return confidence

    @classmethod
    def from_cfg(cls, sparrow_folder: str, cfg: dict):
        """
        from_cfg Create a new instance from a dictionary containing keyword arguments. Usually loaded from a config file.

        Args:
            sparrow_dir (str): Installation directory of the Sparrow package
            cfg (dict): Dictionary containing the keyword arguments

        Returns:
            Model: New model instance created with the supplied kwargs.
        """
        cfg["model_path"] = str(
            Path(sparrow_folder) / Path("models") / cfg["model_path"]
        )

        return cls(**cfg)