annotate notes/hnmf.m @ 372:af71cbdab621 tip

Update bqvec code
author Chris Cannam
date Tue, 19 Nov 2019 10:13:32 +0000
parents f1f8c84339d0
children
rev   line source
Chris@16 1 function [w,h,z,xa] = hnmf( x, K, R, iter, sh, sz, w, h, pl, lh, lz)
Chris@16 2 % function [w,h,z,xa] = hnmf( x, K, R, iter, sh, sz, w, h, pl, lh, lz)
Chris@16 3 %
Chris@16 4 % Perform Multi-source NMF
Chris@16 5 %
Chris@16 6 % Inputs:
Chris@16 7 % x input distribution
Chris@16 8 % K number of components
Chris@16 9 % R number of sources
Chris@16 10 % iter number of EM iterations [default = 100]
Chris@16 11 % sh sparsity of h
Chris@16 12 % sz sparsity of z
Chris@16 13 % w initial value of w
Chris@16 14 % h initial value of h
Chris@16 15 % pl plot flag
Chris@16 16 % lh update h flag
Chris@16 17 % lz update z flag
Chris@16 18 %
Chris@16 19 % Outputs:
Chris@16 20 % w spectral bases
Chris@16 21 % h component activation
Chris@16 22 % z source activation per component
Chris@16 23 % xa approximation of input
Chris@16 24 %
Chris@16 25 % Emmanouil Benetos 2011
Chris@16 26
Chris@16 27
Chris@16 28 % Get sizes
Chris@16 29 [M,N] = size( x);
Chris@16 30 sumx = sum(x);
Chris@16 31
Chris@16 32 % Default training iterations
Chris@16 33 if ~exist( 'iter')
Chris@16 34 iter = 100;
Chris@16 35 end
Chris@16 36
Chris@16 37 % Default plot flag
Chris@16 38 if ~exist( 'pl')
Chris@16 39 pl = 1;
Chris@16 40 end
Chris@16 41
Chris@16 42 % Initialize
Chris@16 43 if ~exist( 'w') || isempty( w)
Chris@16 44 w = rand( M, R, K);
Chris@16 45 end
Chris@16 46 for r=1:R
Chris@16 47 for k=1:K
Chris@16 48 w(:,k,r) = w(:,k,r) ./ sum(w(:,k,r));
Chris@16 49 end;
Chris@16 50 end;
Chris@16 51 if ~exist( 'h') || isempty( h)
Chris@16 52 h = rand( K, N);
Chris@16 53 end
Chris@16 54 n=1:N;
Chris@16 55 h(:,n) = repmat(sumx(n),K,1) .* (h(:,n) ./ repmat( sum( h(:,n), 1), K, 1));
Chris@16 56 if ~exist( 'z') || isempty( z)
Chris@16 57 z = rand( R, K, N);
Chris@16 58 end
Chris@16 59 for k=1:K
Chris@16 60 for n=1:N
Chris@16 61 z(:,k,n) = z(:,k,n) ./ sum(z(:,k,n));
Chris@16 62 end;
Chris@16 63 end;
Chris@16 64
Chris@16 65
Chris@16 66
Chris@16 67 % Iterate
Chris@16 68 for it = 1:iter
Chris@16 69
Chris@16 70 % E-step
Chris@19 71 zh = z .* permute(repmat(h,[1 1 R]),[3 1 2]); %% z is the source activation distribution, h the component (pitch) activation
Chris@16 72 xa=eps;
Chris@16 73 for r=1:R
Chris@16 74 for k=1:K
Chris@16 75 xa = xa + w(:,k,r) * squeeze(zh(r,k,:))';
Chris@16 76 end;
Chris@16 77 end;
Chris@16 78 Q = x ./ xa;
Chris@16 79
Chris@16 80 % M-step (update h,z)
Chris@16 81 if (lh && lz)
Chris@16 82 nh=zeros(K,N);
Chris@16 83 for k=1:K
Chris@16 84 for r=1:R
Chris@16 85 nh(k,:) = nh(k,:) + squeeze(z(r,k,:))' .* (squeeze(w(:,k,r))' * Q);
Chris@16 86 nz = h(k,:) .* (squeeze(w(:,k,r))' * Q);
Chris@16 87 nz = nz .* squeeze(z(r,k,:))';
Chris@16 88 z(r,k,:) = nz;
Chris@16 89 end;
Chris@16 90 end;
Chris@16 91 nh = h .* nh;
Chris@16 92 end
Chris@16 93
Chris@16 94
Chris@16 95 % Assign and normalize
Chris@16 96 k=1:K;
Chris@16 97 n=1:N;
Chris@16 98 if lh
Chris@16 99 nh = nh.^sh;
Chris@16 100 h(:,n) = repmat(sumx(n),K,1) .* (nh(:,n) ./ repmat( sum( nh(:,n), 1), K, 1));
Chris@16 101 end
Chris@16 102 if lz
Chris@16 103 z = z.^sz;
Chris@16 104 z(:,k,n) = z(:,k,n) ./ repmat( sum( z(:,k,n), 1), R, 1);
Chris@16 105 end
Chris@16 106
Chris@16 107 end
Chris@16 108
Chris@16 109 % Show me
Chris@16 110 if pl
Chris@16 111 subplot(3, 1, 1), imagesc(x), axis xy
Chris@16 112 subplot(3, 1, 2), imagesc(xa), axis xy
Chris@16 113 subplot(3, 1, 3), imagesc(h), axis xy
Chris@16 114 end