#algorithm #matlab #signal-processing
#алгоритм #matlab #обработка сигналов
Вопрос:
Я запускаю алгоритм улучшения речи, основанный на модели гауссовой смеси. Проблема в том, что алгоритм оценки переполняется во время обработки обучения. Я пытаюсь вычислить PDF-файл фрейма логарифмического спектра X
с учетом гауссовского кластера, который является произведением PDF каждого частотного компонента X_k
(fft выполняется для k = 1 ..256), что я получаю, является произведением 256 exp(-v(k))
такого, что v(k)>=0
Вот фрагмент вычисления MATLAB: N
— количество кадров; M
— количество смесей; c_i
вес для каждой смеси;
gamma(n,i) = c_i*f(X_n|I = i)
for i=1 : N
rep_DataMat(:,:,i) = repmat(DataMat(:,i),1,M);
gamma_exp(:,:) = (1./sqrt((2*pi*sigmaSqr_curr))).*exp(((-1)*((rep_DataMat(:,:,i) - mue_curr).^2)./(2*sigmaSqr_curr)));
gamma_curr(i,:) = c_curr.*(prod(10*gamma_exp(:,:),1));
alpha_curr(i,:) = gamma_curr(i,:)./sum(gamma_curr(i,:));
end
Произведение быстро стремится к нулю из-за K = 256, поскольку числа меньше единицы. Есть ли способ, которым я могу вычислить это, вызвав недостаточный поток (например, logsum или аналогичный)?
Ответ №1:
Вы можете выполнять вычисления в лог-домене.
Преобразование произведений в суммы является простым. Суммы, с другой стороны, могут быть преобразованы с помощью чего-то вроде logsumexp. Это работает с использованием формулы:
log(a b) = log(exp(log(a)) exp(log(b)))
= log(exp(loga) exp(logb))
Где loga
и logb
являются соответствующим представлением a
и b
в логарифмической области.
Основная идея состоит в том, чтобы разложить показатель степени на множители с наибольшим аргументом (например. loga
для иллюстрации):
log(exp(loga) exp(logb)) = log(exp(loga)*(1 exp(logb-loga)))
= loga log(1 exp(logb-loga))
Обратите внимание, что та же идея применима, если у вас есть более 2 терминов для добавления.