wolffd@0: function [means, covs, weights, ll] = gmmem_multi_restart(K, data, varargin) wolffd@0: % GMMEM_MULTI_RESTART Multiple restart wrapper for gmmem_kpm wolffd@0: % function [means, covs, weights, ll] = gmmem_multi_restart(K, data, varargin) wolffd@0: % wolffd@0: % Input: wolffd@0: % K = number of mixture components wolffd@0: % data(i,:) is the i'th example (feature vector) wolffd@0: % wolffd@0: % Output: wolffd@0: % The parameters for the k'th mixture component, k=1:K, are wolffd@0: % means(k,:), covs(:,:,k) and weights(k) wolffd@0: % wolffd@0: % [ ... ] = gmmem_multi_restart(..., 'param1',val1, 'param2',val2, ...) wolffd@0: % allows you to specify optional parameter name/value pairs. wolffd@0: % Parameters are below [default value in brackets] wolffd@0: % wolffd@0: % 'nrestarts' - number of EM restarts [2] wolffd@0: % 'cov_type' - 'full', 'diag' or 'spherical' ['full'] wolffd@0: % 'init_cov' - the initial covariance matrix [0.1*cov(data) for each k] wolffd@0: % 'init_means' - [] means sample from randn(); otherwise, use wolffd@0: % init_means(k,:,r) for the k'th comp. on the r'th restart [ [] ] wolffd@0: % 'restartfn' - this function, if non-empty, will be called before/after every restart wolffd@0: % (e.g., to display the parameters as they evolve) [ [] ] wolffd@0: % The fn is called as fn(mix{r}, data, restart_num, niter, outerfnargs) wolffd@0: % where niter is the number of iterations performed (0 initially) wolffd@0: % 'restartfnargs' - additional arguments to be passed to restartfn [ {} ] wolffd@0: % wolffd@0: % Optional arguments for gmmem_kpm are passed through. wolffd@0: % wolffd@0: % Written by Kevin P Murphy, 30 Dec 2002 wolffd@0: wolffd@0: [ndata nfeatures] = size(data); wolffd@0: wolffd@0: %Cinit = repmat(0.1*diag(diag(cov(data))), [1 1 K]); wolffd@0: Cinit = repmat(0.1*cov(data), [1 1 K]); wolffd@0: wolffd@0: [nrestarts, init_cov, init_means, cov_type, ... wolffd@0: restartfn, restartfnargs, unused_args] = ... wolffd@0: process_options(varargin, ... wolffd@0: 'nrestarts', 2, 'init_cov', Cinit, 'init_means', [], ... wolffd@0: 'cov_type', 'full', 'restartfn', [], 'restartfnargs', {}); wolffd@0: wolffd@0: mix = cell(1, nrestarts); wolffd@0: cost = inf*ones(1,nrestarts); wolffd@0: wolffd@0: for r=1:nrestarts wolffd@0: mix{r} = gmm(nfeatures, K, cov_type); % random centers wolffd@0: if ~isempty(init_means), mix{r}.centres = init_means(:,:,r); end wolffd@0: mix{r}.covars = init_cov; wolffd@0: if ~isempty(restartfn) wolffd@0: feval(restartfn, mix{r}, data, r, 0, restartfnargs{:}); wolffd@0: end wolffd@0: [mix{r}, niter, ll] = gmmem_kpm(mix{r}, data, unused_args{:}); wolffd@0: cost(r) = -ll; %-sum(log(gmmprob(mix{r}, data))); wolffd@0: if ~isempty(restartfn) wolffd@0: feval(restartfn, mix{r}, data, r, niter, restartfnargs{:}); wolffd@0: end wolffd@0: end wolffd@0: wolffd@0: [nll, bestr] = min(cost); wolffd@0: fprintf('best r = %d\n', bestr); wolffd@0: ll = -nll; wolffd@0: means = mix{bestr}.centres; wolffd@0: covs = mix{bestr}.covars; wolffd@0: weights = mix{bestr}.priors;