Small feed-forward neural network library written in C.
The repository builds three outputs:
ANN_lib: reusable static library targetANN: sample executable inANN/Main.cANN_test: test executable inANN/ANN_test.c
The canonical build is defined in CMakeLists.txt. The root Makefile is a convenience wrapper around the same CMake build.
- CMake 3.16 or newer
- A C11 compiler
makeif you want to use the wrapper commands on macOS or Linux
From the repository root:
makeThis performs a clean rebuild by running:
cmake -S . -B buildcmake --build build
Useful Make targets:
make: clean, configure, and buildmake build: build the existingbuilddirectorymake run: rebuild and run the sample programmake test: rebuild and run the test suitemake run-test: run tests in the existingbuilddirectorymake clean: remove thebuilddirectory
From the repository root:
cmake -S . -B build
cmake --build buildOn macOS and Linux, the static library is produced as:
build/libANN_lib.aThe sample executable is produced as:
build/ANNThe test executable is produced as:
build/ANN_testRun the sample application:
make runOr run it directly after building:
./build/ANNTo load or save a weights file with the sample executable:
./build/ANN --load weights.txt --save weights.txtThe Make wrapper also passes optional arguments through:
make run ARGS="--load weights.txt --save weights.txt"Run the full test suite:
make testOr with CTest directly:
ctest --test-dir build --output-on-failureYes, this project can be used from another C program.
The public header is:
#include "ANN.h"The library API currently exposes:
ANN* NewAnn(size_t inputCount, size_t hiddenCount, size_t outputCount)void FreeAnn(ANN* ann)size_t AnnMemoryUsage(const ANN* ann)int Compute(ANN* ann, const double* data, size_t dataLength)int BackProp(ANN* ann, const double* targets, size_t targLength)void PrintAnn(const ANN* ann)void PrintOutput(const ANN* ann)int SaveAnnWeights(const ANN* ann, const char* filePath)int LoadAnnWeights(ANN* ann, const char* filePath)
The ANN struct is public, so runtime parameters such as LearnRate are configured directly on the instance.
#include <stdlib.h>
#include <time.h>
#include "ANN.h"
int main(void)
{
ANN* ann;
double input[3] = { 0.1, -0.2, 0.3 };
double target[1] = { 0.4 };
srand((unsigned)time(NULL));
ann = NewAnn(3, 8, 1);
if (ann == NULL)
return 1;
ann->LearnRate = 0.05;
if (Compute(ann, input, 3) != 0)
{
FreeAnn(ann);
return 1;
}
if (BackProp(ann, target, 1) != 0)
{
FreeAnn(ann);
return 1;
}
if (SaveAnnWeights(ann, "weights.txt") != 0)
{
FreeAnn(ann);
return 1;
}
if (LoadAnnWeights(ann, "weights.txt") != 0)
{
FreeAnn(ann);
return 1;
}
FreeAnn(ann);
return 0;
}If another CMake project wants to use this library directly from source:
add_subdirectory(/path/to/ANN ann_build)
target_link_libraries(your_app PRIVATE ANN_lib)Because ANN_lib publishes the ANN include directory, #include "ANN.h" works in the consuming target.
If you already built this repository, you can link your own program against the generated archive:
cc your_program.c build/libANN_lib.a -IANN -lmOn Unix-like systems the math library flag -lm is required.
NewAnninitializes weights withrand(), so callsrand(...)before creating a network if you want non-deterministic initialization.- Weight files are stored as plain text with a version header and the expected layer sizes.
LoadAnnWeights(...)rejects files that do not match the ANN dimensions. - There is currently no
install()step orfind_package()support. Reuse is done either byadd_subdirectory(...)or by linking the generated static library directly.