?? bp.h
字號:
#include <stdio.h>
#include <math.h>
#include <time.h>
#include <stdlib.h>
#define BIGRND 32767
double drnd();
double dpn1();
double squash(double x);
double *alloc_1d_dbl(int n);
double *alloc_1d_dbl(int n);
double **alloc_2d_dbl(int m, int n);
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 *delta, 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_weight(double **w,int n1,int n2,char*name);
bool r_weight(double **w,int n1,int n2,char *name);
void w_num(int n1,int n2,int n3,char*name);
bool r_num(int *n,char *name);
void code(BYTE*image ,int *p,int w,int h,int dw);
void BpTrain(HDIB hDIB,int n_hidden,double min_ex,double momentum,double eta ,int width,int height);
void CodeRecognize(HDIB hDIB,int width ,int height ,int n_in ,int n_hidden,int n_out);
/*** 返回0-1的雙精度隨機數 ***/
double drnd()
{
return ((double) rand() / (double) BIGRND);
}
/*** 返回-1.0到1.0之間的雙精度隨機數 ***/
double dpn1()
{
return ((drnd() * 2.0) - 1.0);
}
double squash(double x)
{
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 doubles\n");
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 ptrs\n");
return (NULL);
}
for (i = 0; i < m; i++) {
new1[i] = alloc_1d_dbl(n);
}
return (new1);
}
/*** 設置隨機數種子 ***/
void bpnn_initialize(int seed)
{
//printf("Random number generator seed: %d\n", seed);
srand(seed);
}
/*** 隨機初始化權值 ***/
void bpnn_randomize_weights(double **w, int m, int n)
{
int i, j;
for (i = 0; i <= m; i++) {
for (j = 0; j <= n; j++) {
w[i][j] = dpn1();
}
}
}
/*** 0初始化權值 ***/
void bpnn_zero_weights(double **w, int m, int n)
{
int i, j;
for (i = 0; i <= m; i++) {
for (j = 0; j <= n; j++) {
w[i][j] = 0.0;
}
}
}
/*********前向傳輸*********/
void bpnn_layerforward(double *l1, double *l2, double **conn, int n1, int n2)
{
double sum;
int j, 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);
}
}
/* 輸出誤差 */
void bpnn_output_error(double *delta, double *target, double *output, int nj)
{
int j;
double o, t, errsum;
errsum = 0.0;
for (j = 1; j <= nj; j++) {
o = output[j];
t = target[j];
delta[j] = 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;
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;
}
}
/* 調整權值 */
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;
ly[0] = 1.0;
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;
}
}
}
/*******保存權值**********/
void w_weight(double **w,int n1,int n2,char*name)
{
int i,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);
}
/************讀取權值*************/
bool r_weight(double **w,int n1,int n2,char *name)
{
int i,j;
double *buffer;
FILE *fp;
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);
return(true);
}
/*****保存各層結點的數目******/
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));
buffer[0]=n1;
buffer[1]=n2;
buffer[2]=n3;
fwrite((char*)buffer,sizeof(int),3,fp);
fclose(fp);
free(buffer);
}
/********讀取各層結點數目*********/
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,"結點參數",NULL,MB_ICONSTOP);
return (false);
}
fread((char*)buffer,sizeof(int),3,fp);
n[0]=buffer[0];
n[1]=buffer[1];
n[2]=buffer[2];
fclose(fp);
free(buffer);
return(true);
}
/********************************************************
* 函數名稱 VerticalCode()
*
* 參量:
* BYTE* lpDIBBits -指向輸入圖像的象素其實位置的指針
* int num -圖片中樣本的個數
* LONG lLineByte -輸入圖片每行的字節數
* LONG lSwidth -預處理時歸一化的寬度
* LONG lSheight -預處理時歸一化的長度
*
* 返回值:
* double** -特征向量矩陣
*
* 函數功能 :
* 對于輸入樣本提取特征向量,在這里把歸一化樣本的
* 水平和豎直方向的統計特征作為特征提取出來
***************************************************************/
double** VerticalCode(BYTE* lpDIBBits,int num, LONG lLineByte,LONG lSwidth,LONG lSheight)
{
//循環變量
int i,j,k;
BYTE* lpSrc;
//統計變量
int sum;
// 建立保存特征向量的二維數組
double **data;
// 為這個數組申請二維存儲空間
data = alloc_2d_dbl(num,lSwidth+lSheight);
// 將歸一化的樣本的每個象素作為一個特征點提取出來
//逐個數據掃描
for(k=0;k<num;k++)
{
//統計每行的象素點個數
for(i=0;i<lSheight;i++)
{
//對統計變量初始化
sum=0;
//對每個數據逐列掃描
for(j=k*lSwidth;j<(k+1)*lSwidth;j++)
{
// 指向圖像第i行第j列個象素的指針
lpSrc = lpDIBBits + i*lLineByte + j;
//如果這個象素是黑色的
if(*(lpSrc)==0)
//統計變量加1
sum++;
}
data[k][i]=sum;
}
//統計每列的象素點個數
for(j=k*lSwidth;j<(k+1)*lSwidth;j++)
{
//對統計變量初始化
sum=0;
//對每個數據逐行掃描
for(i=0;i<lSheight;i++)
{
// 指向圖像第i行第j列個象素的指針
lpSrc = lpDIBBits + i*lLineByte + j;
//如果這個象素是黑色的
if(*(lpSrc)==0)
//統計變量加1
sum++;
}
data[k][j-k*lSwidth+lSheight]=sum;
}
}
//返回特征向量矩陣
return(data);
}
/*******************************************************************
*
*函數名稱:
* TZTQ_13
*參數:
* HDIB hDIB -待提取特征的位圖的句柄
* int num -字符的數目
* int dim -提取特征的維數。這里固定為13
*說明:
* 圖像分為8塊,作為8個特征;象素總數作為一個特征;水平切割過去兩條線,得*到兩個特征;垂直的兩個,總共得到13個特征
*
*********************************************************************/
double * * TZTQ_13(HDIB hDIB,int num,int dim)
{
int i,j,k,m;
//分配一個內存空間并得到二維指針
double * * tezheng=alloc_2d_dbl(num,dim);
//鎖定圖像句柄并獲取其指針
BYTE* lpDIB=(BYTE*)::GlobalLock ((HGLOBAL)hDIB);
//取得圖像象素數據區的起始地址
BYTE* lpDIBBits=(BYTE*)::FindDIBBits((char*)lpDIB);
BYTE* lpSrc;
//獲取圖像高度
LONG lHeight=::DIBHeight ((char*)lpDIB);
//獲取圖像寬度
LONG lWidth=::DIBWidth ((char*)lpDIB);
LONG width=lWidth/num;
//每行的字節數
LONG lLineBytes = WIDTHBYTES(lWidth * 8);
int b;
//存儲臨時的特征
double * tz=new double[dim];
for(k=0;k<num;k++)
{
for(i=0;i<dim;i++) tz[i]=0;
//提取前8個特征
for(m=0;m<8;m++)
{ for(i=int(m/2)*8;i<(int(m/2)+1)*8;i++)
for(j=m%2*8+k*width;j<(m%2+1)*8+k*width;j++)
{ lpSrc=(unsigned char*)lpDIBBits + lLineBytes * i + j;
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -