function [loglik, stateseq, recon, lattice, tb, mllattice] = decode_hmm(hmm, frameLogLike, maxRank, beamLogProb, normalize_lattice, verb)
% [loglik, stateseq, recon, lattice, tb] = decode_hmm(hmm, seq, rank, beam)
%
% Performs Viterbi decode of seq. Does rank and beam pruning.
% Assumes all hmm params are logprobs.
%
% 2007-02-26 ronw@ee.columbia.edu
% Copyright (C) 2007 Ron J. Weiss
%
% This program is free software: you can redistribute it and/or modify
% it under the terms of the GNU General Public License as published by
% the Free Software Foundation, either version 3 of the License, or
% (at your option) any later version.
%
% This program is distributed in the hope that it will be useful,
% but WITHOUT ANY WARRANTY; without even the implied warranty of
% MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
% GNU General Public License for more details.
%
% You should have received a copy of the GNU General Public License
% along with this program. If not, see <http://www.gnu.org/licenses/>.
zeroLogProb = -1e200;
% no rank pruning by default
if nargin < 3
maxRank = 0;
end
% no beam pruning by default
if nargin < 4
beamLogProb = -Inf;
end
if nargin < 5
normalize_lattice = 0;
end
if nargin < 6
verb = 0;
end
[nstates, nobs] = size(frameLogLike);
if nstates ~= hmm.nstates && nstates == size(hmm.means, 1)
seq = frameLogLike;
ndim = nstates;
nstates = hmm.nstates;
if strcmp(hmm.emission_type, 'gaussian')
frameLogLike = lmvnpdf(seq, hmm.means, hmm.covars);
elseif strcmp(hmm.emission_type, 'GMM')
for s = 1:hmm.nstates
frameLogLike(s,:) = eval_gmm(hmm.gmms(s), seq);
end
else
error('Unknown HMM emission distribution.');
end
end
% how big should our rank pruning histogram be?
histSize = 1000;
stateseq = zeros(1, nobs);
tb = zeros(hmm.nstates, nobs);
if nargout > 3
lattice = repmat(zeroLogProb, [hmm.nstates, nobs]);
end
% FIXME - there is a bug here in how the first frame is handled -
% an extra transition probability from the non-existant 0th frame
% to the 1st frame is added into lattice...
prevLatticeFrame = hmm.start_prob(:);
%prevLatticeFrame = hmm.start_prob(:) + frameLogLike(:,1);
tb = zeros(hmm.nstates, nobs);
% fill in the lattice...
avg_nactive = 0;
prevFrameMaxLogProb = 0;
for obs = 1:nobs
if verb >= 2
tic
end
% beam pruning
threshLogProb = prevFrameMaxLogProb + beamLogProb;
% rank pruning
if maxRank > 0
tmp = prevLatticeFrame(:);
min_tmp = 2*min(tmp(tmp > zeroLogProb));
tmp(tmp < zeroLogProb) = min_tmp;
[hst cdf] = hist(tmp, histSize);
% want to look at the high ranks of the last frame
hst = hst(end:-1:1);
cdf = cdf(end:-1:1);
hst = cumsum(hst);
idx = min(find(hst >= maxRank));
rankThresh = cdf(idx);
% only change the threshold if it is stricter than the beam
% threshold
threshLogProb = max(threshLogProb, rankThresh);
if verb >= 3
%imgsc(prevLatticeFrame), colorbar, title(num2str(obs)), drawnow
disp(['beam thresh = ' num2str(prevFrameMaxLogProb+beamLogProb) ...
', rank thresh = ' num2str(rankThresh) ...
', final thresh = ' num2str(threshLogProb)]);
end
end
% which states are active?
s_idx = find(prevLatticeFrame >= threshLogProb);
nactive = numel(s_idx);
avg_nactive = avg_nactive + nactive/nobs;
vitPr = hmm.transmat(s_idx, :)' + repmat(prevLatticeFrame(s_idx), [1, hmm.nstates])';
currllik = frameLogLike(:,obs);
% v_idx = find(max(vitPr,[], 2) > zeroLogProb);
% nv = length(v_idx);
% currllik = repmat(zeroLogProb, [hmm.nstates, 1]);
% if strcmp(hmm.emission_type, 'gaussian')
% currllik(v_idx) = lmvnpdf(seq(:,obs), hmm.means(:, v_idx), ...
% hmm.covars(:, v_idx));
% else
% for s = 1:nv
% currllik(v_idx(s)) = eval_gmm(hmm.gmms(v_idx(s)), seq(:,obs));
% end
% end
[prevLatticeFrame tb_tmp] = max(vitPr + repmat(currllik, [1, nactive]), [], 2);
% This is equivalent to the above?
%[prevLatticeFrame tb_tmp] = max(vitPr, [], 2);
%prevLatticeFrame = prevLatticeFrame + currllik;
tb(:,obs) = s_idx(tb_tmp);
if nargout > 3
lattice(:,obs) = prevLatticeFrame;
end
prevFrameMaxLogProb = max(prevLatticeFrame);
if verb >= 2
T = toc;
disp(['frame ' num2str(obs), ' (' num2str(T) ' sec)' ...
': total active states: ' num2str(nactive)]);
end
end
% include end_prob in lattice:
ptmp = prevLatticeFrame;
prevLatticeFrame = prevLatticeFrame + hmm.end_prob(:);
%%%
% do the traceback:
[loglik s] = max(prevLatticeFrame(:));
% we might have pruned too much, don't want to give up if end_prob
% restrictions are too strong - so just ignore them in this case
if loglik <= zeroLogProb
warning(['decode_hmm: overpruned during decode,' ...
' ignoring probabilities that the hmms end in a' ...
' particular state']);
prevLatticeFrame = ptmp;
[loglik s] = max(prevLatticeFrame);
end
if nargout > 3
lattice(:,end) = prevLatticeFrame;
end
for obs = nobs:-1:1
stateseq(obs) = s;
s = tb(s, obs);
end
% need to keep track of which gmm component was used in the
% traceback for reconstruction - since this code doesn't do that,
% can only guess as to the right reconstruction for GMM emissions -
% should use convert_hmm_to_gaussian_emissions before calling this
% function to get the full traceback
if strcmp(hmm.emission_type, 'gaussian')
recon = hmm.means(:,stateseq);
else
for s = 1:hmm.nstates
means(:,s) = hmm.gmms(s).means * exp(hmm.gmms(s).priors)';
end
recon = means(:,stateseq);
end
if nargout > 3 & normalize_lattice
nrm = logsum(lattice, 1);
lattice = exp(lattice - repmat(nrm, [hmm.nstates, 1]));
lattice(lattice < 1e-5) = 0;
end
if nargout > 4
mllattice = sparse(hmm.nstates, nobs);
for o = 1:nobs
mllattice(stateseq(o),o) = 1;
end
end
if verb
disp(['decode_hmm: log likelihood: ' num2str(loglik) ...
', average number of active states per frame: ' ...
num2str(avg_nactive)]);
end
没有合适的资源?快使用搜索试试~ 我知道了~
MATLAB functions for training and evaluating HMMs and GMMs.zip
共18个文件
m:16个
readme:1个
copying:1个
1.该资源内容由用户上传,如若侵权请联系客服进行举报
2.虚拟产品一经售出概不退款(资源遇到问题,请及时私信上传者)
2.虚拟产品一经售出概不退款(资源遇到问题,请及时私信上传者)
版权申诉
0 下载量 151 浏览量
2023-07-19
20:09:03
上传
评论
收藏 32KB ZIP 举报
温馨提示
MATLAB functions for training and evaluating HMMs and GMMs.zip
资源推荐
资源详情
资源评论
收起资源包目录
MATLAB functions for training and evaluating HMMs and GMMs.zip (18个子文件)
matlab_hmm-master
sample_gmm.m 1KB
train_gmm.m 2KB
convert_hmm_to_gaussian_emissions.m 2KB
README 3KB
is_valid_gmm.m 2KB
eval_hmm.m 5KB
logsum.m 383B
decode_hmm.m 6KB
lmvnpdf.m 2KB
is_valid_hmm.m 4KB
merge_states.m 3KB
adapt_gmm.m 4KB
reorder_states.m 2KB
kmeans.m 2KB
sample_gaussian.m 903B
eval_gmm.m 2KB
sample_hmm.m 2KB
COPYING 34KB
新建文件夹
共 18 条
- 1
资源评论
AbelZ_01
- 粉丝: 875
- 资源: 5441
上传资源 快速赚钱
- 我的内容管理 展开
- 我的资源 快来上传第一个资源
- 我的收益 登录查看自己的收益
- 我的积分 登录查看自己的积分
- 我的C币 登录后查看C币余额
- 我的收藏
- 我的下载
- 下载帮助
安全验证
文档复制为VIP权益,开通VIP直接复制
信息提交成功