Navigation Menu

Skip to content

Commit

Permalink
Merge pull request #4 from yarikoptic/master
Browse files Browse the repository at this point in the history
FastICA -- introduce coarse_limit to trigger switching to fine_g before reaching target limit. 

Thanks to Prantik Kundu and Yaroslav Halchenko for the patch!
  • Loading branch information
Tiziano Zito committed Nov 21, 2012
2 parents 7a508b4 + f6b5c46 commit 7bbd889
Show file tree
Hide file tree
Showing 2 changed files with 29 additions and 5 deletions.
24 changes: 21 additions & 3 deletions mdp/nodes/ica_nodes.py
Expand Up @@ -320,13 +320,14 @@ class FastICANode(ICANode):
- 25.5.2005 now independent from scipy. Requires Numeric or numarray
- 26.6.2006 converted to numpy
- 14.9.2007 updated to Matlab version 2.5
- 26.6.2012 added ability to run two stages of optimization [PK]
"""

def __init__(self, approach = 'defl', g = 'pow3', guess = None,
fine_g = 'pow3', mu = 1,
sample_size = 1, fine_tanh = 1, fine_gaus = 1,
max_it = 1000, max_it_fine = 100,
failures = 5, limit = 0.001, verbose = False,
max_it = 5000, max_it_fine = 100,
failures = 5, coarse_limit=None, limit = 0.001, verbose = False,
whitened = False, white_comp = None, white_parm = None,
input_dim = None, dtype=None):
"""
Expand Down Expand Up @@ -374,6 +375,11 @@ def __init__(self, approach = 'defl', g = 'pow3', guess = None,
sample_size -- Percentage of samples used in one iteration. If
sample_size < 1, samples are chosen in random order.
coarse_limit -- initial convergence threshold, to switch to
fine_g function (i.e. linear to non-linear) even
before reaching the limit and final tuning. Set
it to a value higher than limit to be in effect.
fine_tanh -- parameter for 'tanh' nonlinearity
fine_gaus -- parameter for 'gaus' nonlinearity
Expand Down Expand Up @@ -417,6 +423,7 @@ def __init__(self, approach = 'defl', g = 'pow3', guess = None,
self.fine_gaus = fine_gaus
self.max_it = max_it
self.max_it_fine = max_it_fine
self.coarse_limit = coarse_limit
self.failures = failures
self.guess = guess

Expand Down Expand Up @@ -458,6 +465,7 @@ def core(self, data):
guess = mult(guess, self.white.get_recmatrix(transposed=1))

limit = self.limit
coarse_limit = self.coarse_limit
max_it = self.max_it
max_it_fine = self.max_it_fine
failures = self.failures
Expand Down Expand Up @@ -501,6 +509,7 @@ def core(self, data):
used_g = gOrig
stroke = 0
fine_tuned = False
coarse_limit_reached = False
lng = False

# SYMMETRIC APPROACH
Expand Down Expand Up @@ -529,6 +538,15 @@ def core(self, data):
v2 = 1.-abs((mult(Q.T, QOldF)).diagonal()).min(axis=0)
convergence_fine.append(v2)

if self.g != self.fine_g \
and coarse_limit is not None \
and convergence[round] < coarse_limit \
and not coarse_limit_reached:
if verbose:
print 'Coarse convergence, switching to fine cost...'
used_g = gFine
coarse_limit_reached = True

if convergence[round] < limit:
if fine_tuning and (not fine_tuned):
if verbose:
Expand Down Expand Up @@ -569,7 +587,7 @@ def core(self, data):
# Show the progress...
if verbose:
msg = ('Step no. %d,'
' convergence: %.3f' % (round+1,convergence[round]))
' convergence: %.7f' % (round+1,convergence[round]))
print msg


Expand Down
10 changes: 8 additions & 2 deletions mdp/test/test_fastica.py
Expand Up @@ -12,6 +12,7 @@ def _fastica_test_factory(metafunc):
'fine_g': [None, 'pow3', 'tanh', 'gaus', 'skew'],
'sample_size': [1, 0.99999],
'mu': [1, 0.999999],
'coarse_limit': [None, 0.01],
}

for parms in mdp.utils.orthogonal_permutations(fica_parm):
Expand All @@ -20,7 +21,11 @@ def _fastica_test_factory(metafunc):
continue
if parms['g'] == 'skew' and parms['fine_g'] != 'skew':
continue

# skip testing coarse_limit if g's are the same --
# it should not be in effect
if parms['coarse_limit'] is not None \
and parms['g'] == parms['fine_g']:
continue
funcargs = dict(parms=parms)
theid = fastICA_id(parms)
metafunc.addcall(funcargs, id=theid)
Expand All @@ -29,6 +34,7 @@ def fastICA_id(parms):
app = 'AP:'+parms['approach']
nl = 'NL:'+parms['g']
fine_nl = 'FT:'+str(parms['fine_g'])
coarse_l = 'CL:'+str(parms['coarse_limit'])
if parms['sample_size'] == 1:
compact = 'SA:01 '
else:
Expand All @@ -37,7 +43,7 @@ def fastICA_id(parms):
compact += 'S:01'
else:
compact += 'S:<1'
desc = ' '.join([app, nl, fine_nl, compact])
desc = ' '.join([app, nl, fine_nl, compact, coarse_l])
return desc


Expand Down

0 comments on commit 7bbd889

Please sign in to comment.