class NeuralNetworkManager: def __init__(self): self.type = None self.nn = MLP() self.training_method = None self.hidden_activation_function = None self.output_activation_function = None self.dropout_rate = 0.0 self.training = True self.learning_rate = 0.1 self.fitness_threshold = 0.75 self.epoch_threshold = -1 self.batch_size = 100 self.shuffle_rate = 2500 self.display_step = 1000 self.epoch = 0 self.layers = [] self.data_set = None self.bed = BinaryEncoderDecoder() self.utils = Utilities() self.controller = StaticController() self.debug_mode = False # Plotting variables self.losses = [] self.fitnesses = [] self.iterations = [] self.save_location = './nn/log/' self.encode = None self.non_det = False # Getters and setters def getType(self): return self.type def getTrainingMethod(self): return self.training_method def getActivationFunctionHidden(self): return self.hidden_activation_function def getActivationFunctionOutput(self): return self.output_activation_function def getLearningRate(self): return self.learning_rate def getFitnessThreshold(self): return self.fitness_threshold def getBatchSize(self): return self.batch_size def getDisplayStep(self): return self.display_step def getEpoch(self): return self.epoch def getEpochThreshold(self): return self.epoch_threshold def getDropoutRate(self): return self.dropout_rate def getShuffleRate(self): return self.shuffle_rate def getSaveLocation(self): return self.save_location def setType(self, value): self.type = value def setTrainingMethod(self, optimizer): self.training_method = optimizer def setActivationFunctionHidden(self, activation_function): self.hidden_activation_function = activation_function def setActivationFunctionOutput(self, activation_function): self.output_activation_function = activation_function def setLearningRate(self, value): self.learning_rate = value def setFitnessThreshold(self, value): self.fitness_threshold = value def setBatchSize(self, value): self.batch_size = value def setDisplayStep(self, value): self.display_step = value def setEpochThreshold(self, value): self.epoch_threshold = value def setDropoutRate(self, value): self.dropout_rate = value def setShuffleRate(self, value): self.shuffle_rate = value def setSaveLocation(self, value): self.save_location = value def setDebugMode(self, value): self.debug_mode = value def setDataSet(self, data_set): self.data_set = data_set def setEncodeTypes(self, value): self.encode = value # Hidden layer generation functions # Linearly increase/decrease neurons per hidden layer based on the input and ouput neurons def linearHiddenLayers(self, num_hidden_layers): self.layers = [] x_dim = self.data_set.getXDim() y_dim = self.data_set.getYDim() a = (y_dim - x_dim)/(num_hidden_layers + 1) self.layers.append(x_dim) for i in range(1, num_hidden_layers + 1): self.layers.append(round(x_dim + a*i)) self.layers.append(y_dim) return self.layers # Rectangular hidden layer def rectangularHiddenLayers(self, width, height): self.layers = [] self.layers.append(self.data_set.getXDim()) for i in range(width): self.layers.append(height) self.layers.append(self.data_set.getYDim()) #Customize layer sturcture def customHiddenLayers(self, layer): self.layers = [] x_dim = self.data_set.getXDim() y_dim = self.data_set.getYDim() self.layers.append(x_dim) for i in range(1, len(layer)+1): self.layers.append(layer[i-1]) self.layers.append(y_dim) return self.layers # Initialize neural network def initializeNeuralNetwork(self): if(self.debug_mode): print("\nNeural network initialization:") if(self.type == NNTypes.MLP): self.nn = MLP() self.nn.setDebugMode(self.debug_mode) if(self.debug_mode): print("Neural network type: MLP") # Initialize network and loss function self.nn.setNeurons(self.layers) self.nn.setDropoutRate(self.dropout_rate) self.nn.setActivationFunctionHidden(self.hidden_activation_function) self.nn.setActivationFunctionOutput(self.output_activation_function) self.nn.setTaskTypes(self.encode) self.nn.initializeNetwork() # Print neural network status if(self.debug_mode): print("Generated network neuron topology: " + str(self.layers) + " with dropout rate: " + str(self.nn.getDropoutRate())) # Initialize training function def initializeTraining(self, learning_rate, fitness_threshold, batch_size, display_step, epoch_threshold = -1, shuffle_rate = 10000): self.learning_rate = learning_rate self.fitness_threshold = fitness_threshold self.batch_size = batch_size self.display_step = display_step self.epoch_threshold = epoch_threshold self.shuffle_rate = shuffle_rate self.nn.initializeLossFunction() self.nn.initializeTrainFunction(self.training_method, self.learning_rate) # Initialize fitness function def initializeFitnessFunction(self): with tf.name_scope("fitness"): eta = self.data_set.getYEta() size = self.data_set.getSize() lower_bound = tf.subtract(self.nn.y, eta) upper_bound = tf.add(self.nn.y, eta) is_fit = tf.logical_and(tf.greater_equal(self.nn.predictor, lower_bound), tf.less(self.nn.predictor, upper_bound)) non_zero = tf.to_float(tf.count_nonzero(tf.reduce_min(tf.cast(is_fit, tf.int8), 1))) self.fitness = non_zero/size tf.summary.scalar("fitness", self.fitness) # General initialization function to call all functions def initialize(self, learning_rate, fitness_threshold, batch_size, display_step, epoch_threshold = -1, shuffle_rate = 10000): self.initializeNeuralNetwork() self.initializeFitnessFunction() self.initializeTraining(learning_rate, fitness_threshold, batch_size, display_step, epoch_threshold, shuffle_rate) self.train_writer = tf.summary.FileWriter(self.save_location, self.nn.session.graph) # Check a state against the dataset and nn by using its id in the dataset def checkByIndex(self, index, out): x = self.data_set.x[index] estimation = self.nn.estimate([x])[0] y = self.data_set.getY(index) y_eta = self.data_set.getYEta() equal = True for i in range(self.data_set.getYDim()): if(not((y[i] - y_eta[i]) <= estimation[i] and (y[i] + y_eta[i]) > estimation[i])): equal = False if(out): print("u: " + str(y) + " u_: " + str(np.round(estimation,2)) + " within etas: " + str(equal)) return equal # Check fitness of the neural network for a specific dataset and return wrong states # as of right now it assumes a binary encoding of the dataset def checkFitness(self, data_set): self.data_set = data_set size = self.data_set.getSize() fit = size wrong = [] x, y = self.data_set.x, self.data_set.y y_eta = self.data_set.getYEta() y_dim = self.data_set.getYDim() estimation = self.nn.estimate(self.data_set.x) for i in range(size): equal = True for j in range(y_dim): if(not((y[i][j] - y_eta[j]) <= estimation[i][j] and (y[i][j] + y_eta[j]) > estimation[i][j]) and equal): wrong.append(self.bed.baton(x[i])) fit -= 1 equal = False fitness = fit/size*100 return fitness, wrong # Check fitness of the neural network for a specific dataset and return wrong states # as of right now it assumes a binary encoding of the dataset def checkFitnessAllGridPoint(self, data_set): print("\nCalculating fitness and storing wrong states") self.data_set = data_set size = self.data_set.getSize() fit = size wrong = [] x, y = self.data_set.x, self.data_set.y y_eta = self.data_set.getYEta() y_dim = self.data_set.getYDim() estimation = self.nn.estimate(self.data_set.x) # for binary labels = np.array(y) # predictions = np.array(np.round(estimation)) # invalid_flag = (labels[:,-1] == 0) if(not self.non_det): # check the control input prediction and invalid flag based on controller type (D or ND) if(self.controller.con_det): predictions = np.array(np.round(estimation)) # array of boolean with output flag equal to invalid control invalid_flag = (labels[:,-1] == 0) # check the control input prediction same_inputs = (predictions[:,:-1] == labels[:,:-1]).all(axis = 1) # check if the prediction and true output is equal same_flag = (predictions[:,-1] == labels[:,-1]) else: predictions = np.array(estimation) invalid_flag = (labels[:,-1] == 1) predictions_soft = np.zeros_like(predictions) predictions_soft[np.arange(len(predictions)), predictions.argmax(1)] = 1 same_inputs = (labels[np.arange(len(labels)), predictions_soft.argmax(1)]) # check if the prediction flag and true output flag is equal car_u = self.controller.input_total_gp flag_one = np.logical_and(np.argmax(predictions_soft, 1) == (car_u), labels[:,-1] == 1) flag_zero = np.logical_and(np.argmax(predictions_soft, 1) != (car_u), labels[:,-1] == 0) same_flag = np.logical_or(flag_one, flag_zero) # same_flag = (predictions[:,-1] == labels[:,-1]) early_check = np.logical_and(invalid_flag, same_flag) # if it is same flag and same input, we have the performance here same_all = np.logical_and(same_flag, same_inputs) # we need to or to compensate incorrect prediction but does not matter because it is not winning domain logic_all = np.logical_or(early_check, same_all) # average the value to get fitness in the range of [0,1] fitness = (np.mean(logic_all)) # valid inputs but wrong prediction wrong_idx = np.where(np.logical_and((logic_all == 0), np.logical_not(invalid_flag))) else: predictions = np.array(np.round(estimation)) fitness = (np.mean(predictions == labels)) wrong_idx = np.where((np.logical_not(predictions == labels)).any(axis=1)) # get the index of wrong states states = np.array(self.data_set.x) if(self.data_set.encode == EncodeTypes.Classification): wrong = np.squeeze(states[wrong_idx]) elif(self.data_set.encode == EncodeTypes.Boolean): if(self.data_set.order == Ordering.Original): wrong = states[wrong_idx] wrong_temp = list(map(self.bed.baton, wrong)) wrong_x = list(map(self.controller.stox, wrong_temp)) wrong = [] for i in range(len(wrong_x)): wrong.append([wrong_temp[i], wrong_x[i]]) else: ss_dim = int(self.controller.state_space_dim) wrong_states = states[wrong_idx] if(wrong_states.size == 0): return fitness, wrong # len_one_dim = int(len(wrong_states[0])/ss_dim) bit_dim = self.controller.bit_dim temp = [] for i in range(ss_dim): # bin_i = wrong_states[:,i*len_one_dim:(i+1)*len_one_dim] bin_i = wrong_states[:,i*bit_dim[i]:(i+1)*bit_dim[i]] array_i_add_dim = np.array(list(map(self.bed.baton, bin_i)))[:,None] temp.append(array_i_add_dim) wrong_temp = temp[0] for i in range(ss_dim-1): wrong_temp = np.concatenate((wrong_temp, temp[i+1]), axis = 1) wrong_x = list(map(self.controller.sstox, wrong_temp)) wrong_s = list(map(self.controller.sstos, wrong_temp)) wrong = [] for i in range(len(wrong_s)): wrong.append([wrong_s[i], wrong_x[i]]) return fitness, wrong # Fitness modification for including as wel the non-winning domain to the NN # the last bit as the valid flag change the calculation quite a lot def allGridPointFitness(self, data_set): self.data_set = data_set size = self.data_set.getSize() fit = size wrong = [] x, y = self.data_set.x, self.data_set.y y_eta = self.data_set.getYEta() y_dim = self.data_set.getYDim() estimation = self.nn.estimate(self.data_set.x) # calculate the fitness by using np array to optimize computation labels = np.array(y) # predictions = np.array(np.round(estimation)) if(not self.non_det): # check the control input prediction and invalid flag based on controller type (D or ND) if(self.controller.con_det): # print('deterministic') predictions = np.array(np.round(estimation)) # array of boolean with output flag equal to invalid control invalid_flag = (labels[:,-1] == 0) # check the control input prediction same_inputs = (predictions[:,:-1] == labels[:,:-1]).all(axis = 1) # check if the prediction flag and true output flag is equal same_flag = (predictions[:,-1] == labels[:,-1]) else: # print('determinizing') predictions = np.array(estimation) invalid_flag = (labels[:,-1] == 1) predictions_soft = np.zeros_like(predictions) predictions_soft[np.arange(len(predictions)), predictions.argmax(1)] = 1 same_inputs = (labels[np.arange(len(labels)), predictions_soft.argmax(1)]) # check if the prediction flag and true output flag is equal car_u = self.controller.input_total_gp # print(car_u) # check the correctness of the output prediction # both for invalid and valid label flag_one = np.logical_and(np.argmax(predictions_soft, 1) == (car_u), labels[:,-1] == 1) flag_zero = np.logical_and(np.argmax(predictions_soft, 1) != (car_u), labels[:,-1] == 0) same_flag = np.logical_or(flag_one, flag_zero) # print(np.mean(same_flag)) # if it is invalid and it predicted right we have a flag that we do not have to check the rest of the bit early_check = np.logical_and(invalid_flag, same_flag) # if it is the same flag and same input, we have the performance here same_all = np.logical_and(same_flag, same_inputs) # we need to or to compensate incorrect prediction but does not matter because it is not winning domain logic_all = np.logical_or(early_check, same_all) # average the value to get fitness in the range of [0,1] fitness = (np.mean(logic_all)) else: # print('non-deterministic') predictions = np.array(np.round(estimation)) fitness = (np.mean(predictions == labels)) # print(labels[:10]) # print(predictions[:10]) return fitness # Fitness modification for including as wel the non-winning domain to the NN # the last bit as the valid flag change the calculation quite a lot def allGridPointFitnessDeterminizing(self, data_set): self.data_set = data_set size = self.data_set.getSize() fit = size wrong = [] x, y = self.data_set.x, self.data_set.y y_eta = self.data_set.getYEta() y_dim = self.data_set.getYDim() estimation = self.nn.estimate(self.data_set.x) # calculate the fitness by using np array to optimize computation labels = np.array(y) predictions = np.array(np.round(estimation)) # array of boolean with output flag equal to invalid control invalid_flag = (labels[:,-1] == 1) # check if the prediction and true output is equal same_flag = (predictions[:,-1] == labels[:,-1]) # if it is invalid and it predicted right we have a flag that we do not have to check the rest of the bit early_check = np.logical_and(invalid_flag, same_flag) # TO DO branch condition regression and classification # check the control input prediction # same_inputs = (predictions[:,:-1] == labels[:,:-1]).all(axis = 1) predictions_soft = np.zeros_like(predictions) predictions_soft[np.arange(len(predictions)), predictions.argmax(1)] = 1 same_inputs = (labels[np.arange(len(labels)), predictions_soft.argmax(1)]) # if it is same flag and same input, we have the performance here same_all = np.logical_and(same_flag, same_inputs) # we need to or to compensate incorrect prediction but does not matter because it is not winning domain logic_all = np.logical_or(early_check, same_all) # average the value to get fitness in the range of [0,1] fitness = (np.mean(logic_all)) return fitness # Randomly check neural network against a dataset def randomCheck(self, data_set): self.data_set = data_set self.initializeFitnessFunction() print("\nValidating:") for i in range(10): r = round(random.random()*(self.data_set.getSize()-1)) self.checkByIndex(r, True) # Train network def train(self): self.clear() print("\nTraining (Ctrl+C to interrupt):") signal.signal(signal.SIGINT, self.interrupt) i, batch_index, loss, fit = 0,0,0,0.0 old_epoch = 0 stagnan = False self.merged_summary = tf.summary.merge_all() start_time = time.time() while self.training: batch = self.data_set.getBatch(self.batch_size, batch_index) loss, summary = self.nn.trainStep(batch, self.merged_summary) # if(i % self.shuffle_rate == 0 and i != 0): self.data_set.shuffle() # if(fit > 0.999): # fit = self.allGridPointFitness(self.data_set) # self.batch_size = 4096 # if(i % self.display_step == 0 and i != 0): if((self.epoch % self.display_step == 0) and (old_epoch != self.epoch)): old_epoch = self.epoch # fit = self.nn.runInSession(self.fitness, self.data_set.x, self.data_set.y, 1.0) fit = self.allGridPointFitness(self.data_set) # self.addToLog(loss, fit, i) self.addToLog(loss, fit, self.epoch) print("i = " + str(i) + "\tepoch = " + str(self.epoch) + "\tloss = " + str(float("{0:.4f}".format(loss))) + "\tfit = " + str(float("{0:.4f}".format(fit)))) self.train_writer.add_summary(summary, i) if(self.epoch >= self.epoch_threshold and self.epoch_threshold > 0): print("i = " + str(i) + "\tepoch = " + str(self.epoch) + "\tloss = " + str(float("{0:.4f}".format(loss))) + "\tfit = " + str(float("{0:.4f}".format(fit)))) print("Finished training, epoch threshold reached") break if(fit >= self.fitness_threshold): print("Finished training") break if (len(self.fitnesses) > 40) and stagnan == False: if((self.fitnesses[-1] - 0.001) <= self.fitnesses[-40]): print("Finished training, fitness did not improve after "+str(40*self.display_step)+" epoch") stagnan = True if(math.isnan(loss)): print("i = " + str(i) + "\tepoch = " + str(self.epoch) + "\tloss = " + str(float("{0:.3f}".format(loss))) + "\tfit = " + str(float("{0:.3f}".format(fit)))) print("Finished training, solution did not converge") break batch_index += self.batch_size if(batch_index >= self.data_set.getSize()): batch_index = batch_index % self.data_set.getSize() self.data_set.shuffle() self.epoch += 1 i += 1 end_time = time.time() print("Time taken: " + self.utils.formatTime(end_time - start_time)) # Interrupt handler to interrupt the training while in progress def interrupt(self, signal, frame): self.training = False # Plotting loss and fitness functions def plot(self): plt.figure(1) plt.plot(self.iterations, self.losses, 'bo') plt.xlabel("Iterations") plt.ylabel("Loss") plt.grid() x1,x2,y1,y2 = plt.axis() plt.axis((x1,x2,0,y2+0.1)) plt.figure(2) plt.plot(self.iterations, self.fitnesses, 'r-') plt.xlabel("Iterations") plt.ylabel("Fitness") plt.grid() x1,x2,y1,y2 = plt.axis() plt.axis((x1,x2,0,1)) plt.show() # Add to log def addToLog(self, loss, fit, iteration): self.losses.append(loss) self.fitnesses.append(fit) self.iterations.append(iteration) # Get projected data size def getDataSize(self): size = self.nn.calculateDataSize() print("Minimal neural network size of: " + self.utils.formatBytes(size)) return size # Clear variables def clear(self): self.epoch = 0 self.training = True self.fitnesses = [] self.iterations = [] self.losses = [] # Save network def save(self, filename): print("\nSaving neural network") self.nn.save(filename) # Close session def close(self): self.nn.close() self.train_writer.close() # create loosing points to be plotted on matlab def createLoosingPoints(self, wrong_states): print("\nStoring loosing states for matlab simulation") # print("\nLoop", self.controller.state_total_gp) # for i in range(self.controller.state_total_gp): #if i not in self.controller.states or i in wrong: # if i not in self.controller.states: # loosing_states.append(i) total = set(range(self.controller.state_total_gp)) winning = set(self.controller.states) loosing_states = total - winning # print(len(total), len(winning), len(loosing_states)) # print("\nConvert to x") loosing_states_x = list(map(self.controller.stox, loosing_states)) return loosing_states_x
class NeuralNetworkManager: def __init__(self): self.type = None self.nn = MLP() self.training_method = None self.activation_function = None self.dropout_rate = 0.0 self.training = True self.learning_rate = 0.1 self.fitness_threshold = 0.75 self.epoch_threshold = -1 self.batch_size = 100 self.shuffle_rate = 2500 self.display_step = 1000 self.epoch = 0 self.layers = [] self.data_set = None self.bed = BinaryEncoderDecoder() self.utils = Utilities() self.debug_mode = False # Plotting variables self.losses = [] self.fitnesses = [] self.iterations = [] self.save_location = './nn/log/' # Getters and setters def getType(self): return self.type def getTrainingMethod(self): return self.training_method def getActivationFunction(self): return self.activation_function def getLearningRate(self): return self.learning_rate def getFitnessThreshold(self): return self.fitness_threshold def getBatchSize(self): return self.batch_size def getDisplayStep(self): return self.display_step def getEpoch(self): return self.epoch def getEpochThreshold(self): return self.epoch_threshold def getDropoutRate(self): return self.dropout_rate def getShuffleRate(self): return self.shuffle_rate def getSaveLocation(self): return self.save_location def setType(self, type): self.type = type def setTrainingMethod(self, optimizer): self.training_method = optimizer def setActivationFunction(self, activation_function): self.activation_function = activation_function def setLearningRate(self, value): self.learning_rate = value def setFitnessThreshold(self, value): self.fitness_threshold = value def setBatchSize(self, value): self.batch_size = value def setDisplayStep(self, value): self.display_step = value def setEpochThreshold(self, value): self.epoch_threshold = value def setDropoutRate(self, value): self.dropout_rate = value def setShuffleRate(self, value): self.shuffle_rate = value def setSaveLocation(self, value): self.save_location = value def setDebugMode(self, value): self.debug_mode = value def setDataSet(self, data_set): self.data_set = data_set # Hidden layer generation functions # Linearly increase/decrease neurons per hidden layer based on the input and ouput neurons def linearHiddenLayers(self, num_hidden_layers): self.layers = [] x_dim = self.data_set.getXDim() y_dim = self.data_set.getYDim() a = (y_dim - x_dim) / (num_hidden_layers + 1) self.layers.append(x_dim) for i in range(1, num_hidden_layers + 1): self.layers.append(round(x_dim + a * i)) self.layers.append(y_dim) return self.layers # Rectangular hidden layer def rectangularHiddenLayers(self, width, height): self.layers = [] self.layers.append(self.data_set.getXDim()) for i in range(width): self.layers.append(height) self.layers.append(self.data_set.getYDim()) #Customize layer sturcture def customHiddenLayers(self, layer): self.layers = [] x_dim = self.data_set.getXDim() y_dim = self.data_set.getYDim() self.layers.append(x_dim) for i in range(1, len(layer) + 1): self.layers.append(layer[i - 1]) self.layers.append(y_dim) return self.layers # Initialize neural network def initializeNeuralNetwork(self): if (self.debug_mode): print("\nNeural network initialization:") if (self.type == NNTypes.MLP): self.nn = MLP() self.nn.setDebugMode(self.debug_mode) if (self.debug_mode): print("Neural network type: MLP") # Initialize network and loss function self.nn.setNeurons(self.layers) self.nn.setDropoutRate(self.dropout_rate) self.nn.setActivationFunction(self.activation_function) self.nn.initializeNetwork() # Print neural network status if (self.debug_mode): print("Generated network neuron topology: " + str(self.layers) + " with dropout rate: " + str(self.nn.getDropoutRate())) # Initialize training function def initializeTraining(self, learning_rate, fitness_threshold, batch_size, display_step, epoch_threshold=-1, shuffle_rate=10000): self.learning_rate = learning_rate self.fitness_threshold = fitness_threshold self.batch_size = batch_size self.display_step = display_step self.epoch_threshold = epoch_threshold self.shuffle_rate = shuffle_rate self.nn.initializeLossFunction() self.nn.initializeTrainFunction(self.training_method, self.learning_rate) # Initialize fitness function def initializeFitnessFunction(self): with tf.name_scope("fitness"): eta = self.data_set.getYEta() size = self.data_set.getSize() lower_bound = tf.subtract(self.nn.y, eta) upper_bound = tf.add(self.nn.y, eta) is_fit = tf.logical_and( tf.greater_equal(self.nn.predictor, lower_bound), tf.less(self.nn.predictor, upper_bound)) non_zero = tf.to_float( tf.count_nonzero(tf.reduce_min(tf.cast(is_fit, tf.int8), 1))) self.fitness = non_zero / size tf.summary.scalar("fitness", self.fitness) # General initialization function to call all functions def initialize(self, learning_rate, fitness_threshold, batch_size, display_step, epoch_threshold=-1, shuffle_rate=10000): self.initializeNeuralNetwork() self.initializeFitnessFunction() self.initializeTraining(learning_rate, fitness_threshold, batch_size, display_step, epoch_threshold, shuffle_rate) self.train_writer = tf.summary.FileWriter(self.save_location, self.nn.session.graph) # Check a state against the dataset and nn by using its id in the dataset def checkByIndex(self, index, out): x = self.data_set.x[index] estimation = self.nn.estimate([x])[0] y = self.data_set.getY(index) y_eta = self.data_set.getYEta() equal = True for i in range(self.data_set.getYDim()): if (not ((y[i] - y_eta[i]) <= estimation[i] and (y[i] + y_eta[i]) > estimation[i])): equal = False if (out): print("u: " + str(y) + " u_: " + str(numpy.round(estimation, 2)) + " within etas: " + str(equal)) return equal # Check fitness of the neural network for a specific dataset and return wrong states # as of right now it assumes a binary encoding of the dataset def checkFitness(self, data_set): self.data_set = data_set size = self.data_set.getSize() fit = size wrong = [] x, y = self.data_set.x, self.data_set.y y_eta = self.data_set.getYEta() y_dim = self.data_set.getYDim() estimation = self.nn.estimate(self.data_set.x) for i in range(size): equal = True for j in range(y_dim): if (not ((y[i][j] - y_eta[j]) <= estimation[i][j] and (y[i][j] + y_eta[j]) > estimation[i][j]) and equal): wrong.append(self.bed.baton(x[i])) fit -= 1 equal = False fitness = fit / size * 100 print("\nDataset fitness: " + str(float("{0:.3f}".format(fitness))) + "%") return fitness, wrong # Randomly check neural network against a dataset def randomCheck(self, data_set): self.data_set = data_set self.initializeFitnessFunction() print("\nValidating:") for i in range(10): r = round(random.random() * (self.data_set.getSize() - 1)) self.checkByIndex(r, True) # Train network def train(self): self.clear() print("\nTraining (Ctrl+C to interrupt):") signal.signal(signal.SIGINT, self.interrupt) i, batch_index, loss, fit = 0, 0, 0, 0.0 self.merged_summary = tf.summary.merge_all() start_time = time.time() while self.training: batch = self.data_set.getBatch(self.batch_size, batch_index) loss, summary = self.nn.trainStep(batch, self.merged_summary) if (i % self.shuffle_rate == 0 and i != 0): self.data_set.shuffle() if (i % self.display_step == 0 and i != 0): fit = self.nn.runInSession(self.fitness, self.data_set.x, self.data_set.y, 1.0) self.addToLog(loss, fit, i) print("i = " + str(i) + "\tepoch = " + str(self.epoch) + "\tloss = " + str(float("{0:.3f}".format(loss))) + "\tfit = " + str(float("{0:.3f}".format(fit)))) self.train_writer.add_summary(summary, i) if (self.epoch >= self.epoch_threshold and self.epoch_threshold > 0): print("i = " + str(i) + "\tepoch = " + str(self.epoch) + "\tloss = " + str(float("{0:.3f}".format(loss))) + "\tfit = " + str(float("{0:.3f}".format(fit)))) print("Finished training, epoch threshold reached") break if (fit >= self.fitness_threshold): print("Finished training") break if (math.isnan(loss)): print("i = " + str(i) + "\tepoch = " + str(self.epoch) + "\tloss = " + str(float("{0:.3f}".format(loss))) + "\tfit = " + str(float("{0:.3f}".format(fit)))) print("Finished training, solution did not converge") break batch_index += self.batch_size if (batch_index >= self.data_set.getSize()): batch_index = batch_index % self.data_set.getSize() self.epoch += 1 i += 1 end_time = time.time() print("Time taken: " + self.utils.formatTime(end_time - start_time)) # Interrupt handler to interrupt the training while in progress def interrupt(self, signal, frame): self.training = False # Plotting loss and fitness functions def plot(self): plt.figure(1) plt.plot(self.iterations, self.losses, 'bo') plt.xlabel("Iterations") plt.ylabel("Loss") plt.grid() x1, x2, y1, y2 = plt.axis() plt.axis((x1, x2, 0, y2 + 0.1)) plt.figure(2) plt.plot(self.iterations, self.fitnesses, 'r-') plt.xlabel("Iterations") plt.ylabel("Fitness") plt.grid() x1, x2, y1, y2 = plt.axis() plt.axis((x1, x2, 0, 1)) plt.show() # Add to log def addToLog(self, loss, fit, iteration): self.losses.append(loss) self.fitnesses.append(fit) self.iterations.append(iteration) # Get projected data size def getDataSize(self): size = self.nn.calculateDataSize() print("Minimal neural network size of: " + self.utils.formatBytes(size)) return size # Clear variables def clear(self): self.epoch = 0 self.training = True self.fitnesses = [] self.iterations = [] self.losses = [] # Save network def save(self, filename): print("\nSaving neural network") self.nn.save(filename) # Close session def close(self): self.nn.close() self.train_writer.close()