Résumé

PySicLib Neural Net


Testing SicLib's Neural Network

PySicLib is the Python interface to SicLib, my experimental C++ scientific computing library. This demo trains SicLib's small neural network alongside an equivalent NumPy implementation. Both models start with the same weights, process the same MNIST samples, and should remain synchronized if the C++ operations are correct.

Source Code

The source code is on GitHub.

SicLib Documentation & Installation

See the SicLib documentation and installation notes.


import pysiclib as psl import numpy as np import matplotlib.pyplot as plt %matplotlib inline #open our test and train datasets train_data = None with open("mnist_train_5000.csv", "r") as f: train_data = f.readlines() test_data = None with open("mnist_test_2000.csv", "r") as f: test_data = f.readlines()
#quick look at what the inputs look like as an image demo_value = train_data[0].split(',') img_arr = np.asfarray(demo_value[1:]).reshape((28,28)) plt.imshow(img_arr, cmap='Greys', interpolation='None')

#net params input_nodes = 784 hidden_nodes = 100 hidden_layers = 1 output_nodes = 10 learning_rate = 0.1 #initialize pysiclib neural net implementation using random weights pysiclib_net = psl.adaptive.ProtoNet( input_nodes, hidden_nodes, hidden_layers, output_nodes, learning_rate) #initialize numpy neural net implementation using the same weights from pysiclib numpy_net = psl.adaptive.ProtoNet_Numpy( input_nodes, hidden_nodes, hidden_layers, output_nodes, learning_rate, pysiclib_net)
#training loop num_train_epochs = len(train_data) for record in train_data[:num_train_epochs]: all_values = record.split(',') scaled_input_raw = (np.asfarray(all_values[1:])/255.0 * 0.99) + 0.01 scaled_input = psl.linalg.Tensor(scaled_input_raw).transpose() scaled_target_raw = np.zeros(output_nodes) + 0.01 scaled_target_raw[int(all_values[0])] = 0.99 scaled_target = psl.linalg.Tensor(scaled_target_raw).transpose() pysiclib_net.run_epoch(scaled_input, scaled_target) numpy_net.run_epoch(scaled_input_raw, scaled_target_raw)
#test loop num_test_epochs = len(test_data) score = [] nscore = [] for record in test_data[:num_test_epochs]: all_values = record.split(',') scaled_input_raw = (np.asfarray(all_values[1:])/255.0 * 0.99) + 0.01 scaled_input = psl.linalg.Tensor(scaled_input_raw).transpose() correct_label = int(all_values[0]) query_res = pysiclib_net.query_net(scaled_input) numpy_query = numpy_net.query_net(scaled_input_raw) label = np.argmax(query_res.to_numpy()) numpy_label = np.argmax(numpy_query) if label == correct_label: score.append(1) else: score.append(0) if numpy_label == correct_label: nscore.append(1) else: nscore.append(0)
#calulate performance correct_perc = sum(score) / len(score) * 100 np_correct_perc = sum(nscore) / len(nscore) * 100 print("pysiclib net score:\n------") print("{}%".format(round(correct_perc, 2))) print("numpy net score:\n------") print("{}%".format(round(np_correct_perc, 2))) print("\n")

Results

pysiclib net score: ------ 89.305% numpy net score: ------ 89.305%

Result

Both implementations reached 89.305% accuracy and kept their weights synchronized throughout training. Matching results do not prove the entire library correct, but they provide a useful end-to-end check of the tensor and neural network operations used in this example.