Дополнительные советы по извлечению аудио функций - PullRequest
1 голос
/ 13 апреля 2019

Я пытаюсь создать модель распознавания эмоций речи с помощью Keras, я выполнил весь код и обучил эту модель.Он занимает около 50% проверки и переоснащение.

Когда я использую model.predict () с невидимыми данными, кажется, что трудно различать «нейтральный», «спокойный», «счастливый» и «удивленный», но, похоже, может предсказатьсердитый 'правильно в большинстве случаев - я предполагаю, потому что есть четкая разница в высоте или что-то.

Я думаю, возможно, что из-за этих эмоций мне не хватает функций, которые помогли бы модели различить их.

В настоящее время я использую Librosa и передаю аудио в MFCC.Есть ли какой-либо другой способ, даже с использованием Librosa, который я могу сделать, чтобы извлечь функции для модели, чтобы помочь ей лучше различать «нейтральный», «спокойный», «счастливый», «удивленный» и т. Д.?

код извлечения некоторых функций:

wav_clip, sample_rate = librosa.load(file_path, duration=3, mono=True, sr=None)     
mfcc = librosa.feature.mfcc(wav_clip, sample_rate)

Кроме того, это с 1400 семплами.

1 Ответ

1 голос
/ 13 апреля 2019

Несколько замечаний для стартера:

  • Вероятно, у вас слишком мало образцов для эффективного использования нейронных сетей. Используйте простой алгоритм для начинающих, чтобы хорошо понять, как ваша модель делает прогноз.
  • Убедитесь, что у вас достаточно (30% или более) семплов от разных динамиков, отложенных для окончательного тестирования. Вы можете использовать этот набор тестов только один раз, поэтому подумайте о построении конвейера для генерации наборов поездов, проверок и тестов. Убедитесь, что вы не устанавливаете один и тот же динамик в более чем 1 комплект.
  • Первый коэффициент из librosa дает AFAIK смещение. Я бы порекомендовал представить, как ваши функции соотносятся с ярлыками и насколько они перекрываются, я думаю, некоторые из них могут быть легко запутаны. Найдите, есть ли какая-либо особенность, которая будет отличать ваши классы. Не делайте этого, запустив модель, сначала проведите визуальный осмотр.

К актуальным возможностям! Вы правы, полагая, что шаг должен играть жизненно важную роль. Я бы порекомендовал проверить aubio - у него есть привязки Python.

Yaafe также предлагает отличный выбор функций.

Вы можете легко получить более 150 функций. Возможно, вы захотите уменьшить размерность задачи, возможно, даже сжать ее до 2d и посмотреть, сможете ли вы как-то разделить классы. Здесь - мой собственный пример с Dash.

И последнее, но не менее важное: некоторый базовый код для извлечения частот из аудио. В этом случае я также пытаюсь найти три пиковые частоты.

import numpy as np

def spectral_statistics(y: np.ndarray, fs: int, lowcut: int = 0) -> dict:
    """
    Compute selected statistical properties of spectrum
    :param y: 1-d signsl
    :param fs: sampling frequency [Hz]
    :param lowcut: lowest frequency [Hz]
    :return: spectral features (dict)
    """
    spec = np.abs(np.fft.rfft(y))
    freq = np.fft.rfftfreq(len(y), d=1 / fs)
    idx = int(lowcut / fs * len(freq) * 2)
    spec = np.abs(spec[idx:])
    freq = freq[idx:]

    amp = spec / spec.sum()
    mean = (freq * amp).sum()
    sd = np.sqrt(np.sum(amp * ((freq - mean) ** 2)))
    amp_cumsum = np.cumsum(amp)
    median = freq[len(amp_cumsum[amp_cumsum <= 0.5]) + 1]
    mode = freq[amp.argmax()]
    Q25 = freq[len(amp_cumsum[amp_cumsum <= 0.25]) + 1]
    Q75 = freq[len(amp_cumsum[amp_cumsum <= 0.75]) + 1]
    IQR = Q75 - Q25
    z = amp - amp.mean()
    w = amp.std()
    skew = ((z ** 3).sum() / (len(spec) - 1)) / w ** 3
    kurt = ((z ** 4).sum() / (len(spec) - 1)) / w ** 4

    top_peaks_ordered_by_power = {'stat_freq_peak_by_power_1': 0, 'stat_freq_peak_by_power_2': 0, 'stat_freq_peak_by_power_3': 0}
    top_peaks_ordered_by_order = {'stat_freq_peak_by_order_1': 0, 'stat_freq_peak_by_order_2': 0, 'stat_freq_peak_by_order_3': 0}
    amp_smooth = signal.medfilt(amp, kernel_size=15)
    peaks, height_d = signal.find_peaks(amp_smooth, distance=100, height=0.002)
    if peaks.size != 0:
        peak_f = freq[peaks]
        for peak, peak_name in zip(peak_f, top_peaks_ordered_by_order.keys()):
            top_peaks_ordered_by_order[peak_name] = peak

        idx_three_top_peaks = height_d['peak_heights'].argsort()[-3:][::-1]
        top_3_freq = peak_f[idx_three_top_peaks]
        for peak, peak_name in zip(top_3_freq, top_peaks_ordered_by_power.keys()):
            top_peaks_ordered_by_power[peak_name] = peak

    specprops = {
        'stat_mean': mean,
        'stat_sd': sd,
        'stat_median': median,
        'stat_mode': mode,
        'stat_Q25': Q25,
        'stat_Q75': Q75,
        'stat_IQR': IQR,
        'stat_skew': skew,
        'stat_kurt': kurt
    }
    specprops.update(top_peaks_ordered_by_power)
    specprops.update(top_peaks_ordered_by_order)
    return specprops
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...