Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
35 commits
Select commit Hold shift + click to select a range
aa06920
add recom sys
akkadhim Nov 4, 2024
6280bfb
rename
akkadhim Nov 4, 2024
771edcf
complete recom sys
akkadhim Nov 6, 2024
ec3fc87
rename
akkadhim Dec 4, 2024
08693ab
tunning
akkadhim Dec 4, 2024
9c4be1f
update
akkadhim Dec 16, 2024
daf8d5a
update
akkadhim Dec 17, 2024
9dacba5
update
akkadhim Dec 18, 2024
3dd2b7c
run on gpu 6
akkadhim Dec 18, 2024
e9bdcd6
add requirments
akkadhim Dec 18, 2024
da31b30
update
akkadhim Dec 18, 2024
fababa5
expanded ds
akkadhim Dec 18, 2024
82305ab
update
akkadhim Dec 19, 2024
218a96f
before add example no
akkadhim Dec 20, 2024
799493f
orgnizing files
akkadhim Dec 20, 2024
801b7e3
update
akkadhim Dec 20, 2024
fdfb81f
add TMClassifier
akkadhim Dec 24, 2024
3168dc7
update
akkadhim Dec 24, 2024
e2232de
add graph nn
akkadhim Dec 24, 2024
c454631
add main.bash
akkadhim Dec 25, 2024
84d8012
add results
akkadhim Dec 25, 2024
347a43c
Merge branch 'master' into master
akkadhim Dec 25, 2024
d68ae71
fair comparisons
akkadhim Dec 26, 2024
c3d895b
update
akkadhim Feb 17, 2025
26e2083
adding exp id
akkadhim Feb 25, 2025
f057bbe
update
akkadhim Feb 28, 2025
de8eb1b
update
akkadhim Feb 28, 2025
dcaaba8
Merge remote-tracking branch 'upstream/master'
akkadhim Apr 9, 2025
bfdf40c
rerun
akkadhim Apr 10, 2025
cedabda
calc total time
akkadhim May 10, 2025
14b0b68
prepare as sup. mat.
akkadhim May 20, 2025
bf709bf
add explainable exp
akkadhim Nov 18, 2025
587f09d
ploting
akkadhim Nov 18, 2025
06b7172
fix graph nn
akkadhim Nov 29, 2025
9f7c00f
ploting
akkadhim Dec 1, 2025
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions .devcontainer/devcontainer.json
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
{
"name": "TM Graph Devcontainer",
"name": "TM Graph Recomm",
"dockerComposeFile": "docker-compose.yml",
"service": "tm-graph-development",
"service": "tm-graph-recomm",
"workspaceFolder": "/app",
"forwardPorts": [],
"postCreateCommand": "echo 'Devcontainer is ready'",
Expand Down
5 changes: 3 additions & 2 deletions .devcontainer/docker-compose.yml
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
services:
tm-graph-development:
tm-graph-recomm:
build:
context: ../
dockerfile: .devcontainer/Dockerfile
Expand All @@ -9,4 +9,5 @@ services:
devices:
- driver: nvidia
capabilities: [gpu]
count: 1 # Assign number of GPUs or use 'all' to assign all available GPUs
# count: 1 # Assign number of GPUs or use 'all' to assign all available GPUs
device_ids: ["6"]
1 change: 0 additions & 1 deletion GraphTsetlinMachine/kernels.py
Original file line number Diff line number Diff line change
Expand Up @@ -787,7 +787,6 @@
unsigned int *local_ta_state = &ta_state[clause * chunks * STATE_BITS];

for (int literal = 0; literal < literals; ++literal) {
unsigned int state = 0;
int chunk_nr = literal / INT_SIZE;
int chunk_pos = literal % INT_SIZE;
out[clause * literals + literal] = (local_ta_state[chunk_nr * STATE_BITS + STATE_BITS - 1] & (1 << chunk_pos)) > 0;
Expand Down
3 changes: 1 addition & 2 deletions GraphTsetlinMachine/tm.py
Original file line number Diff line number Diff line change
Expand Up @@ -75,7 +75,6 @@ def __init__(
self.number_of_state_bits = number_of_state_bits
self.message_size = message_size
self.message_bits = message_bits
self.message_literals = message_size*2

self.double_hashing = double_hashing
self.one_hot_encoding = one_hot_encoding
Expand Down Expand Up @@ -541,7 +540,7 @@ def _init_fit(self, graphs, encoded_Y, incremental):
self.current_clause_node_output_train_gpu = cuda.mem_alloc(int(self.number_of_clauses * graphs.max_number_of_graph_node_chunks) * 4)
self.next_clause_node_output_train_gpu = cuda.mem_alloc(int(self.number_of_clauses * graphs.max_number_of_graph_node_chunks) * 4)

self.clause_X_int_train_gpu = cuda.mem_alloc(int(graphs.max_number_of_graph_nodes * self.message_literals) * 4)
self.clause_X_int_train_gpu = cuda.mem_alloc(int(graphs.max_number_of_graph_nodes * self.number_of_message_literals) * 4)

self.clause_X_train_gpu = []
for depth in range(self.depth-1):
Expand Down
2 changes: 1 addition & 1 deletion LICENSE
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
MIT License

Copyright (c) 2024 Ole-Christoffer Granmo
Copyright (c) 2025 Ole-Christoffer Granmo and University of Agder

Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
Expand Down
4 changes: 2 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,7 @@ pip3 install graphtsetlinmachine
or
```bash
python ./setup.py sdist
pip3 install dist/GraphTsetlinMachine-0.3.1.tar.gz
pip3 install dist/GraphTsetlinMachine-0.3.4.tar.gz
```

## Tutorial
Expand Down Expand Up @@ -339,7 +339,7 @@ tm = MultiClassGraphTsetlinMachine(

## Licence

Copyright (c) 2024 Ole-Christoffer Granmo
Copyright (c) 2025 Ole-Christoffer Granmo and University of Agder

Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
Expand Down
13 changes: 0 additions & 13 deletions examples/MNISTConvolutionDemo.py
Original file line number Diff line number Diff line change
Expand Up @@ -63,18 +63,13 @@ def default_args(**kwargs):
double_hashing = args.double_hashing,
one_hot_encoding = args.one_hot_encoding
)

for graph_id in range(X_train.shape[0]):
graphs_train.set_number_of_graph_nodes(graph_id, number_of_nodes)

graphs_train.prepare_node_configuration()

for graph_id in range(X_train.shape[0]):
for node_id in range(graphs_train.number_of_graph_nodes[graph_id]):
graphs_train.add_graph_node(graph_id, node_id, 0)

graphs_train.prepare_edge_configuration()

for graph_id in range(X_train.shape[0]):
if graph_id % 1000 == 0:
print(graph_id, X_train.shape[0])
Expand All @@ -90,23 +85,17 @@ def default_args(**kwargs):

graphs_train.add_graph_node_property(graph_id, node_id, "C:%d" % (q))
graphs_train.add_graph_node_property(graph_id, node_id, "R:%d" % (r))

graphs_train.encode()

print("Training data produced")

graphs_test = Graphs(X_test.shape[0], init_with=graphs_train)
for graph_id in range(X_test.shape[0]):
graphs_test.set_number_of_graph_nodes(graph_id, number_of_nodes)

graphs_test.prepare_node_configuration()

for graph_id in range(X_test.shape[0]):
for node_id in range(graphs_test.number_of_graph_nodes[graph_id]):
graphs_test.add_graph_node(graph_id, node_id, 0)

graphs_test.prepare_edge_configuration()

for graph_id in range(X_test.shape[0]):
if graph_id % 1000 == 0:
print(graph_id, X_test.shape[0])
Expand All @@ -122,9 +111,7 @@ def default_args(**kwargs):

graphs_test.add_graph_node_property(graph_id, node_id, "C:%d" % (q))
graphs_test.add_graph_node_property(graph_id, node_id, "R:%d" % (r))

graphs_test.encode()

print("Testing data produced")

tm = MultiClassGraphTsetlinMachine(
Expand Down
46 changes: 15 additions & 31 deletions examples/MNISTVanillaDemo.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@
from GraphTsetlinMachine.tm import MultiClassGraphTsetlinMachine
from time import time
import argparse
from skimage.util import view_as_windows
from keras.datasets import mnist
from numba import jit

Expand Down Expand Up @@ -55,51 +54,36 @@ def default_args(**kwargs):
double_hashing = args.double_hashing,
one_hot_encoding = args.one_hot_encoding
)

for graph_id in range(X_train.shape[0]):
graphs_train.set_number_of_graph_nodes(graph_id, number_of_nodes)

graphs_train.prepare_node_configuration()

for graph_id in range(X_train.shape[0]):
number_of_outgoing_edges = 0
graphs_train.add_graph_node(graph_id, 'Image Node', number_of_outgoing_edges)

graphs_train.prepare_edge_configuration()

for graph_id in range(X_train.shape[0]):
if graph_id % 1000 == 0:
print(graph_id, X_train.shape[0])

# if graph_id % 1000 == 0:
# print(graph_id, X_train.shape[0])
for k in X_train[graph_id].nonzero()[0]:
graphs_train.add_graph_node_property(graph_id, 'Image Node', "W%d,%d" % (k // 28, k % 28))

graphs_train.encode()

print("Training data produced")

graphs_test = Graphs(X_test.shape[0], init_with=graphs_train)

for graph_id in range(X_test.shape[0]):
graphs_test.set_number_of_graph_nodes(graph_id, number_of_nodes)

graphs_test.prepare_node_configuration()

for graph_id in range(X_test.shape[0]):
number_of_outgoing_edges = 0
graphs_test.add_graph_node(graph_id, 'Image Node', number_of_outgoing_edges)

graphs_test.prepare_edge_configuration()

for graph_id in range(X_test.shape[0]):
if graph_id % 1000 == 0:
print(graph_id, X_test.shape[0])

for k in X_test[graph_id].nonzero()[0]:
graphs_test.add_graph_node_property(graph_id, 'Image Node', "W%d,%d" % (k // 28, k % 28))

graphs_test.encode()

print("Testing data produced")

tm = MultiClassGraphTsetlinMachine(
Expand Down Expand Up @@ -128,16 +112,16 @@ def default_args(**kwargs):

print("%d %.2f %.2f %.2f %.2f" % (i, result_train, result_test, stop_training-start_training, stop_testing-start_testing))

weights = tm.get_state()[1].reshape(2, -1)
for i in range(tm.number_of_clauses):
print("Clause #%d Weights:(%d %d)" % (i, weights[0,i], weights[1,i]), end=' ')
l = []
for k in range(args.hypervector_size * 2):
if tm.ta_action(0, i, k):
if k < args.hypervector_size:
l.append("x%d" % (k))
else:
l.append("NOT x%d" % (k - args.hypervector_size))
print(" AND ".join(l))

print(graphs_train.hypervectors)
# weights = tm.get_state()[1].reshape(2, -1)
# for i in range(tm.number_of_clauses):
# print("Clause #%d Weights:(%d %d)" % (i, weights[0,i], weights[1,i]), end=' ')
# l = []
# for k in range(args.hypervector_size * 2):
# if tm.ta_action(0, i, k):
# if k < args.hypervector_size:
# l.append("x%d" % (k))
# else:
# l.append("NOT x%d" % (k - args.hypervector_size))
# print(" AND ".join(l))

# print(graphs_train.hypervectors)
20 changes: 2 additions & 18 deletions examples/NoisyXORDemo.py
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,6 @@ def default_args(**kwargs):
print("Creating training data")

# Create train data

graphs_train = Graphs(
args.number_of_examples,
symbols=['A', 'B'],
Expand All @@ -48,21 +47,16 @@ def default_args(**kwargs):

for graph_id in range(args.number_of_examples):
graphs_train.set_number_of_graph_nodes(graph_id, 2)

graphs_train.prepare_node_configuration()

for graph_id in range(args.number_of_examples):
number_of_outgoing_edges = 1
graphs_train.add_graph_node(graph_id, 'Node 1', number_of_outgoing_edges)
graphs_train.add_graph_node(graph_id, 'Node 2', number_of_outgoing_edges)

graphs_train.prepare_edge_configuration()

graphs_train.prepar_eedge_configuration()
for graph_id in range(args.number_of_examples):
edge_type = "Plain"
graphs_train.add_graph_node_edge(graph_id, 'Node 1', 'Node 2', edge_type)
graphs_train.add_graph_node_edge(graph_id, 'Node 2', 'Node 1', edge_type)

Y_train = np.empty(args.number_of_examples, dtype=np.uint32)
for graph_id in range(args.number_of_examples):
x1 = random.choice(['A', 'B'])
Expand All @@ -78,32 +72,23 @@ def default_args(**kwargs):

if np.random.rand() <= args.noise:
Y_train[graph_id] = 1 - Y_train[graph_id]

graphs_train.encode()

# Create test data

# Create test data
print("Creating testing data")

graphs_test = Graphs(args.number_of_examples, init_with=graphs_train)

for graph_id in range(args.number_of_examples):
graphs_test.set_number_of_graph_nodes(graph_id, 2)

graphs_test.prepare_node_configuration()

for graph_id in range(args.number_of_examples):
number_of_outgoing_edges = 1
graphs_test.add_graph_node(graph_id, 'Node 1', number_of_outgoing_edges)
graphs_test.add_graph_node(graph_id, 'Node 2', number_of_outgoing_edges)

graphs_test.prepare_edge_configuration()

for graph_id in range(args.number_of_examples):
edge_type = "Plain"
graphs_test.add_graph_node_edge(graph_id, 'Node 1', 'Node 2', edge_type)
graphs_test.add_graph_node_edge(graph_id, 'Node 2', 'Node 1', edge_type)

Y_test = np.empty(args.number_of_examples, dtype=np.uint32)
for graph_id in range(args.number_of_examples):
x1 = random.choice(['A', 'B'])
Expand All @@ -116,7 +101,6 @@ def default_args(**kwargs):
Y_test[graph_id] = 0
else:
Y_test[graph_id] = 1

graphs_test.encode()

tm = MultiClassGraphTsetlinMachine(
Expand Down
16 changes: 0 additions & 16 deletions examples/NoisyXORMNISTDemo.py
Original file line number Diff line number Diff line change
Expand Up @@ -54,24 +54,18 @@ def default_args(**kwargs):
hypervector_size=args.hypervector_size,
hypervector_bits=args.hypervector_bits,
)

for graph_id in range(args.number_of_examples):
graphs_train.set_number_of_graph_nodes(graph_id, 2)

graphs_train.prepare_node_configuration()

for graph_id in range(args.number_of_examples):
number_of_outgoing_edges = 1
graphs_train.add_graph_node(graph_id, 'Node 1', number_of_outgoing_edges)
graphs_train.add_graph_node(graph_id, 'Node 2', number_of_outgoing_edges)

graphs_train.prepare_edge_configuration()

for graph_id in range(args.number_of_examples):
edge_type = "Plain"
graphs_train.add_graph_node_edge(graph_id, 'Node 1', 'Node 2', edge_type)
graphs_train.add_graph_node_edge(graph_id, 'Node 2', 'Node 1', edge_type)

Y_train = np.empty(args.number_of_examples, dtype=np.uint32)
for graph_id in range(args.number_of_examples):
x1 = random.choice([0, 1])
Expand All @@ -91,32 +85,23 @@ def default_args(**kwargs):

if np.random.rand() <= args.noise:
Y_train[graph_id] = 1 - Y_train[graph_id]

graphs_train.encode()

# Create test data

print("Creating testing data")

graphs_test = Graphs(args.number_of_examples, init_with=graphs_train)

for graph_id in range(args.number_of_examples):
graphs_test.set_number_of_graph_nodes(graph_id, 2)

graphs_test.prepare_node_configuration()

for graph_id in range(args.number_of_examples):
number_of_outgoing_edges = 1
graphs_test.add_graph_node(graph_id, 'Node 1', number_of_outgoing_edges)
graphs_test.add_graph_node(graph_id, 'Node 2', number_of_outgoing_edges)

graphs_test.prepare_edge_configuration()

for graph_id in range(args.number_of_examples):
edge_type = "Plain"
graphs_test.add_graph_node_edge(graph_id, 'Node 1', 'Node 2', edge_type)
graphs_test.add_graph_node_edge(graph_id, 'Node 2', 'Node 1', edge_type)

Y_test = np.empty(args.number_of_examples, dtype=np.uint32)
for graph_id in range(args.number_of_examples):
x1 = random.choice([0, 1])
Expand All @@ -133,7 +118,6 @@ def default_args(**kwargs):
Y_test[graph_id] = 0
else:
Y_test[graph_id] = 1

graphs_test.encode()

tm = MultiClassGraphTsetlinMachine(
Expand Down
Loading