annotate toolboxes/FullBNT-1.0.7/Kalman/learn_kalman.m @ 0:cc4b1211e677 tip

initial commit to HG from Changeset: 646 (e263d8a21543) added further path and more save "camirversion.m"
author Daniel Wolff
date Fri, 19 Aug 2016 13:07:06 +0200
parents
children
rev   line source
Daniel@0 1 function [A, C, Q, R, initx, initV, LL] = ...
Daniel@0 2 learn_kalman(data, A, C, Q, R, initx, initV, max_iter, diagQ, diagR, ARmode, constr_fun, varargin)
Daniel@0 3 % LEARN_KALMAN Find the ML parameters of a stochastic Linear Dynamical System using EM.
Daniel@0 4 %
Daniel@0 5 % [A, C, Q, R, INITX, INITV, LL] = LEARN_KALMAN(DATA, A0, C0, Q0, R0, INITX0, INITV0) fits
Daniel@0 6 % the parameters which are defined as follows
Daniel@0 7 % x(t+1) = A*x(t) + w(t), w ~ N(0, Q), x(0) ~ N(init_x, init_V)
Daniel@0 8 % y(t) = C*x(t) + v(t), v ~ N(0, R)
Daniel@0 9 % A0 is the initial value, A is the final value, etc.
Daniel@0 10 % DATA(:,t,l) is the observation vector at time t for sequence l. If the sequences are of
Daniel@0 11 % different lengths, you can pass in a cell array, so DATA{l} is an O*T matrix.
Daniel@0 12 % LL is the "learning curve": a vector of the log lik. values at each iteration.
Daniel@0 13 % LL might go positive, since prob. densities can exceed 1, although this probably
Daniel@0 14 % indicates that something has gone wrong e.g., a variance has collapsed to 0.
Daniel@0 15 %
Daniel@0 16 % There are several optional arguments, that should be passed in the following order.
Daniel@0 17 % LEARN_KALMAN(DATA, A0, C0, Q0, R0, INITX0, INITV0, MAX_ITER, DIAGQ, DIAGR, ARmode)
Daniel@0 18 % MAX_ITER specifies the maximum number of EM iterations (default 10).
Daniel@0 19 % DIAGQ=1 specifies that the Q matrix should be diagonal. (Default 0).
Daniel@0 20 % DIAGR=1 specifies that the R matrix should also be diagonal. (Default 0).
Daniel@0 21 % ARMODE=1 specifies that C=I, R=0. i.e., a Gauss-Markov process. (Default 0).
Daniel@0 22 % This problem has a global MLE. Hence the initial parameter values are not important.
Daniel@0 23 %
Daniel@0 24 % LEARN_KALMAN(DATA, A0, C0, Q0, R0, INITX0, INITV0, MAX_ITER, DIAGQ, DIAGR, F, P1, P2, ...)
Daniel@0 25 % calls [A,C,Q,R,initx,initV] = f(A,C,Q,R,initx,initV,P1,P2,...) after every M step. f can be
Daniel@0 26 % used to enforce any constraints on the params.
Daniel@0 27 %
Daniel@0 28 % For details, see
Daniel@0 29 % - Ghahramani and Hinton, "Parameter Estimation for LDS", U. Toronto tech. report, 1996
Daniel@0 30 % - Digalakis, Rohlicek and Ostendorf, "ML Estimation of a stochastic linear system with the EM
Daniel@0 31 % algorithm and its application to speech recognition",
Daniel@0 32 % IEEE Trans. Speech and Audio Proc., 1(4):431--442, 1993.
Daniel@0 33
Daniel@0 34
Daniel@0 35 % learn_kalman(data, A, C, Q, R, initx, initV, max_iter, diagQ, diagR, ARmode, constr_fun, varargin)
Daniel@0 36 if nargin < 8, max_iter = 10; end
Daniel@0 37 if nargin < 9, diagQ = 0; end
Daniel@0 38 if nargin < 10, diagR = 0; end
Daniel@0 39 if nargin < 11, ARmode = 0; end
Daniel@0 40 if nargin < 12, constr_fun = []; end
Daniel@0 41 verbose = 1;
Daniel@0 42 thresh = 1e-4;
Daniel@0 43
Daniel@0 44
Daniel@0 45 if ~iscell(data)
Daniel@0 46 N = size(data, 3);
Daniel@0 47 data = num2cell(data, [1 2]); % each elt of the 3rd dim gets its own cell
Daniel@0 48 else
Daniel@0 49 N = length(data);
Daniel@0 50 end
Daniel@0 51
Daniel@0 52 N = length(data);
Daniel@0 53 ss = size(A, 1);
Daniel@0 54 os = size(C,1);
Daniel@0 55
Daniel@0 56 alpha = zeros(os, os);
Daniel@0 57 Tsum = 0;
Daniel@0 58 for ex = 1:N
Daniel@0 59 %y = data(:,:,ex);
Daniel@0 60 y = data{ex};
Daniel@0 61 T = length(y);
Daniel@0 62 Tsum = Tsum + T;
Daniel@0 63 alpha_temp = zeros(os, os);
Daniel@0 64 for t=1:T
Daniel@0 65 alpha_temp = alpha_temp + y(:,t)*y(:,t)';
Daniel@0 66 end
Daniel@0 67 alpha = alpha + alpha_temp;
Daniel@0 68 end
Daniel@0 69
Daniel@0 70 previous_loglik = -inf;
Daniel@0 71 loglik = 0;
Daniel@0 72 converged = 0;
Daniel@0 73 num_iter = 1;
Daniel@0 74 LL = [];
Daniel@0 75
Daniel@0 76 % Convert to inline function as needed.
Daniel@0 77 if ~isempty(constr_fun)
Daniel@0 78 constr_fun = fcnchk(constr_fun,length(varargin));
Daniel@0 79 end
Daniel@0 80
Daniel@0 81
Daniel@0 82 while ~converged & (num_iter <= max_iter)
Daniel@0 83
Daniel@0 84 %%% E step
Daniel@0 85
Daniel@0 86 delta = zeros(os, ss);
Daniel@0 87 gamma = zeros(ss, ss);
Daniel@0 88 gamma1 = zeros(ss, ss);
Daniel@0 89 gamma2 = zeros(ss, ss);
Daniel@0 90 beta = zeros(ss, ss);
Daniel@0 91 P1sum = zeros(ss, ss);
Daniel@0 92 x1sum = zeros(ss, 1);
Daniel@0 93 loglik = 0;
Daniel@0 94
Daniel@0 95 for ex = 1:N
Daniel@0 96 y = data{ex};
Daniel@0 97 T = length(y);
Daniel@0 98 [beta_t, gamma_t, delta_t, gamma1_t, gamma2_t, x1, V1, loglik_t] = ...
Daniel@0 99 Estep(y, A, C, Q, R, initx, initV, ARmode);
Daniel@0 100 beta = beta + beta_t;
Daniel@0 101 gamma = gamma + gamma_t;
Daniel@0 102 delta = delta + delta_t;
Daniel@0 103 gamma1 = gamma1 + gamma1_t;
Daniel@0 104 gamma2 = gamma2 + gamma2_t;
Daniel@0 105 P1sum = P1sum + V1 + x1*x1';
Daniel@0 106 x1sum = x1sum + x1;
Daniel@0 107 %fprintf(1, 'example %d, ll/T %5.3f\n', ex, loglik_t/T);
Daniel@0 108 loglik = loglik + loglik_t;
Daniel@0 109 end
Daniel@0 110 LL = [LL loglik];
Daniel@0 111 if verbose, fprintf(1, 'iteration %d, loglik = %f\n', num_iter, loglik); end
Daniel@0 112 %fprintf(1, 'iteration %d, loglik/NT = %f\n', num_iter, loglik/Tsum);
Daniel@0 113 num_iter = num_iter + 1;
Daniel@0 114
Daniel@0 115 %%% M step
Daniel@0 116
Daniel@0 117 % Tsum = N*T
Daniel@0 118 % Tsum1 = N*(T-1);
Daniel@0 119 Tsum1 = Tsum - N;
Daniel@0 120 A = beta * inv(gamma1);
Daniel@0 121 %A = (gamma1' \ beta')';
Daniel@0 122 Q = (gamma2 - A*beta') / Tsum1;
Daniel@0 123 if diagQ
Daniel@0 124 Q = diag(diag(Q));
Daniel@0 125 end
Daniel@0 126 if ~ARmode
Daniel@0 127 C = delta * inv(gamma);
Daniel@0 128 %C = (gamma' \ delta')';
Daniel@0 129 R = (alpha - C*delta') / Tsum;
Daniel@0 130 if diagR
Daniel@0 131 R = diag(diag(R));
Daniel@0 132 end
Daniel@0 133 end
Daniel@0 134 initx = x1sum / N;
Daniel@0 135 initV = P1sum/N - initx*initx';
Daniel@0 136
Daniel@0 137 if ~isempty(constr_fun)
Daniel@0 138 [A,C,Q,R,initx,initV] = feval(constr_fun, A, C, Q, R, initx, initV, varargin{:});
Daniel@0 139 end
Daniel@0 140
Daniel@0 141 converged = em_converged(loglik, previous_loglik, thresh);
Daniel@0 142 previous_loglik = loglik;
Daniel@0 143 end
Daniel@0 144
Daniel@0 145
Daniel@0 146
Daniel@0 147 %%%%%%%%%
Daniel@0 148
Daniel@0 149 function [beta, gamma, delta, gamma1, gamma2, x1, V1, loglik] = ...
Daniel@0 150 Estep(y, A, C, Q, R, initx, initV, ARmode)
Daniel@0 151 %
Daniel@0 152 % Compute the (expected) sufficient statistics for a single Kalman filter sequence.
Daniel@0 153 %
Daniel@0 154
Daniel@0 155 [os T] = size(y);
Daniel@0 156 ss = length(A);
Daniel@0 157
Daniel@0 158 if ARmode
Daniel@0 159 xsmooth = y;
Daniel@0 160 Vsmooth = zeros(ss, ss, T); % no uncertainty about the hidden states
Daniel@0 161 VVsmooth = zeros(ss, ss, T);
Daniel@0 162 loglik = 0;
Daniel@0 163 else
Daniel@0 164 [xsmooth, Vsmooth, VVsmooth, loglik] = kalman_smoother(y, A, C, Q, R, initx, initV);
Daniel@0 165 end
Daniel@0 166
Daniel@0 167 delta = zeros(os, ss);
Daniel@0 168 gamma = zeros(ss, ss);
Daniel@0 169 beta = zeros(ss, ss);
Daniel@0 170 for t=1:T
Daniel@0 171 delta = delta + y(:,t)*xsmooth(:,t)';
Daniel@0 172 gamma = gamma + xsmooth(:,t)*xsmooth(:,t)' + Vsmooth(:,:,t);
Daniel@0 173 if t>1 beta = beta + xsmooth(:,t)*xsmooth(:,t-1)' + VVsmooth(:,:,t); end
Daniel@0 174 end
Daniel@0 175 gamma1 = gamma - xsmooth(:,T)*xsmooth(:,T)' - Vsmooth(:,:,T);
Daniel@0 176 gamma2 = gamma - xsmooth(:,1)*xsmooth(:,1)' - Vsmooth(:,:,1);
Daniel@0 177
Daniel@0 178 x1 = xsmooth(:,1);
Daniel@0 179 V1 = Vsmooth(:,:,1);
Daniel@0 180
Daniel@0 181
Daniel@0 182