Идентификация звука

Послушайте, чтобы понять, что звук, похожий на человеческий, или звук, присутствующий в естественной среде, может быть воспроизведен машиной с использованием методов искусственного интеллекта. Обучение с учителем — это один из методов ИИ, который обычно применяется в классификации и регрессии. В процессе классификации и регрессии модель строится перед обучением и обучением на огромном количестве размеченных обучающих наборов данных, которые могут состоять либо из вектора признаков, описывающего объект события, либо из достоверных выходных данных, представленных меткой. .

Обработка сигналов была развернута в области медицины для процесса диагностики, чтобы получить более точный и информативный результат от системы. Биосигналы, такие как электрокардиограмма (ЭКГ) или фонокардиограмма (ПКГ), действительно предоставляют характеристики сигнала, которые можно извлечь и передать в алгоритмы машинного обучения или контролируемого обучения для классификации заболеваний сердечных клапанов. Характеристики сигнала, которые различаются во временной области, амплитудной области, частотном составе и интенсивности, можно использовать для различения нормального и аномального сердечного звука.

Автоматическая классификация звуков сердца с помощью машинного обучения, как правило, предназначена для улучшения адаптации алгоритма модели машинного обучения к изменениям звуков сердца, таких как звук сердца из записанных аудиоданных, очень тонкий. Для повышения точности классификации необходимо учитывать некоторые основные процедуры или методы, используемые при обработке сигналов. Процедуры классификации тонов сердца с использованием модели машинного обучения описаны в следующих разделах.

Шумоподавление/очистка

Быстрое преобразование Фурье (БПФ) вычисляется по шумовому аудиоклипу и сигнальному аудиоклипу для преобразования сигнала в его частотную область. Затем маска сглаживается фильтром по частоте и времени перед применением к БПФ аудиоклипа сигнала.

import noisereduce as nr
#remove the noise of the signal
reduced_noise = nr.reduce_noise(audio_clip=signal,noise_clip=signal, verbose=False)
#change the output to ndarray
reduced_signal_noise = np.array(reduced_noise)
np.set_printoptions(threshold=np.inf)

Нормализация

Затем сигнал без шума нормализуется с максимальным значением сигнала, как показано ниже.

import numpy as np
#extract the maximum signal
maximum_signal = max(np.abs(reduced_signal_noise))
#normalize the signal
normalized_signal = np.array([(abs(signal) / maximum_signal) for signal in reduced_signal_noise])

Сегментация

Затем в процессе сегментации энергия Шеннона вычисляется по нормализованному сигналу. Эта энергия является квадратом входного сигнала, потому что квадрат сигнала близок к энергии сигнала.

#iterate through the normalized signal
for x in range(0, len(normalized_signal)):
    #power the signal by 2 
    signal_sample = abs(normalized_signal[x]) ** 2 
    if signal_sample <= 0: #set the signal to 1 if it is empty
       signal_sample = 1.0
    
    #calculate Shannon energy
    shannon_energy = signal_sample * math.log(signal_sample)
    
    #replace the normalized signal with Shannon energy       
    normalized_signal[x] = shannon_energy

После этого вектор энергий Шеннона передается на усреднение. Энергии Шеннона усредняются в непрерывных сигналах с интервалом 0,01 секунды.

import numpy as np
#obtain the length of signal
length_of_signal = len(shannon_energy_signal)
#Initialize the signal
segment_signal = 0 
#Set the segmented signal to 0.0002 seconds for realtime analysis, otherwise 0.02 seconds for audio recorder
if realtime:
   #set the segment of 0.0002 seconds
   segment_signal = int(sample_rate * 0.0002)
else:
   #set the segment of 0.02 seconds
   segment_signal = int(sample_rate * 0.02)
segment_energy = [] #initialize the array
for x in range(0, len(shannon_energy_signal), segment_signal):
    sum_signal = 0 
    #retrieve the signal in a segment of 0.02 seconds
    current_segment_energy=shannon_energy_signal[x:x+segment_signal]
    for i in range(0, len(current_segment_energy)):
        #sum up the Shannon energy
        sum_signal += current_segment_energy[i]
    #assign the average Shannon energy to array    
    segment_energy.append(-(sum_signal/segment_signal))
#convert to numpy array
segment_energy_signal = np.array(segment_energy)

Затем средняя энергия Шеннона нормализуется для преобразования в энергетический пакет, который также известен как огибающая энергии Шеннона с использованием среднего значения и стандартного отклонения. Огибающая уменьшает базу сигнала и помещает сигнал ниже базовой линии.

import numpy as np
import librosa, librosa.display
#calculate mean
mean_SE = np.mean(segment_energy_signal)
#calculate standard deviation
std_SE = np.std(segment_energy_signal)
#calculate Shannon Envelope
for x in range(0, len(segment_energy_signal)):
    envelope = 0
    envelope = (segment_energy_signal[x] - mean_SE) / std_SE
    segment_energy_signal[x] = envelope
shannon_envelope = segment_energy_signal
#calculate envelope size
envelope_size = range(0, shannon_envelope.size)
#calculate envelope time
envelope_time = librosa.frames_to_time(envelope_size,hop_length=442)

Пороговое значение является определением для определения пиков (расположения комплекса QRS) с учетом того, что в качестве выходного сигнала выбирается образец с большей амплитудой, чем пороговое значение. Пороговое значение определяется с использованием среднего значения, стандартного отклонения и константы.

import numpy as np
segment_signal = [0] * len(clean_signal)
threshold = 0
k = 0.001
#calculate threshold
if std_SE < mean_SE:
   threshold = abs(k * mean_SE * (1 - std_SE ** 2))
elif std_SE > mean_SE:
     threshold = abs(k * std_SE * (1 -  mean_SE ** 2))
#extract the signal that is greater than threshold   
for x in range(0, len(clean_signal)):
    if np.abs(clean_signal[x]) > threshold:
       segment_signal[x] = clean_signal[x]
segmented_signal = np.array(segment_signal)
#remove 0 
clean_segmented_signal = np.delete(segmented_signal, np.where(segmented_signal == 0))

Извлечение признаков

В общей сложности семь признаков извлекаются из разных доменов. Функции обрабатываются с помощью библиотек «librosa» и «pyAudioAnalysis». Извлеченные признаки включали скорость пересечения нуля, кепстральные коэффициенты Mel-частоты (MFCC), спектральный центроид, спектральный спад, спектральный поток, частоту и энергетическую энтропию. Скорость перехода через нуль и энергетическая энтропия являются характеристиками во временной области, тогда как остальные пять характеристик относятся к характеристикам в частотной области.

Скорость пересечения нуля

from pyAudioAnalysis import ShortTermFeatures as stf
zero_crossing_rate = stf.zero_crossing_rate(clean_segmented_signal)

Мел-частотные кепстральные коэффициенты (MFCC)

import librosa, librosa.display
import numpy as np
mfcc =librosa.feature.mfcc(clean_segmented_signal.astype('float32'), sr=sample_rate)
mean_mfcc = np.mean(mfcc)
std_mfcc = np.std(mfcc)

Спектральный центроид

import librosa, librosa.display
spectral_centroid = librosa.feature.spectral_centroid(clean_segmented_signal, sr=sample_rate)

Спектральный спад

import librosa, librosa.display
spectral_rolloff = librosa.feature.spectral_rolloff(clean_segmented_signal, sr=sample_rate)

Спектральный поток

from pyAudioAnalysis import ShortTermFeatures as stf
import numpy as np
#divide the segmented signal length by half
fft_frame_length = len(clean_segmented_signal) / 2
#extract the signal by half
first_frame = clean_segmented_signal[:int(fft_frame_length)]
second_frame = clean_segmented_signal[int(fft_frame_length):]
frame_step = 1
while(first_frame.shape != second_frame.shape):
      first_frame = clean_segmented_signal[:frame_step+int(fft_frame_length)]
      second_frame = clean_segmented_signal[int(fft_frame_length):]
            frame_step = frame_step + 1
#calculate the fft of the signal
fft_first_frame = np.array([np.fft.fft(first_frame)])
fft_second_frame = np.array([np.fft.fft(second_frame)])
#extract the spectral flux features
spectral_flux = np.array(stf.spectral_flux(np.abs(fft_first_frame), np.abs(fft_second_frame)))

Частота

import numpy as np
frequency_domain = np.array([np.fft.fft(clean_segmented_signal)])
#calculate mean
mean_frequency_domain = np.mean(frequency_domain)
#calculate standard deviation
std_frequency_domain = np.std(frequency_domain)
#extract the real and the imaginary number from complex number
mean_frequency_domain_real = mean_frequency_domain.real
mean_frequency_domain_imaginary = mean_frequency_domain.imag

Энергетическая энтропия

from pyAudioAnalysis import ShortTermFeatures as stf
import numpy as np
#Extract the energy entropy
energy_entropy = np.array(stf.energy_entropy(clean_segmented_signal))

Признаки используются в качестве характеристик каждого образца сердечного тона. Затем значения сохраняются в файле значений с разделителями-запятыми (CSV) в соответствии с соответствующим столбцом. Действительно, добавлен новый столбец для обозначения типов сердечного тона.

2D модель сверточной нейронной сети (CNN)

Структура двумерной модели CNN напоминает многослойный персептрон (MLP), и каждый нейрон в MLP связан с функцией активации, которая отображает взвешенные входные данные в выходные данные. В модели CNN есть несколько основных уровней, а именно сверточный слой, слой максимального объединения, отсев, пакетная нормализация и полностью связанный слой или плотный слой с выпрямленной линейной функцией активации в архитектуре CNN. Кроме того, конструкция конструкции модели показана ниже,

Предлагаемая двумерная (2D) модель сверточной нейронной сети (CNN) обучается и тестируется с использованием наборов данных, сохраненных в файле CSV. Затем набор данных разделяется на 80 % обучающего набора, 10 % проверочного набора и 10 % тестового набора.

Результаты

Ссылка

Beyramienanlou H, Lotfivand N (2017)Энергетический алгоритм Шеннона для обработки сигналов ЭКГ. Вычислительно-математические методы в медицине 2017:1–16. https://doi.org/10.1155/2017/8081361