How to add a member function to an existing Python object? - python

Previously I created a lot of Python objects of class A, and I would like to add a new function plotting_in_PC_space_with_coloring_option() (the purpose of this function is to plot some data in this object) to class A and use those old objects to call plotting_in_PC_space_with_coloring_option().
An example is:
import copy
import numpy as np
from math import *
from pybrain.structure import *
from pybrain.supervised.trainers import BackpropTrainer
from pybrain.datasets.supervised import SupervisedDataSet
import pickle
import neural_network_related
class A(object):
"""the neural network for simulation"""
'''
todo:
- find boundary
- get_angles_from_coefficients
'''
def __init__(self,
index, # the index of the current network
list_of_coor_data_files, # accept multiple files of training data
energy_expression_file, # input, output files
preprocessing_settings = None,
connection_between_layers = None, connection_with_bias_layers = None,
PCs = None, # principal components
):
self._index = index
self._list_of_coor_data_files = list_of_coor_data_files
self._energy_expression_file = energy_expression_file
self._data_set = []
for item in list_of_coor_data_files:
self._data_set += self.get_many_cossin_from_coordiantes_in_file(item)
self._preprocessing_settings = preprocessing_settings
self._connection_between_layers = connection_between_layers
self._connection_with_bias_layers = connection_with_bias_layers
self._node_num = [8, 15, 2, 15, 8]
self._PCs = PCs
def save_into_file(self, filename = None):
if filename is None:
filename = "network_%s.pkl" % str(self._index) # by default naming with its index
with open(filename, 'wb') as my_file:
pickle.dump(self, my_file, pickle.HIGHEST_PROTOCOL)
return
def get_cossin_from_a_coordinate(self, a_coordinate):
num_of_coordinates = len(a_coordinate) / 3
a_coordinate = np.array(a_coordinate).reshape(num_of_coordinates, 3)
diff_coordinates = a_coordinate[1:num_of_coordinates, :] - a_coordinate[0:num_of_coordinates - 1,:] # bond vectors
diff_coordinates_1=diff_coordinates[0:num_of_coordinates-2,:];diff_coordinates_2=diff_coordinates[1:num_of_coordinates-1,:]
normal_vectors = np.cross(diff_coordinates_1, diff_coordinates_2);
normal_vectors_normalized = np.array(map(lambda x: x / sqrt(np.dot(x,x)), normal_vectors))
normal_vectors_normalized_1 = normal_vectors_normalized[0:num_of_coordinates-3, :];normal_vectors_normalized_2 = normal_vectors_normalized[1:num_of_coordinates-2,:];
diff_coordinates_mid = diff_coordinates[1:num_of_coordinates-2]; # these are bond vectors in the middle (remove the first and last one), they should be perpendicular to adjacent normal vectors
cos_of_angles = range(len(normal_vectors_normalized_1))
sin_of_angles_vec = range(len(normal_vectors_normalized_1))
sin_of_angles = range(len(normal_vectors_normalized_1)) # initialization
for index in range(len(normal_vectors_normalized_1)):
cos_of_angles[index] = np.dot(normal_vectors_normalized_1[index], normal_vectors_normalized_2[index])
sin_of_angles_vec[index] = np.cross(normal_vectors_normalized_1[index], normal_vectors_normalized_2[index])
sin_of_angles[index] = sqrt(np.dot(sin_of_angles_vec[index], sin_of_angles_vec[index])) * np.sign(sum(sin_of_angles_vec[index]) * sum(diff_coordinates_mid[index]));
return cos_of_angles + sin_of_angles
def get_many_cossin_from_coordinates(self, coordinates):
return map(self.get_cossin_from_a_coordinate, coordinates)
def get_many_cossin_from_coordiantes_in_file (self, filename):
coordinates = np.loadtxt(filename)
return self.get_many_cossin_from_coordinates(coordinates)
def mapminmax(self, my_list): # for preprocessing in network
my_min = min(my_list)
my_max = max(my_list)
mul_factor = 2.0 / (my_max - my_min)
offset = (my_min + my_max) / 2.0
result_list = np.array(map(lambda x : (x - offset) * mul_factor, my_list))
return (result_list, (mul_factor, offset)) # also return the parameters for processing
def get_mapminmax_preprocess_result_and_coeff(self,data=None):
if data is None:
data = self._data_set
data = np.array(data)
data = np.transpose(data)
result = []; params = []
for item in data:
temp_result, preprocess_params = self.mapminmax(item)
result.append(temp_result)
params.append(preprocess_params)
return (np.transpose(np.array(result)), params)
def mapminmax_preprocess_using_coeff(self, input_data=None, preprocessing_settings=None):
# try begin
if preprocessing_settings is None:
preprocessing_settings = self._preprocessing_settings
temp_setttings = np.transpose(np.array(preprocessing_settings))
result = []
for item in input_data:
item = np.multiply(item - temp_setttings[1], temp_setttings[0])
result.append(item)
return result
# try end
def get_expression_of_network(self, connection_between_layers=None, connection_with_bias_layers=None):
if connection_between_layers is None:
connection_between_layers = self._connection_between_layers
if connection_with_bias_layers is None:
connection_with_bias_layers = self._connection_with_bias_layers
node_num = self._node_num
expression = ""
# first part: network
for i in range(2):
expression = '\n' + expression
mul_coef = connection_between_layers[i].params.reshape(node_num[i + 1], node_num[i])
bias_coef = connection_with_bias_layers[i].params
for j in range(np.size(mul_coef, 0)):
temp_expression = 'layer_%d_unit_%d = tanh( ' % (i + 1, j)
for k in range(np.size(mul_coef, 1)):
temp_expression += ' %f * layer_%d_unit_%d +' % (mul_coef[j, k], i, k)
temp_expression += ' %f);\n' % (bias_coef[j])
expression = temp_expression + expression # order of expressions matter in OpenMM
# second part: definition of inputs
index_of_backbone_atoms = [2, 5, 7, 9, 15, 17, 19];
for i in range(len(index_of_backbone_atoms) - 3):
index_of_coss = i
index_of_sins = i + 4
expression += 'layer_0_unit_%d = (raw_layer_0_unit_%d - %f) * %f;\n' % \
(index_of_coss, index_of_coss, self._preprocessing_settings[index_of_coss][1], self._preprocessing_settings[index_of_coss][0])
expression += 'layer_0_unit_%d = (raw_layer_0_unit_%d - %f) * %f;\n' % \
(index_of_sins, index_of_sins, self._preprocessing_settings[index_of_sins][1], self._preprocessing_settings[index_of_sins][0])
expression += 'raw_layer_0_unit_%d = cos(dihedral_angle_%d);\n' % (index_of_coss, i)
expression += 'raw_layer_0_unit_%d = sin(dihedral_angle_%d);\n' % (index_of_sins, i)
expression += 'dihedral_angle_%d = dihedral(p%d, p%d, p%d, p%d);\n' % \
(i, index_of_backbone_atoms[i], index_of_backbone_atoms[i+1],index_of_backbone_atoms[i+2],index_of_backbone_atoms[i+3])
return expression
def write_expression_into_file(self, out_file = None):
if out_file is None: out_file = self._energy_expression_file
expression = self.get_expression_of_network()
with open(out_file, 'w') as f_out:
f_out.write(expression)
return
def get_mid_result(self, input_data=None, connection_between_layers=None, connection_with_bias_layers=None):
if input_data is None: input_data = self._data_set
if connection_between_layers is None: connection_between_layers = self._connection_between_layers
if connection_with_bias_layers is None: connection_with_bias_layers = self._connection_with_bias_layers
node_num = self._node_num
temp_mid_result = range(4)
mid_result = []
# first need to do preprocessing
for item in self.mapminmax_preprocess_using_coeff(input_data, self._preprocessing_settings):
for i in range(4):
mul_coef = connection_between_layers[i].params.reshape(node_num[i + 1], node_num[i]) # fix node_num
bias_coef = connection_with_bias_layers[i].params
previous_result = item if i == 0 else temp_mid_result[i - 1]
temp_mid_result[i] = np.dot(mul_coef, previous_result) + bias_coef
if i != 3: # the last output layer is a linear layer, while others are tanh layers
temp_mid_result[i] = map(tanh, temp_mid_result[i])
mid_result.append(copy.deepcopy(temp_mid_result)) # note that should use deepcopy
return mid_result
def get_PC_and_save_it_to_network(self):
'''get PCs and save the result into _PCs
'''
mid_result = self.get_mid_result()
self._PCs = [item[1] for item in mid_result]
return
def train(self):
####################### set up autoencoder begin #######################
node_num = self._node_num
in_layer = LinearLayer(node_num[0], "IL")
hidden_layers = [TanhLayer(node_num[1], "HL1"), TanhLayer(node_num[2], "HL2"), TanhLayer(node_num[3], "HL3")]
bias_layers = [BiasUnit("B1"),BiasUnit("B2"),BiasUnit("B3"),BiasUnit("B4")]
out_layer = LinearLayer(node_num[4], "OL")
layer_list = [in_layer] + hidden_layers + [out_layer]
molecule_net = FeedForwardNetwork()
molecule_net.addInputModule(in_layer)
for item in (hidden_layers + bias_layers):
molecule_net.addModule(item)
molecule_net.addOutputModule(out_layer)
connection_between_layers = range(4); connection_with_bias_layers = range(4)
for i in range(4):
connection_between_layers[i] = FullConnection(layer_list[i], layer_list[i+1])
connection_with_bias_layers[i] = FullConnection(bias_layers[i], layer_list[i+1])
molecule_net.addConnection(connection_between_layers[i]) # connect two neighbor layers
molecule_net.addConnection(connection_with_bias_layers[i])
molecule_net.sortModules() # this is some internal initialization process to make this module usable
####################### set up autoencoder end #######################
trainer = BackpropTrainer(molecule_net, learningrate=0.002,momentum=0.4,verbose=False, weightdecay=0.1, lrdecay=1)
data_set = SupervisedDataSet(node_num[0], node_num[4])
sincos = self._data_set
(sincos_after_process, self._preprocessing_settings) = self.get_mapminmax_preprocess_result_and_coeff(data = sincos)
for item in sincos_after_process: # is it needed?
data_set.addSample(item, item)
trainer.trainUntilConvergence(data_set, maxEpochs=50)
self._connection_between_layers = connection_between_layers
self._connection_with_bias_layers = connection_with_bias_layers
print("Done!\n")
return
def create_sge_files_for_simulation(self,potential_centers = None):
if potential_centers is None:
potential_centers = self.get_boundary_points()
neural_network_related.create_sge_files(potential_centers)
return
def get_boundary_points(self, list_of_points = None, num_of_bins = 5):
if list_of_points is None: list_of_points = self._PCs
x = [item[0] for item in list_of_points]
y = [item[1] for item in list_of_points]
temp = np.histogram2d(x,y, bins=[num_of_bins, num_of_bins])
hist_matrix = temp[0]
# add a set of zeros around this region
hist_matrix = np.insert(hist_matrix, num_of_bins, np.zeros(num_of_bins), 0)
hist_matrix = np.insert(hist_matrix, 0, np.zeros(num_of_bins), 0)
hist_matrix = np.insert(hist_matrix, num_of_bins, np.zeros(num_of_bins + 2), 1)
hist_matrix = np.insert(hist_matrix, 0, np.zeros(num_of_bins +2), 1)
hist_matrix = (hist_matrix != 0).astype(int)
sum_of_neighbors = np.zeros(np.shape(hist_matrix)) # number of neighbors occupied with some points
for i in range(np.shape(hist_matrix)[0]):
for j in range(np.shape(hist_matrix)[1]):
if i != 0: sum_of_neighbors[i,j] += hist_matrix[i - 1][j]
if j != 0: sum_of_neighbors[i,j] += hist_matrix[i][j - 1]
if i != np.shape(hist_matrix)[0] - 1: sum_of_neighbors[i,j] += hist_matrix[i + 1][j]
if j != np.shape(hist_matrix)[1] - 1: sum_of_neighbors[i,j] += hist_matrix[i][j + 1]
bin_width_0 = temp[1][1]-temp[1][0]
bin_width_1 = temp[2][1]-temp[2][0]
min_coor_in_PC_space_0 = temp[1][0] - 0.5 * bin_width_0 # multiply by 0.5 since we want the center of the grid
min_coor_in_PC_space_1 = temp[2][0] - 0.5 * bin_width_1
potential_centers = []
for i in range(np.shape(hist_matrix)[0]):
for j in range(np.shape(hist_matrix)[1]):
if hist_matrix[i,j] == 0 and sum_of_neighbors[i,j] != 0: # no points in this block but there are points in neighboring blocks
temp_potential_center = [round(min_coor_in_PC_space_0 + i * bin_width_0, 2), round(min_coor_in_PC_space_1 + j * bin_width_1, 2)]
potential_centers.append(temp_potential_center)
return potential_centers
# this function is added after those old objects of A were created
def plotting_in_PC_space_with_coloring_option(self,
list_of_coordinate_files_for_plotting=None, # accept multiple files
color_option='pure'):
'''
by default, we are using training data, and we also allow external data input
'''
if list_of_coordinate_files_for_plotting is None:
PCs_to_plot = self._PCs
else:
temp_sincos = []
for item in list_of_coordinate_files_for_plotting:
temp_sincos += self.get_many_cossin_from_coordiantes_in_file(item)
temp_mid_result = self.get_mid_result(input_data = temp_sincos)
PCs_to_plot = [item[1] for item in temp_mid_result]
(x, y) = ([item[0] for item in PCs_to_plot], [item[1] for item in PCs_to_plot])
# coloring
if color_option == 'pure':
coloring = 'red'
elif color_option == 'step':
coloring = range(len(x))
fig, ax = plt.subplots()
ax.scatter(x,y, c=coloring)
ax.set_xlabel("PC1")
ax.set_ylabel("PC2")
plt.show()
return
But it seems that plotting_in_PC_space_with_coloring_option() was not binded to those old objects, is here any way to fix it (I do not want to recreate these objects since creation involves CPU-intensive calculation and would take very long time to do it)?
Thanks!

Something like this:
class A:
def q(self): print 1
a = A()
def f(self): print 2
setattr(A, 'f', f)
a.f()
This is called a monkey patch.

Related

Python negative Value Error dimensions are not allowed

I am implementing genetic algorithm but I am facing an error after the first generation with the message: ValueError: negative dimensions are not allowed
I actually change the nfilters parameter from nfilters=[74,27,23] to nfilters=[64,128,256], I don't know if it is due to this parameters.
I declared my class sequential as follow:
class CNN(Sequential):
def __init__(self,nfilters,sfilters):
super().__init__()
tf.random.set_seed(0)
self.add(Conv2D(nfilters[0],kernel_size=(sfilters[0],sfilters[0]),padding='same',activation='relu',input_shape=(50,50,3)))
self.add(MaxPooling2D(pool_size=(2,2),strides=(2,2)))
self.add(Conv2D(nfilters[1],kernel_size=(sfilters[1],sfilters[1]),padding='same',activation='relu'))
self.add(MaxPooling2D(pool_size=(2,2),strides=(2,2)))
self.add(Conv2D(nfilters[2],kernel_size=(sfilters[2],sfilters[2]),padding='same',activation='relu'))
self.add(Conv2D(nfilters[2], kernel_size=(sfilters[2], sfilters[2]), padding='same', activation='relu'))
self.add(Flatten())
self.add(Dropout(0.5))
self.add(Dense(128,activation='relu'))
self.add(Dropout(0.5))
self.add(Dense(128, activation='relu'))
self.add(Dense(num_classes, activation='sigmoid'))
self.compile(loss=keras.losses.binary_crossentropy,
optimizer=tf.optimizers.Adam(learning_rate=0.001),
metrics=['accuracy'])
nfilters = [64,128,256] #nfilters = [74,27,23]
sfilters = [9,3,2] #sfilters = [9,3,2]
Then my class genetic is declared as the following:
class Genetic:
def __init__(self,pop_size,nlayers,max_nfilters,max_sfilters):
self.pop_size = pop_size
self.nlayers = nlayers
self.max_nfilters = max_nfilters
self.max_sfilters = max_sfilters
self.max_acc = 0
self.best_arch = np.zeros((1,6))
self.gen_acc = []
def generate_population(self):
np.random.seed(0)
pop_nlayers = np.random.randint(1,self.max_nfilters,(self.pop_size,self.nlayers))
pop_sfilters = np.random.randint(1,self.max_sfilters,(self.pop_size,self.nlayers))
pop_total = np.concatenate((pop_nlayers,pop_sfilters),axis=1)
return pop_total
def select_parents(self,pop,nparents,fitness):
parents = np.zeros((nparents,pop.shape[1]))
for i in range(nparents):
best = np.argmax(fitness)
parents[i] = pop[best]
fitness[best] = -99999
return parents
def crossover(self,parents):
nchild = self.pop_size - parents.shape[0]
nparents = parents.shape[0]
child = np.zeros((nchild,parents.shape[1]))
for i in range(nchild):
first = i % nparents
second = (i+1) % nparents
child[i,:2] = parents[first][:2]
child[i,2] = parents[second][2]
child[i,3:5] = parents[first][3:5]
child[i,5] = parents[second][5]
return child
def mutation(self,child):
for i in range(child.shape[0]):
val = np.random.randint(1,6)
ind = np.random.randint(1,4) - 1
if child[i][ind] + val > 100:
child[i][ind] -= val
else:
child[i][ind] += val
val = np.random.randint(1,4)
ind = np.random.randint(4,7) - 1
if child[i][ind] + val > 20:
child[i][ind] -= val
else:
child[i][ind] += val
return child
def fitness(self,pop,X,Y,epochs):
pop_acc = []
for i in range(pop.shape[0]):
nfilters = pop[i][0:3]
sfilters = pop[i][3:]
model = CNN(nfilters,sfilters)
#H = model.fit_generator(datagen.flow(X,Y,batch_size=256),epochs=epochs,callbacks=[early_stopping_monitor])
H = model.fit_generator(datagen.flow(X,Y,batch_size=256),steps_per_epoch=len(X_trainRusReshaped) / batch_size,epochs=epochs,validation_data=(X_testRusReshaped, Y_testRusHot),callbacks=[early_stopping_monitor])
acc = H.history['accuracy']
pop_acc.append(max(acc)*100)
if max(pop_acc) > self.max_acc:
self.max_acc = max(pop_acc)
self.best_arch = pop[np.argmax(pop_acc)]
self.gen_acc.append(max(pop_acc))
return pop_acc
def smooth_curve(self,factor,gen):
smoothed_points = []
for point in self.gen_acc:
if smoothed_points:
prev = smoothed_points[-1]
smoothed_points.append(prev*factor + point * (1-factor))
else:
smoothed_points.append(point)
plt.plot(range(gen+1),smoothed_points,'g',label='Smoothed training acc')
plt.xticks(np.arange(gen+1))
plt.legend()
plt.title('Fitness Accuracy vs Generations')
plt.xlabel('Generations')
plt.ylabel('Fitness (%)')
plt.show()
plt.savefig('smoothCurve.png')
When I launch these lines of codes, I have the error after 20 epochs on the first generation:
#Starting Genetic Algoritm
pop_size = 2 #10
nlayers = 3 #3
max_nfilters = 500 #100
max_sfilters = 20
epochs = 20
num_generations = 2 #10
genCNN = Genetic(pop_size,nlayers,max_nfilters,max_sfilters)
pop = genCNN.generate_population()
for i in range(num_generations+1):
pop_acc = genCNN.fitness(pop,X_trainRusReshaped,Y_trainRusHot,epochs)
print('Best Accuracy at the generation {}: {}'.format(i,genCNN.max_acc))
parents = genCNN.select_parents(pop,5,pop_acc.copy())
child = genCNN.crossover(parents)
child = genCNN.mutation(child)
pop = np.concatenate((parents,child),axis=0).astype('int')
Any idea where this error is coming from? I tried to increase max_filters from 100 to 500 but it does not solved anything.

problem with moving data from device to host

Hi I'm trying to create an AI inspired NEAT but I ran into a problem after performing the calculation, the data from the device can't be moved to the host.
I'm trying to use cuda.synchronize () before moving the data, but in this case the error has already occurred on this line.
I tried the cuda features before and they worked without problems until now.
I'm attaching the code with an error.
Please can you help me?
code:
import os
# needs to appear before cuda import
os.environ["NUMBA_ENABLE_CUDASIM"] = "0"
# set to "1" for more debugging, but slower performance
os.environ["NUMBA_CUDA_DEBUGINFO"] = "0"
from numba import cuda
import numpy as np
from random import uniform
from pprint import pprint
#cuda.jit(device=True)
def LeakyRelu(x):
return max(x * 0.1, x)
#cuda.jit
def Calculate(set_io, many_neurons, many_inputs, reindex_io, memory_io, weights_io, biases_io, nets_info_io, auxmemort_io):
x = cuda.grid(1)
shape = set_io.shape
if x < shape[0]:
netidx = reindex_io[x, 0]
neuidx = reindex_io[x, 1]
weiidx = reindex_io[x, 2]
result = 0
for i in range(nets_info_io[netidx, 1]):
result += memory_io[nets_info_io[netidx, 0] + i] * weights_io[weiidx + i]
result += biases_io[x]
result = LeakyRelu(result)
auxmemort_io[neuidx] = result
def CalculateSlow():
pass
class ANET:
def __init__(self, many_inputs, many_outputs, many_networks, info = True, activation_function = LeakyRelu):
self.many_inputs = many_inputs
self.many_outputs = many_outputs
self.many_networks = many_networks
self.activation_function = activation_function
self.info = info
self.netid = -1
self.cuda_many_input = cuda.to_device(self.many_inputs)
if self.info:
print("starting Setup:\n|")
device = str(cuda.get_current_device()).split("'b'")[1].split("''")[0]
print(f"| cuda run on: {device}")
print(f"| generate genomes")
self.networks_genomes = [self._GenerateGenome() for _ in range(self.many_networks)]
self._BuildPopulation()
def _CudaPre(self, block, array):
griddim = tuple(np.array(array.shape) // block + 1)
blockdim = tuple(np.full_like(griddim, block))
return griddim, blockdim
def _GenerateGenome(self):
neurons_genome = [[self.activation_function, uniform(-1,1), i + self.many_inputs] for i in range(self.many_outputs)]
synapses_genome = [[[i, ii], uniform(-1,1), True] for i in range(self.many_inputs) for ii in range(self.many_inputs, self.many_outputs + self.many_inputs)]
self.netid += 1
return [neurons_genome, synapses_genome, self.netid]
def _BuildPopulation(self):
memory_len = sum([(len(i[0]) + self.many_inputs) for i in self.networks_genomes])
memory = np.zeros(memory_len, dtype=np.float64)
auxmemory = np.copy(memory)
weights_len = sum([(len(i[1]) + self.many_inputs + 1) for i in self.networks_genomes])
weights = np.zeros(weights_len, dtype=np.float64)
biases_len = sum([len(i[0]) for i in self.networks_genomes])
biases = np.zeros(biases_len, dtype=np.float64)
nets_info = np.zeros([self.many_networks, 5], dtype=np.int64)
movmem = 0
movwei = 0
movbia = 0
for idx,i in enumerate(self.networks_genomes):
nets_info[idx] = (movmem, len(i[0]) + self.many_inputs, movwei, movbia, i[2])
movmem += len(i[0]) + self.many_inputs
movwei += len(i[1]) + self.many_inputs + 1
movbia += len(i[0])
biaidx = 0
for genome, net_info in zip(self.networks_genomes, nets_info):
for gen, biagen in zip(genome[1], genome[0]):
if gen[2]:
if gen[0][0] < self.many_inputs:
target = gen[0][0]
else:
target = genome[0][gen[0][0] - self.many_inputs - self.many_outputs][2] + self.many_inputs
weights[(gen[0][1] - self.many_inputs) * net_info[1] + net_info[2] + target] = gen[1]
biases[biaidx] = biagen[1]
biaidx += 1
reindex = np.empty([sum([(i[1] - self.many_inputs) for i in nets_info]), 3], dtype=np.int64)
write = 0
weiidx = 0
for idx,inf in enumerate(nets_info):
for i in range(inf[1] - self.many_inputs):
reindex[write][0] = idx
reindex[write][1] = inf[0] + i + self.many_inputs
reindex[write][2] = weiidx
weiidx += inf[1]
write += 1
if self.info:
print("| move arrays to device")
self.memory = memory
self.cuda_auxmemory = cuda.to_device(auxmemory)
print(self.cuda_auxmemory.copy_to_host())
self.cuda_weights = cuda.to_device(weights)
self.cuda_biases = cuda.to_device(biases)
self.nets_info = nets_info
self.cuda_nets_info = cuda.to_device(nets_info)
self.many_neurons = np.sum(nets_info, axis=0)[1]
self.cuda_many_neurons = cuda.to_device(self.many_neurons)
self.cuda_reindex = cuda.to_device(reindex)
# print(nets_info)
# print(f"{memory_len} | {weights_len} | {biases_len}")
def MathPopulation(self, inputs):
for idx, inp in enumerate(inputs):
self.memory[self.nets_info[idx][0]: self.nets_info[idx][0] + self.many_inputs] = inp
self.cuda_memory = cuda.to_device(self.memory)
setlen = cuda.to_device(np.zeros(self.many_neurons))
Calculate[self._CudaPre(32, np.empty([self.many_neurons]))](setlen, self.cuda_many_neurons, self.cuda_many_input, self.cuda_reindex, self.cuda_memory, self.cuda_weights, self.cuda_biases, self.cuda_nets_info, self.cuda_auxmemory)
# cuda.synchronize()
arr = self.cuda_auxmemory.copy_to_host()
print(arr)
if __name__ == '__main__':
anet = ANET(many_inputs = 3, many_outputs = 2, many_networks = 5)
# pprint(anet._GenerateGenome())
anet.MathPopulation([[1,2,3], [4,5,6], [7,8,9], [10,11,12], [13,14,15]])
error:
Traceback (most recent call last):
File "c:\Users\Ondra\Documents\Pythonporno\ANET\ANET.py", line 144, in <module>
anet.MathPopulation([[1,2,3], [4,5,6], [7,8,9], [10,11,12], [13,14,15]])
File "c:\Users\Ondra\Documents\Pythonporno\ANET\ANET.py", line 138, in MathPopulation
arr = self.cuda_auxmemory.copy_to_host()
File "C:\Users\Ondra\AppData\Local\Programs\Python\Python310\lib\site-packages\numba\cuda\cudadrv\devices.py", line 232, in _require_cuda_context
return fn(*args, **kws)
File "C:\Users\Ondra\AppData\Local\Programs\Python\Python310\lib\site-packages\numba\cuda\cudadrv\devicearray.py", line 277, in copy_to_host
_driver.device_to_host(hostary, self, self.alloc_size,
File "C:\Users\Ondra\AppData\Local\Programs\Python\Python310\lib\site-packages\numba\cuda\cudadrv\driver.py", line 2998, in device_to_host
fn(host_pointer(dst), device_pointer(src), size, *varargs)
File "C:\Users\Ondra\AppData\Local\Programs\Python\Python310\lib\site-packages\numba\cuda\cudadrv\driver.py", line 319, in safe_cuda_api_call
self._check_ctypes_error(fname, retcode)
File "C:\Users\Ondra\AppData\Local\Programs\Python\Python310\lib\site-packages\numba\cuda\cudadrv\driver.py", line 384, in _check_ctypes_error
raise CudaAPIError(retcode, msg)
numba.cuda.cudadrv.driver.CudaAPIError: [700] Call to cuMemcpyDtoH results in UNKNOWN_CUDA_ERROR

Problems with float overflow in backpropagation

In few trained lines, some numbers have too many digits that overflow float precision.
Im new to Machine Learning, Python (my college teacher recommended using Python) and this is my first StackOverflow question.
I googled first, ofc, but i didnt find something to help me.
This http://jrusev.github.io/post/hacking-mnist/ looks like interesting, but i cannot compare to my code because of my lack of experience. (I've always worked as Front-End)
import pandas as pd
import numpy as np
# Global variables
outputDictionary = {'0':[1,0,0,0,0,0,0,0,0,0], '1':[0,2,0,0,0,0,0,0,0,0],
'2':[0,0,1,0,0,0,0,0,0,0], '3':[0,0,0,1,0,0,0,0,0,0], '4':[0,0,0,0,1,0,0,0,0,0],
'5':[0,0,0,0,0,1,0,0,0,0], '6':[0,0,0,0,0,0,1,0,0,0], '7':[0,0,0,0,0,0,0,1,0,0],
'8':[0,0,0,0,0,0,0,0,1,0], '9':[0,0,0,0,0,0,0,0,0,1] }
learningRate = 0.2
middleLayerSize = 100
outputSize = 10
inputSize = 11
v = np.random.uniform(-1.00, 1.00,(inputSize, middleLayerSize)) # [linhas, middleLayerSize]
w = np.random.uniform(-1.00, 1.00,(middleLayerSize, outputSize)) # [middleLayerSize, outputSize]
errors = []
inputCsv = pd.read_csv('a.csv')
inputData = []
# Functions
def prepareData():
for row in inputCsv.itertuples(index=False):
arrRow = list(row)
for i in range(len(arrRow)):
if(i != 0):
arrRow[i] = float(arrRow[i]) / 255
inputData.append(arrRow)
def train(maxEpochs):
global errors
global graph
global inputData
for epoch in range(maxEpochs):
errorCount = 0
print('Period ' + str(epoch))
for row in inputData:
expectedNumber = row.pop(0)
expectedNumberObj = outputDictionary[str(expectedNumber)]
zIn = calcZIn(row)
zOutput = calcDelta(zIn, middleLayerSize)
yIn = calcYIn(zOutput)
yOutput = calcDelta(yIn, outputSize)
validate = validadeOutput(expectedNumberObj, yOutput)
if(validate == False):
errorCount+= 1;
propagateError(expectedNumberObj, row, yOutput, zOutput, zIn, yIn)
errors.append(errorCount)
print(errorCount)
def calcZIn(row):
result = []
for j in range(middleLayerSize):
result.append(0)
for i in range(inputSize):
result[j] += v[i,j] * row[i]
return result
def calcYIn(zOutput):
result = []
for j in range(outputSize):
result.append(0)
for i in range(middleLayerSize):
result[j] += w[i,j] * zOutput[i]
return result
def calcDelta(arr, arrSize):
deltas = []
for i in range(arrSize):
deltas.append(activationFunction(arr[i]))
return deltas
def activationFunction(x):
return 1.0 / (1.0 + np.exp(-x))
def validadeOutput(targetObj, yOutput):
for i in range(len(yOutput)):
if(targetObj[i] != yOutput[i]):
return False
return True
def propagateError(expectedArr, row, yOutput, zOutput, zIn, yIn):
errorY = calcError(expectedArr, yOutput, yIn, outputSize)
errorW = calcWeightCorrection(errorY, zOutput, middleLayerSize, outputSize)
sumError = sumDelta(errorY, w, middleLayerSize, outputSize)
errorZ = calcError(sumError, zOutput, zIn, middleLayerSize)
errorV = calcWeightCorrection(errorZ, row, inputSize, middleLayerSize)
updateWeight(w, errorW, middleLayerSize, outputSize)
updateWeight(v, errorV, inputSize, middleLayerSize)
def calcError(expectedArr, outputArr, inArr, size):
error = []
for i in range(size):
error.append((expectedArr[i] - outputArr[i]) * inArr[i] * (1.0 - inArr[i]));
return error
def calcWeightCorrection(error, output, lenght1, length2):
delta = [];
for i in range(lenght1):
delta.append([])
for j in range(length2):
delta[i].append(learningRate * error[j] * output[i])
return delta
def sumDelta(error, weights, lenght1, length2):
delta = []
for i in range(lenght1):
deltaValue = 0.0
for j in range(length2):
deltaValue += error[j] * weights[i][j];
delta.append(deltaValue)
return delta
def updateWeight(weight, delta, lenght1, length2):
# (lenght1)
# print(length2)
for i in range(lenght1):
for j in range(length2):
# print(str(i) + ' - ' + str(j))
weight[i][j] += delta[i][j]
# Execution
prepareData()
train(1)```

How to plot character state changes from a presence-absence matrix on to a phylogeny

I am trying to assign character state changes from a presence-absence matrix to a phylogeny.
I have tried assigning each character to its leaf node, and then if the leaf node's sister has the same character I reassign the character to the parent node (and work back until all nodes are assigned). I am using a dummy dataset to try to achieve this:
Matrix
>Dme_001
1110000000000111
>Dme_002
1110000000000011
>Cfa_001
0110000000000011
>Mms_001
0110000000000011
>Hsa_001
0110000000000010
>Ptr_002
0110000000000011
>Mmu_002
0110000000000011
>Hsa_002
0110000000000011
>Ptr_001
0110000000000011
>Mmu_001
0110000000000011
Phylogeny
((Dme_001,Dme_002),(((Cfa_001,Mms_001),((Hsa_001,Ptr_001),Mmu_001)),(Ptr_002,(Hsa_002,Mmu_002))));
I assign internal nodes using ete3, so my output should be:
BranchID CharacterState Change
Node_1: 0 0->1
Hsa_001: 15 1->0
As my code assigns character states based on their sisters if a loss is encountered it messes up the output so that:
BranchID CharacterState Change
Node_1: 0 0->1
Node_3 15 0->1
Node_5 15 0->1
Node_8 15 0->1
Could someone please help me with this? I'm coding in python and developing tunnel vision. Thanks in advance
My code:
from ete3 import PhyloTree
from collections import Counter
import itertools
PAM = open('PAM','r')
gene_tree = '((Dme_001,Dme_002),(((Cfa_001,Mms_001),((Hsa_001,Ptr_001),Mmu_001)),(Ptr_002,(Hsa_002,Mmu_002))));'
NodeIDs = []
tree = PhyloTree(gene_tree)
edge = 0
for node in tree.traverse():
if not node.is_leaf():
node.name = "Node_%d" %edge
edge +=1
NodeIDs.append(node.name)
if node.is_leaf():
NodeIDs.append(node.name)
f = open('PAM','r')
taxa = []
pap = []
for line in f:
term = line.strip().split('\t')
taxa.append(term[0])
p = [p for p in term[1]]
pap.append(p)
statesD = dict(zip(taxa, pap))
def PlotCharacterStates():
Plots = []
events = []
for key, value in statesD.iteritems():
count = -1
for s in value:
count+=1
if s == CharacterState:
a = key, count
events.append(a)
Round3_events = []
while len(events) > 0:
for rel in Relationships:
node_store = []
sis_store = []
for event in events:
if rel[0] == event[0]:
node_store.append(event[1])
if rel[1] == event[0]:
sis_store.append(event[1])
if (len(node_store) > 0) and (len(sis_store) > 0):
place = rel, node_store, sis_store
Round3_events.append(place)
moved = []
for placement in Round3_events:
intercept = (set(placement[1]) & set(placement[2]))
node_plot = (set(placement[1]) - set(placement[2]))
sis_plot = (set(placement[2]) - set(placement[1]))
if len(node_plot) > 0:
for x in node_plot:
y = placement[0][0], x
Plots.append(y)
moved.append(y)
if len(sis_plot) > 0:
for x in sis_plot:
y = placement[0][1], x
Plots.append(y)
moved.append(y)
if len(intercept) > 0:
for x in intercept:
y = placement[0][2], x
y1 = placement[0][0], x
y2 = placement[0][1], x
moved.append(y1)
moved.append(y2)
events.append(y)
for event in events:
if event[0] == "Node_0":
Plots.append(event)
moved.append(event)
events2 = (set(events) - set(moved))
events = []
for event in events2:
events.append(event)
pl = set(Plots)
Plots = []
for p in pl:
Plots.append(p)
print CharacterState, Plots
'''
assign sisters to leaves, internals
'''
e = []
round1b_e = []
round2a_e = []
placements = []
Relationships = []
Rounds = []
for node in tree.traverse():
sisters = node.get_sisters()
parent = node.up
cycle1 = []
if node.is_leaf():
for sister in sisters:
if sister.is_leaf():
round1a = ["Round1a", node.name, sister.name, parent.name]
node_names = node.name, sister.name
Rounds.append(round1a)
e.append(node_names)
x = node.name, sister.name, parent.name, "leaf-leaf"
Relationships.append(x)
if not sister.is_leaf():
round1b = ["Round1b", node.name, sister.name, parent.name]
node_names = node.name, sister.name
Rounds.append(round1b)
round1b_e.append(node_names)
x = node.name, sister.name, parent.name, "node-leaf"
Relationships.append(x)
elif not node.is_leaf():
if not node.is_root():
for sister in sisters:
if not sister.is_leaf():
node_names = node.name, sister.name
round2a_e.append(node_names)
x = node.name, sister.name, parent.name, "node-node"
Relationships.append(x)
x = []
CharacterStates = []
for key, value in statesD.iteritems():
for value in value:
x.append(value)
y = sorted(set(x))
for x in y:
CharacterStates.append(x)
for CharacterState in CharacterStates:
PlotCharacterStates()

Optimizing a complex algorithm

I know this is not an ideal place for questions of this scope, but I'm not sure where else to ask this or how to break it down. I've been working on a function for the past couple weeks, that runs, but for it to be feasible for my purposes, I need to speed it up 200-300x.
I have an image array, where all pixels of similar color have been averaged and set to that average value. Then I have a 2D array of the same height and width, which labels each unique and non-contiguous feature of the image.
Using these I need to assess the size of each feature and its level of contrast to each of its neighbors. These values are used in an equation and if the output of that equation is below a certain threshold, that feature is merged with its most similar neighbor.
I've uploaded the image and the feature label array (printed with numpy.savetext()) to OneDrive and attached links
code:
def textureRemover(pix, labeledPix, ratio = 1.0):
numElements = numpy.amax(labeledPix)
maxSize = numpy.count_nonzero(labeledPix)
MAXIMUMCONTRAST = 443.405
for regionID in range(numElements):
start = time.clock()
regionID += 1
if regionID not in labeledPix:
continue
#print(regionID)
#print((regionID / numElements) * 100, '%')
neighborIDs = getNeighbors(labeledPix, regionID)
if 0 in neighborIDs:
neighborIDs.remove(0) #remove white value
regionMask = labeledPix == regionID
region = pix[regionMask]
size = numpy.count_nonzero(regionMask)
contrastMin = (ratio - (size / maxSize)) * MAXIMUMCONTRAST
regionMean = region.mean(axis = 0)
if len(neighborIDs) > 200:
contrast = numpy.zeros(labeledPix.shape)
contrast[labeledPix!=0] = numpy.sqrt(numpy.sum((regionMean - pix[labeledPix!=0])**2, axis = -1))
significantMask = (contrast < contrastMin)
significantContrasts = list(numpy.unique(contrast[significantMask]))
significantNeighbors = {}
for significantContrast in significantContrasts:
minContrast = min(significantContrasts)
if labeledPix[contrast == minContrast][0] in neighborIDs:
significantNeighbors[minContrast] = labeledPix[contrast == minContrast][0]
else:
significantContrasts.pop(significantContrasts.index(minContrast))
else:
significantNeighbors = {}
for neighborID in neighborIDs:
neighborMask = labeledPix == neighborID
neighbor = pix[neighborMask]
neighborMean = neighbor.mean(axis = 0)
contrast = numpy.sqrt(numpy.sum((regionMean - neighborMean)**2, axis = -1))
if contrast < contrastMin:
significantNeighbors[contrast] = neighborID
if significantNeighbors:
contrasts = significantNeighbors.keys()
minContrast = min(contrasts)
minNeighbor = significantNeighbors[minContrast]
neighborMask = labeledPix == minNeighbor
neighborSize = numpy.count_nonzero(neighborMask)
if neighborSize <= size:
labeledPix[neighborMask] = regionID
pix[neighborMask] = regionMean
else:
labeledPix[regionMask] = minNeighbor
pix[regionMask] = pix[neighborMask].mean(axis = 0)
print(time.clock() - start)
return pix
pix
labeledPix
I know I'm asking for a lot of help, but I've been stuck on this for a few weeks and am unsure what else I can do. Any help will be greatly appreciated!
Here is an optimized version of most of your logic (I underestimated the amount of work that would be...). I skipped the >200 branch and am using fake data because I couldn't access your link. When I switch off your >200 branch your and my code appear to give the same result but mine is quite a bit faster on the fake example.
Sample output:
original
26.056154000000003
optimized
0.763613000000003
equal
True
Code:
import numpy as np
from numpy.lib.stride_tricks import as_strided
def mockdata(m, n, k):
colors = np.random.random((m, n, 3))
i, j = np.ogrid[:m, :n]
labels = np.round(k*k * (np.sin(0.05 * i) + np.sin(0.05 * j)**2)).astype(int) % k
return colors, labels
DIAG_NEIGHBORS = True
MAXIMUMCONTRAST = 443.405
def textureRemover2(pix, labeledPix, ratio=1.0):
start = time.clock()
pix, labeledPix = pix.copy(), labeledPix.copy()
pixf, labeledPixf = pix.reshape(-1, 3), labeledPix.ravel()
m, n = labeledPix.shape
s, t = labeledPix.strides
# find all sizes in O(n)
sizes = np.bincount(labeledPixf)
n_ids = len(sizes)
# make index for quick access to labeled areas
lblidx = np.split(np.argsort(labeledPixf), np.cumsum(sizes[:-1]))
lblidx[0] = None
# find all mean colors in O(n)
regionMeans = np.transpose([np.bincount(labeledPix.ravel(), px)
/ np.maximum(sizes, 1)
for px in pix.reshape(-1, 3).T])
# find all neighbors in O(n)
horz = set(frozenset(p) for bl in as_strided(labeledPix, (m,n-1,2), (s,t,t))
for p in bl)
vert = set(frozenset(p) for bl in as_strided(labeledPix, (m-1,n,2), (s,t,s))
for p in bl)
nb = horz|vert
if DIAG_NEIGHBORS:
dwnrgt = set(frozenset(p) for bl in as_strided(
labeledPix, (m-1,n-1,2), (s,t,s+t)) for p in bl)
dwnlft = set(frozenset(p) for bl in as_strided(
labeledPix[::-1], (m-1,n-1,2), (-s,t,t-s)) for p in bl)
nb = nb|dwnrgt|dwnlft
nb = {p for p in nb if len(p) == 2 and not 0 in p}
nb_dict = {}
for a, b in nb:
nb_dict.setdefault(a, set()).add(b)
nb_dict.setdefault(b, set()).add(a)
maxSize = labeledPix.size - sizes[0]
for id_ in range(1, n_ids):
nbs = list(nb_dict.get(id_, set()))
if not nbs:
continue
d = regionMeans[id_] - regionMeans[nbs]
d = np.einsum('ij,ij->i', d, d)
mnd = np.argmin(d)
if d[mnd] < ((ratio - sizes[id_]/maxSize) * MAXIMUMCONTRAST)**2:
mn = nbs[mnd]
lrg, sml = (id_, mn) if sizes[id_] >= sizes[mn] else (mn, id_)
sizes[lrg], sizes[sml] = sizes[lrg] + sizes[sml], 0
for nb in nb_dict[sml]:
nb_dict[nb].remove(sml)
nb_dict[nb].add(lrg)
nb_dict[lrg].update(nb_dict[sml])
nb_dict[lrg].remove(lrg)
nb_dict[sml] = set()
pixf[lblidx[sml]] = regionMeans[lrg]
labeledPixf[lblidx[sml]] = lrg
lblidx[lrg], lblidx[sml] = np.r_[lblidx[lrg],lblidx[sml]], None
print(time.clock() - start)
return pix
from scipy.ndimage.morphology import binary_dilation
import time
STRUCTEL = np.ones((3,3), int) if DIAG_NEIGHBORS else np.array([[0,1,0],[1,1,1],[0,1,0]], int)
def getNeighbors(labeledPix, regionID):
nb = set(labeledPix[binary_dilation(labeledPix == regionID, structure=STRUCTEL)])
nb.remove(regionID)
return sorted(nb)
numpy = np
def textureRemover(pix, labeledPix, ratio = 1.0):
pix, labeledPix = pix.copy(), labeledPix.copy()
numElements = numpy.amax(labeledPix)
maxSize = numpy.count_nonzero(labeledPix)
MAXIMUMCONTRAST = 443.405
start = time.clock()
for regionID in range(numElements):
regionID += 1
if regionID not in labeledPix:
continue
#print(regionID)
#print((regionID / numElements) * 100, '%')
neighborIDs = getNeighbors(labeledPix, regionID)
if 0 in neighborIDs:
neighborIDs.remove(0) #remove white value
regionMask = labeledPix == regionID
region = pix[regionMask]
size = numpy.count_nonzero(regionMask)
contrastMin = (ratio - (size / maxSize)) * MAXIMUMCONTRAST
regionMean = region.mean(axis = 0)
if len(neighborIDs) > 20000:
contrast = numpy.zeros(labeledPix.shape)
contrast[labeledPix!=0] = numpy.sqrt(numpy.sum((regionMean - pix[labeledPix!=0])**2, axis = -1))
significantMask = (contrast < contrastMin)
significantContrasts = list(numpy.unique(contrast[significantMask]))
significantNeighbors = {}
for significantContrast in significantContrasts:
minContrast = min(significantContrasts)
if labeledPix[contrast == minContrast][0] in neighborIDs:
significantNeighbors[minContrast] = labeledPix[contrast == minContrast][0]
else:
significantContrasts.pop(significantContrasts.index(minContrast))
else:
significantNeighbors = {}
for neighborID in neighborIDs:
neighborMask = labeledPix == neighborID
neighbor = pix[neighborMask]
neighborMean = neighbor.mean(axis = 0)
contrast = numpy.sqrt(numpy.sum((regionMean - neighborMean)**2, axis = -1))
if contrast < contrastMin:
significantNeighbors[contrast] = neighborID
if significantNeighbors:
contrasts = significantNeighbors.keys()
minContrast = min(contrasts)
minNeighbor = significantNeighbors[minContrast]
neighborMask = labeledPix == minNeighbor
neighborSize = numpy.count_nonzero(neighborMask)
if neighborSize <= size:
labeledPix[neighborMask] = regionID
pix[neighborMask] = regionMean
else:
labeledPix[regionMask] = minNeighbor
pix[regionMask] = pix[neighborMask].mean(axis = 0)
print(time.clock() - start)
return pix
data = mockdata(200, 200, 1000)
print('original')
res0 = textureRemover(*data)
print('optimized')
res2 = textureRemover2(*data)
print('equal')
print(np.allclose(res0, res2))

Categories