wolffd@0
|
1 function [means, covs, weights, ll] = gmmem_multi_restart(K, data, varargin)
|
wolffd@0
|
2 % GMMEM_MULTI_RESTART Multiple restart wrapper for gmmem_kpm
|
wolffd@0
|
3 % function [means, covs, weights, ll] = gmmem_multi_restart(K, data, varargin)
|
wolffd@0
|
4 %
|
wolffd@0
|
5 % Input:
|
wolffd@0
|
6 % K = number of mixture components
|
wolffd@0
|
7 % data(i,:) is the i'th example (feature vector)
|
wolffd@0
|
8 %
|
wolffd@0
|
9 % Output:
|
wolffd@0
|
10 % The parameters for the k'th mixture component, k=1:K, are
|
wolffd@0
|
11 % means(k,:), covs(:,:,k) and weights(k)
|
wolffd@0
|
12 %
|
wolffd@0
|
13 % [ ... ] = gmmem_multi_restart(..., 'param1',val1, 'param2',val2, ...)
|
wolffd@0
|
14 % allows you to specify optional parameter name/value pairs.
|
wolffd@0
|
15 % Parameters are below [default value in brackets]
|
wolffd@0
|
16 %
|
wolffd@0
|
17 % 'nrestarts' - number of EM restarts [2]
|
wolffd@0
|
18 % 'cov_type' - 'full', 'diag' or 'spherical' ['full']
|
wolffd@0
|
19 % 'init_cov' - the initial covariance matrix [0.1*cov(data) for each k]
|
wolffd@0
|
20 % 'init_means' - [] means sample from randn(); otherwise, use
|
wolffd@0
|
21 % init_means(k,:,r) for the k'th comp. on the r'th restart [ [] ]
|
wolffd@0
|
22 % 'restartfn' - this function, if non-empty, will be called before/after every restart
|
wolffd@0
|
23 % (e.g., to display the parameters as they evolve) [ [] ]
|
wolffd@0
|
24 % The fn is called as fn(mix{r}, data, restart_num, niter, outerfnargs)
|
wolffd@0
|
25 % where niter is the number of iterations performed (0 initially)
|
wolffd@0
|
26 % 'restartfnargs' - additional arguments to be passed to restartfn [ {} ]
|
wolffd@0
|
27 %
|
wolffd@0
|
28 % Optional arguments for gmmem_kpm are passed through.
|
wolffd@0
|
29 %
|
wolffd@0
|
30 % Written by Kevin P Murphy, 30 Dec 2002
|
wolffd@0
|
31
|
wolffd@0
|
32 [ndata nfeatures] = size(data);
|
wolffd@0
|
33
|
wolffd@0
|
34 %Cinit = repmat(0.1*diag(diag(cov(data))), [1 1 K]);
|
wolffd@0
|
35 Cinit = repmat(0.1*cov(data), [1 1 K]);
|
wolffd@0
|
36
|
wolffd@0
|
37 [nrestarts, init_cov, init_means, cov_type, ...
|
wolffd@0
|
38 restartfn, restartfnargs, unused_args] = ...
|
wolffd@0
|
39 process_options(varargin, ...
|
wolffd@0
|
40 'nrestarts', 2, 'init_cov', Cinit, 'init_means', [], ...
|
wolffd@0
|
41 'cov_type', 'full', 'restartfn', [], 'restartfnargs', {});
|
wolffd@0
|
42
|
wolffd@0
|
43 mix = cell(1, nrestarts);
|
wolffd@0
|
44 cost = inf*ones(1,nrestarts);
|
wolffd@0
|
45
|
wolffd@0
|
46 for r=1:nrestarts
|
wolffd@0
|
47 mix{r} = gmm(nfeatures, K, cov_type); % random centers
|
wolffd@0
|
48 if ~isempty(init_means), mix{r}.centres = init_means(:,:,r); end
|
wolffd@0
|
49 mix{r}.covars = init_cov;
|
wolffd@0
|
50 if ~isempty(restartfn)
|
wolffd@0
|
51 feval(restartfn, mix{r}, data, r, 0, restartfnargs{:});
|
wolffd@0
|
52 end
|
wolffd@0
|
53 [mix{r}, niter, ll] = gmmem_kpm(mix{r}, data, unused_args{:});
|
wolffd@0
|
54 cost(r) = -ll; %-sum(log(gmmprob(mix{r}, data)));
|
wolffd@0
|
55 if ~isempty(restartfn)
|
wolffd@0
|
56 feval(restartfn, mix{r}, data, r, niter, restartfnargs{:});
|
wolffd@0
|
57 end
|
wolffd@0
|
58 end
|
wolffd@0
|
59
|
wolffd@0
|
60 [nll, bestr] = min(cost);
|
wolffd@0
|
61 fprintf('best r = %d\n', bestr);
|
wolffd@0
|
62 ll = -nll;
|
wolffd@0
|
63 means = mix{bestr}.centres;
|
wolffd@0
|
64 covs = mix{bestr}.covars;
|
wolffd@0
|
65 weights = mix{bestr}.priors;
|