annotate notes/hnmf.m @ 135:8db5e4ab56ce

Ground-truth data in CSV and lab format, converted from the MIDI using Sonic Visualiser and then to lab using the script here
author Chris Cannam
date Thu, 08 May 2014 12:59:09 +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