Skip to content

Commit

Permalink
Update HDC_library.py
Browse files Browse the repository at this point in the history
  • Loading branch information
spyrchat authored Jan 13, 2024
1 parent 5e13e79 commit 616085a
Showing 1 changed file with 63 additions and 58 deletions.
121 changes: 63 additions & 58 deletions HDC_library.py
Original file line number Diff line number Diff line change
@@ -1,31 +1,29 @@
import numpy as np
from sklearn.utils import shuffle
from scipy.linalg import lu_factor, lu_solve

# Receives the HDC encoded test set "HDC_cont_test" and test labels "Y_test"
# Computes test accuracy w.r.t. the HDC prototypes (centroids) and the biases found at training time

def compute_accuracy(HDC_cont_test, Y_test, centroids, biases):
Acc = 0
n_class = int(np.max(Y_test) + 1)
n_class = int(np.max(Y_test)) + 1
for i in range(Y_test.shape[0]): # Y_test.shape[0] = rows of Y_test = each patient
received_HDC_vector = (HDC_cont_test[i])
all_resp = np.zeros(n_class)
for cl in range(n_class): # classes is true or false (cancer or no cancer)
final_HDC_centroid = (centroids[cl])
#compute LS-SVM response
response = np.dot(np.transpose(final_HDC_centroid),received_HDC_vector) + biases[cl]

all_resp[cl] = response
class_idx = np.argmax(all_resp)

if class_idx == 0:
class_idx = 1
else:
class_idx = -1
class_idx = -1

if class_idx == Y_test[i]:
Acc += 1
Acc += 1
#print(Acc/Y_test.shape[0])
return Acc/Y_test.shape[0]


Expand All @@ -44,12 +42,14 @@ def lookup_generate(dim, n_keys, mode = 1):
row = np.random.choice([-1, 1], size=(dim), p=[1-probability, probability])
table[i,:] = row
prob_array[i] = probability

return table.astype(np.int8)#,prob_array
return table.astype(np.int8)

# dim is the HDC dimensionality D
def encode_HDC_RFF(img, position_table, grayscale_table, dim):
#img contains the 30 features of the current patient
#img containts the 30 features of the current patient

# print("Features Shape", np.shape(img))
# print("geryscale_table size", np.shape(grayscale_table))
img_hv = np.zeros(dim, dtype=np.int16)
container = np.zeros((len(position_table), dim))

Expand All @@ -59,14 +59,12 @@ def encode_HDC_RFF(img, position_table, grayscale_table, dim):
xor_result = (encoded_input[pixel] ^ position_table[pixel])
xor_result = (xor_result != 0).astype(int)
xor_result[xor_result == 0] = -1

hv = xor_result
container[pixel, :] = hv*1

img_hv = np.sum(container, axis = 0) #bundling without the cyclic step yet
return img_hv #,container


return img_hv
# Train the HDC circuit on the training set : (Y_train, HDC_cont_train)
# n_class: number of classes
# N_train: number of data points in training set
Expand All @@ -85,11 +83,11 @@ def train_HDC_RFF(n_class, N_train, Y_train_init, HDC_cont_train, gamma, D_b):
#Beta.alpha = L -> alpha (that we want)
Beta = np.zeros((N_train+1, N_train+1)) #LS-SVM regression matrix
omega = np.zeros((N_train, N_train))
#Fill Beta:
for i in range(N_train):
for j in range(N_train):
omega[i, j] = Y_train[i] * Y_train[j] * np.dot(np.transpose(HDC_cont_train[i]), HDC_cont_train[j])

Y_train_outer = np.outer(Y_train, Y_train) # Outer product of Y_train
HDC_dot_products = np.dot(HDC_cont_train, HDC_cont_train.T) # Dot product of HDC_cont_train vectors
omega = Y_train_outer * HDC_dot_products # Element-wise multiplication

Beta[1:N_train+1,0] = Y_train
Beta[0,1:N_train+1] = np.transpose(Y_train)
Beta[1:N_train+1,1:N_train+1] = omega + pow(gamma,-1) * np.identity(N_train)
Expand All @@ -99,23 +97,20 @@ def train_HDC_RFF(n_class, N_train, Y_train_init, HDC_cont_train, gamma, D_b):
L[1:N_train+1] = np.ones(N_train)

#Solve the system of equations to get the vector alpha:
alpha = np.zeros(N_train+1)
alpha = np.zeros(N_train)
alpha = np.linalg.solve(Beta,L) #alpha here is the whole v vector from the slides
#print("beta =",Beta)
#print("L =",L)
#print("alpha =",alpha)

# Get HDC prototype for class cla, still in floating point
final_HDC_centroid = np.zeros(100)
final_HDC_centroid_q = np.zeros(100)
final_HDC_centroid = np.zeros(np.shape(HDC_cont_train[0]))
final_HDC_centroid_q = np.zeros(np.shape(HDC_cont_train[0]))

for i in range(N_train):
final_HDC_centroid = final_HDC_centroid + Y_train[i]*alpha[i+1]*HDC_cont_train[i] #this is mu(vector) from the slides

# Quantization
max_centroid = np.max(np.abs(final_HDC_centroid))
final_HDC_centroid_q = np.round(final_HDC_centroid*(2**(D_b-1)-1)/max_centroid)

#Amplification factor for the LS-SVM bias
fact = (2**(D_b-1)-1)/max_centroid

Expand Down Expand Up @@ -153,56 +148,66 @@ def evaluate_F_of_x(Nbr_of_trials, HDC_cont_all, LABELS, beta_, bias_, gamma, al
HDC_cont_train_ = HDC_cont_all[:N_train,:] # Take training set
HDC_cont_train_cpy = HDC_cont_train_ * 1
bias_train = bias_[:N_train]
HDC_cont_train_cpy = HDC_cont_train_cpy*beta_ + bias_train[trial_]
# Apply cyclic accumulation with biases and accumulation speed beta_
HDC_cont_train_cpy = HDC_cont_train_cpy*beta_ + bias_train
cyclic_accumulation_train = HDC_cont_train_cpy % (2 ** B_cnt)
# Ternary thresholding with threshold alpha_sp:
for row in range(cyclic_accumulation_train.shape[0]):
for col in range(cyclic_accumulation_train.shape[1]):
if cyclic_accumulation_train[row,col] - pow(2,B_cnt-1) > alpha_sp:
cyclic_accumulation_train[row,col] = 1
elif cyclic_accumulation_train[row,col] - pow(2,B_cnt-1) < -alpha_sp:
cyclic_accumulation_train[row,col] = -1
elif abs(cyclic_accumulation_train[row,col] - pow(2,B_cnt-1)) <= alpha_sp:
cyclic_accumulation_train[row,col] = 0

Y_train = (LABELS[:N_train] - 1)*2-1
Y_train = Y_train.astype(int)
HDC_cont_train_cyclic = np.zeros((cyclic_accumulation_train.shape[0],HDC_cont_all.shape[1]))

threshold = pow(2, B_cnt - 1)
# Subtract the threshold from all elements (element-wise operation)
delta_train = cyclic_accumulation_train - threshold

# Apply the conditions using numpy's vectorized operations (element-wise)
HDC_cont_train_cyclic = np.zeros_like(cyclic_accumulation_train)
HDC_cont_train_cyclic[delta_train > alpha_sp] = 1
HDC_cont_train_cyclic[delta_train < -alpha_sp] = -1


# Apply cyclic accumulation with biases and accumulation speed beta_
Y_train = (LABELS[:N_train] - 1)*2-1
Y_train = Y_train.astype(int)

# Train the HDC system to find the prototype hypervectors, _q meqns quantized
centroids, biases, centroids_q, biases_q = train_HDC_RFF(n_class, N_train, Y_train, cyclic_accumulation_train, gamma, D_b)
centroids, biases, centroids_q, biases_q = train_HDC_RFF(n_class, N_train, Y_train, HDC_cont_train_cyclic, gamma, D_b)

# Do the same encoding steps with the test set
# put testset equal to training set for unit test 2, we want 100% accuracy
HDC_cont_test_ = HDC_cont_all[N_train:,:]
#HDC_cont_test_ = HDC_cont_train_*1
HDC_cont_test_cpy = HDC_cont_test_ * 1
bias_test = bias_[N_train:]
#bias_test = bias_train

#bias_test = np.array(bias_train)
# Apply cyclic accumulation with biases and accumulation speed beta_
HDC_cont_test_cpy = HDC_cont_test_cpy*beta_ + bias_test
bias_test = bias_[N_train:] - 1

HDC_cont_test_cpy = HDC_cont_test_cpy * beta_ + bias_test[trial_]

cyclic_accumulation_test = HDC_cont_test_cpy % (2 ** B_cnt)
# cyclic_accumulation_test1 = HDC_cont_test_cpy % (2 ** B_cnt)

# print("Cyclic Accumulation :", np.min(cyclic_accumulation_test))
HDC_cont_test_cyclic = np.zeros((cyclic_accumulation_test.shape[0],HDC_cont_all.shape[1]))

# Subtract the threshold from all elements (element-wise operation)
delta_test = cyclic_accumulation_test - threshold

# Apply the conditions using numpy's vectorized operations (element-wise)
HDC_cont_test_cyclic = np.zeros_like(cyclic_accumulation_test)
HDC_cont_test_cyclic[delta_test > alpha_sp] = 1
HDC_cont_test_cyclic[delta_test < -alpha_sp] = -1
# Ternary thresholding with threshold alpha_sp:
for row in range(cyclic_accumulation_test.shape[0]):
for col in range(cyclic_accumulation_test.shape[1]):
if cyclic_accumulation_test[row,col] - pow(2,B_cnt-1) > alpha_sp:
cyclic_accumulation_test[row,col] = 1
elif cyclic_accumulation_test[row,col] - pow(2,B_cnt-1) < -alpha_sp:
cyclic_accumulation_test[row,col] = -1
elif abs(cyclic_accumulation_test[row,col] - pow(2,B_cnt-1)) <= alpha_sp:
cyclic_accumulation_test[row,col] = 0

Y_test = (LABELS[N_train:] - 1)*2-1
#Y_test = Y_train*1

Y_test = (LABELS[N_train:] - 1)*2-1
Y_test = Y_test.astype(int)

# Compute accuracy and sparsity of the test set w.r.t the HDC prototypes
Acc = compute_accuracy(cyclic_accumulation_test, Y_test, centroids_q, biases_q)
Acc = compute_accuracy(HDC_cont_test_cyclic, Y_test, centroids_q, biases_q)
sparsity_HDC_centroid = np.array(centroids_q).flatten()
nbr_zero = np.sum((sparsity_HDC_centroid == 0).astype(int))
SPH = nbr_zero/(sparsity_HDC_centroid.shape[0])
local_avg[trial_] = lambda_1 * Acc + lambda_2 * SPH #Cost F(x) is defined as 1 - this quantity
local_avgre[trial_] = Acc
local_sparse[trial_] = SPH

return local_avg, local_avgre, local_sparse
return local_avg, local_avgre, local_sparse




0 comments on commit 616085a

Please sign in to comment.