-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathrel_network.py
More file actions
335 lines (268 loc) · 11.6 KB
/
rel_network.py
File metadata and controls
335 lines (268 loc) · 11.6 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
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
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
import pickle
from neuron import Neuron
# Pathos multiprocessing import
from pathos.multiprocessing import Pool
# Detect system import
from detect_system import DetectSystem
## \defgroup RelBlocks Relational network related classes
#
# Relational network related classes are a group of classes that
# represent relational knowledge, neurons and networks
# @{
#
## Relational knowledge is a 3-tuple that
# relate a sight RbfNeuron id, a hearing RbfNeuron id and a weight.
class RelKnowledge:
## Create RelKnowledge instance given
# a hearing id (id_h), sight id (id_s) and weight which defaults to zero
def __init__(self, h_id, s_id, weight=0):
self.set_h_id(h_id)
self.set_s_id(s_id)
self.set_weight(weight)
## Set hearing id
# @param h_id Integer. Hearing id.
def set_h_id(self, h_id):
self._h_id = h_id
## Set sight id
# @param s_id Integer. Sight id.
def set_s_id(self, s_id):
self._s_id = s_id
## Set weight
# @param w Integer. Weight.
def set_weight(self, w):
if w >= 0:
self._weight = w
else:
raise ValueError("Invalid value for w")
## Increase weight of relation by a given value
# @param amount Integer Optional, 1 by default
def increase_weight(self, amount=1):
if self._weight + amount >= 0:
self._weight += amount
## Get hearing id of relation
# @retval h_id Integer. Hearing id.
def get_h_id(self):
return self._h_id
## Get sight id of relation
# @retval s_id Integer. Sight id.
def get_s_id(self):
return self._s_id
## Get weight of relation
# @retval weight Integer.
def get_weight(self):
return self._weight
## Return True if knowledge's hearing id is equal to given parameter h_id and
# False in any other case
def is_equal_hearing(self, h_id):
return self._h_id == h_id
## Return True if knowledge sight id is equal to given parameter s_id and
# False in any other case
def is_equal_sight(self, s_id):
return self._s_id == s_id
## Return true if knowledge's sight id is equal to given parameter s_id and
# knowledge's hearing id is equal to given parameter h_id. Return false in any other case
def is_equal(self, h_id, s_id):
return self._h_id == h_id and self._s_id == s_id
## Relational neuron
class RelNeuron(Neuron):
## The constructor
def __init__(self):
super(RelNeuron, self).__init__()
self._hit = False
## Set knowledge of type RelKnowledge
# @param knowledge RelKnowledge to be learned
def learn(self, knowledge):
if isinstance(knowledge, RelKnowledge):
self._knowledge = knowledge
self._has_knowledge = True
else:
raise ValueError("value must be of type RelKnowledge")
## Set knowledge of type RelKnowledge
# @param knowledge RelKnowledge to be learned
def set_knowledge(self, knowledge):
self.learn(knowledge)
## Return True if h_id is recognized as the hearing-id part of the RelKnowledge.
# Also set an internal flag to indicate whether the last recognition process was successful (True)
# or not (False). The value of the internal flag is accessible through the is_hit() method
# @param h_id Integer. Hearing id.
def recognize_hearing(self, h_id):
if self.has_knowledge():
self._hit = self._knowledge.is_equal_hearing(h_id)
return self._hit
## Return true if s_id is recognized as the sight-id part of the relational knowledge.
# Also set an internal flag to indicate whether the last recognition process was successful (True)
# or not (False). The value of the internal flag is accessible through the is_hit() method
# @param s_id Integer. Sight id.
def recognize_sight(self, s_id):
if self.has_knowledge():
self._hit = self._knowledge.is_equal_sight(s_id)
return self._hit
## Return hearing id if neuron has knowledge and an object of type None in any other case
# @retval h_id Integer or None. Hearing id.
def get_h_id(self):
if self.has_knowledge():
# Increase weight everytime that the relation is somehow used
self._knowledge.increase_weight()
return self._knowledge.get_h_id()
return None
## Return sight id if neuron has knowledge and an object of type None in any other case
# @retval s_id Integer or None. Sight id.
def get_s_id(self):
if self.has_knowledge():
# Increase weight everytime that the relation is somehow used
self._knowledge.increase_weight()
return self._knowledge.get_s_id()
return None
## Returns knowledge stored by neuron if neuron has knowledge,
# and None object in any other case
# @retval knowledge RelKnowledge or None.
def get_knowledge(self):
if self.has_knowledge():
# Increase weight everytime that the relation is somehow used
self._knowledge.increase_weight()
return self._knowledge
return None
## Return weight of relation if neuron has knowledge and an object of type None in any other case
# @retval weight Integer or None.
def get_weight(self):
if self.has_knowledge():
return self._knowledge.get_weight()
return None
## Set hearing id if neuron has knowledge. Raise an exception of type AttributeError if an attempt to
# set the hearing id to a neuron with no previous knowledge is made
# @param h_id Hearing id.
def set_h_id(self, h_id):
if self.has_knowledge():
self._knowledge.set_h_id(h_id)
else:
raise AttributeError("neuron has no knowledge")
## Set sight id if neuron has knowledge. Raise an exception of type AttributeError if an attempt to
# set the sight id to a neuron with no previous knowledge is made.
# @param s_id Sight id
def set_s_id(self, s_id):
if self.has_knowledge():
self._knowledge.set_s_id(s_id)
else:
raise AttributeError("neuron has no knowledge")
## Return true if neuron has h_id and s_id as hearing and sight ids respectively
# @param h_id Hearing id
# @param s_id Sight id
def has_ids(self, h_id, s_id):
return self._knowledge.is_equal(h_id, s_id)
## Relational network
class RelNetwork:
## The constructor
# @param neuron_count Network size
def __init__(self, neuron_count):
# Create neuron list
self.neuron_list = []
# Fill neuron list with nre RelNeuron instances
# 3.2.2.1 todo: parallel
# Detect system and determine threads number to use
detect_system = DetectSystem()
# Init thread's pool, with the determined threads number
pool = Pool(detect_system.cpu_count())
self.neuron_list = pool.map(lambda index: RelNeuron(), range(neuron_count))
#for index in range(neuron_count):
# self.neuron_list.append(RelNeuron())
# Index of ready to learn neuron
self._index_ready_to_learn = 0
## Learn new knowledge in ready-to-learn neuron
# @param knowledge RelKnowledge to be learned.
def learn(self, knowledge):
# If there is no capacity in neuron list, double size
if self._index_ready_to_learn == (len(self.neuron_list)-1):
new_list = []
# Fill neuron list with nre RelNeuron instances
# 3.2.2.2 todo: parallel
# Detect system and determine threads number to use
detect_system = DetectSystem()
# Init thread's pool, with the determined threads number
pool = Pool(detect_system.cpu_count())
new_list = pool.map(lambda index: RelNeuron(), range(len(self.neuron_list)))
#for index in range(len(self.neuron_list)):
# new_list.append(RelNeuron())
self.neuron_list = self.neuron_list + new_list
# Check for neurons that already have given knowledge ids
for index in range(self._index_ready_to_learn):
if self.neuron_list[index].has_ids(knowledge.get_h_id(), knowledge.get_s_id()):
return False
# If there are no neurons with given pair of ids, learn
self.neuron_list[self._index_ready_to_learn].learn(knowledge)
self._index_ready_to_learn += 1
return True
## Return a list of all knowledge in net such that it has parameter h_id as hearing id
# @retval hearing_rels RelKnowledge vector
def get_hearing_rels(self, h_id):
# List of hearing relations
hearing_rels = []
# 3.2.2.3 todo: parallel
# Detect system and create threads pool
pool = Pool(DetectSystem().cpu_count())
hearing_rels = pool.map(lambda index: self.neuron_list[index].get_knowledge() if self.neuron_list[index].recognize_hearing(h_id) else None, range(self._index_ready_to_learn))
hearing_rels = filter(None, hearing_rels)
#for index in range(self._index_ready_to_learn):
# if self.neuron_list[index].recognize_hearing(h_id):
# hearing_rels.append(self.neuron_list[index].get_knowledge())
return hearing_rels
## Return a list of all knowledge in net such that it has parameter s_id as sight id
# @retval sight_rels RelKnowledge vector
def get_sight_rels(self, s_id):
# List of sight relations
sight_rels = []
# 3.2.2.3 todo: parallel
# Detect system and create threads pool
pool = Pool(DetectSystem().cpu_count())
sight_rels = pool.map(lambda index: self.neuron_list[index].get_knowledge() if self.neuron_list[index].recognize_sight(s_id) else None, range(self._index_ready_to_learn) )
sight_rels = filter(None, sight_rels)
#for index in range(self._index_ready_to_learn):
# if self.neuron_list[index].recognize_sight(s_id):
# sight_rels.append(self.neuron_list[index].get_knowledge())
return sight_rels
## Returns number of neurons in network
# @retval count Integer.
def get_neuron_count(self):
return len(self.neuron_list)
@classmethod
## Serialize object and store it in given file
# @param cls RelNetwork class
# @param obj RelNetwork object to be serialized
# @param name Name of the file where the serialization is to be stored
def serialize(cls, obj, name):
pickle.dump(obj, open(name, "wb"))
@classmethod
## Deserialize object stored in given file
# @param cls RelNetwork class
# @param name Name of the file where the object is serialized
def deserialize(cls, name):
return pickle.load(open(name, "rb"))
## @}
#
# Tests
if __name__ == '__main__':
k1 = RelKnowledge(0, 0, 0)
n1 = RelNeuron()
print "N1 has knowledge: ", n1.has_knowledge()
n1.learn(k1)
print "N1 has knowledge: ", n1.has_knowledge()
print "Neuron h_id ", n1.get_h_id()
print "Neuron s_id ", n1.get_s_id()
print "Neuron w ", n1.get_weight()
n1.set_h_id(5)
n1.set_s_id(-1)
print "Neuron h_id ", n1.get_h_id()
print "Neuron s_id ", n1.get_s_id()
print "Neuron w ", n1.get_weight()
# Create network of size 1
net = RelNetwork(1)
print "Size ", net.get_neuron_count()
# Create vector of knowledge
k = [RelKnowledge("1", 2, 5), RelKnowledge(1, 3, 5), RelKnowledge(2, 2), RelKnowledge(2, 3)]
# Learn and see how network size increases
for e in k:
net.learn(e)
print "Size ", net.get_neuron_count()
# Get all hearing relations with id == 1
for e in net.get_hearing_rels("1"):
print "Sight:", e.get_s_id()
print "Weight: ", e.get_weight()