Implemented AI stuff
All checks were successful
continuous-integration/drone/push Build is passing

This commit is contained in:
Pünkösd Marcell 2020-09-25 13:48:11 +02:00
parent 80a7557467
commit 09c991baf3
2 changed files with 90 additions and 20 deletions

View File

@ -16,7 +16,7 @@ class AbcPreProcessor(ABC):
Abstract base class PreProcessor. Responsible for manipulating input data from a sensor. Abstract base class PreProcessor. Responsible for manipulating input data from a sensor.
""" """
@abstractmethod @abstractmethod
def preprocesssignal(self, signal): def preprocesssignal(self, file_path) -> bool:
""" """
Preprocess a signal. Preprocess a signal.
:return: :return:

View File

@ -1,9 +1,15 @@
#!/usr/bin/env python3 #!/usr/bin/env python3
import requests import requests
from pyAudioAnalysis import audioTrainTest as aT from pyAudioAnalysis.audioTrainTest import load_model, load_model_knn, classifier_wrapper
from pyAudioAnalysis.audioTrainTest import load_model, load_model_knn
from utils import config from utils import config
from .abcpreprocessor import AbcPreProcessor from .abcpreprocessor import AbcPreProcessor
import tempfile
import os
import logging
from pyAudioAnalysis import audioBasicIO
from pyAudioAnalysis import MidTermFeatures
import numpy
""" """
Abstract base class for Sender Abstract base class for Sender
@ -20,27 +26,91 @@ class SoundPreProcessor(AbcPreProcessor):
SoundPreProcessor class, responsible for detecting birb chirps in sound sample. SoundPreProcessor class, responsible for detecting birb chirps in sound sample.
""" """
def preprocesssignal(self, signal: str) -> bool: def __init__(self):
""" logging.info("Downloading current model...")
Classify a sound sample. _, self._temp_model_name = tempfile.mkstemp()
:param signal: Access path of the sound sample up for processing. self._temp_means_name = self._temp_model_name + "MEANS"
:return:
""" logging.debug("Fetching model info...")
# TODO: Dynamic model injection? r = requests.get(f"{config.API_URL}/model/$default/details")
r = requests.get(f"http://model-service/model/{config.MODEL_ID}/details")
r.raise_for_status() r.raise_for_status()
model_details = r.json() self._model_details = r.json()
if model_details['type'] == 'knn': logging.debug("Downloading model...")
classifier, mean, std, classes, mid_window, mid_step, short_window, short_step, compute_beat \ r = requests.get(f"{config.API_URL}/model/{self._model_details['id']}")
= load_model_knn(config.MODEL_ID + "MEANS") r.raise_for_status()
with open(self._temp_model_name, 'wb') as f:
f.write(r.content)
logging.debug("Downloading MEANS...")
r = requests.get(f"{config.API_URL}/model/{self._model_details['id']}?means")
r.raise_for_status()
with open(self._temp_means_name, 'wb') as f:
f.write(r.content)
logging.info("Loading current model...")
if self._model_details['type'] == 'knn':
self._classifier, self._mean, self._std, self._classes, \
self._mid_window, self._mid_step, self._short_window, \
self._short_step, self._compute_beat = load_model_knn(self._temp_model_name)
else: else:
classifier, mean, std, classes, mid_window, mid_step, short_window, short_step, compute_beat \ self._classifier, self._mean, self._std, self._classes, \
= load_model(config.MODEL_ID + "MEANS") self._mid_window, self._mid_step, self._short_window, \
self._short_step, self._compute_beat = load_model(self._temp_model_name)
target_id = classes.index(config.TARGET_NAME) def preprocesssignal(self, file_path: str) -> bool:
"""
Classify a sound sample.
:param file_path: Access path of the sound sample up for processing.
:return:
"""
logging.info("Running extraction...")
class_id, probability = aT.file_classification(signal, config.MODEL_ID, "svm") sampling_rate, signal = audioBasicIO.read_audio_file(file_path)
return class_id == target_id signal = audioBasicIO.stereo_to_mono(signal)
if sampling_rate == 0:
raise Exception("Could not read the file properly: Sampling rate zero")
if signal.shape[0] / float(sampling_rate) <= self._mid_window:
raise Exception("Could not read the file properly: Signal shape is not good")
# feature extraction:
mid_features, s, _ = \
MidTermFeatures.mid_feature_extraction(signal, sampling_rate,
self._mid_window * sampling_rate,
self._mid_step * sampling_rate,
round(sampling_rate * self._short_window),
round(sampling_rate * self._short_step))
# long term averaging of mid-term statistics
mid_features = mid_features.mean(axis=1)
if self._compute_beat:
beat, beat_conf = MidTermFeatures.beat_extraction(s, self._short_step)
mid_features = numpy.append(mid_features, beat)
mid_features = numpy.append(mid_features, beat_conf)
logging.info("Running classification...")
target_id = self._classes.index('chirp') # Might raise ValueError
feature_vector = (mid_features - self._mean) / self._std
class_id, probability = classifier_wrapper(self._classifier, self._model_details['type'], feature_vector)
return bool(class_id == target_id)
def __del__(self):
try:
os.remove(self._temp_model_name)
except FileNotFoundError:
pass
try:
os.remove(self._temp_means_name)
except FileNotFoundError:
pass