annotate notes/hnmf.m @ 167:416b555df3b2 finetune

More on returning fine tuning (but we're treating different shifts of the same pitch as different notes at the moment which is not right)
author Chris Cannam
date Tue, 20 May 2014 17:49:07 +0100
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