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

上传人:b****6 文档编号:20917534 上传时间: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网络各层结点数目

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_

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

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

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

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