jacobian

Unnamed repository; edit this file 'description' to name the repository.
Log | Files | Refs | README

commit 0e501e7d0e142ae992cb5d0b7576f06f25e7d673
parent ecc13627b7bc17e1c378d6055615a198dbc242d0
Author: David Freifeld <freifeld.david@gmail.com>
Date:   Thu, 30 Jul 2020 21:49:22 -0700

Tweaks + readme update

Diffstat:
Mreadme.md | 25++++++++++---------------
Msrc/cnn.cpp | 16+++++++++-------
Mtests/simd_simple.cpp | 12++++++------
3 files changed, 25 insertions(+), 28 deletions(-)

diff --git a/readme.md b/readme.md @@ -63,21 +63,16 @@ Finally, train your network for one epoch with `train()`. Training one epoch at ### Examples In the `/scripts` directory there is a example of a neural network being used in conjuction with Weights & Biases, allowing for effective hyperparameter searches and accuracy reporting. -## Compiling/Installing - -### Precompiled Libraries -**Coming soon:**: Precompiled pyc files and binaries in 'Releases' section for you if you don't want to build from source. - -### Python Bindings - -1. Install both the C++ end of pybind11 and the python end. -2. Build with your chosen configuration using `make`. -3. Copy the `mrbpnn.cpython-37m-darwin.so` file into your personal project directory. -4. Import `mrbpnn` from your Python code and use it. -5. Look to the `example.py` file for simple usage of the library. - -**Coming soon:** A guide on how to properly install Jacobian as a python library. -**Coming soon:** Availability through package managers or a less convoluted install process. +## Installing + +### Main Steps +Note: This is all ideally the process, but it's so confusing that I'm not sure. You're better off manually copying the .so file! +1. Install the C++ library Eigen. +2. Install the C++ and python ends of the pybind11 library. +3. Run `make` with the configuration of your choosing. +4. Run `python setup.py bdist_wheel` +5. `cd` into `dist` and run `python3 -m pip install --upgrade Jacobian-1.0-cp37-cp37m-macosx_10_13_x86_64.whl` +6. Be unhappy when it doesn't work out and resort to just copying .so files. ### Build Configurations (Building from Source) diff --git a/src/cnn.cpp b/src/cnn.cpp @@ -8,6 +8,8 @@ #include "bpnn.hpp" #include "utils.hpp" +#include <Eigen/unsupported/CXX11/Tensor> + #define LARGE_NUM 1000000 // Remove me. #if (!RECKLESS) @@ -250,13 +252,13 @@ void ConvNet::process() // Assumes pooling is immediately after any conv layer. for (int i = 0; i < preprocess_length-1; i++) { conv_layers[i].convolute(); - pool_layers[i].input = conv_layers[i].output; - pool_layers[i].pool(); + // pool_layers[i].input = conv_layers[i].output; + // pool_layers[i].pool(); conv_layers[i+1].input = conv_layers[i].output; } conv_layers[preprocess_length-1].convolute(); - pool_layers[preprocess_length-1].input = conv_layers[preprocess_length-1].output; - pool_layers[preprocess_length-1].pool(); + //pool_layers[preprocess_length-1].input = conv_layers[preprocess_length-1].output; + //pool_layers[preprocess_length-1].pool(); // std::cout << "Output:\n" << *pool_layers[preprocess_length-1].output << "\n\n"; Eigen::Map<Eigen::RowVectorXf> flattened (conv_layers[preprocess_length-1].output->data(), conv_layers[preprocess_length-1].output->size()); // std::cout << "Flattened:\n" << flattened << "\n\n"; @@ -379,10 +381,10 @@ int main() ConvNet net ("../data_banknote_authentication.txt", 0.05, 0.01, 5, 0.9); Eigen::MatrixXf labels (1,1); net.add_conv_layer(28,28,1,9,9,0); - net.add_pool_layer(20,20,1,6,6,0); + // net.add_pool_layer(20,20,1,6,6,0); net.add_conv_layer(15,15,1,6,6,0); - net.add_pool_layer(10,10,1,2,2,0); - net.add_layer(81, "sigmoid"); + //net.add_pool_layer(10,10,1,2,2,0); + net.add_layer(400, "sigmoid"); net.add_layer(5, "lecun_tanh"); net.add_layer(10, "resig"); // net.list_net(); diff --git a/tests/simd_simple.cpp b/tests/simd_simple.cpp @@ -13,23 +13,23 @@ int main() Eigen::MatrixXf a = Eigen::MatrixXf::Random(1, sz); Eigen::MatrixXf::Index maxRow, maxCol; float max = a.maxCoeff(&maxRow, &maxCol); - Eigen::MatrixXf m1 = ((a.array() - max) / ((a.array() - max).exp().sum())).matrix(); + Eigen::MatrixXf m1 = ((a.array() - max).exp() / ((a.array() - max).exp().sum())).matrix(); auto softmax_simd_start = std::chrono::high_resolution_clock::now(); Eigen::MatrixXf a1 = (1 + (-1 * a.array()).exp()).pow(-1).matrix(); auto softmax_simd_end = std::chrono::high_resolution_clock::now(); auto softmax_start = std::chrono::high_resolution_clock::now(); - float sum = 0; + // float sum = 0; Eigen::MatrixXf::Index maxRow2, maxCol2; float max2 = a.maxCoeff(&maxRow2, &maxCol2); Eigen::MatrixXf m2 = (a.array() - max2).matrix(); - for (int j = 0; j < m2.cols(); j++) { - sum += exp(m2(0,j)); - } + // for (int j = 0; j < m2.cols(); j++) { + // sum += exp(m2(0,j)); + // } + float sum = ((a.array() - max2).exp().sum()); for (int j = 0; j < m2.cols(); j++) { m2(0,j) = exp(m2(0,j))/sum; } auto softmax_end = std::chrono::high_resolution_clock::now(); - std::cout << m1 << " | " << m1.sum() << "\n\n" << m2 << " | " << m2.sum() << "\n\n"; if (m1.isApprox(m2)) std::cout << "Softmax matrices are equal!\n\n"; double eigen_time = std::chrono::duration_cast<std::chrono::nanoseconds>(softmax_simd_end - softmax_simd_start).count();