神经网络文字识别关键代码.docx

上传人:b****6 文档编号:7790096 上传时间:2023-01-26 格式:DOCX 页数:31 大小:22.73KB
下载 相关 举报
神经网络文字识别关键代码.docx_第1页
第1页 / 共31页
神经网络文字识别关键代码.docx_第2页
第2页 / 共31页
神经网络文字识别关键代码.docx_第3页
第3页 / 共31页
神经网络文字识别关键代码.docx_第4页
第4页 / 共31页
神经网络文字识别关键代码.docx_第5页
第5页 / 共31页
点击查看更多>>
下载资源
资源描述

神经网络文字识别关键代码.docx

《神经网络文字识别关键代码.docx》由会员分享,可在线阅读,更多相关《神经网络文字识别关键代码.docx(31页珍藏版)》请在冰豆网上搜索。

神经网络文字识别关键代码.docx

神经网络文字识别关键代码

神经网络文字识别关键代码

下面作者列出bp网络训练及识别的完整源代码bp.h。

#include

#include

#include

#include

#defineBIGRND32767

/************************函数声明部分*****************************/

//随机数产生函数

doubledrnd();

doubledpn1();

//S函数

doublesquash(doublex);

//分配1维double型的内存

double*alloc_1d_dbl(intn);

//分配2维double型的内存

double**alloc_2d_dbl(intm,intn);

//初始化BP网络

voidbpnn_initialize(intseed);

//随机初始化权值

voidbpnn_randomize_weights(double**w,intm,intn);

//零初始化权值

voidbpnn_zero_weights(double**w,intm,intn);

//信息的前向传输

voidbpnn_layerforward(double*l1,double*l2,double**conn,intn1,intn2);

//误差输出

voidbpnn_output_error(double*delta,double*target,double*output,intnj);

//隐层误差

voidbpnn_hidden_error(double*delta_h,intnh,double*delta_o,intno,double**who,double*hidden);

//根据误差调整权值

voidbpnn_adjust_weights(double*delta,intndelta,double*ly,intnly,double**w,double**oldw,doubleeta,doublemomentum);

//保存权值

voidw_weight(double**w,intn1,intn2,char*name);

//读取权值

boolr_weight(double**w,intn1,intn2,char*name);

//保存Bp网络各层结点数目

voidw_num(intn1,intn2,intn3,char*name);

//读取Bp网络各层结点数目

boolr_num(int*n,char*name);

//特征提取

voidcode(BYTE*image,int*p,intw,inth,intdw);

//BP网络训练

voidBpTrain(HDIBhDIB,intn_hidden,doublemin_ex,doublemomentum,doubleeta,intwidth,intheight);

//利用BP网络进行识别

voidCodeRecognize(HDIBhDIB,intwidth,intheight,intn_in,intn_hidden,intn_out);

/**********************************************************************/

/******************以下是函数的实现部分***********************************/

/***返回0-1的双精度随机数***/

doubledrnd()

{

//BIGRND定义为随机数的最大范围

return((double)rand()/(double)BIGRND);

}

/***返回-1.0到1.0之间的双精度随机数***/

doubledpn1()

{

return((drnd()*2.0)-1.0);

}

doublesquash(doublex)

{

//返回S激活函数

return(1.0/(1.0+exp(-x)));

}

/***申请1维双精度实数数组***/

double*alloc_1d_dbl(intn)

{

double*new1;

//申请内存

new1=(double*)malloc((unsigned)(n*sizeof(double)));

//申请内存失败处理

if(new1==NULL){

printf("ALLOC_1D_DBL:

Couldn'tallocatearrayofdoubles\n");

return(NULL);

}

//返回申请到的内存的指针

return(new1);

}

/***申请2维双精度实数数组***/

double**alloc_2d_dbl(intm,intn)

{

inti;

//定义一二维指针

double**new1;

//先申请一维内存

new1=(double**)malloc((unsigned)(m*sizeof(double*)));

//申请失败处理

if(new1==NULL){

//printf("ALLOC_2D_DBL:

Couldn'tallocatearrayofdblptrs\n");

return(NULL);

}

//再申请二维内存。

一维内存中存放的是指针

for(i=0;i

new1[i]=alloc_1d_dbl(n);

}

//返回申请到的二维内存(可以看作矩阵)

return(new1);

}

/***设置随机数种子***/

voidbpnn_initialize(intseed)

{

//printf("Randomnumbergeneratorseed:

%d\n",seed);

srand(seed);

}

/***随机初始化权值***/

voidbpnn_randomize_weights(double**w,intm,intn)

{

inti,j;

//调用dpn1随机初始化权值

for(i=0;i<=m;i++){

for(j=0;j<=n;j++){

w[i][j]=dpn1();

}

}

}

/*******零初始化权值*******/

voidbpnn_zero_weights(double**w,intm,intn)

{

inti,j;

//将权值逐个赋0

for(i=0;i<=m;i++){

for(j=0;j<=n;j++){

w[i][j]=0.0;

}

}

}

/*********前向传输*********/

voidbpnn_layerforward(double*l1,double*l2,double**conn,intn1,intn2)

{

doublesum;

intj,k;

/***设置阈值***/

l1[0]=1.0;

/***对于第二层的每个神经元***/

for(j=1;j<=n2;j++){

/***计算输入的加权总和***/

sum=0.0;

for(k=0;k<=n1;k++){

sum+=conn[k][j]*l1[k];

}

l2[j]=squash(sum);

}

}

/*输出误差*/

voidbpnn_output_error(double*delta,double*target,double*output,intnj)

{

intj;

doubleo,t,errsum;

//先将误差归零

errsum=0.0;

//循环计算delta

for(j=1;j<=nj;j++){

o=output[j];

t=target[j];

//计算delta值

delta[j]=o*(1.0-o)*(t-o);

}

}

/*隐含层误差*/

voidbpnn_hidden_error(double*delta_h,intnh,double*delta_o,intno,double**who,double*hidden)

{

intj,k;

doubleh,sum,errsum;

//误差归零

errsum=0.0;

//计算新delta

for(j=1;j<=nh;j++){

h=hidden[j];

sum=0.0;

for(k=1;k<=no;k++){

sum+=delta_o[k]*who[j][k];

}

delta_h[j]=h*(1.0-h)*sum;

}

}

/*调整权值*/

voidbpnn_adjust_weights(double*delta,intndelta,double*ly,intnly,double**w,double**oldw,doubleeta,doublemomentum)

{

doublenew_dw;

intk,j;

ly[0]=1.0;

//请参考文章中BP网络权值调整的计算公式

for(j=1;j<=ndelta;j++){

for(k=0;k<=nly;k++){

new_dw=((eta*delta[j]*ly[k])+(momentum*oldw[k][j]));

w[k][j]+=new_dw;

oldw[k][j]=new_dw;

}

}

}

/*******保存权值**********/

voidw_weight(double**w,intn1,intn2,char*name)

{

inti,j;

double*buffer;

//创建文件指针

FILE*fp;

//打开文件

fp=fopen(name,"wb+");

//分配缓冲区

buffer=(double*)malloc((n1+1)*(n2+1)*sizeof(double));

//填写缓冲区内容

for(i=0;i<=n1;i++)

{

for(j=0;j<=n2;j++)

buffer[i*(n2+1)+j]=w[i][j];

}

//将缓冲区内容写入文件

fwrite((char*)buffer,sizeof(double),(n1+1)*(n2+1),fp);

//关闭文件

fclose(fp);

//清空缓冲区

free(buffer);

}

/************读取权值*************/

boolr_weight(double**w,intn1,intn2,char*name)

{

inti,j;

//临时缓冲区指针

double*buffer;

//文件指针

FILE*fp;

//判断是否可以正确打开文件。

若失败则返回false

if((fp=fopen(name,"rb"))==NULL)

{

:

:

MessageBox(NULL,"无法读取权值信息",NULL,MB_ICONSTOP);

return(false);

}

//将临时缓冲区指针执行新申请的内存

buffer=(double*)malloc((n1+1)*(n2+1)*sizeof(double));

//读取文件内容到缓冲区

fread((char*)buffer,sizeof(double),(n1+1)*(n2+1),fp);

//由缓冲区内容填写权值

for(i=0;i<=n1;i++)

{

for(j=0;j<=n2;j++)

w[i][j]=buffer[i*(n2+1)+j];

}

//关闭文件

fclose(fp);

//释放临时缓冲区

free(buffer);

//返回true表示已经正确读取

return(true);

}

/*****保存Bp网络各层结点的数目******/

voidw_num(intn1,intn2,intn3,char*name)

{

//文件指针

FILE*fp;

//打开文件

fp=fopen(name,"wb+");

//缓冲区指针

int*buffer;

//分配内存并指向缓冲区指针

buffer=(int*)malloc(3*sizeof(int));

//将网络各层参数信息保存在临时缓冲区

buffer[0]=n1;

buffer[1]=n2;

buffer[2]=n3;

//将临时缓冲区内容写入文件

fwrite((char*)buffer,sizeof(int),3,fp);

//关闭文件

fclose(fp);

//清空缓冲区

free(buffer);

}

/********读取Bp网络各层结点数目*********/

boolr_num(int*n,char*name)

{

//临时缓冲区指针

int*buffer;

//文件指针

FILE*fp;

//分配内存空间

buffer=(int*)malloc(3*sizeof(int));

if((fp=fopen(name,"rb"))==NULL)

{

:

:

MessageBox(NULL,"结点参数",NULL,MB_ICONSTOP);

return(false);

}

//读取文件到缓冲区

fread((char*)buffer,sizeof(int),3,fp);

//从缓冲区中取出数据,存入n[0]~n[2]

n[0]=buffer[0];

n[1]=buffer[1];

n[2]=buffer[2];

//关闭文件

fclose(fp);

//清空缓冲区

free(buffer);

//正确读取,返回true

return(true);

}

/**********************************

*函数名称code()

*

*参量:

*BYTE*lpDIBBits-指向输入图像的像素其实位置的指针

*intnum-图片中样本的个数

*LONGlLineByte-输入图片每行的字节数

*LONGlSwidth-预处理时归一化的宽度

*LONGlSheight-预处理时归一化的长度

*

*函数功能:

*对于输入样本提取特征向量,在这里把归一化样本的

*每一个像素都作为特征提取出来

**************************************/

double**code(BYTE*lpDIBBits,intnum,LONGlLineByte,LONGlSwidth,LONGlSheight)

{

//循环变量

inti,j,k;

BYTE*lpSrc;

//建立保存特征向量的二维数组

double**data;

//为这个数组申请二维存储空间

data=alloc_2d_dbl(num,lSwidth*lSheight);

//将归一化的样本的每个像素作为一个特征点提取出来

//逐个数据扫描

for(k=0;k

{

//对每个数据逐行扫描

for(i=0;i

{

//对每个数据逐列扫描

for(j=k*lSwidth;j<(k+1)*lSwidth;j++)

{

//指向图像第i行第j列个像素的指针

lpSrc=lpDIBBits+i*lLineByte+j;

//如果这个像素是黑色的

if(*(lpSrc)==0)

//将特征向量的相应位置填1

data[k][i*lSwidth+j-k*lSwidth]=1;

//如果这个像素是其他的

if(*(lpSrc)!

=0)

//将特征向量的相应位置填0

data[k][i*lSwidth+j-k*lSwidth]=0;

}

}

}

//返回指向特征矩阵的二维指针

//特征矩阵构成:

每个样本×每个样本的特征

return(data);

}

/****************************************************

*函数名称BpTrain()

*

*参数:

*double**data_in-指向输入的特征向量数组的指针

*double**data_out-指向理想输出数组的指针

intn_in-输入层结点的个数

*intn_hidden-BP网络隐层结点的数目

*doublemin_ex-训练时允许的最大均方误差

*doublemomentum-BP网络的相关系数

*doubleeta-BP网络的训练步长

*intnum-输入样本的个数

*

*函数功能:

*根据输入的特征向量和期望的理想输出对BP网络尽行训练

*训练结束后将权值保存并将训练的结果显示出来

********************************************************/

voidBpTrain(double**data_in,double**data_out,intn_in,intn_hidden,doublemin_ex,doublemomentum,doubleeta,intnum)

{

//循环变量

inti,k,l;

//输出层结点数目

intn_out=4;

//指向输入层数据的指针

double*input_unites;

//指向隐层数据的指针

double*hidden_unites;

//指向输出层数据的指针

double*output_unites;

//指向隐层误差数据的指针

double*hidden_deltas;

//指向输出层误差数剧的指针

double*output_deltas;

//指向理想目标输出的指针

double*target;

//指向输入层于隐层之间权值的指针

double**input_weights;

//指向隐层与输出层之间的权值的指针

double**hidden_weights;

//指向上一此输入层于隐层之间权值的指针

double**input_prev_weights;

//指向上一此隐层与输出层之间的权值的指针

double**hidden_prev_weights;

//每次循环后的均方误差误差值

doubleex;

//为各个数据结构申请内存空间

input_unites=alloc_1d_dbl(n_in+1);

hidden_unites=alloc_1d_dbl(n_hidden+1);

output_unites=alloc_1d_dbl(n_out+1);

hidden_deltas=alloc_1d_dbl(n_hidden+1);

output_deltas=alloc_1d_dbl(n_out+1);

target=alloc_1d_dbl(n_out+1);

input_weights=alloc_2d_dbl(n_in+1,n_hidden+1);

input_prev_weights=alloc_2d_dbl(n_in+1,n_hidden+1);

hidden_prev_weights=alloc_2d_dbl(n_hidden+1,n_out+1);

hidden_weights=alloc_2d_dbl(n_hidden+1,n_out+1);

//为产生随机序列撒种

time_tt;

bpnn_initialize((unsigned)time(&t));

//对各种权值进行初始化初始化

bpnn_randomize_weights(input_weights,n_in,n_hidden);

bpnn_randomize_weights(hidden_weights,n_hidden,n_out);

bpnn_zero_weights(input_prev_weights,n_in,n_hidden);

bpnn_zero_weights(hidden_prev_weights,n_hidden,n_out);

//开始进行BP网络训练

//这里设定最大的迭代次数为15000次

for(l=0;l<15000;l++)

{

//对均方误差置零

ex=0;

//对样本进行逐个的扫描

for(k=0;k

{

//将提取的样本的特征向量输送到输入层上

for(i=1;i<=n_in;i++)

input_unites[i]=data_

展开阅读全文
相关资源
猜你喜欢
相关搜索

当前位置:首页 > 求职职场 > 面试

copyright@ 2008-2022 冰豆网网站版权所有

经营许可证编号:鄂ICP备2022015515号-1