1 """
2 SOM-based learning functions for CFProjections.
3
4 $Id: som.py 11316 2010-07-27 17:52:53Z ceball $
5 """
6 __version__ = "$Revision: 11316 $"
7
8
9 from math import ceil
10
11 import param
12
13 from topo.base.arrayutil import L2norm, array_argmax
14 from topo.base.boundingregion import BoundingBox
15 from topo.base.cf import CFPLearningFn
16 from topo.base.patterngenerator import PatternGenerator
17
18 from topo.pattern.basic import Gaussian
19
20
21
22
24 """
25 An abstract base class of learning functions for Self-Organizing Maps.
26
27 This implementation is obsolete and will be removed soon.
28 Please see examples/cfsom_or.ty for current SOM support.
29 """
30 __abstract = True
31
32 learning_radius = param.Number(default=0.0,doc=
33 """
34 The radius of the neighborhood function to be used for
35 learning. Typically, this value will be set by the Sheet or
36 Projection owning this CFPLearningFn, but it can also be set
37 explicitly by the user.
38 """)
39
41 self.warning("CFPLF_SOM is deprecated -- see the example in cfsom_or.ty for how to build a SOM")
42
43 - def __call__(self, proj, input_activity, output_activity, learning_rate, **params):
44 raise NotImplementedError
45
46
47
48
49
51 """
52 Hebbian learning rule for CFProjections to Self-Organizing Maps.
53
54 This implementation is obsolete and will be removed soon.
55 Please see examples/cfsom_or.ty for current SOM support.
56 """
57
58 learning_radius = param.Number(default=0.0)
59
60 crop_radius_multiplier = param.Number(default=3.0,doc=
61 """
62 Factor by which the radius should be multiplied,
63 when deciding how far from the winner to keep updating the weights.
64 """)
65
66 neighborhood_kernel_generator = param.ClassSelector(PatternGenerator,
67 default=Gaussian(x=0.0,y=0.0,aspect_ratio=1.0),
68 doc="Neighborhood function")
69
70
71 - def __call__(self, iterator, input_activity, output_activity, learning_rate, **params):
72 cfs = iterator.proj.cfs.tolist()
73 rows,cols = output_activity.shape
74
75
76
77 single_connection_learning_rate = learning_rate
78
79
80
81
82
83
84
85
86 radius = self.learning_radius
87 crop_radius = max(1.25,radius*self.crop_radius_multiplier)
88
89
90
91
92
93
94
95
96
97
98 wr,wc = array_argmax(output_activity)
99
100
101
102
103 cmin = int(max(wc-crop_radius,0))
104 cmax = int(min(wc+crop_radius+1,cols))
105 rmin = int(max(wr-crop_radius,0))
106 rmax = int(min(wr+crop_radius+1,rows))
107
108
109
110 nk_generator = self.neighborhood_kernel_generator
111 radius_int = int(ceil(crop_radius))
112 rbound = radius_int + 0.5
113 bb = BoundingBox(points=((-rbound,-rbound), (rbound,rbound)))
114
115
116
117
118 neighborhood_matrix = nk_generator(bounds=bb,xdensity=1,ydensity=1,
119 size=2*radius)
120
121 for r in range(rmin,rmax):
122 for c in range(cmin,cmax):
123 cwc = c - wc
124 rwr = r - wr
125 lattice_dist = L2norm((cwc,rwr))
126 if lattice_dist <= crop_radius:
127 cf = cfs[r][c]
128 rate = single_connection_learning_rate * neighborhood_matrix[rwr+radius_int,cwc+radius_int]
129 X = cf.get_input_matrix(input_activity)
130 cf.weights += rate * (X - cf.weights)
131
132
133 cf.weights *= cf.mask
134