{"id":21644611,"url":"https://github.com/armaggheddon/plainnn.cpp","last_synced_at":"2025-03-19T11:07:23.798Z","repository":{"id":253459620,"uuid":"841944852","full_name":"Armaggheddon/PlainNN.cpp","owner":"Armaggheddon","description":"PlainNN 🧠⚙️ – A lightweight, extensible C++ library with no external dependencies for building and training neural networks. Supports dense layers, and easily expandable with custom layers, data loaders, and activations. Optimized for performance and flexibility. 🚀","archived":false,"fork":false,"pushed_at":"2024-09-23T19:25:33.000Z","size":15156,"stargazers_count":0,"open_issues_count":0,"forks_count":0,"subscribers_count":1,"default_branch":"main","last_synced_at":"2025-03-19T11:07:15.966Z","etag":null,"topics":["backpropagation","cpp","neural-network"],"latest_commit_sha":null,"homepage":"","language":"C++","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/Armaggheddon.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2024-08-13T11:07:34.000Z","updated_at":"2024-09-23T19:25:36.000Z","dependencies_parsed_at":"2024-09-06T00:54:41.253Z","dependency_job_id":"336f80a4-245e-4d27-9a45-4a8607b609cf","html_url":"https://github.com/Armaggheddon/PlainNN.cpp","commit_stats":null,"previous_names":["armaggheddon/mnist.cpp","armaggheddon/plainnn.cpp"],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Armaggheddon%2FPlainNN.cpp","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Armaggheddon%2FPlainNN.cpp/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Armaggheddon%2FPlainNN.cpp/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Armaggheddon%2FPlainNN.cpp/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/Armaggheddon","download_url":"https://codeload.github.com/Armaggheddon/PlainNN.cpp/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":244413461,"owners_count":20448710,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["backpropagation","cpp","neural-network"],"created_at":"2024-11-25T05:41:28.563Z","updated_at":"2025-03-19T11:07:23.772Z","avatar_url":"https://github.com/Armaggheddon.png","language":"C++","funding_links":[],"categories":[],"sub_categories":[],"readme":"\u003cdiv id=\"top\"\u003e\u003c/div\u003e\n\u003cbr/\u003e\n\u003cbr/\u003e\n\n\u003cp align=\"center\"\u003e\n  \u003cimg src=\"./docs/images/plain_nn_logo.png\" width=\"150\" height=\"150\"\u003e\n\u003c/p\u003e\n\n\u003ch1 align=center\u003e\n    \u003ca href=\"https://github.com/Armaggheddon/PlainNN.cpp\"\u003ePlainNN.cpp\u003c/a\u003e\n\u003c/h1\u003e\n\n\u003cp align=\"center\"\u003e\n\u003ca href=\"https://github.com/Armaggheddon/PlainNN.cpp/commits/main\"\u003e\n\u003cimg src=\"https://img.shields.io/github/last-commit/Armaggheddon/PlainNN.cpp\"\u003e\n\u003c/a\u003e\n\u003ca href=\"https://github.com/Armaggheddon/PlainNN.cpp\"\u003e\n\u003cimg src=\"https://img.shields.io/badge/Maintained-yes-green.svg\"/\u003e\n\u003c/a\u003e\n\u003ca href=\"https://github.com/Armaggheddon/PlainNN.cpp/issues\"\u003e\n\u003cimg alt=\"GitHub Issues or Pull Requests\" src=\"https://img.shields.io/github/issues/Armaggheddon/PlainNN.cpp\"\u003e\n\u003c/a\u003e\n\u003ca href=\"https://github.com/Armaggheddon/PlainNN.cpp/blob/main/LICENSE\"\u003e\n\u003cimg alt=\"GitHub License\" src=\"https://img.shields.io/github/license/Armaggheddon/PlainNN.cpp\"/\u003e\n\u003c/a\u003e\n\u003c!--\u003ca href=\"https://github.com/Armaggheddon/PlainNN.cpp\"\u003e\n\u003cimg src=\"https://img.shields.io/badge/Maintained%3F-no-red.svg\"\u003e\n\u003c/a\u003e --\u003e\n\u003ca href=\"https://colab.research.google.com/github/Armaggheddon/PlainNN.cpp/blob/main/live_demo/PlainNN_live_demo_colab.ipynb\"\u003e\n\u003cimg src=\"https://colab.research.google.com/assets/colab-badge.svg\" alt=\"Open In Colab\"/\u003e\n\u003c/a\u003e\n\u003c/p\u003e\n\n\u003cp align=\"center\"\u003e\n    Neural Networks in plain C++!🎉\n\u003c/p\u003e\n\n##\nWelcome to **PlainNN.cpp**, the lightweight C++ library for building, training, and evaluating neural networks—all without the need for any external libraries! 🚀 This project is designed to be super simple, fully customizable, and perfect for anyone who loves to code deep learning from scratch.\n\n## 💡 Project Motivation\nThe journey of **PlainNN.cpp** began with a simple goal: to deeply understand how the **backpropagation algorithm** works. 🚀 Initially, I created a static network implementation to tackle the **MNIST dataset**. However, as I dug deeper, the project evolved into the flexible PlainNN library we have today! 🌟\n\nThis evolution allows for custom layers, activation functions, and more—making it a powerful tool for anyone looking to explore the fascinating world of neural networks! 🧠✨\n\n## 🌟 Features at a Glance\n- 💡 **Dense Layer:** Fully connected layers right out of the box!\n- ⚡ **Activation Functions:** ReLU, Sigmoid, and Softmax included!\n- 📦 **MNIST/Fashion Dataloader:** Ready to load and train on classic datasets.\n- 🔌 **Extensibility:** Easily create your own custom layers, activation functions, and dataloaders.\n- 🚫 **No External Dependencies:** 100% plain C++—no need for extra libraries!\n- 🌍 **Live Demo:** Explore a live demo through your browser!\n\n## 🗂️ Folder Breakdown\n\n- `data/`:\u003cbr\u003e\n    Contains all the essentials, including the MNIST dataset, the saved model, and some helpful utilities to convert PyTorch weights into a format that’s compatible with this library. Perfect for when you want to load pre-trained models or use custom weights! 🧠\n\n- `docs/`:\u003cbr\u003e\n    Documentation for the nitty-gritty details (if you're into that 😎) and behind-the-scenes magic for the README. 😉\n\n- `examples/`:\u003cbr\u003e\n    Looking to get started quickly? This folder has got you covered with a couple of useful examples to help you understand how to work with PlainNN.cpp. Dive in and start building! 🔧\n\n- `live_demo/`:\u003cbr\u003e\n    Want to see the neural network in action? Head over here for the Colab live demo code. You can run the demo in your browser, draw some digits, and watch the model guess them! 🎨🖥️\n    \u003ca href=\"https://colab.research.google.com/github/Armaggheddon/PlainNN.cpp/blob/main/live_demo/PlainNN_live_demo_colab.ipynb\"\u003e\u003cimg src=\"https://colab.research.google.com/assets/colab-badge.svg\" alt=\"Open In Colab\"/\u003e\u003c/a\u003e\n\n- `plain_nn/`:\u003cbr\u003e\n    This is the heart of the library, containing all the actual neural network code. If you want to dig into how things work under the hood, this is the place to explore! 💡\n\n- `test/`:\u003cbr\u003e\n    This folder contains some tests for the image_utils wrapper around stb_image and stb_image_write. It's all about making sure the image handling is working smoothly! 🖼️✅\n\n## 🚀 Getting Started\n### 💻 Prerequisites\n- A C++11 compatible compiler (g++ or clang++ will do the trick 🛠️).\n\n### 📦 Clone the Repository\n1. **Clone the Repo:**\u003cbr\u003e\n    First, clone the repository from GitHub:\n    ```bash\n    git clone https://github.com/Armaggheddon/PlainNN.cpp\n    ```\n1. **Navigate to the Project directory:**\u003cbr\u003e\n    Move into the project folder:\n    ```bash\n    cd PlainNN.cpp\n    ```\n\n### ⚙️ Compilation Steps\n1. **Create a build directory:**\u003cbr\u003e\n    Start by creating a `build` directory to keep everything organized:\n    ```bash\n    mkdir -p build\n    ```\n1. **Navigate to the Build Directory:**\u003cbr\u003e\n    Switch to the `build` directory:\n    ```bash\n    cd build\n    ```\n1. **Generate Build Files with CMake:**\u003cbr\u003e\n    Use **CMake** to generate the build files. 🌟 If you're looking for speed, enable optimizations for a performance boost! Just keep in mind that while the code will run much faster, the compilation time will be a bit longer. ⏳💨\u003cbr\u003e\n    - For a standard build:\u003cbr\u003e\n        ```bash\n        cmake ..\n        ```\n    - For a build with optimizations enabled:\u003cbr\u003e\n        ```bash\n        cmake -DCMAKE_BUILD_TYPE=Release ..\n        ```\n1. **Compile the Code:**\u003cbr\u003e\n    Finally, compile the project using `make`:\n    ```bash\n    make\n    ```\n\nAfter these steps, your PlainNN.cpp library will be compiled and ready to use in the `build` folder as `libplain_nn.so`! 🎉\n\n### 🏃‍♂️ Usage\nOnce compiled, dive into the `examples/` folder to see how PlainNN.cpp works. Here's a sneak peek:\n```cpp\n#include \"plain_nn.h\"\n#include \u003ciostream\u003e\n\n// Set up your neural network here and watch it learn 🤖\nint main() {\n    // Initialization, forward pass, backpropagation...\n    PlainNN model;\n    model.add_layer(new Input({784}));\n    model.add_layer(new Dense(128, new ReLU()));\n    model.add_layer(new Dense(10, new Sigmoid()));\n\n    std::vector\u003cdouble\u003e input(784, 0.0);\n    Tensor t({784}, input);\n    Tensor result = model.forward(t);\n\n    for(int i=0; i\u003cresult.size(); i++){\n        std::printf(\"Label %d -\u003e %.1f\\n\", i, result[i]);\n    }\n}\n```\n\n### 🌐 Running the Live Demo \nCurious to see PlainNN in action? 🎉 You can either head to the `live_demo/` folder and follow the instructions to fire up a neural network right in your browser, or check out our shared **Colab notebook** for an easy, interactive experience! 🖥️✨ It’s like magic—draw a digit, and watch the model predict it in real-time! Don’t miss out on the fun! 🎨🤖\n\u003ca href=\"https://colab.research.google.com/github/Armaggheddon/PlainNN.cpp/blob/main/live_demo/PlainNN_live_demo_colab.ipynb\"\u003e\n  \u003cimg src=\"https://colab.research.google.com/assets/colab-badge.svg\" alt=\"Open In Colab\"/\u003e\n\u003c/a\u003e\n\n\u003cp align=\"center\"\u003e\n  \u003cimg src=\"./docs/images/live_demo_image.png\" width=\"740\" height=\"468\"\u003e\n\u003c/p\u003e\n\n## 🛠️ Extending PlainNN\nFeeling creative? You can:\n\n- 🧱 **Add New Layers:** Simply extend the `Layer` class and create something cool!\n- 🔧 **Custom Activation Functions:** Roll your own activation functions by implementing the `ActivationFn` interface.\n- 📊 **Custom Dataloaders:** Need a new dataset? Add your own `DataLoader` and explore fresh data!\n\n\nCheck out the `examples/` folder for some inspiration on how to extend the library. Let your imagination run wild! 🧠\n\n\n## 📊 Understanding the MNIST Dataset\nThe **MNIST dataset** is a classic benchmark in the field of machine learning, consisting of 70,000 handwritten digits (0-9). Each image is a grayscale 28x28 pixel square, making it perfect for training neural networks. The challenge is to correctly classify these digits based on the pixel values.\n\n### Mathematical Approach\nTo tackle this classification problem, we employ the backpropagation algorithm, which is key to training our neural network. Here’s a brief overview:\n\n1. **Forward Pass:** The input image is fed through the network, generating an output vector that represents the predicted probabilities for each digit.\n- **Loss Calculation:** We use a loss function, like cross-entropy, to quantify the difference between the predicted probabilities and the actual labels.\n- **Backward Pass:** Using the chain rule, we calculate gradients for each weight in the network. This involves:\n    - Calculating the derivative of the loss with respect to each weight.\n    - Updating the weights in the opposite direction of the gradient to minimize the loss.\n\n\nBy repeating this process over multiple epochs, the model learns to improve its predictions! 📈\n\n### Useful links\n- [How the backpropagation algorithm works](http://neuralnetworksanddeeplearning.com/chap2.html)\n\n\n## 🏆 Sample Output from Training\nAfter training our model on the MNIST dataset, you might see an output similar to the following:\n```\n___________________________________________________________\nLayer        (Type)       Output Shape            Param #\n===========================================================\ninput        (Input)      (784)                         0\ndense        (Dense)      (128)                    100480\ndense_1      (Dense)      (10)                       1290\n===========================================================\nTotal params: 101770 (795.08 KB)\nTrainable params: 101770 (795.08 KB)\nNon-trainable params: 0 (0.00 B)\n___________________________________________________________\nEpoch 1/10\n    937/937 [====================]    9s  10ms/step - Error: 0.1462 - Accuracy: 0.8594\nEpoch 2/10\n    937/937 [====================]    9s   9ms/step - Error: 0.0985 - Accuracy: 0.9062\nEpoch 3/10\n    937/937 [====================]    9s  10ms/step - Error: 0.0697 - Accuracy: 0.8750\nEpoch 4/10\n    937/937 [====================]    9s   9ms/step - Error: 0.0530 - Accuracy: 0.9375\nEpoch 5/10\n    937/937 [====================]    9s   9ms/step - Error: 0.0803 - Accuracy: 0.9375\nEpoch 6/10\n    937/937 [====================]    9s   9ms/step - Error: 0.0654 - Accuracy: 0.9688\nEpoch 7/10\n    937/937 [====================]    9s  10ms/step - Error: 0.0719 - Accuracy: 0.9219\nEpoch 8/10\n    937/937 [====================]    9s   9ms/step - Error: 0.0822 - Accuracy: 0.9062\nEpoch 9/10\n    937/937 [====================]    9s  11ms/step - Error: 0.0385 - Accuracy: 0.9844\nEpoch 10/10\n    937/937 [====================]    9s   9ms/step - Error: 0.0485 - Accuracy: 0.9531\n10000/10000 [====================] Loss: 0.0626 - Accuracy: 0.9313 -    1s elapsed - 127us/step\nCorrect: 9313/10000\n```\n\nThis output shows the progress of the model over epochs, with decreasing loss and increasing accuracy, reflecting its improved ability to classify handwritten digits! 🎉\n\n\u003e [!NOTE] \n\u003e The weights and model architechture for epoch 6 are saved in `data/model_save/trained_model.json` and `.weights` files respectively\n\n## ⚠️ Challenges with the MNIST Dataset\nWhile the MNIST dataset is a fantastic starting point, there are some challenges that can arise during the live demo:\n\n- **Misclassification of Certain Digits:** The model may struggle with digits like '4' and '9' due to their similar structures. This can lead to confusion during classification. 🔄\n- **Inconsistency:** Variations in how different people write digits can introduce inconsistencies. For example, a '1' might be drawn in a way that closely resembles a '7', causing the model to misclassify. ✍️❓\n- **Noise and Distortion:** If users draw too lightly or add extra strokes, the model might misinterpret the digit, leading to unexpected predictions.\n\n\nDespite these challenges, the MNIST dataset is extremely important. It provides a simplified yet powerful benchmark for neural networks, helping us test models in controlled environments. However, it's crucial that datasets represent real-world scenarios as closely as possible to ensure models generalize well beyond the lab! 🌍🔬\n\n## 📚 Libraries Used\n**PlainNN.cpp** is built with pure C++, but a few handy libraries helped make the project more efficient:\n\n- [`json.h`](https://github.com/sheredom/json.h/tree/master): Used for parsing JSON files, keeping our configuration management clean and simple. 📝🔧\n- [`stb_image.h` **\u0026** `stb_image_write.h`](https://github.com/nothings/stb/tree/master): Handle reading and writing image files. 🖼️📥\n\n## 🤝 Contributing\nWe’d love to see your contributions! Found a bug? Have a feature idea? Open an issue or submit a pull request. Let’s build something awesome together! 💪\n\n## 📄 License\nThis project is licensed under the MIT License, so feel free to use it, modify it, and share it. 🎉\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Farmaggheddon%2Fplainnn.cpp","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Farmaggheddon%2Fplainnn.cpp","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Farmaggheddon%2Fplainnn.cpp/lists"}