Kalzn
文章20
标签13
分类7
使用C++实现的简单ANN(人工神经网络)

使用C++实现的简单ANN(人工神经网络)

使用C++实现的简单ANN(人工神经网络)

github地址 使用C++实现的最简单的人工神经网络,包含梯度下降的反向传播算法(BP)。内有部分注释,适合初学学习。至于为什么不用python?还是觉得从最底层(矩阵运算)写比较能加深印象和对算法的理解。(绝对不是因为我不会写python)

警告,此代码仅为初学学习之用,请勿用作任何工程项目!

一、跑起来

方式一

使用vscode+cmake插件或者Clion打开目录。然后直接编译运行。

方式二

1、确保安装cmake环境,没有请先装cmake。 2、在工程目录下键入:

1
2
3
4
mkdir build
cd build
cmake ..
make

3、运行build目录下的ANN程序

然后在data目录下生成文件output.csv,这是一个回归函数的拟合。 拟合情况如下: 在这里插入图片描述

二、用起来

1、使用十分简便,首先新建ANN模型,设置误差函数cost及其对于输出层每一项的偏导,这里使用默认的平方差函数

1
2
3
ANNModel model;
model.cost = Sqrt_Cost_Func::sqrt_cost;
model.d_cost = Sqrt_Cost_Func::d_sqrt_cost;
1、设置学习率(一般0.0001~0.1)
1
model.learning_rate = 0.01;
2、开始添加层级,从输入层开始,直到输出层,这里请保证输入层的神经元个数与输入向量的维度相同。并设置这些层级的激活函数和其导数。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
// 输入层 1个神经元
ANNLayer layer0(1);
layer0.activition = Linear_Func::linear; // 设置本层激活函数为线性函数f(x)=x
// 根据ANN结构,输入层的激活函数应设置为线性
layer0.d_activition = Linear_Func::linear;// 设置本层激活函数的导数
model.add_layer(layer0);

// 隐藏层 20个神经元
ANNLayer layer1(20);
layer1.activition = Signmod_Func::signmod; // 设置本层激活函数为sigmod
layer1.d_activition = Signmod_Func::d_signmod;
model.add_layer(layer1);

// 输出层1个神经院
ANNLayer layer2(1);
layer2.activition = Linear_Func::linear;
layer2.d_activition = Linear_Func::d_linear;
model.add_layer(layer2);

3、编译模型

1
Compiled_ANNModel compiled_model = model.compile();

4、训练模型,查看输出

1
2
Vector data, expectation;
Vector output = compiled_model.feed(data, expectation);

5、只输出,不训练

1
Vector output = compiled_model.get_output(data);

三、学起来

这里给出最终公式,公式的推导请见其他教程、参考书。

1、获得神经元的激活值,这里使用表示第层的第个神经元的激活值大小 其中 其中为第层的激活函数,为从层第个神经元链接到第层第个神经元的边权(注意下标的顺序!),另外是第层第个神经元的偏置阈值。为第层的神经元个数。

2、反向传播公式(以平方差误差函数为例)

其中

最终有

最后对进行更新如下

其中,为第层激活函数的导数。为误差函数,为预期输出向量的分量。为学习率。

具体实现的解释请,见代码注释。

本文作者:Kalzn
本文链接:http://kalzncc.github.io/2022/11/19/ml-ann/
版权声明:除文章中特别注明外,本站所有文章采用 CC BY 3.0 CN 协议进行许可
即在署明文章作者及来源的情况下,您可以将本文用于包括商业目在内的任何用途。
除此之外,本文不做正确性担保,本人不对产生的问题负责。
×