简介
FANN(Fast Artificial Neural Network Library)是一个用 C/C++ 编写的开源人工神经网络库,专注于提供高性能、轻量级的神经网络实现。它支持多层前馈神经网络(MLP),并提供快速训练算法,包括标准反向传播、快速反向传播和批量训练方法。
FANN 提供简单易用的 API,可以快速创建、训练和保存神经网络模型。用户可以灵活设置网络层数、每层神经元数量、激活函数类型(Sigmoid、Tanh、线性等),以及训练参数(学习率、误差阈值等),非常适合中小型机器学习任务和快速原型开发。
FANN 支持多种数据输入输出格式,网络模型可序列化保存或加载,从而便于在不同平台或项目中复用。它也提供多语言绑定,包括 C++、Python、Java 等,方便与其他系统集成。
由于其 轻量、高效、跨平台 的特点,FANN 广泛应用于分类、回归、控制系统和预测任务中,尤其适合对资源要求不高但需要快速部署的嵌入式和桌面应用场景。
编译安装
FANN的github地址:https://github.com/libfann/fann
直接下载源码解压,需要使用cmake编译源码成库。我使用的是windows10系统,cmake3.8.0,mingw5.4
打开cmake,定位到FANN源码目录,填写输出目录。点击configure,选择自己编译系统需要的makefile类型,点finish。
configure完成之后出现红色条目,一般就不用改了
再点击1次configure,变成普通颜色之后,点击generate产生makefile文件
到输出目录,已经产生了工程文件或者makefile,使用自己的编译系统进行编译,我用的mingw。因为看到cmake配置的安装文件夹是系统程序目录,所以需要使用管理员身份运行cmd,输入下面命令开始编译
mingw32-make
编译完成后直接安装
mingw32-make install
之后就会发现安装目录出现了FANN库文件夹,目录结构:
├─bin
├─include
│ ├─gmock
│ │ └─internal
│ │ └─custom
│ └─gtest
│ └─internal
│ └─custom
└─lib
├─cmake
│ ├─fann
│ └─GTest
└─pkgconfig
其中bin目录里面是FANN的动态链接库,需要加入系统环境变量PATH里面,确保运行时找到需要的动态库文件。include和lib是编译程序需要的头文件和库文件目录
这个库文件夹可以直接copy到需要的路径,之后使用。
测试
一
这是chatgpt5给的测试程序:当然,我可以给你一个使用 FANN(Fast Artificial Neural Network Library)的完整示例,演示如何训练一个简单的神经网络。
#include <stdio.h>
#include "fann.h"
int main()
{
// 1. 创建神经网络
const unsigned int num_input = 2;
const unsigned int num_hidden = 3;
const unsigned int num_output = 1;
struct fann *ann = fann_create_standard(3, num_input, num_hidden, num_output);
// 2. 设置激活函数
fann_set_activation_function_hidden(ann, FANN_SIGMOID_SYMMETRIC);
fann_set_activation_function_output(ann, FANN_SIGMOID_SYMMETRIC);
// 3. 创建训练数据
fann_type input[4][2] = {
{0, 0},
{0, 1},
{1, 0},
{1, 1}
};
fann_type output[4][1] = {
{0},
{1},
{1},
{0}
};
struct fann_train_data *train_data = fann_create_train(4, num_input, num_output);
for (int i = 0; i < 4; i++) {
for (int j = 0; j < num_input; j++){
train_data->input[i][j] = input[i][j];
}
for (int j = 0; j < num_output; j++){
train_data->output[i][j] = output[i][j];
}
}
// 4. 训练网络
fann_train_on_data(ann, train_data, 1000, 100, 0.001);
// 5. 测试网络
printf("XOR Neural Network Results:\n");
for (int i = 0; i < 4; i++) {
fann_type *calc_out = fann_run(ann, input[i]);
printf("Input: %g, %g -> Predicted: %g, Actual: %g\n", input[i][0], input[i][1], calc_out[0], output[i][0]);
}
// 6. 清理
fann_destroy_train(train_data);
fann_destroy(ann);
return 0;
}
编译链接,运行
g++ main.cpp -ID:\BuildTools\FANN\include -LD:\BuildTools\FANN\lib -lfann
./a.exe
这个神经网络学会了简单的XOR逻辑,结果:
Max epochs 1000. Desired error: 0.0010000000.
Epochs 1. Current error: 0.1205339134. Bit fail 2.
Epochs 93. Current error: 0.0009803015. Bit fail 0.
XOR Neural Network Results:
Input: 0, 0 -> Predicted: 0.0139892, Actual: 0
Input: 0, 1 -> Predicted: 0.913798, Actual: 1
Input: 1, 0 -> Predicted: 0.917462, Actual: 1
Input: 1, 1 -> Predicted: 0.0148878, Actual: 0
二
chatgpt5给的一个拟合2x^2-6函数的神经网络
#include <fann.h>
#include <iostream>
#include <vector>
int main() {
const unsigned int num_data = 11;
std::vector<float> x_vals, y_vals;
// 准备数据并归一化
for (int i = -5; i <= 5; ++i) {
x_vals.push_back(i / 5.0f);
y_vals.push_back((2*i*i - 6) / 44.0f * 2 - 1);
}
// 创建网络
struct fann *ann = fann_create_standard(3, 1, 10, 1);
fann_set_activation_function_hidden(ann, FANN_SIGMOID_SYMMETRIC);
fann_set_activation_function_output(ann, FANN_LINEAR);
fann_set_training_algorithm(ann, FANN_TRAIN_RPROP);
fann_set_train_stop_function(ann, FANN_STOPFUNC_MSE);
// 内存训练数据
struct fann_train_data *train_data = fann_create_train(num_data, 1, 1);
for (unsigned int i = 0; i < num_data; ++i) {
train_data->input[i][0] = x_vals[i];
train_data->output[i][0] = y_vals[i];
}
// 手动训练循环,自己打印
const unsigned int max_epochs = 5000;
const unsigned int print_every = 100;
const float desired_error = 0.0001f;
for (unsigned int epoch = 1; epoch <= max_epochs; ++epoch) {
fann_train_epoch(ann, train_data); // 每轮训练一次
if (epoch % print_every == 0) {
float mse = fann_get_MSE(ann);
std::cout << "Epoch " << epoch
<< ", MSE = " << mse << std::endl;
if (mse < desired_error) break; // 达到目标误差就停止
}
}
// 测试
std::cout << "Testing:\n";
for (int i = -5; i <= 5; ++i) {
float x = i / 5.0f;
float* y_pred = fann_run(ann, &x);
float y_out = ((y_pred[0] + 1)/2)*44; // 反归一化
std::cout << "x=" << i << " pred=" << y_out << " real=" << (2*i*i-6) << "\n";
}
fann_destroy_train(train_data);
fann_destroy(ann);
}
输出
Epoch 100, MSE = 0.00245492
Epoch 200, MSE = 0.000612225
Epoch 300, MSE = 0.000457924
Epoch 400, MSE = 0.000353085
Epoch 500, MSE = 0.000268855
Epoch 600, MSE = 0.0002015
Epoch 700, MSE = 0.000143414
Epoch 800, MSE = 8.59194e-005
Testing:
x=-5 pred=43.8645 real=44
x=-4 pred=26.2812 real=26
x=-3 pred=11.7201 real=12
x=-2 pred=2.10291 real=2
x=-1 pred=-4.00705 real=-4
x=0 pred=-6.00509 real=-6
x=1 pred=-3.85829 real=-4
x=2 pred=1.79174 real=2
x=3 pred=11.8935 real=12
x=4 pred=26.3925 real=26
x=5 pred=43.798 real=44