This project is still a work in progress, many things will be subject to change in the near future.
This repository hosts a library for constructing, training, evaluating, and managing feed-forward neural network models, all implemented in C. This project leverages graph theory and adjacency matrices to represent the network's structure, providing a more "theoretical" perspective on neural network design.
The project allows for minimal dependency compilation, as well as data types defined at compile time. See below for details.
- Model Construction: Define neural networks as graphs using nodes and weighted edges, represented through adjacency matrices.
- Training Module: Implement training routines to adjust weights and optimize network performance.
- Inference Engine: Compute outputs from the network trough a given prompt.
- Memory Management: Create and delete models to maintain optimal resource usage.
- Demonstrative Example: Train the network to compute the square root of an integer (provided in binary form), showcasing a practical application of the library.
The primary goal of this project is to deepen understanding of feed-forward neural networks by building one from the ground up. Detailed design decisions, implementation insights, and theoretical underpinnings are documented in Documentation.odt.
The tests I've done during the development are integrated within the Tests folder, where edge cases and incorrect inputs are validated, ensuring the reliability of the library.
This project uses a Makefile. Ensure you have GNU Make and GCC installed on your system. Follow the steps below:
-
Clone the Repository
git clone <repository_url> cd <repository_directory>
-
Compile the Project
Use the
makecommand to compile the source files and generate the executable:make
This will produce the executable named
main.a.out. -
Additional Makefile Commands
-
Clean Build Artifacts
To remove the compiled object files and the executable, use:
make clean
-
-
Adding New Source or Header Files
If you add new
.cor.hfiles to the project, you must update theMakefileaccordingly. This involves:-
Updating Source Files
Add the new
.cfiles to theSRCvariables. For example, if you addnew_module.c, include it as follows:SRC_NEW_MODULE = new_module.c -
Updating Object Files
Similarly, add the corresponding
.ofiles to theOBJvariables:OBJ_NEW_MODULE = new_module.o -
Linking New Object Files
Ensure that the new object files are included in the linking step for the target executable:
$(TARGET): $(OBJ_MATRIX) $(OBJ_MODEL) $(OBJ_MAIN) $(OBJ_NODE) $(OBJ_NEW_MODULE) $(CC) $(CFLAGS) -o $(TARGET) $(OBJ_MATRIX) $(OBJ_MODEL) $(OBJ_MAIN) $(OBJ_NODE) $(OBJ_NEW_MODULE) -lm
-
Compiling New Source Files
Add rules to compile the new source files:
new_module.o: $(SRC_NEW_MODULE) $(HEADERS) $(CC) $(CFLAGS) -c $(SRC_NEW_MODULE)
After updating the
Makefile, runmakeagain to build the project with the new files. -
Enabling / Disabling Debug verbosity ; Changing the data types ; Disabling the need for dependencies
The project uses the header file settings.h to manage settings and the enabling or disabling of features.
The majority of things are handled at compile time using Defines, so that the excluded features won't inlfuence the performance negatively and will make the executable lighter. Also enhancing the overall understandability of the code.
-
Minimal Dependency compilation: The only truly needed external functions are malloc and calloc. Set
DEBUGto0to disable all debug messages and prevent inclusion of<stdio.h>; tweak the data types so that there is no need to include any other library and then you are good to go!. (compile dependency free!) -
Flexible data types: Customize the data types the program uses at compile time directly in settings.h to match your platform or precision needs.
- parameter type (ffw_param_t),
- structure counters (ucount_t/count_t),
- and loop indices (uindex_t/index_t)
Here is a list of the modifiable settings:
This enum allows for a fast and reliable definition of the bool type, across all files.
The use of this enum is used instead of the inclusion of the stdbool library to allow for standard library free compilation.
Can be useful mostly for code readability purposes.
If set to 1, then all the debug messages will be printed.
Also enabling the definition of an "ad hoc" DEBUG_PRINT function.
Note: since debug messages need to be printed, the standard library stdlib will be included, if you would like to not include any libraries, you should not use this function
If set to 1, certain portion of the code will be added.
These aren't necessary for the normal operation of the code, nor they should be considered as a mean to "making the program more able" or more "complete".
This macro is intended to add other "in code" tools for courious developers that would like to modify the code.
This section provides an overview of the key files in this library and explains their roles. You can use this guide to navigate and understand how each file contributes to the project.
-
Purpose:
Serves as the primary entry point for the library. (as it contains the onlymain()function of the library) -
Details:
- It includes all header and source files in the library.
- Mainly used for test and demonstration purposes, it also contains some sample test functions to demonstrate the library's functionality.
- You may uncomment the provided test routines to see immediate output and behavior just for reference or curiosity (^_^)
-
Usage:
Developers can usemain.cas a starting point to experiment with the library. In a production environment, you might replace or exclude this file to integrate the library into your own projects.
-
Purpose:
Provides a centralized location for global settings, compiler macros, type definitions, and other configurable parameters used throughout the project. -
Key Features:
- Debug Configuration:
DEBUGmacro controls whether debug logging is enabled.DEBUG_PRINTmacro prints file and line information when debug mode is active.
- Additional Flags:
VERBOSEtoggles more detailed debugging messages.autoModeswitches between automatic and manual training modes.MOREincludes or excludes optional code paths deemed non-essential but potentially useful.
- Unified Typedefs:
Boolenum provides a simple, project-wide boolean convention (TRUE = 1,FALSE = 0).
- Debug Configuration:
-
Usage:
- Include
settings.hin any file that needs these macros, flags, or type definitions. - Adjust the macro values in
settings.hto customize debugging verbosity, enable or disable features, and unify project-wide data types. - Expect ongoing additions or modifications to this file as the project evolves.
- Include
This project is licensed under the Creative Commons Attribution-NonCommercial 4.0 International (CC BY-NC 4.0). This permits sharing and adapting the code for non-commercial purposes, provided appropriate credit is given to the original author. For more information, refer to the LICENSE file.