在mlpack中实现极其高效的前馈神经网络(C++)
MLPACK是一个用C ++编写的快速,灵活的机器学习库,为用户提供各种强大的机器学习模型和高度优化的常用ML任务中使用的数学函数实现。有关它提供的高级功能列表,请查看此链接(https://www.mlpack.org/about.html)。
在本教程中,我想向您展示实现一个简单的多层神经网络模型。本文侧重于更深入地了解它的实现方面,而不是深度学习本身的理论方面。
前提条件:
- 您现在已在系统上安装了MLPACK。
- 您对前馈神经网络以及简单的FFN模型包含的内容有基本的了解(输入层,输出层,损失函数和中间的一堆隐藏层,以及您选择的激活函数)
- 您的系统上安装了python3。{5 | 6}。(用于生成数据,可选)
示例数据集
使用python脚本生成一些人工(非线性可分离)数据。
import numpy as np import math # number of data points to generate size = 400 # data points generated using this func # given X, radius R return Y = SquareRoot(R^2 - X^2) def circle(x,r): return math.sqrt(r**2-x**2) # Generate 400 random datapoints for X between [-3.0,3.0] X = np.random.uniform(low=-3.0,high=3.0,size=size) Y = [] # Generate 400 random labels = (1,0) O = np.random.randint(low=0,high=2,size=size) # [low,high) # Find Y for each given X for x,o in zip(X,O): if o == 1 : Y.append(circle(x,3.5)) else: Y.append(circle(x,4.0)) data = [] for x,y,o in zip(X,Y,O): data.append([x,y,int(o)]) np.savetxt("foo.csv", data, delimiter=",")
foo.csv的格式:
- 第0,1列=特征0,特征1
- 第2列=标签
绘制数据,如下图所示。数据点属于2个单独的标签,如不同颜色所示。
请注意,MLPACK使用Armadillo库(C ++ lib for linear algebra),它以 column-major ordering存储矩阵,因为它在内存带宽使用和缓存性能方面更有效,可以访问数组的元素,顺序是按照它们在内存中的排列顺序排列的。
神教网络型概述
我们在这里遇到的问题是二进制分类。
- 损失函数: 均方误差
- 输入层: 8个感知器(2个输入),每个(2x8),Sigmoid激活函数。
- 隐藏层: 8个感知器(8个输入),每个(8x8),Sigmoid激活函数。
- 输出层: 1个感知器(8个输入),每个(8x1),Sigmoid激活函数。
编码,(C ++ 11)
我们将从从mlpack导入必需的.hpp文件开始
#include <mlpack/core.hpp> #include <mlpack/methods/ann/layer/layer.hpp> #include <mlpack/methods/ann/loss_functions/mean_squared_error.hpp> #include <mlpack/methods/ann/ffn.hpp>
接下来,我们将使用mlpack、armadillo和stdlib,声明我们将使用的命名空间
using namespace mlpack; using namespace mlpack::ann; using namespace mlpack::optimization; using namespace arma; using namespace std;
启动main()并加载数据
int main(){ mat data; data::Load("foo.csv",data,true);
mat数据类型是在armadillo库中定义的,它是密集矩阵的存储类,元素以column-major顺序存储。MLPACK定义了一个load函数,用于将数据从csv文件加载到mat变量中。
将数据拆分为火车和测试集
mat traindata = data.submat(0, 0, data.n_rows-2,data.n_cols-6); mat trainlabels = data.submat(data.n_rows-1,0, data.n_rows-1,data.n_cols-6); mat testdata = data.submat(0, data.n_cols-5, data.n_rows-2,data.n_cols-1); mat testlabels = data.submat(data.n_rows-1,data.n_cols-5, data.n_rows-1,data.n_cols-1);
在上面给出的代码中,我们将数据点总数分为2组,train (number of points-5)和test set(5个数据点)。你可以随意调整数字(5)。
神经网络模型
FFN<MeanSquaredError<>, RandomInitialization> model; model.Add<Linear<> >(traindata.n_rows,8); model.Add<SigmoidLayer<> >(); model.Add<Linear<> >(8,8); model.Add<SigmoidLayer<> >(); model.Add<Linear<> >(8,1); model.Add<SigmoidLayer<> >();
通过训练函数循环4个epochs
for (int i = 0; i < 4; ++i) { model.Train(traindata, trainlabels); }
经过训练,对测试数据进行预测,
mat assignments; model.Predict(testdata, assignments); cout<<"Predictions : "<<assignments<<endl; cout<<"Correct Labels : "<<testlabels<<endl; return 0; }
这就是代码的结尾。
编译和运行代码
假设文件名是mlp-mlpack.cpp,使用以下命令编译并运行代码。
g++ mlp-mlpack.cpp -o mlp-mlpack -std=c++11 -larmadillo -lmlpack
./mlp-mlpack
输出
c++代码应该给出以下输出
正如所见,这些预测相当准确。