-
Notifications
You must be signed in to change notification settings - Fork 8
Expand file tree
/
Copy pathonline_dictionary_learning.m
More file actions
72 lines (56 loc) · 2.47 KB
/
online_dictionary_learning.m
File metadata and controls
72 lines (56 loc) · 2.47 KB
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
function [ D, alpha, A, B ] = online_dictionary_learning( t, D, A, B, X, wl1 )
% define the problem dimensions
N = size( X, 1 ); % length of sample vector
M = size( X, 2 ); % number of sample vectors
Nd = size( D, 2 ); % number of dictionary atoms
% =====================================================================
% first step, perform sparse coding of the columns (patches) of X
% w.r.t. the columns (atoms) of the dictionary D. Use proximal form
% of ADMM to perform the sparse coding task with an LLT factorization
% of the system arising in the data term for efficiency
% =====================================================================
lambda = 1.0; % ADMM splitting penalty weight
gamma = wl1; % L1 penalty weight on sparse coding
admm_iters = 200; % number of ADMM iterations to perform
% objective function for sparse coding us
% alpha = argmin (1/2) || D alpha - X ||_2^2 + gamma || alpha ||_1
% f(alpha) = (1/(2*gamma))|| D alpha - X ||_2^2
% g(alpha) = || alpha ||_1
% intialize the sparse coding coefficients
alpha = randn( Nd, M );
% pre-factorize the regularized problem for efficiency
pI = pinv( (lambda/gamma)*((D')*D) + eye( Nd ) );
% defind the proximal operators for the ADMM sparse coding operation
prox_f = @( v ) pI*((lambda/gamma)*((D')*X) + v);
prox_g = @( v ) max( v - lambda, 0 ) - max( -v - lambda, 0 );
% initialize sparse coding solution, splitting variable and Lagrange
% multipliers
Z = alpha;
U = alpha-Z;
% perform the ADMM algorithm
for iter=1:admm_iters,
% update the sparse coding vector
alpha = prox_f( Z - U );
% update the splitting variable
Z = prox_g( alpha + U );
% update the Lagrange multipliers
U = U + alpha - Z;
end
% =====================================================================
% second step, update the dictionary
% =====================================================================
% update A and B
if t < size(X,2),
theta = t*size(X,2);
else
theta = size(X,2)^2+t-size(X,2);
end
beta = (theta+1-size(X,2))/(theta+1);
A = beta*A + alpha*alpha';
B = beta*B + X*alpha';
% update each column of the dictionary sequentially
for j=1:size( D, 2 ),
u = (B(:,j) - D*alpha(:,j))/A(j,j) + D(:,j);
D(:,j) = u/max( norm(u), 1 );
end
end