用BP神经网络算法实现数字识别

合集下载
  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。

/* =====================
用BP神经网络算法实现数字识别
************************/
#include <>
#include <>
#include <>
#include <>
/***********************
宏概念
************************/
typedef int BOOL;
typedef int INT;
typedef double REAL;
typedef char CHAR;
#define FALSE 0
#define TRUE 1
#define NOT !
#define AND &&
#define OR ||
#define MIN(x,y) ((x)<(y) ? (x) : (y))
#define MAX(x,y) ((x)>(y) ? (x) : (y))
#define sqr(x) ((x)*(x))
#define LO
#define HI
#define BIAS
#define NUM_LAYERS 3 .\\n", / Error) * 100);
}\n");
getch();
SaveWeights(&Net);\nPlease check the rusult in the file:.\\n"); printf("Please put any key to over this program.\\n");
getch();
getch();
}
/***********************
产生随机数
************************/
//设置伪随机数种子
void InitializeRandoms()
{
srand(4711);
}
//产生一个LOW - TOP之间的伪随机整数
INT RandomEqualINT(INT Low, INT High)
{
return rand() % (High-Low+1) + Low;
}
//产生一个LOW - TOP之间的伪随机浮点数
REAL RandomEqualREAL(REAL Low, REAL High)
{
return ((REAL) rand() / RAND_MAX) * (High-Low) + Low;
}
/***********************
//关闭文件
************************/
void FinalizeApplication(NET* Net)
{
fclose(f);
}
/***********************
//随机生成联接权
************************/
void RandomWeights(NET* Net)
{
INT l,i,j;
for (l=1; l<NUM_LAYERS; l++) { //每层
for (i=1; i<=Net->Layer[l]->Units; i++) {
for (j=0; j<=Net->Layer[l-1]->Units; j++) {
Net->Layer[l]->Weight[i][j] = RandomEqualREAL, ;//随机值
}
}
}
}
/***********************
//保存连接权,防止丢失宝贵的联接权
************************/
void SaveWeights(NET* Net)
{
INT l,i,j;
for (l=1; l<NUM_LAYERS; l++) {
for (i=1; i<=Net->Layer[l]->Units; i++) {
for (j=0; j<=Net->Layer[l-1]->Units; j++) {
Net->Layer[l]->WeightSave[i][j] = Net->Layer[l]->Weight[i][j];
}
}
}
}
/***********************
//恢复连接权,以便需要的时候可以重新调用,重组网络
************************/
void RestoreWeights(NET* Net)
{
INT l,i,j;
for (l=1; l<NUM_LAYERS; l++) {
for (i=1; i<=Net->Layer[l]->Units; i++) {
for (j=0; j<=Net->Layer[l-1]->Units; j++) {
Net->Layer[l]->Weight[i][j] = Net->Layer[l]->WeightSave[i][j]; }
}
}
}
/***********************
//创建网络,为网络分配空间
************************/
void GenerateNetwork(NET* Net)
{
INT l,i;
Net->Layer = (LAYER**) calloc(NUM_LAYERS, sizeof(LAYER*));
for (l=0; l<NUM_LAYERS; l++) {
Net->Layer[l] = (LAYER*) malloc(sizeof(LAYER));
Net->Layer[l]->Units = Units[l];
Net->Layer[l]->Output = (REAL*) calloc(Units[l]+1, sizeof(REAL));
Net->Layer[l]->Activation = (REAL*) calloc(Units[l]+1, sizeof(REAL)); Net->Layer[l]->Error = (REAL*) calloc(Units[l]+1, sizeof(REAL));
Net->Layer[l]->Weight = (REAL**) calloc(Units[l]+1, sizeof(REAL*));
Net->Layer[l]->WeightSave = (REAL**) calloc(Units[l]+1, sizeof(REAL*)); Net->Layer[l]->dWeight = (REAL**) calloc(Units[l]+1, sizeof(REAL*));
Net->Layer[l]->Output[0] = BIAS;
if (l != 0) {
for (i=1; i<=Units[l]; i++) {
Net->Layer[l]->Weight[i] = (REAL*) calloc(Units[l-1]+1, sizeof(REAL)); Net->Layer[l]->WeightSave[i] = (REAL*) calloc(Units[l-1]+1, sizeof(REAL)) ;
Net->Layer[l]->dWeight[i] = (REAL*) calloc(Units[l-1]+1, sizeof(REAL)); }
}
}
Net->InputLayer = Net->Layer[0];//为输入层分配指针
Net->OutputLayer = Net->Layer[NUM_LAYERS-1];//为输出层分配指针
Net->Alpha = ;//冲量参数
Net->Eta = ;//学习率
Net->Epsilon =;//控制精度
}
/***********************
将输入样本转换成为输入模式,并创建一个文件以保存显示结果
************************/
void InitializeApplication(NET* Net)
{
INT n, i,j;
for (n=0; n<NUM_DATA; n++) {
for (i=0; i<Y; i++) {
for (j=0; j<X; j++) {
if ( Pattern[n][i][j] == ’O’)
Input[n][i*X+j] = HI ;
else Input[n][i*X+j] =LO ;
//NUM_DATA输入模式,输入层X*Y个神经元
}
}
}
f = fopen("", "w");
}
/***********************
//计算输出层误差,* Target是导师信号
************************/
void ComputeOutputError(NET* Net, REAL* Target)
{
INT i;
REAL Err,Out;
Net->Error = 0;
for (i=1; i<=Net->OutputLayer->Units; i++) {
Out = Net->OutputLayer->Output[i];//输出层的输出
Err = Target[i-1]-Out;//误差计算
Net->OutputLayer->Error[i] = Out * (1-Out) * Err; //用delta规则计算误差,因为用了可导的s形函数
Net->Error += * sqr(Err);//平方差公式
}
}
/***********************
//误差反向传播Upper 为前层,Lower为后层,层数值大的为前层
************************/
void BackpropagateLayer(NET* Net, LAYER* Upper, LAYER* Lower) {
INT i,j;//循环变量
REAL Out, Err;
for (i=1; i<=Lower->Units; i++) {
Out = Lower->Output[i];//后层的输出
Err = 0;//用来记录隐含层输出的误差的估计值
for (j=1; j<=Upper->Units; j++) {
Err += Upper->Weight[j][i] * Upper->Error[j];
//误差的反馈,通过已经处理的前层的delta值和联接权去估计,有理论基础}
Lower->Error[i] =Out * (1-Out) * Err; //delta规则
}
}
/***********************
//整个网络误差的后传
************************/
void BackpropagateNet(NET* Net)
{
INT l;//循环变量
for (l=NUM_LAYERS-1; l>1; l--) {
BackpropagateLayer(Net, Net->Layer[l], Net->Layer[l-1]);//对每层处理}
}
/***********************
//调整网络每一层的联接权
************************/
void AdjustWeights(NET* Net)
{
INT l,i,j;//循环变量
REAL Out, Err, dWeight;
//记录后层的输出、当前层的输出误差、当前神经元联接权上次的调整量
for (l=1; l<NUM_LAYERS; l++) {
for (i=1; i<=Net->Layer[l]->Units; i++) {
for (j=0; j<=Net->Layer[l-1]->Units; j++) {
Out = Net->Layer[l-1]->Output[j];//后层的输出
Err = Net->Layer[l]->Error[i];//当前层的输出误差
dWeight = Net->Layer[l]->dWeight[i][j];
//将本神经元联接权上次的调整量取出,初始值为0,初始化网络时赋值的
Net->Layer[l]->Weight[i][j] += Net->Eta * Err * Out + Net->Alpha * dWeight;
//Alpha为冲量参数,加快网络的收敛速度
Net->Layer[l]->dWeight[i][j] = Net->Eta * Err * Out;
//记录本次神经元联接权的调整量
}
}
}
}
/***********************
//显示输入模式
************************/
void WriteInput(NET* Net, REAL* Input)
{
INT i;
for (i=0; i<N; i++) {
if (i%X == 0) {
fprintf(f, "\\n");
}
fprintf(f, "%c", (Input[i] == HI) ? ’0’: ’’); }
fprintf(f, " -> ");
}
/***********************
//显示输出模式
************************/
void WriteOutput(NET* Net, REAL* Output)
{
INT i;//循环变量
INT Index;//用来记录最大输出值的下标,也就是最后识别的结果REAL MaxOutput;//用来记录最大的输出值
MaxOutput=0;//初始化
for (i=0; i<M; i++)
{
if(MaxOutput<Output[i]){
MaxOutput=MAX(MaxOutput,Output[i]);//保存最大值
Index=i;
}
}
fprintf(f, "%i\\n", Index);//写进文件
}
/***********************
初始化测试样本
************************/
void Initializetest()
{
INT n,i,j;//循环变量
for (n=0; n<NUM_DATA; n++) {
for (i=0; i<Y; i++) {
for (j=0; j<X; j++)
if (testPattern[n][i][j]==’O’)
Inputtest[n][i*X+j] = HI;
else Inputtest[n][i*X+j] =LO; //NUM_DATA输入模式,输入层X*Y个神经元}
}
}。

相关文档
最新文档