




版權說明:本文檔由用戶提供并上傳,收益歸屬內容提供方,若內容存在侵權,請進行舉報或認領
文檔簡介
1、神經網絡文字識別關鍵代碼下面作者列出bp網絡訓練及識別的完整源代碼bp.h。#include <stdio.h>#include <math.h> #include <time.h>#include <stdlib.h>#define BIGRND 32767/*函數聲明部分*/隨機數產生函數double drnd();double dpn1();/S函數double squash(double x);/分配1維double型的內存double *alloc_1d_dbl(int n);/分配2維double型的內存double *alloc_2
2、d_dbl(int m, int n);/初始化BP網絡void bpnn_initialize(int seed);/隨機初始化權值void bpnn_randomize_weights(double *w, int m, int n);/零初始化權值void bpnn_zero_weights(double *w, int m, int n);/信息的前向傳輸void bpnn_layerforward(double *l1, double *l2, double *conn, int n1, int n2);/誤差輸出void bpnn_output_error(double *delt
3、a, double *target, double *output, int nj);/隱層誤差void bpnn_hidden_error(double* delta_h, int nh, double *delta_o, int no, double *who, double *hidden);/根據誤差調整權值void bpnn_adjust_weights(double *delta, int ndelta, double *ly, int nly, double* w, double *oldw, double eta, double momentum);/保存權值void w_we
4、ight(double *w,int n1,int n2,char*name);/讀取權值bool r_weight(double *w,int n1,int n2,char *name);/保存Bp網絡各層結點數目void w_num(int n1,int n2,int n3,char*name);/讀取Bp網絡各層結點數目bool r_num(int *n,char *name);/特征提取void code(BYTE*image ,int *p,int w,int h,int dw);/BP網絡訓練void BpTrain(HDIB hDIB,int n_hidden,double mi
5、n_ex,double momentum,double eta ,int width,int height);/利用BP網絡進行識別void CodeRecognize(HDIB hDIB,int width ,int height ,int n_in ,int n_hidden,int n_out);/*/* 以下是函數的實現部分*/* 返回01的雙精度隨機數 */double drnd()/BIGRND定義為隨機數的最大范圍return (double) rand() / (double) BIGRND);/* 返回-1.0到1.0之間的雙精度隨機數 */double dpn1()retu
6、rn (drnd() * 2.0) - 1.0);double squash(double x)/返回S激活函數return (1.0 / (1.0 + exp(-x);/* 申請1維雙精度實數數組 */double *alloc_1d_dbl(int n)double *new1;/申請內存new1 = (double *) malloc (unsigned) (n * sizeof (double);/申請內存失敗處理if (new1 = NULL) printf("ALLOC_1D_DBL: Couldn't allocate array of doublesn&quo
7、t;);return (NULL);/返回申請到的內存的指針return (new1);/* 申請2維雙精度實數數組 */double *alloc_2d_dbl(int m, int n)int i;/定義一二維指針double *new1;/先申請一維內存new1 = (double *) malloc (unsigned) (m * sizeof (double *);/申請失敗處理if (new1 = NULL) /printf("ALLOC_2D_DBL: Couldn't allocate array of dbl ptrsn");return (NUL
8、L);/再申請二維內存。一維內存中存放的是指針for (i = 0; i < m; i+) new1i = alloc_1d_dbl(n);/返回申請到的二維內存(可以看作矩陣)return (new1);/* 設置隨機數種子 */void bpnn_initialize(int seed)/printf("Random number generator seed: %dn", seed);srand(seed);/* 隨機初始化權值 */void bpnn_randomize_weights(double *w, int m, int n)int i, j;/調用d
9、pn1隨機初始化權值for (i = 0; i <= m; i+) for (j = 0; j <= n; j+) wij = dpn1();/* 零初始化權值 */void bpnn_zero_weights(double *w, int m, int n)int i, j;/將權值逐個賦0for (i = 0; i <= m; i+) for (j = 0; j <= n; j+) wij = 0.0;/*前向傳輸*/void bpnn_layerforward(double *l1, double *l2, double *conn, int n1, int n2
10、)double sum;int j, k;/* 設置閾值 */l10 = 1.0;/* 對于第二層的每個神經元 */for (j = 1; j <= n2; j+) /* 計算輸入的加權總和 */sum = 0.0;for (k = 0; k <= n1; k+) sum += connkj * l1k;l2j = squash(sum);/* 輸出誤差 */void bpnn_output_error(double *delta, double *target, double *output, int nj)int j;double o, t, errsum;/先將誤差歸零err
11、sum = 0.0;/循環計算deltafor (j = 1; j <= nj; j+) o = outputj;t = targetj;/計算delta值deltaj = o * (1.0 - o) * (t - o);/* 隱含層誤差 */void bpnn_hidden_error(double* delta_h, int nh, double *delta_o, int no, double *who, double *hidden)int j, k;double h, sum, errsum;/誤差歸零errsum = 0.0;/計算新deltafor (j = 1; j &l
12、t;= nh; j+) h = hiddenj;sum = 0.0;for (k = 1; k <= no; k+) sum += delta_ok * whojk;delta_hj = h * (1.0 - h) * sum;/* 調整權值 */void bpnn_adjust_weights(double *delta, int ndelta, double *ly, int nly, double* w, double *oldw, double eta, double momentum)double new_dw;int k, j;ly0 = 1.0;/請參考文章中BP網絡權值調
13、整的計算公式for (j = 1; j <= ndelta; j+) for (k = 0; k <= nly; k+) new_dw = (eta * deltaj * lyk) + (momentum * oldwkj);wkj += new_dw;oldwkj = new_dw;/*保存權值*/void w_weight(double *w,int n1,int n2,char*name)int i,j;double *buffer;/創建文件指針FILE *fp;/打開文件fp=fopen(name,"wb+");/分配緩沖區buffer=(double
14、*)malloc(n1+1)*(n2+1)*sizeof(double);/填寫緩沖區內容for(i=0;i<=n1;i+)for(j=0;j<=n2;j+)bufferi*(n2+1)+j=wij;/將緩沖區內容寫入文件fwrite(char*)buffer,sizeof(double),(n1+1)*(n2+1),fp);/關閉文件fclose(fp);/清空緩沖區free(buffer);/*讀取權值*/bool r_weight(double *w,int n1,int n2,char *name)int i,j;/臨時緩沖區指針double *buffer;/文件指針FI
15、LE *fp;/判斷是否可以正確打開文件。若失敗則返回falseif(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;
16、i+)for(j=0;j<=n2;j+)wij=bufferi*(n2+1)+j;/關閉文件fclose(fp);/釋放臨時緩沖區free(buffer);/返回true表示已經正確讀取return(true);/*保存Bp網絡各層結點的數目*/void w_num(int n1,int n2,int n3,char*name)/文件指針FILE *fp;/打開文件fp=fopen(name,"wb+");/緩沖區指針int *buffer;/分配內存并指向緩沖區指針buffer=(int*)malloc(3*sizeof(int);/將網絡各層參數信息保存在臨時緩沖
17、區buffer0=n1;buffer1=n2;buffer2=n3;/將臨時緩沖區內容寫入文件fwrite(char*)buffer,sizeof(int),3,fp);/關閉文件fclose(fp);/清空緩沖區free(buffer);/*讀取Bp網絡各層結點數目*/bool r_num(int *n,char *name)/臨時緩沖區指針int *buffer;/文件指針FILE *fp;/分配內存空間buffer=(int *)malloc(3*sizeof(int);if(fp=fopen(name,"rb")=NULL):MessageBox(NULL,&quo
18、t;結點參數",NULL,MB_ICONSTOP);return (false);/讀取文件到緩沖區fread(char*)buffer,sizeof(int),3,fp);/從緩沖區中取出數據,存入n0n2n0=buffer0;n1=buffer1;n2=buffer2;/關閉文件fclose(fp);/清空緩沖區free(buffer);/正確讀取,返回truereturn(true);/* 函數名稱 code()* 參量:* BYTE* lpDIBBits -指向輸入圖像的像素其實位置的指針 * int num -圖片中樣本的個數* LONG lLineByte -輸入圖片每行
19、的字節數* LONG lSwidth -預處理時歸一化的寬度* LONG lSheight -預處理時歸一化的長度* 函數功能 :* 對于輸入樣本提取特征向量,在這里把歸一化樣本的* 每一個像素都作為特征提取出來*/double* code (BYTE* lpDIBBits,int num, LONG lLineByte,LONG lSwidth,LONG lSheight) /循環變量int i,j,k;BYTE* lpSrc; / 建立保存特征向量的二維數組double *data;/ 為這個數組申請二維存儲空間data = alloc_2d_dbl(num,lSwidth*lSheigh
20、t);/ 將歸一化的樣本的每個像素作為一個特征點提取出來/逐個數據掃描for(k=0;k<num;k+) /對每個數據逐行掃描for(i=0;i<lSheight;i+) /對每個數據逐列掃描for(j=k*lSwidth;j<(k+1)*lSwidth;j+)/ 指向圖像第i行第j列個像素的指針lpSrc = lpDIBBits + i*lLineByte + j;/如果這個像素是黑色的if(*(lpSrc)=0)/將特征向量的相應位置填1dataki*lSwidth+j-k*lSwidth=1;/如果這個像素是其他的 if(*(lpSrc)!=0)/將特征向量的相應位置填
21、0dataki*lSwidth+j-k*lSwidth=0;/返回指向特征矩陣的二維指針/特征矩陣構成:每個樣本×每個樣本的特征return(data); /* 函數名稱 BpTrain()* * 參數:* double *data_in -指向輸入的特征向量數組的指針 *double *data_out -指向理想輸出數組的指針int n_in -輸入層結點的個數 * int n_hidden -BP網絡隱層結點的數目* double min_ex -訓練時允許的最大均方誤差* double momentum -BP網絡的相關系數* double eta -BP網絡的訓練步長* i
22、nt num -輸入樣本的個數* 函數功能:* 根據輸入的特征向量和期望的理想輸出對BP網絡盡行訓練* 訓練結束后將權值保存并將訓練的結果顯示出來*/void BpTrain(double * data_in, double* data_out,int n_in,int n_hidden,double min_ex,double momentum,double eta ,int num)/循環變量 int i,k,l;/輸出層結點數目int n_out=4; /指向輸入層數據的指針double* input_unites; /指向隱層數據的指針double* hidden_unites;/指向
23、輸出層數據的指針double* output_unites; /指向隱層誤差數據的指針double* hidden_deltas;/指向輸出層誤差數劇的指針double* output_deltas; /指向理想目標輸出的指針double* target; /指向輸入層于隱層之間權值的指針double* input_weights;/指向隱層與輸出層之間的權值的指針double* hidden_weights;/指向上一此輸入層于隱層之間權值的指針double* input_prev_weights ;/指向上一此隱層與輸出層之間的權值的指針double* hidden_prev_weight
24、s;/每次循環后的均方誤差誤差值 double ex;/為各個數據結構申請內存空間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(
25、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_t t; bpnn_initialize(unsigned)time(&t);/對各種權值進行初始化初始化bpnn_randomize_weights( input_w
26、eights,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<num;k+) /將提取的樣本的特征向量輸送到輸
27、入層上for(i=1;i<=n_in;i+)input_unitesi = data_inki-1;/將預定的理想輸出輸送到BP網絡的理想輸出單元for(i=1;i<=n_out;i+)targeti=data_outki-1;/前向傳輸激活/將數據由輸入層傳到隱層 bpnn_layerforward(input_unites,hidden_unites,input_weights, n_in,n_hidden);/將隱層的輸出傳到輸出層bpnn_layerforward(hidden_unites, output_unites,hidden_weights,n_hidden,n_
28、out);/誤差計算/將輸出層的輸出與理想輸出比較計算輸出層每個結點上的誤差bpnn_output_error(output_deltas,target,output_unites,n_out);/根據輸出層結點上的誤差計算隱層每個節點上的誤差bpnn_hidden_error(hidden_deltas,n_hidden, output_deltas, n_out,hidden_weights, hidden_unites);/權值調整/根據輸出層每個節點上的誤差來調整隱層與輸出層之間的權值 bpnn_adjust_weights(output_deltas,n_out, hidden_un
29、ites,n_hidden,hidden_weights, hidden_prev_weights, eta, momentum); /根據隱層每個節點上的誤差來調整隱層與輸入層之間的權值 bpnn_adjust_weights(hidden_deltas, n_hidden, input_unites, n_in,input_weights, input_prev_weights, eta, momentum); /誤差統計for(i=1;i<=n_out;i+)ex+=(output_unitesi-data_outki-1)*(output_unitesi-data_outki-1
30、);/計算均方誤差ex=ex/double(num*n_out);/如果均方誤差已經足夠的小,跳出循環,訓練完畢 if(ex<min_ex)break;/相關保存/保存輸入層與隱層之間的權值w_weight(input_weights,n_in,n_hidden,"win.dat");/保存隱層與輸出層之間的權值w_weight(hidden_weights,n_hidden,n_out,"whi.dat");/保存各層結點的個數w_num(n_in,n_hidden,n_out,"num");/顯示訓練結果CString st
31、r;if(ex<=min_ex)str.Format ("迭代%d次,n平均誤差%.4f",l,ex);:MessageBox(NULL,str,"訓練結果",NULL);if(ex>min_ex)str.Format("迭代%d次,平均誤差%.4fn我已經盡了最大努力了還是達不到您的要求n請調整參數重新訓練吧!",l,ex);:MessageBox(NULL,str,"訓練結果",NULL);/釋放內存空間free(input_unites);free(hidden_unites);free(outp
32、ut_unites);free(hidden_deltas);free(output_deltas);free(target);free(input_weights);free(hidden_weights);free(input_prev_weights);free(hidden_prev_weights);/* 函數名稱* CodeRecognize()* 參量* double *data_in -指向待識別樣本特征向量的指針* int num -待識別的樣本的個數 * int n_in -Bp網絡輸入層結點的個數 * int n_hidden -Bp網絡隱層結點的個數* int n_ou
33、t -Bp網絡輸出層結點的個數* 函數功能: * 讀入輸入樣本的特征相量并根據訓練所得的權值 * 進行識別,將識別的結果寫入result.txt */void CodeRecognize(double *data_in, int num ,int n_in,int n_hidden,int n_out)/循環變量int i,k;/ 指向識別結果的指針 int *recognize;/為存放識別的結果申請存儲空間recognize=(int*)malloc(num*sizeof(int);/指向輸入層數據的指針double* input_unites; /指向隱層數據的指針double* hid
34、den_unites;/指向輸出層數據的指針double* output_unites; /指向輸入層于隱層之間權值的指針double* input_weights;/指向隱層與輸出層之間的權值的指針double* hidden_weights;/為各個數據結構申請內存空間input_unites= alloc_1d_dbl(n_in + 1);hidden_unites=alloc_1d_dbl(n_hidden + 1);output_unites=alloc_1d_dbl(n_out + 1);input_weights=alloc_2d_dbl(n_in + 1, n_hidden +
35、 1);hidden_weights = alloc_2d_dbl(n_hidden + 1, n_out + 1);/讀取權值if( r_weight(input_weights,n_in,n_hidden,"win.dat")=false)return;if(r_weight(hidden_weights,n_hidden,n_out,"whi.dat")=false)return;/逐個樣本掃描for(k=0;k<num;k+) /將提取的樣本的特征向量輸送到輸入層上for(i=1;i<=n_in;i+)input_unitesi=da
36、ta_inki-1;/前向輸入激活bpnn_layerforward(input_unites,hidden_unites,input_weights, n_in,n_hidden);bpnn_layerforward(hidden_unites, output_unites,hidden_weights,n_hidden,n_out);/根據輸出結果進行識別int result=0 ;/考察每一位的輸出for(i=1;i<=n_out;i+)/如果大于0.5判為1if(output_unitesi>0.5)result+=(int)pow(2,double(4-i);/如果判定的
37、結果小于等于9,認為合理if(result<=9)recognizek=result;/如果判定的結果大于9,認為不合理將結果定位為一個特殊值20if(result>9)recognizek=20;/將識別結果寫到文本中FILE *fp;fp=fopen("result.txt","w+");for(i=0;i<num;i+) if(recognizei=20)fprintf(fp,"無法識別,");elsefprintf(fp,"%d,",recognizei);fclose(fp);/將識別的
38、結果顯示出來CString str,str1;for(i=0;i<num;i+)if(recognizei!=20)str.Format("%d ",recognizei);if(recognizei=20)str.Format("無法識別 ");str1+=str;/通知用戶訓練完成:MessageBox(NULL,str1,"識別結果",NULL);/釋放存儲空間free(input_unites);free(hidden_unites);free(output_unites);free(input_weights);fre
39、e(hidden_weights);下面是菜單事件響應函數。訓練BP網絡:void CChildView:OnBpnetTrain() OnImgprcAll();/判斷是否經過了歸一劃的處理if(gyhfinished=false)/如果沒有進行提示錯誤并返回:MessageBox(NULL,"沒有進行歸一劃預處理",NULL,MB_ICONSTOP);return;/建立BP網絡訓練參數對話框CDBpParamater BpPa;/用默認值初始化變量/動量因子BpPa.m_a=0;/學習步長BpPa.m_eta=0.015;/允許誤差BpPa.m_ex=0.001;/隱
40、層神經元數目BpPa.m_hn=10;/ 顯示對話框if(BpPa.DoModal()!=IDOK)/返回return;/用戶獲得參數信息/相關系數(動量因子)double momentum=BpPa.m_a; /最小均方誤差double min_ex=BpPa.m_ex; /隱層數目int n_hidden=BpPa.m_hn; /訓練步長double eta=BpPa.m_eta;/獲得指向DIB的指針BYTE *lpDIB=(BYTE*):GlobalLock(HGLOBAL) m_hDIB);/獲得指向DIB像素的指針,并指向像素的起始位置BYTE *lpDIBBits =(BYTE*
41、):FindDIBBits(char *)lpDIB);/獲得顏色信息int numColors=(int) :DIBNumColors(char *)lpDIB);/不是灰度圖返回if (numColors!=256) :GlobalUnlock(HGLOBAL) m_hDIB);:MessageBox(NULL,"只能處理灰度圖像",NULL,MB_ICONSTOP);return;/獲取圖像的寬度LONG lWidth = (LONG) :DIBWidth(char *)lpDIB); /獲取圖像的高度LONG lHeight = (LONG) :DIBHeight(
42、char *)lpDIB);/計算圖像每行的字節數LONG lLineByte = (lWidth+3)/4*4; /歸一化的寬度LONG lSwidth = w_sample;/歸一化的高度LONG LSheight = h_sample;/指向輸入樣本的特征向量的指針 double *data_in;/從輸入的訓練樣本中提取特征向量data_in = code ( lpDIBBits, digicount, lLineByte, lSwidth, LSheight);/計算輸入層結點的數目int n_in = LSheight*lSwidth;/設定目標輸出向量double out4= 0.1,0.1,0.1,0.1,0.1,0.1,0.1,0.9,0.1,0.1,0.9,0.1,0.1,0.1,0.9,0.9,0.1,0.9,0.1,0.1,0.1,0.9,0.1,0.9,0.1,0.9,0.9,0.1,0.1,0.9,0.9,0.9,0.9,0.1,0.1,0.1,0.9,0.1,0.1,0.9;/指向輸出double *data_out;data_out = alloc_2d_dbl(digicount,4);for(int i=0;i<digicount;i+)for(int
溫馨提示
- 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
- 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯系上傳者。文件的所有權益歸上傳用戶所有。
- 3. 本站RAR壓縮包中若帶圖紙,網頁內容里面會有圖紙預覽,若沒有圖紙預覽就沒有圖紙。
- 4. 未經權益所有人同意不得將文件中的內容挪作商業或盈利用途。
- 5. 人人文庫網僅提供信息存儲空間,僅對用戶上傳內容的表現方式做保護處理,對用戶上傳分享的文檔內容本身不做任何修改或編輯,并不能對任何下載內容負責。
- 6. 下載文件中如有侵權或不適當內容,請與我們聯系,我們立即糾正。
- 7. 本站不保證下載資源的準確性、安全性和完整性, 同時也不承擔用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。
最新文檔
- 口腔科用生物材料性能考核試卷
- 演出經紀人職業素養提升與道德規范踐行考核試卷
- 礦用設備虛擬現實維修培訓考核試卷
- 電影道具制作中的藝術表現考核試卷
- 紡織品企業戰略合作伙伴關系管理考核試卷
- 核果類水果種植園防寒保暖考核試卷
- 電纜的絕緣材料耐熱性能研究考核試卷
- 遼寧省阜新市清河門區2025屆三下數學期末聯考模擬試題含解析
- 濟寧醫學院《機器人學》2023-2024學年第二學期期末試卷
- 泉州海洋職業學院《三維動畫綜合實訓》2023-2024學年第一學期期末試卷
- 大概念科學教學
- 2025-2030中國行李物品行業市場發展趨勢與前景展望戰略分析研究報告
- 心理咨詢師的倫理與試題及答案
- 2024年勞務員考試題庫完美版
- 2025年商丘職業技術學院單招職業技能考試題庫附答案
- 礦山地質環境保護與土地復墾方案報告正文
- IATF16949-應急計劃評審報告
- 第12課 遼宋夏金元時期經濟的繁榮 教案2024-2025學年七年級歷史下冊新課標
- 輸血病人的個案護理
- 企業生產安全臺賬資料填寫模板
- 2025年婚內財產約定協議書模板電子版
評論
0/150
提交評論