-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathNMF2D.m
executable file
·150 lines (119 loc) · 3.99 KB
/
NMF2D.m
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
function [W, H] = NMF2D(V,R,T,Phi,Niter,plotIter)
% [W, H] = NMF2D(V,R,T,Phi,Niter,plotIter)
% NMF2D as proposed by Morup and Schmidt (Non-negative Matrix Factor 2D
% Deconvolutionfor Blind Single channel source separation). KL
% divergence minimization.
% Input :
% - V : log-frequency magnitude spectrogram to factorize (a MxN matrix)
% - R : number of templates
% - T : template time size (in number of frames in the log-frequency spectrogram)
% - Phi : template frequency size (in number of bin in the log-frequency spectrogram)
% - Niter : number of iterations
% - plotIter : plot results for each iteration (value : true or false, default : false)
% Output :
% - W : time/frequency template (TxMxR array, each template is TxM)
% - H : time frequency activation for each template (PhixRxN matrix)
%
% Copyright (C) 2010 Romain Hennequin
if nargin == 5
plotIter = false;
end
% data size
M = size(V,1);
N = size(V,2);
% sparsity of H
lambdaH = 0;
epsilon = 10^-20;
% initialization
H = rand(Phi,R,N);
W = rand(T,M,R);
One = ones(M,N);
Ht = zeros(T,R,N);
Lambda = zeros(M,N);
% Waitbar
message = ['computing NMF2D. iteration : 0/' int2str(Niter)];
h = waitbar(0,message);
for iter =1:Niter
% computation of Lambda (estimate of V)
Lambda = 0;
for t=0:T-1
for phi = 0:Phi-1
Lambda = Lambda + shiftUD(reshape(W(t+1,:,:),M,R),phi)* shiftLR(reshape(H(phi+1,:,:),R,N),-t);
end
end
Lambda = Lambda + epsilon;
% update of W for each t
denom = zeros(M,R);
num = zeros(M,R);
for t=0:T-1
num = 0;
denom = 0;
for phi = 0:Phi-1
num = num + shiftUD((V./Lambda),-phi) * (shiftLR(reshape(H(phi+1,:,:),R,N),-t)');
denom = denom + One * (shiftLR(reshape(H(phi+1,:,:),R,N),-t)');
end
W(t+1,:,:) = reshape(W(t+1,:,:),M,R).* (num./denom);
end
% recomputation of Lambda (estimate of V)
Lambda = 0;
for t=0:T-1
for phi = 0:Phi-1
Lambda = Lambda + shiftUD(reshape(W(t+1,:,:),M,R),phi)* shiftLR(reshape(H(phi+1,:,:),R,N),-t);
end
end
Lambda = Lambda + epsilon;
% update of H for each value of phi
denom = zeros(R,N);
num = zeros(R,N);
for phi=0:Phi-1
num = 0;
denom = 0;
for t = 0:T-1
num = num + shiftUD(reshape(W(t+1,:,:),M,R),phi)' *shiftLR((V./Lambda),t);
denom = denom + shiftUD(reshape(W(t+1,:,:),M,R),phi)'*One;
end
H(phi+1,:,:) = reshape(H(phi+1,:,:),R,N).* (num./(denom + lambdaH));
end
for r=1:R
normW = sqrt(sum(sum(W(:,:,r).^2)));
W(:,:,r) = W(:,:,r)/normW;
H(:,r,:) = H(:,r,:)*normW;
end
%%%%% PLOT %%%%%
if plotIter
% templates and activation
figure(1)
for r = 1:R
subplot(2,R,r)
imagesc(db(reshape(W(:,:,r),T,M))');
title(['template ' int2str(r)])
axis xy
caxis([-100,0])
subplot(2,R,r+R)
imagesc(db(reshape(H(:,r,:),Phi,N)));
title(['activation ' int2str(r)])
axis xy
caxis([max(db(V(:)))-50,max(db(V(:)))])
end
% (log-freq) spectrogram (original and reconstructed)
figure(2)
subplot(211)
imagesc(db(V))
title('original magnitude log-frequency spectrogram')
axis xy
subplot(212)
Lambda = zeros(M,N);
for t=0:T-1
for phi = 0:Phi-1
Lambda = Lambda + shiftUD(reshape(W(t+1,:,:),M,R),phi)* shiftLR(reshape(H(phi+1,:,:),R,N),-t);
end
end
imagesc(db(Lambda))
title('reconstructed log-frequency spectrogram')
axis xy
end
%%%%%%%%%%%%%%
message = ['computing NMF2D. iteration : ' int2str(iter) '/' int2str(Niter)];
waitbar(iter/Niter,h,message);
end
close(h)