def train(self, x_train: np.ndarray, y_train: np.ndarray, num_epochs=10, verbose=True): """ Train a `Network` using the data provided for a given number of epochs. An epoch correspond to a full-pass on the data-set for a training. :param x_train: the inputs to use to train :param y_train: the labels to use to train :param num_epochs: the number of epochs for the training :param verbose: if true, logs progress :return: the same `Network` but trained one more time """ self._prepropagation_check(x_train, y_train) def printv(t): not verbose or print(t) # If the dataset only consists of one example, it is represented as a vector # If it is the case, we change it to be a matrix so that the processing is the same if len(x_train.shape) == 1: x_train = x_train[:, np.newaxis] y_train = y_train[:, np.newaxis] n_sample = x_train.shape[1] printv(f"Training the network for the {self._times_trained+1} time") for n_epoch in range(1, num_epochs + 1): printv(f"| Epoch {n_epoch} / {num_epochs}") accuracy, cost = 0., 0. for n_b, batch_indices in enumerate(self._batcher(self.batch_size, n_sample)): x_batch = x_train[:, batch_indices] y_batch = y_train[:, batch_indices] y_hat = self._forward_propagation(x_batch) y_pred = one_hot(y_hat.argmax(axis=0)) accuracy = np.mean(1 * (y_pred == y_batch)) cost = self._output_layer.cost(y_hat, y_batch) assert y_hat.shape[0] == self._output_layer.size assert y_batch.shape[0] == self._output_layer.size self._back_propagation(y_batch) self._optimize() self.logger.log_cost_accuracy(n_epoch, cost, accuracy) self._times_trained += 1 return self
def test(self, x_test: np.ndarray, y_test: np.ndarray, warn=True): """ Test a `Network` using the data provided for a given number of epochs. An epoch correspond to a full-pass on the data-set for a training. :param x_test: the inputs used to test :param y_test: the labels used to test :param warn: if true, warn in case of a `Network` not having been trained. :return: the predictions, the outputs and associated accuracy """ self._prepropagation_check(x_test, y_test) if warn and self._times_trained == 0: warnings.warn( "The network has not been trained yet: results will be fuzzy!") # If the dataset only consists of one example, it is represented as a vector # If it is the case, we change it to be a matrix so that the processing is the same if len(x_test.shape) == 1: x_test = x_test[:, np.newaxis] y_test = y_test[:, np.newaxis] n_sample = x_test.shape[1] # Outputs of the networks y_hat = y_test * 0 for batch_indices in self._batcher(self.batch_size, n_sample): x_batch = x_test[:, batch_indices] # Here, we don't persist the results calculate during the forward # propagation because results are persisted uniquely for training y_hat[:, batch_indices] = self._forward_propagation(x_batch, persist=False) # Doing an hard max on the output to find the prediction y_pred = one_hot(y_hat.argmax(axis=0), num_classes=self._output_layer.size) accuracy = np.mean(1 * (y_pred == y_test)) return y_pred, y_hat, accuracy
def benchmark(self, x_train: np.ndarray, y_train: np.ndarray, x_test: np.ndarray, y_test: np.ndarray, num_epochs=10, verbose=True, csv_file_name=None, learning_rate=0.01, momentum=0.9, warn=True): """ Benchmark a network. This consist of training a network with dataset (x_train,_train) from scratch and testing it at each iteration with dataset (x_test, y_test) An iteration correspond to the processing of a mini-batch. This routine can be slow has testing is done at each iteration. A `BenchmarkLogger` is updated with the logs of the benchmark and can be then used to plot the results. :param x_train: the inputs to use for the training :param y_train: the labels to use for the training :param x_test: the inputs to use for the training :param y_test: the labels to use for the training :param num_epochs: the number of epochs to perform :param verbose: if true, logs progress :param csv_file_name: the csv file to use to persist the log :param learning_rate: parameter for the optimisation routine :param momentum: parameter to add momentum to gradients :param warn: if true, warns about the network being already trained :return: a `BenchmarkLogger` containing logs of the benchmark """ self._prepropagation_check(x_train, y_train) def printv(t): not verbose or print(t) if warn and self._times_trained > 0: warnings.warn( "The network has already been trained: results might not be representative for the benchmark" ) # If the dataset only consists of one example, it is represented as a vector # If it is the case, we change it to be a matrix so that the processing is the same if len(x_train.shape) == 1: x_train = x_train[:, np.newaxis] y_train = y_train[:, np.newaxis] n_sample = x_train.shape[1] printv(f"Training the network for the {self._times_trained+1} time") logger = BenchmarkLogger(csv_file_name=csv_file_name) for n_epoch in range(1, num_epochs + 1): printv(f"| Epoch {n_epoch} / {num_epochs}") train_cost, test_cost, train_acc, test_acc = 0, 0, 0, 0 for n_b, batch_indices in enumerate( self._batcher(self.batch_size, n_sample)): x_batch = x_train[:, batch_indices] y_batch = y_train[:, batch_indices] y_hat = self._forward_propagation(x_batch) y_pred = one_hot(y_hat.argmax(axis=0)) train_acc = np.mean(1 * (y_pred == y_batch)) train_cost = self._output_layer.cost(y_hat, y_batch) assert y_hat.shape[0] == self._output_layer.size assert y_batch.shape[0] == self._output_layer.size self._back_propagation(y_batch) self._optimize(learning_rate=learning_rate, momentum=momentum) y_pred_test, y_hat_test, test_acc = self.test(x_test, y_test, warn=False) test_cost = self._output_layer.cost(y_hat_test, y_test) logger.benchmark_log(train_cost=train_cost, train_acc=train_acc, test_cost=test_cost, test_acc=test_acc) print("Training Cost:", train_cost) print("Testing Cost:", test_cost) print("Training Accuracy:", train_acc) print("Testing Accuracy:", test_acc) return logger
x_train = x_train.T x_test = x_test.T # Conversion to integers y_train = y_train.astype(int) y_test = y_test.astype(int) return x_train, y_train, x_test, y_test if __name__ == "__main__": # Loading data data_folder = "../data" # set your own value x_train, y_train, x_test, y_test = load_sets(data_folder) y_train = one_hot(y_train) y_test = one_hot(y_test) # Defining the network network = Network(input_size=14, name="14-100-40-4 Arch") network.stack(Layer(size=100, activation_function=ReLu())) network.stack(Layer(size=40, activation_function=ReLu())) network.output(SoftMaxCrossEntropyOutputLayer(size=4)) # Printing information print(network) # Defining a log file current_datetime = strftime("%Y-%m-%d-%H:%M:%S", gmtime())