神经网络文字识别关键代码文档格式.docx
《神经网络文字识别关键代码文档格式.docx》由会员分享,可在线阅读,更多相关《神经网络文字识别关键代码文档格式.docx(31页珍藏版)》请在冰豆网上搜索。
//保存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*)));
//申请失败处理
//printf("
ALLOC_2D_DBL:
tallocatearrayofdblptrs\n"
//再申请二维内存。
一维内存中存放的是指针
for(i=0;
i<
m;
i++){
new1[i]=alloc_1d_dbl(n);
//返回申请到的二维内存(可以看作矩阵)
/***设置随机数种子***/
voidbpnn_initialize(intseed)
//printf("
Randomnumbergeneratorseed:
%d\n"
seed);
srand(seed);
/***随机初始化权值***/
voidbpnn_randomize_weights(double**w,intm,intn)
inti,j;
//调用dpn1随机初始化权值
=m;
for(j=0;
j<
=n;
j++){
w[i][j]=dpn1();
}
/*******零初始化权值*******/
voidbpnn_zero_weights(double**w,intm,intn)
//将权值逐个赋0
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;
=n2;
/***计算输入的加权总和***/
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
=nj;
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)
doubleh,sum,errsum;
//误差归零
//计算新delta
=nh;
h=hidden[j];
for(k=1;
=no;
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网络权值调整的计算公式
=ndelta;
=nly;
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)
//临时缓冲区指针
//文件指针
//判断是否可以正确打开文件。
若失败则返回false
if((fp=fopen(name,"
rb"
))==NULL)
:
:
MessageBox(NULL,"
无法读取权值信息"
NULL,MB_ICONSTOP);
return(false);
//将临时缓冲区指针执行新申请的内存
//读取文件内容到缓冲区
fread((char*)buffer,sizeof(double),(n1+1)*(n2+1),fp);
//由缓冲区内容填写权值
w[i][j]=buffer[i*(n2+1)+j];
//释放临时缓冲区
//返回true表示已经正确读取
return(true);
/*****保存Bp网络各层结点的数目******/
voidw_num(intn1,intn2,intn3,char*name)
//缓冲区指针
int*buffer;
//分配内存并指向缓冲区指针
buffer=(int*)malloc(3*sizeof(int));
//将网络各层参数信息保存在临时缓冲区
buffer[0]=n1;
buffer[1]=n2;
buffer[2]=n3;
//将临时缓冲区内容写入文件
fwrite((char*)buffer,sizeof(int),3,fp);
/********读取Bp网络各层结点数目*********/
boolr_num(int*n,char*name)
//分配内存空间
buffer=(int*)malloc(3*sizeof(int));
结点参数"
//读取文件到缓冲区
fread((char*)buffer,sizeof(int),3,fp);
//从缓冲区中取出数据,存入n[0]~n[2]
n[0]=buffer[0];
n[1]=buffer[1];
n[2]=buffer[2];
//正确读取,返回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<
num;
k++)
{
//对每个数据逐行扫描
for(i=0;
lSheight;
{
//对每个数据逐列扫描
for(j=k*lSwidth;
(k+1)*lSwidth;
{
//指向图像第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;
//将提取的样本的特征向量输送到输入层上
for(i=1;
=n_in;
input_unites[i]=data_