您的位置:首页 > 理论基础 > 计算机网络

BP神经网络原理分析及c++代码实现(下)

2013-06-03 09:45 295 查看
本部分主要是BP神经网络的C++代码部分,在这里简单的介绍下代码的头文件,具体代码的实现以及测试数据,请在csdn资源里下载:http://download.csdn.net/detail/hjkhjk007/5503911

为了方便广大用户的使用,本人将BP神经网络写成了一个BPNNS类,这样用户们可以很方便的将此类潜入到自己的工程当中,此类的具体的使用规则,下面会介绍。

/***************************************************************************
* 文件名称:BPNNs.h
* 摘    要:BP神经网络
* 作    者:黄继昆
*
* 修改记录:
*[日期]     [作者/修改者] [修改原因]
*2012.7.14	    黄继昆    	添加
***************************************************************************/
#pragma once
#include <stdio.h>
#include <math.h>

//算法
#define    traingd                      0                  // 基本的梯度下降算法
#define    traingdm                     1                  // 增加动量项的梯度下降算法
#define    traingdx                     2                  // 动量及自适应学习速率的梯度下降算法
#define    traincgf                     3                  // 共轭梯度算法
#define    trainrp                      4                  // 弹性BP算法
//使用的传递函数
#define     SIGMOID                     10                 // sigmoid 函数
#define     PURLINE                     11                 // purelin函数
// 神经网络 类型
#define     BP                          12                 //bp神经网络
#define     ITEMS                       13
#define     MAXWEIGHT                  ((float)0.3)
#define     SCALEWEIGHT                ((float)32767)
typedef  float *PFLOAT;
typedef  PFLOAT VECTOR;
typedef  PFLOAT *MATRIX;

//创建BP神经网络参数结构体
typedef struct _NNS_CREACTE
{

int   InputNodes;                // 输入层节点数
int   HiddenLayers;              // 隐层数
int   *HiddenNodes;              // 各隐层的节点数
int   OutputNodes;               // 输出层节点数
int   Patterns;                  // 训练实例数

}BPNNS_CreateInfo,*pBPNNS_CreateInfo;
//训练神经网络参数结构体
typedef struct _NNS_TRAIN
{
int   TrainMethod;               // 训练中使用的算法
int   OLTF;                      // OutputLayerTransferFunc输出层使用的传递函数
int   HLTF;                      // HindderLayerTransferFunc隐层使用的传递函数
int   Iterations;                // 训练次数
float ErrorLeve;                 // 误差级别
float eta;                       // 定义学习速率(步长)
float alpha;                     // 定义动量因子(该值在有动量的梯度下降算法当中才有效)

}BPNNS_TrainInfo,*pBPNNS_TrainInfo;

class CBPNNs
{

public:
CBPNNs(void);

public:
CBPNNs(BPNNS_CreateInfo CreateInfo);

public:
~CBPNNs(void);
public:
//构造网络
// 为训练数据开辟空间(1)(2)(3)
void     VectorAllocate(VECTOR *vector,int nCols);                 // (1)
void     AllocateCols(PFLOAT matrix[],int nRows,int nCols);        // (2)
void     MatrixAllocate(MATRIX *pmatrix,int nRows,int nCols);      // (3)
void     MatrixFree(MATRIX matrix,int nRows);                      // 释放空间
bool     AlotSize();                                               // 变量分配空间
bool     FreeMatrix();                                             // 释放开辟好的空间
bool     InitWeight();                                             // 初始化权值
//网络的训练用到的成员函数
public:                                                         // 计算各层输出
bool     CaculateLayeoutValue();                                   // 计算每层神经元的输出和计算一般化误差
bool     CaculateHiddenLayoutValue(int p,int j);                   // 计算隐层各神经元的输出
bool     CaculateOutLayerOutputValue(int p,int j);                 // 计算输出层各神经元的输出
public:                                                         // 各层权值的确定
bool     AdjustWeight(int Temp,int q);                             // 调整权值
bool     Adjust_BP_OutputWeight(int j);                            // 调整traingd算法的输出层权值
bool     Adjust_Bp_HiddenWeight(int j);                            // 调整traingd算法的隐层权值
bool     Adjust_IMBP_OutputWeight(int j);                          // 调整traingdm算法的输出层权值
bool     Adjust_IMBp_HiddenWeight( int j );                        // 调整traingdm算法的隐层权值
bool     Adjust_VLBP_OutputWeight(int j);                          // 调整traingdx算法的输出层权值
bool     Adjust_VLBp_HiddenWeight(int j);                          // 调整traingdx算法的隐层权值
bool     Adjust_trainrp_OutputWeight(int j,int q);                 // 调整弹性梯度下降算法的输出层的权值
bool     Adjust_trainrp_HiddenWeight(int j,int q);                 // 调整弹性梯度下降算法的yin层的权值
bool     Adjust_CGBP_OutputWeight(int j,int q);                    // 调整traincgf算法的输出层权值
bool     Adjust_CGBp_HiddenWeight(int j,int q);                    // 调整traincgf算法的隐层权值
bool     LimitValue_0_1(float *value);                             // Sigmoid函数输出限幅
bool     InputTrainData(char* TrainInput);                         // 输入训练数据
bool     OutputWeight(char* WeightOutput);                         // 输出训练权值

public:
//网络的应用用到的成员函数
bool     GetWeight(char* InputWeight);                             // 获取权值
bool     OutputNet(char* NetName);                                 // 输出训练好的网络参数
bool     GetNet(char* NetName);                                    // 获取训练好的网络参数

/*	bool     TestData();                                               // 开辟空间测试  */
//网络的应用
public://供外界调用的借口
bool     CreateBPNNS(BPNNS_CreateInfo CreateInfo);
bool     Train(BPNNS_TrainInfo TrainInfo,char* TrainInput,char* WeightOutput,char* NetOutput);
bool     Calculate(char* TestDate,char* TestResult );                                     // 训练过之后再实际当中应用
bool     GetNetAndWeight(char* NetName,char* InputWeight);
//测试接口
bool     OutputTrainResult(char* TrainResult);                     // 输出训练结果

public:
//定义成员变量
//网络结构
int      nInputNodes;                // 输入层节点数
int      nHiddenLayers;              // 隐层数
int      *nHiddenNodes;              // 各隐层的节点数
int      nOutputNodes;               // 输出层节

//网络训练参数
int      nPatterns;                  // 训练实例数
int      nIterations;                // 训练次数
float    nErrorLevel;                // 误差级
int      nTrainMethod;               // 训练算法
int      nOLTF;                      // 输出层传递函数
int      nHLTF;                      // 隐层使用的传递函数

//用来保存网络运行当中所依赖的变量
MATRIX   out0;                       // 输入数据
MATRIX   *out1;                      // 隐层输出
MATRIX   *delta1;                    // 输入层->隐层一般化误差
MATRIX   *delw1;                     // 输入层->隐层 前一次训练得到的权值
MATRIX   *beta1;                     // 隐层共轭梯度算法因子
MATRIX   *dk_hidden;                 // 隐层共轭梯度算法因子
MATRIX   *deldk_hidden;              // 保存上次迭代的算法因子
MATRIX   *Tempdelw1;                 // 缓存改变的权值
MATRIX   *w1;                        // 输入层->隐层的权值
MATRIX   out2;                       // 输出层输出
MATRIX   delta2;                     // 隐层->输出层一般化误差
MATRIX   dk_out;                     // 共轭梯度下降算法的保存因子
MATRIX   deldk_out;                  // 保存上一次算法因子数值
MATRIX   beta;                       // 共轭梯度下降算法的保存因子
MATRIX   delta2Temp;                 // 记录delta2的前一次的值
MATRIX   delw2;                      // 隐层->输出成前一次训练得到的权值
MATRIX   Tempdelw2;                  // 缓存权值
MATRIX   w2;                         // 隐层->输出层的权值
MATRIX   target;                     // 目标函数(BP是有导师的训练)
float    neta;                       // 学习速率(步长)
float    nalpha;                     // 动量因子
int      nReportErrors;              // 每一百次输出一次误差
int      JugeError;                  // 学习速度自适应调节判断过度
float    errorTemp;                  // 记录均方误差
bool     AloatSizeJuge;              // 判断是否进行了空间开辟
/*
本神经网络所有的输入、输出数据都是通过读取二进制文件的形式完成的。
*/
FILE      *fpPattern,                // 打开用来训练的txt文件
*fpWeightsOut,             // 保存训练好的权值
*fpNetOut,                 // 保存构建网络的参数
*fpNetInput,               // 获取构建好的网络参数
*fpNetRead,                // 读取之前训练好的网络参数
*fpResults,                // 保存训练好的结果
*fpWeightInput,            // 打开训练好的权值
*fpTest,                   // 打开测试数据
*fpTestResult;             // 输出测试结果

};

在这里介绍下供外界调用接口的使用规则,具体实现原理参考本人博客BP神经网络原理分析及c++代码实现(上),同时各个函数都已经有注释。

public://供外界调用的借口

bool CreateBPNNS(BPNNS_CreateInfo CreateInfo);

bool Train(BPNNS_TrainInfo TrainInfo,char* TrainInput,char* WeightOutput,char* NetOutput);

bool Calculate(char* TestDate,char* TestResult );

bool GetNetAndWeight(char* NetName,char* InputWeight);

(1) bool
CreateBPNNS(BPNNS_CreateInfo
CreateInfo);

BPNNS_CreateInfo结构体的具体信息如头文件所示。使用这种方式构造网络,用户需要首先构造BPNNs对象,构造网络不需要传递任何信息,即为空,然后调用该函数构造网络。当然,如果用户在构造BP神经网络类的过程中已经传递了构造信息,此函数不要调用了。

(2)Train(BPNNS_TrainInfo
TrainInfo,char*
TrainInput,char*
WeightOutput,char*
NetOutput)。

TrainInfo

TrainInfo 是训练参数结构体BPNNs_TrainInfo所定义的变量,里面定义了训练过程中所需要的参数信息。

TrainInput

TrainInput是输入训练数据的文件名,该程序对文件中的数据格式的要求是,文件当中所有的数据之间都要以空格或者换行分开,根据用户创建网络结构体当中用户设定的输入层节点数和输出层节点数,和训练事例数,先是存放所有的输入数据,然后再放前面放置的所有输入数据对应的输出结果。

WeightOutput

WeightOut 是训练好的网络的权值保存的文件名,程序会根据用户传递的文件名来将网络权值保存在该文件当中。

NetOutput

NetOutput是训练好的网络保存的文件名,程序会根据用户传递的文件名将网络保存在该文件当中

(3)Calculate(char*
TestDate,char*
TestResult );

调用这两个函数可完成方式一的使用,Train函数上面已经叙述过了,下面着重叙述Calculate函数。Calculate函数是用来完成用户对实际数据进行处理的函数。

TestDate:数据文件名,是用户用来处理的数据所在的文件名,文件当中第一个数据是数据的组数,然后下面依次排列各组数据,组与组之间以及同一组的数据之间都以空格或者换行进行分割。

TestResult:输出结果文件名,根据TestDate的输入,将处理的结果输出到该文件当中,数据在文件当中排列的顺序依照TestDate中的顺序排列。

同时为了方便用户使用已经创建好的网络进行处理数据,不要每次处理都去训练网络,特引出了另一个借口

用户直接读取已经训练好的网络,对数据进行处理。

GetNetAndWeight(char*
NetInfo,char*
InputWeight);

Calculate(char*
TestDate,char*
TestResult );

NetInfo: 网络信息文件名,文件中存有创建网络参数和训练网络参数,参数在文件当中的存在方式参考函数Train(BPNNS_TrainInfo
TrainInfo,char*
TrainInput,char*
WeightOutput,char*
NetOutput)当中的NetOutput。

InputWeight: 权值文件名,文件中存放了已经训练好的BPNN的权值,存放格式参考函数Train(BPNNS_TrainInfo
TrainInfo,char*
TrainInput,char*
WeightOutput,char*
NetOutput)当中的WeightOutput。

TesDate: 测试数据文件名,文件当中数据存在格式参考函数OutputWeight(char* WeightOutput) 当中的WeightOutput。
TestResult:测试结果文件名,用来保存测试数据处理的结果。数据存在的格式参考函数OutputNet(char* NetInfo)当中的NetInfo。

另外,为了方便用户检测训练好的数据是否能够达到预期的效果,BPNNs 提供了一个输出训练结果的函数

bool OutputTrainResult(char* TrainResult);
// 输出训练结果

TrainResult:训练结果文件名,训练好网络之后调用该函数,会将预期结果和实际输出结果一起输出到该文件当中,用户可以很方便的进行数据对比,检测该网络的训练结果。

到此,整个BP神经网络c++实现过程已经叙述完毕,如有需要,欢迎评论交流
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: