PyHierarchicalTsetlinMachineCUDA 0.2.5__tar.gz → 0.2.7__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (15) hide show
  1. {PyHierarchicalTsetlinMachineCUDA-0.2.5 → PyHierarchicalTsetlinMachineCUDA-0.2.7}/PKG-INFO +1 -1
  2. {PyHierarchicalTsetlinMachineCUDA-0.2.5 → PyHierarchicalTsetlinMachineCUDA-0.2.7}/PyHierarchicalTsetlinMachineCUDA/kernels.py +106 -20
  3. {PyHierarchicalTsetlinMachineCUDA-0.2.5 → PyHierarchicalTsetlinMachineCUDA-0.2.7}/PyHierarchicalTsetlinMachineCUDA/tm.py +47 -19
  4. {PyHierarchicalTsetlinMachineCUDA-0.2.5 → PyHierarchicalTsetlinMachineCUDA-0.2.7}/PyHierarchicalTsetlinMachineCUDA.egg-info/PKG-INFO +1 -1
  5. {PyHierarchicalTsetlinMachineCUDA-0.2.5 → PyHierarchicalTsetlinMachineCUDA-0.2.7}/PyHierarchicalTsetlinMachineCUDA.egg-info/requires.txt +1 -0
  6. {PyHierarchicalTsetlinMachineCUDA-0.2.5 → PyHierarchicalTsetlinMachineCUDA-0.2.7}/README.md +10 -10
  7. {PyHierarchicalTsetlinMachineCUDA-0.2.5 → PyHierarchicalTsetlinMachineCUDA-0.2.7}/setup.py +2 -1
  8. {PyHierarchicalTsetlinMachineCUDA-0.2.5 → PyHierarchicalTsetlinMachineCUDA-0.2.7}/LICENSE +0 -0
  9. {PyHierarchicalTsetlinMachineCUDA-0.2.5 → PyHierarchicalTsetlinMachineCUDA-0.2.7}/PyHierarchicalTsetlinMachineCUDA/__init__.py +0 -0
  10. {PyHierarchicalTsetlinMachineCUDA-0.2.5 → PyHierarchicalTsetlinMachineCUDA-0.2.7}/PyHierarchicalTsetlinMachineCUDA/tools.py +0 -0
  11. {PyHierarchicalTsetlinMachineCUDA-0.2.5 → PyHierarchicalTsetlinMachineCUDA-0.2.7}/PyHierarchicalTsetlinMachineCUDA/utils.py +0 -0
  12. {PyHierarchicalTsetlinMachineCUDA-0.2.5 → PyHierarchicalTsetlinMachineCUDA-0.2.7}/PyHierarchicalTsetlinMachineCUDA.egg-info/SOURCES.txt +0 -0
  13. {PyHierarchicalTsetlinMachineCUDA-0.2.5 → PyHierarchicalTsetlinMachineCUDA-0.2.7}/PyHierarchicalTsetlinMachineCUDA.egg-info/dependency_links.txt +0 -0
  14. {PyHierarchicalTsetlinMachineCUDA-0.2.5 → PyHierarchicalTsetlinMachineCUDA-0.2.7}/PyHierarchicalTsetlinMachineCUDA.egg-info/top_level.txt +0 -0
  15. {PyHierarchicalTsetlinMachineCUDA-0.2.5 → PyHierarchicalTsetlinMachineCUDA-0.2.7}/setup.cfg +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: PyHierarchicalTsetlinMachineCUDA
3
- Version: 0.2.5
3
+ Version: 0.2.7
4
4
  Summary: Hierarchical Tsetlin Machine Architecture.
5
5
  Home-page: https://github.com/cair/PyHierarchicalTsetlinMachineCUDA/
6
6
  Author: Ole-Christoffer Granmo
@@ -159,7 +159,7 @@ code_update = """
159
159
  }
160
160
 
161
161
  // Evaluate example
162
- __global__ void evaluate_leaves(unsigned int *global_ta_state, int *component_weights, int *global_component_output, int depth, int *hierarchy_structure_factors, int *hierarchy_structure_alternatives, int *X, int example)
162
+ __global__ void evaluate_leaves(unsigned int *global_ta_state, int *component_weights, int *global_component_output, int depth, int *hierarchy_structure_factors, int *hierarchy_structure_type, int *X, int example)
163
163
  {
164
164
  int index = blockIdx.x * blockDim.x + threadIdx.x;
165
165
  int stride = blockDim.x * gridDim.x;
@@ -168,35 +168,43 @@ code_update = """
168
168
 
169
169
  // Evaluate each clause component (leaf) in separate threads
170
170
  for (int clause_component = index; clause_component < CLAUSES*COMPONENTS; clause_component += stride) {
171
+ int clause = clause_component / COMPONENTS;
171
172
  int component = clause_component % COMPONENTS;
172
173
 
173
- // Get state of current clause component
174
- unsigned int *ta_state = &global_ta_state[clause_component*TA_CHUNKS_PER_LEAF*STATE_BITS];
175
-
176
174
  int component_remainder = component;
175
+ int feature_chunk_base = 0;
177
176
  int ta_chunk_base = 0;
178
- int size = 1;
177
+ int size_feature_chunk_base = 1;
178
+ int size_ta_chunk_base = 1;
179
179
  for (int d = 0; d < depth-1; ++d) {
180
180
  int depth_d_node_index = component_remainder % hierarchy_structure_factors[d];
181
181
  component_remainder = component_remainder / hierarchy_structure_factors[d];
182
182
 
183
- if (hierarchy_structure_alternatives[d] == 0) {
184
- ta_chunk_base += size * depth_d_node_index * TA_CHUNKS_PER_LEAF;
185
- size *= hierarchy_structure_factors[d];
183
+ if (hierarchy_structure_type[d] != 1) {
184
+ feature_chunk_base += size_feature_chunk_base * depth_d_node_index * TA_CHUNKS_PER_LEAF;
185
+ size_feature_chunk_base *= hierarchy_structure_factors[d];
186
+ }
187
+
188
+ if (hierarchy_structure_type[d] != 2) {
189
+ ta_chunk_base += size_ta_chunk_base * depth_d_node_index * TA_CHUNKS_PER_LEAF;
190
+ size_ta_chunk_base *= hierarchy_structure_factors[d];
186
191
  }
187
192
  }
188
193
 
194
+ // Get state of current ta team component
195
+ unsigned int *ta_state = &global_ta_state[clause*COMPONENTS*TA_CHUNKS_PER_LEAF*STATE_BITS + ta_chunk_base*STATE_BITS];
196
+
189
197
  // Evaluate clause component
190
198
  int component_output = 1;
191
199
  for (int ta_chunk = 0; ta_chunk < TA_CHUNKS_PER_LEAF-1; ++ta_chunk) {
192
200
  // Compare the TA state of the component (leaf) against the corresponding part of the feature vector
193
- if ((ta_state[ta_chunk*STATE_BITS + STATE_BITS - 1] & Xi[ta_chunk_base + ta_chunk]) != ta_state[ta_chunk*STATE_BITS + STATE_BITS - 1]) {
201
+ if ((ta_state[ta_chunk*STATE_BITS + STATE_BITS - 1] & Xi[feature_chunk_base + ta_chunk]) != ta_state[ta_chunk*STATE_BITS + STATE_BITS - 1]) {
194
202
  component_output = 0;
195
203
  break;
196
204
  }
197
205
  }
198
206
 
199
- if ((ta_state[(TA_CHUNKS_PER_LEAF-1)*STATE_BITS + STATE_BITS - 1] & Xi[ta_chunk_base + TA_CHUNKS_PER_LEAF-1] & FILTER_HIERARCHICAL) != (ta_state[(TA_CHUNKS_PER_LEAF-1)*STATE_BITS + STATE_BITS - 1] & FILTER_HIERARCHICAL)) {
207
+ if ((ta_state[(TA_CHUNKS_PER_LEAF-1)*STATE_BITS + STATE_BITS - 1] & Xi[feature_chunk_base + TA_CHUNKS_PER_LEAF-1] & FILTER_HIERARCHICAL) != (ta_state[(TA_CHUNKS_PER_LEAF-1)*STATE_BITS + STATE_BITS - 1] & FILTER_HIERARCHICAL)) {
200
208
  component_output = 0;
201
209
  }
202
210
 
@@ -213,9 +221,15 @@ code_update = """
213
221
  for (int or_group_node = index; or_group_node < CLAUSES*number_of_or_group_nodes; or_group_node += stride) {
214
222
  // Add OR addends
215
223
  int or_group_vote_sum = 0;
224
+ int max_vote_sum = 0;
225
+
216
226
  for (int or_addend = 0; or_addend < number_of_or_group_addends; ++or_addend) {
217
227
  // Aggregate votes from each child node through addition
218
228
 
229
+ if (child_input[or_group_node*number_of_or_group_addends + or_addend] > max_vote_sum) {
230
+ max_vote_sum = child_input[or_group_node*number_of_or_group_addends + or_addend];
231
+ }
232
+
219
233
  int previous_or_group_vote_sum = or_group_vote_sum;
220
234
  or_group_vote_sum += child_input[or_group_node*number_of_or_group_addends + or_addend];
221
235
  if (or_group_vote_sum < 0) {
@@ -224,8 +238,8 @@ code_update = """
224
238
  }
225
239
  }
226
240
 
227
- // Store or group vote sum as node output
228
- or_group_node_output[or_group_node] = or_group_vote_sum;
241
+ //or_group_node_output[or_group_node] = or_group_vote_sum;
242
+ or_group_node_output[or_group_node] = max_vote_sum;
229
243
  }
230
244
  }
231
245
 
@@ -238,12 +252,17 @@ code_update = """
238
252
  for (int and_group_node = index; and_group_node < CLAUSES*number_of_and_group_nodes; and_group_node += stride) {
239
253
  // Multiply and factors
240
254
  int and_group_vote_product = 1;
255
+ int max_vote_sum = 0;
241
256
  for (int and_factor = 0; and_factor < number_of_and_group_factors; ++and_factor) {
242
257
  // Aggregate votes from each child node through multiplication
243
258
 
244
259
  int previous_and_group_vote_product = and_group_vote_product;
245
260
  and_group_vote_product *= child_input[and_group_node*number_of_and_group_factors + and_factor];
246
261
 
262
+ if (child_input[and_group_node*number_of_and_group_factors + and_factor] > max_vote_sum) {
263
+ max_vote_sum = child_input[and_group_node*number_of_and_group_factors + and_factor];
264
+ }
265
+
247
266
  if (and_group_vote_product < 0) {
248
267
  printf("AND OVERFLOW %d -> %d\\n", previous_and_group_vote_product, and_group_vote_product);
249
268
  and_group_vote_product = previous_and_group_vote_product;
@@ -252,6 +271,7 @@ code_update = """
252
271
 
253
272
  // Store and group product as node output
254
273
  and_group_node_output[and_group_node] = and_group_vote_product;
274
+ //and_group_node_output[and_group_node] = max_vote_sum;
255
275
  }
256
276
  }
257
277
 
@@ -272,6 +292,58 @@ code_update = """
272
292
  }
273
293
  }
274
294
 
295
+ __global__ void propagate_or_group_false_truth_values(curandState *state, int *child_input, int *group_node_output, int number_of_group_nodes, int number_of_group_node_children)
296
+ {
297
+ int index = blockIdx.x * blockDim.x + threadIdx.x;
298
+ int stride = blockDim.x * gridDim.x;
299
+
300
+ int non_zero_children[361];
301
+
302
+ /* Copy state to local memory for efficiency */
303
+ curandState localState = state[index];
304
+
305
+ // If a group node is false, all children are made false.
306
+ for (int group_node = index; group_node < CLAUSES*number_of_group_nodes; group_node += stride) {
307
+ int number_of_non_zero_children = 0;
308
+
309
+ if (group_node_output[group_node] == -1) {
310
+ for (int or_addend = 0; or_addend < number_of_group_node_children; ++or_addend) {
311
+ child_input[group_node*number_of_group_node_children + or_addend] = -1;
312
+ }
313
+ } else if (group_node_output[group_node] == 0) {
314
+ for (int or_addend = 0; or_addend < number_of_group_node_children; ++or_addend) {
315
+ if (child_input[group_node*number_of_group_node_children + or_addend] > 0) {
316
+ child_input[group_node*number_of_group_node_children + or_addend] = 0;
317
+ }
318
+ }
319
+ } else {
320
+ for (int or_addend = 0; or_addend < number_of_group_node_children; ++or_addend) {
321
+ if (child_input[group_node*number_of_group_node_children + or_addend] > 0) {
322
+ non_zero_children[number_of_non_zero_children] = or_addend;
323
+ number_of_non_zero_children++;
324
+ }
325
+ }
326
+ }
327
+
328
+ if (group_node_output[group_node] != -1) {
329
+ int selected_child;
330
+ if (number_of_non_zero_children > 0) {
331
+ selected_child = non_zero_children[curand(&localState) % number_of_non_zero_children];
332
+ } else {
333
+ selected_child = curand(&localState) % number_of_group_node_children;
334
+ }
335
+
336
+ for (int or_addend = 0; or_addend < number_of_group_node_children; ++or_addend) {
337
+ if (selected_child != or_addend) {
338
+ child_input[group_node*number_of_group_node_children + or_addend] = -1;
339
+ }
340
+ }
341
+ }
342
+ }
343
+
344
+ state[index] = localState;
345
+ }
346
+
275
347
  __global__ void evaluate_or_alternatives(int *child_input, int *or_alternatives_node_output, int number_of_or_alternatives_nodes, int number_of_or_alternatives)
276
348
  {
277
349
  int index = blockIdx.x * blockDim.x + threadIdx.x;
@@ -316,7 +388,7 @@ code_update = """
316
388
  }
317
389
 
318
390
  // Update state of Tsetlin Automata team
319
- __global__ void update_hierarchy(curandState *state, int number_of_outputs, unsigned int *global_ta_state, int *clause_weights, int *component_output, int depth, int *hierarchy_structure_factors, int *hierarchy_structure_alternatives, int *class_sum, int *X, int *y, int example)
391
+ __global__ void update_hierarchy(curandState *state, int number_of_outputs, unsigned int *global_ta_state, int *clause_weights, int *component_output, int depth, int *hierarchy_structure_factors, int *hierarchy_structure_type, int *class_sum, int *X, int *y, int example)
320
392
  {
321
393
  int index = blockIdx.x * blockDim.x + threadIdx.x;
322
394
  int stride = blockDim.x * gridDim.x;
@@ -328,25 +400,39 @@ code_update = """
328
400
 
329
401
  // Calculate clause output first
330
402
  for (int clause_component = index; clause_component < CLAUSES*COMPONENTS; clause_component += stride) {
403
+ if (component_output[clause_component] == -1) {
404
+ continue;
405
+ }
406
+
331
407
  int clause = clause_component / COMPONENTS;
332
408
  int component = clause_component % COMPONENTS;
333
409
 
334
410
  // Get state of current clause component
335
- unsigned int *ta_state = &global_ta_state[clause_component*TA_CHUNKS_PER_LEAF*STATE_BITS];
411
+ // This one must be updated for reuse of TAs within OR group
336
412
 
337
413
  int component_remainder = component;
414
+ int feature_chunk_base = 0;
338
415
  int ta_chunk_base = 0;
339
- int size = 1;
416
+ int size_feature_chunk_base = 1;
417
+ int size_ta_chunk_base = 1;
340
418
  for (int d = 0; d < depth-1; ++d) {
341
419
  int depth_d_node_index = component_remainder % hierarchy_structure_factors[d];
342
420
  component_remainder = component_remainder / hierarchy_structure_factors[d];
343
421
 
344
- if (hierarchy_structure_alternatives[d] == 0) {
345
- ta_chunk_base += size * depth_d_node_index * TA_CHUNKS_PER_LEAF;
346
- size *= hierarchy_structure_factors[d];
422
+ if (hierarchy_structure_type[d] != 1) {
423
+ feature_chunk_base += size_feature_chunk_base * depth_d_node_index * TA_CHUNKS_PER_LEAF;
424
+ size_feature_chunk_base *= hierarchy_structure_factors[d];
425
+ }
426
+
427
+ if (hierarchy_structure_type[d] != 2) {
428
+ ta_chunk_base += size_ta_chunk_base * depth_d_node_index * TA_CHUNKS_PER_LEAF;
429
+ size_ta_chunk_base *= hierarchy_structure_factors[d];
347
430
  }
348
431
  }
349
432
 
433
+ // Get state of current ta team component
434
+ unsigned int *ta_state = &global_ta_state[clause*COMPONENTS*TA_CHUNKS_PER_LEAF*STATE_BITS + ta_chunk_base*STATE_BITS];
435
+
350
436
  for (unsigned long long class_id = 0; class_id < number_of_outputs; ++class_id) {
351
437
  int local_class_sum = class_sum[class_id];
352
438
  if (local_class_sum > THRESHOLD) {
@@ -355,7 +441,7 @@ code_update = """
355
441
  local_class_sum = -THRESHOLD;
356
442
  }
357
443
 
358
- update_component_hierarchy(&localState, number_of_outputs, &clause_weights[class_id*CLAUSES + clause], ta_state, component_output[clause_component], &Xi[ta_chunk_base], y[example*number_of_outputs + class_id], local_class_sum);
444
+ update_component_hierarchy(&localState, number_of_outputs, &clause_weights[class_id*CLAUSES + clause], ta_state, component_output[clause_component], &Xi[feature_chunk_base], y[example*number_of_outputs + class_id], local_class_sum);
359
445
  }
360
446
  }
361
447
 
@@ -503,7 +589,7 @@ code_clauses = """
503
589
  int index = blockIdx.x * blockDim.x + threadIdx.x;
504
590
  int stride = blockDim.x * gridDim.x;
505
591
 
506
- for (unsigned long long i = index; i < CLAUSES * COMPONENTS * LITERALS_PER_LEAF; i += stride) {
592
+ for (unsigned long long i = index; i < 1LLU * CLAUSES * COMPONENTS * LITERALS_PER_LEAF; i += stride) {
507
593
  unsigned long long clause = i / (COMPONENTS * LITERALS_PER_LEAF);
508
594
  unsigned long long comp = (i / LITERALS_PER_LEAF) % COMPONENTS;
509
595
  unsigned long long ta_idx = i % LITERALS_PER_LEAF;
@@ -28,6 +28,7 @@ import pycuda.driver as cuda
28
28
  import pycuda.autoinit
29
29
  from pycuda.compiler import SourceModule
30
30
  from pycuda import gpuarray
31
+ import sys
31
32
 
32
33
  from time import time
33
34
 
@@ -64,11 +65,13 @@ class CommonTsetlinMachine():
64
65
 
65
66
  # Represents hierarchy structure for transfer to GPU
66
67
  self.hierarchy_structure_factors = [0] * (self.depth - 1)
67
- self.hierarchy_structure_alternatives = [0] * (self.depth - 1)
68
+ self.hierarchy_structure_type = [0] * (self.depth - 1)
68
69
  for d in range(1, self.depth):
69
70
  self.hierarchy_structure_factors[d-1] = self.hierarchy_structure[d][1]
70
71
  if self.hierarchy_structure[d][0] == OR_ALTERNATIVES:
71
- self.hierarchy_structure_alternatives[d-1] = 1
72
+ self.hierarchy_structure_type[d-1] = 1
73
+ elif self.hierarchy_structure[d][0] == OR_GROUP:
74
+ self.hierarchy_structure_type[d-1] = 2
72
75
 
73
76
  # Calculates total number of features spanned by the hierarchy
74
77
  self.number_of_features_hierarchy = 1
@@ -147,6 +150,9 @@ class CommonTsetlinMachine():
147
150
  self.propagate_and_group_false_truth_values = mod_update.get_function("propagate_and_group_false_truth_values")
148
151
  self.propagate_and_group_false_truth_values.prepare("PPii")
149
152
 
153
+ self.propagate_or_group_false_truth_values = mod_update.get_function("propagate_or_group_false_truth_values")
154
+ self.propagate_or_group_false_truth_values.prepare("PPPii")
155
+
150
156
  self.evaluate_or_groups = mod_update.get_function("evaluate_or_groups")
151
157
  self.evaluate_or_groups.prepare("PPii")
152
158
 
@@ -189,8 +195,8 @@ class CommonTsetlinMachine():
189
195
  cuda.memcpy_htod(self.hierarchy_structure_factors_gpu, np.array(self.hierarchy_structure_factors, dtype=np.int32))
190
196
 
191
197
  # GPU memory for storing hierarchy structure
192
- self.hierarchy_structure_alternatives_gpu = cuda.mem_alloc((self.depth-1)*4)
193
- cuda.memcpy_htod(self.hierarchy_structure_alternatives_gpu, np.array(self.hierarchy_structure_alternatives, dtype=np.int32))
198
+ self.hierarchy_structure_type_gpu = cuda.mem_alloc((self.depth-1)*4)
199
+ cuda.memcpy_htod(self.hierarchy_structure_type_gpu, np.array(self.hierarchy_structure_type, dtype=np.int32))
194
200
 
195
201
  # GPU memory for storing Tsetlin Automata states
196
202
  self.ta_state_hierarchy_gpu = cuda.mem_alloc(self.number_of_clauses*self.hierarchy_size[0]*self.number_of_state_bits*4)
@@ -266,7 +272,7 @@ class CommonTsetlinMachine():
266
272
  self.hierarchy_votes[0],
267
273
  self.depth,
268
274
  self.hierarchy_structure_factors_gpu,
269
- self.hierarchy_structure_alternatives_gpu,
275
+ self.hierarchy_structure_type_gpu,
270
276
  encoded_X_hierarchy,
271
277
  np.int32(e)
272
278
  )
@@ -320,6 +326,10 @@ class CommonTsetlinMachine():
320
326
  cuda.Context.synchronize()
321
327
 
322
328
  def _fit(self, X, encoded_Y, epochs=100, incremental=False):
329
+ if self.number_of_features_hierarchy != X.shape[1]:
330
+ print("The number of features spanned by hierarchy does not align with the input data.")
331
+ sys.exit(-1)
332
+
323
333
  number_of_examples = X.shape[0]
324
334
 
325
335
  if self.first:
@@ -347,15 +357,27 @@ class CommonTsetlinMachine():
347
357
  # Propagates the root value and any intermittent node values back to the leaves.
348
358
  # The purpose is to determine which leaves only has True nodes on the path from leaf to root.
349
359
  for d in range(self.depth-1, 0, -1):
350
- self.propagate_and_group_false_truth_values.prepared_call(
351
- self.grid,
352
- self.block,
353
- self.hierarchy_votes[d-1],
354
- self.hierarchy_votes[d],
355
- self.hierarchy_size[d + 1],
356
- self.hierarchy_structure[d][1]
357
- )
358
- cuda.Context.synchronize()
360
+ if self.hierarchy_structure[d][0] != OR_GROUP:
361
+ self.propagate_and_group_false_truth_values.prepared_call(
362
+ self.grid,
363
+ self.block,
364
+ self.hierarchy_votes[d-1],
365
+ self.hierarchy_votes[d],
366
+ self.hierarchy_size[d + 1],
367
+ self.hierarchy_structure[d][1]
368
+ )
369
+ cuda.Context.synchronize()
370
+ else:
371
+ self.propagate_or_group_false_truth_values.prepared_call(
372
+ self.grid,
373
+ self.block,
374
+ self.cuda_rng.state,
375
+ self.hierarchy_votes[d-1],
376
+ self.hierarchy_votes[d],
377
+ self.hierarchy_size[d + 1],
378
+ self.hierarchy_structure[d][1]
379
+ )
380
+ cuda.Context.synchronize()
359
381
 
360
382
  # Updates the clause components (leaves) based on the propagated truth values
361
383
  self.update_hierarchy.prepared_call(
@@ -368,7 +390,7 @@ class CommonTsetlinMachine():
368
390
  self.hierarchy_votes[0],
369
391
  self.depth,
370
392
  self.hierarchy_structure_factors_gpu,
371
- self.hierarchy_structure_alternatives_gpu,
393
+ self.hierarchy_structure_type_gpu,
372
394
  self.class_sum_gpu,
373
395
  encoded_X_hierarchy_training_gpu,
374
396
  Y_gpu,
@@ -517,10 +539,16 @@ class CommonTsetlinMachine():
517
539
  left = []
518
540
  right = []
519
541
  inside = []
542
+ feature_base = 0
543
+ size = self.hierarchy_structure[0][1]
520
544
  for d in range(1, self.depth):
521
545
  depth_d_node_index = component_remainder % self.hierarchy_structure[d][1]
522
546
  component_remainder = component_remainder // self.hierarchy_structure[d][1]
523
547
 
548
+ if self.hierarchy_structure[d][0] != OR_ALTERNATIVES:
549
+ feature_base += size * depth_d_node_index
550
+ size *= self.hierarchy_structure[d][1];
551
+
524
552
  if previous_index[d-1] == -1:
525
553
  left.append("(")
526
554
  elif depth_d_node_index == 0 and previous_index[d-1] != depth_d_node_index:
@@ -545,14 +573,14 @@ class CommonTsetlinMachine():
545
573
  if self.ta_action(i, j, k):
546
574
  if k < self.number_of_literals_per_leaf // 2:
547
575
  if print_ta_state:
548
- l.append("x%d(%d)" % (k, self.ta_state(i, j, k)))
576
+ l.append("x%d(%d)" % (feature_base + k, self.ta_state(i, j, k)))
549
577
  else:
550
- l.append("x%d" % (k,))
578
+ l.append("x%d" % (feature_base + k,))
551
579
  else:
552
580
  if print_ta_state:
553
- l.append("¬x%d(%d)" % (k - self.number_of_literals_per_leaf // 2, self.ta_state(i, j, k)))
581
+ l.append("¬x%d(%d)" % (feature_base + k - self.number_of_literals_per_leaf // 2, self.ta_state(i, j, k)))
554
582
  else:
555
- l.append("¬x%d" % (k - self.number_of_literals_per_leaf // 2,))
583
+ l.append("¬x%d" % (feature_base + k - self.number_of_literals_per_leaf // 2,))
556
584
 
557
585
  if len(l) > 1:
558
586
  print("(" + " ∧ ".join(l) + ")", end = '')
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: PyHierarchicalTsetlinMachineCUDA
3
- Version: 0.2.5
3
+ Version: 0.2.7
4
4
  Summary: Hierarchical Tsetlin Machine Architecture.
5
5
  Home-page: https://github.com/cair/PyHierarchicalTsetlinMachineCUDA/
6
6
  Author: Ole-Christoffer Granmo
@@ -1,10 +1,6 @@
1
1
  # Hierarchical Tsetlin Machine in CUDA
2
2
  Implements the [Hierarchical Tsetlin Machine](https://github.com/cair/HierarchicalTsetlinMachine) in CUDA.
3
3
 
4
- <p align="center">
5
- <img width="60%" src="https://github.com/cair/PyHierarchicalTsetlinMachineCUDA/blob/main/figures/Visualization_voting.png">
6
- </p>
7
-
8
4
  ## Installation
9
5
 
10
6
  ```bash
@@ -15,13 +11,17 @@ or
15
11
  git clone git@github.com:cair/PyHierarchicalTsetlinMachineCUDA.git
16
12
  cd PyHierarchicalTsetlinMachineCUDA
17
13
  python ./setup.py sdist
18
- pip install dist/PyHierarchicalTsetlinMachineCUDA-0.2.2.tar.gz
14
+ pip install dist/PyHierarchicalTsetlinMachineCUDA-0.2.6.tar.gz
19
15
  ```
20
16
 
21
17
  ## Examples
22
18
 
23
19
  ### Noisy Parity Demo
24
20
 
21
+ <p align="center">
22
+ <img width="60%" src="https://github.com/cair/PyHierarchicalTsetlinMachineCUDA/blob/main/figures/Visualization_voting.png">
23
+ </p>
24
+
25
25
  #### Code: NoisyParityDemo.py
26
26
 
27
27
  ```python
@@ -149,11 +149,11 @@ python3 ./examples/HexDemo.py
149
149
 
150
150
  Accuracy over 1000 epochs:
151
151
 
152
- #1 Training Accuracy: 97.71% Testing Accuracy: 97.26% Training Time: 36.00s Testing Time: 5.65s
153
- #2 Training Accuracy: 99.11% Testing Accuracy: 98.61% Training Time: 33.65s Testing Time: 5.65s
154
- #3 Training Accuracy: 99.53% Testing Accuracy: 98.92% Training Time: 33.00s Testing Time: 5.65s
155
- #4 Training Accuracy: 99.74% Testing Accuracy: 99.18% Training Time: 32.66s Testing Time: 5.67s
156
- #5 Training Accuracy: 99.84% Testing Accuracy: 99.35% Training Time: 32.40s Testing Time: 5.67s
152
+ #1 Training Accuracy: 97.98% Testing Accuracy: 97.46% Training Time: 37.02s Testing Time: 5.74s
153
+ #2 Training Accuracy: 99.19% Testing Accuracy: 98.70% Training Time: 34.44s Testing Time: 5.76s
154
+ #3 Training Accuracy: 99.49% Testing Accuracy: 98.92% Training Time: 33.60s Testing Time: 5.75s
155
+ #4 Training Accuracy: 99.65% Testing Accuracy: 99.05% Training Time: 33.15s Testing Time: 5.78s
156
+ #5 Training Accuracy: 99.73% Testing Accuracy: 99.10% Training Time: 32.86s Testing Time: 5.76s
157
157
  ...
158
158
  #446 Training Accuracy: 100.00% Testing Accuracy: 99.45% Training Time: 32.09s Testing Time: 6.09s
159
159
  #447 Training Accuracy: 100.00% Testing Accuracy: 99.46% Training Time: 32.08s Testing Time: 6.09s
@@ -2,7 +2,7 @@ from setuptools import *
2
2
 
3
3
  setup(
4
4
  name='PyHierarchicalTsetlinMachineCUDA',
5
- version='0.2.5',
5
+ version='0.2.7',
6
6
  author='Ole-Christoffer Granmo',
7
7
  author_email='ole.granmo@uia.no',
8
8
  url='https://github.com/cair/PyHierarchicalTsetlinMachineCUDA/',
@@ -16,6 +16,7 @@ setup(
16
16
  'pycuda',
17
17
  'scipy',
18
18
  'scikit-learn',
19
+ 'scikit-image',
19
20
  'networkx',
20
21
  ],
21
22
  extras_require={