crysx_nn
A simplistic and efficient pure-python neural network library from Phys Whiz with CPU and GPU support.
Explore the docs »
View Demo · Report Bug · Request Feature
Table of Contents
About The Project
Neural networks are an integral part of machine learning. The project provides an easy-to-use, yet efficient implementation that can be used in your projects or for teaching/learning purposes.
The library is written in pure-python with some optimizations using numpy, opt_einsum, and numba when using CPU and cupy for CUDA support.
The goal was to create a framework that is efficient yet easy to understand, so that everyone can see and learn about what goes inside a neural network. After all, the project did spawn from a semester project on CP_IV: Machine Learning course at the University of Jena, Germany.
Built With
- Cupy (Optional)
- NumPy (Required)
- numba (Required)
- opt_einsum (Required)
- matplotlib (Required)
- nnv (Required)
Getting Started
To get a local copy up and running follow these simple example steps.
Prerequisites
You need to have python3
installed along with pip
.
Installation
There are many ways to install crysx_nn
- Install the release (stable) version from PyPi
pip install crysx_nn
- Install the latest development version, by cloning the git repo and installing it. This requires you to have
git
installed.git clone https://github.com/manassharma07/crysx_nn.git cd crysx_nn pip install .
- Install the latest development version without
git
.pip install --upgrade https://github.com/manassharma07/crysx_nn/tarball/main
Check if the installation was successful by running python shell and trying to import the package
python3
Python 3.7.11 (default, Jul 27 2021, 07:03:16)
[Clang 10.0.0 ] :: Anaconda, Inc. on darwin
Type "help", "copyright", "credits" or "license" for more information.
>>> import crysx_nn
>>> crysx_nn.__version__
'0.1.0'
>>>
Finally download the example script (here) for simulating logic gates like AND, XOR, NAND, and OR, and try running it
python Simluating_logic_gates.py
Usage
The most important thing for using this library properly is to use 2D NumPy arrays for defining the inputs and exoected outputs (targets) for a network. 1D arrays for inputs and targets are not supported and will result in an error.
For example, let us try to simulate the logic gate AND. The AND gate takes two input bits and returns a single input bit. The bits can take a value of either 0 or 1. The AND gate returns 1 only if both the inputs are 1, otherwise it returns 0.
The truth table of the AND gate is as follows
x1 | x2 | output |
---|---|---|
0 | 0 | 0 |
0 | 1 | 0 |
1 | 0 | 0 |
1 | 1 | 1 |
The four possible set of inputs are
inputs = np.array([[0.,0.,1.,1.],[0.,1.,0.,1.]]).T.astype('float32')
print(inputs)
print(inputs.dtype)
Output:
[[0. 0.]
[0. 1.]
[1. 0.]
[1. 1.]]
float32
Similarly, set the corresponding four possible outputs as a 2D numpy array
# AND outputs
outputAND = np.array([0.,0.,0.,1.]) # 1D array
outputAND = np.asarray([outputAND]).T # 2D array
print('AND outputs\n', outputAND)
Output:
AND outputs
[[0.]
[0.]
[0.]
[1.]]
Next, we need to set some parameters of our Neural network
nInputs = 2 # No. of nodes in the input layer
neurons_per_layer = [3,1] # Neurons per layer (excluding the input layer)
activation_func_names = ['Sigmoid', 'Sigmoid']
nLayers = len(neurons_per_layer)
eeta = 0.5 # Learning rate
nEpochs=10**4 # For stochastic gradient descent
batchSize = 4 # No. of input samples to process at a time for optimization
For a better understanding, let us visualize it.
visualize(nInputs, neurons_per_layer, activation_func_names)
Now let us initialize the weights and biases. Weights and biases are provided as lists of 2D and 1D NumPy arrays, respectively (1 Numpy array for each layer). In our case, we have 2 layers (1 hidden+ 1 output), therefore, the list of Weights and Biases will have 2 NumPy arrays each.
# Initial guesses for weights
w1 = 0.30
w2 = 0.55
w3 = 0.20
w4 = 0.45
w5 = 0.50
w6 = 0.35
w7 = 0.15
w8 = 0.40
w9 = 0.25
# Initial guesses for biases
b1 = 0.60
b2 = 0.05
# need to use a list instead of a numpy array, since the
#weight matrices at each layer are not of the same dimensions
weights = []
# Weights for layer 1 --> 2
weights.append(np.array([[w1,w4],[w2, w5], [w3, w6]]))
# Weights for layer 2 --> 3
weights.append(np.array([[w7, w8, w9]]))
# List of biases at each layer
biases = []
biases.append(np.array([b1,b1,b1]))
biases.append(np.array([b2]))
weightsOriginal = weights
biasesOriginal = biases
print('Weights matrices: ',weights)
print('Biases: ',biases)
Output:
Weights matrices: [array([[0.3 , 0.45],
[0.55, 0.5 ],
[0.2 , 0.35]]), array([[0.15, 0.4 , 0.25]])]
Biases: [array([0.6, 0.6, 0.6]), array([0.05])]
Finally it is time to train our neural network. We will use mean squared error (MSE) loss function as the metric of performance. Currently, only stochastic gradient descent is supported.
# Run optimization
optWeights, optBiases, errorPlot = nn_optimize_fast(inputs, outputAND, activation_func_names, nLayers, nEpochs=nEpochs, batchSize=batchSize, eeta=eeta, weights=weightsOriginal, biases=biasesOriginal, errorFunc=MSE_loss, gradErrorFunc=MSE_loss_grad,miniterEpoch=1,batchProgressBar=False,miniterBatch=100)
The function nn_optimize_fast
returns the optimized weights and biases, as well as the error at each epoch of the optimization.
We can then plot the training loss at each epoch
# Plot the error vs epochs
plt.plot(errorPlot)
plt.yscale('log')
plt.show()
Output: For more examples, please refer to the Examples Section
CrysX-NN (crysx_nn) also provides CUDA support by using cupy versions of all the features ike activation functions, loss functions, neural network calculations, etc. Note: For small networks the Cupy versions may actually be slower than CPU versions. But the benefit becomes evident as you go beyond 1.5 Million parameters.
Features
- Efficient implementations of activation functions and their gradients
- Sigmoid, Sigmoid_grad
- ReLU, ReLU_grad
- Softmax, Softmax_grad
- Softplus, Sofplus_grad
- Tanh, Tanh_grad
- Tanh_offset, Tanh_offset_grad
- Identity, Identity_grad
- Efficient implementations of loss functions and their gradients
- Mean squared error
- Binary cross entropy
- Neural network optimization using
- Stochastic Gradient Descent
- Support for batched inputs, i.e., supplying a matrix of inputs where the collumns correspond to features and rows to the samples
- Support for GPU through Cupy
pip install cupy-cuda102
(Tested with CUDA 10.2) - JIT compiled functions when possible for efficiency
Roadmap
- Weights and biases initialization
- More activation functions
- Identity, LeakyReLU, Tanh, etc.
- More loss functions
- categorical cross entropy, and others
- Optimization algorithms apart from Stochastic Gradient Descent, like ADAM, RMSprop, etc.
- Implement regularizers
- Batch normalization
- Dropout
- Early stopping
- A
predict
function that returns the output of the last layer and the loss/accuracy - Some metric functions, although there is no harm in using
sklearn
for that
See the open issues for a full list of proposed features (and known issues).
Contributing
Contributions are what make the open source community such an amazing place to learn, inspire, and create. Any contributions you make are greatly appreciated.
If you have a suggestion that would make this better, please fork the repo and create a pull request. You can also simply open an issue with the tag "enhancement". Don't forget to give the project a star! Thanks again!
- Fork the Project
- Create your Feature Branch (
git checkout -b feature/AmazingFeature
) - Commit your Changes (
git commit -m 'Add some AmazingFeature'
) - Push to the Branch (
git push origin feature/AmazingFeature
) - Open a Pull Request
License
Distributed under the MIT License. See LICENSE.txt
for more information.
Contact
Manas Sharma - @manassharma07 - [email protected]
Project Link: https://github.com/manassharma07/crysx_nn
Project Documentation: https://bragitoff.com
Blog: https://bragitoff.com
Acknowledgments
- Lecture notes by Prof. Dr. Bernd Bürgmann
- Neural Networks and Deep Learning by Michael Nielsen
- A high-bias, low-variance introduction to Machine Learning for physicists by Mehta et al., 2019
- Deep Learning by Goodfellow et al., 2016
Citation
If you use this library and would like to cite it, you can use:
M. Sharma, "CrysX-NN: Neural Network libray", 2021. [Online]. Available: https://github.com/manassharma07/crysx_nn. [Accessed: DD- Month- 20YY].
or:
@Misc{,
author = {Manas Sharma},
title = {CrysX-NN: Neural Network libray},
month = december,
year = {2021},
note = {Online; accessed
},
url = {https://github.com/manassharma07/crysx_nn},
}