前段时间毕业设计中写的一段代码,三层BP神经网络用于自适应,用Levenberg-Maquardt法进行训练。
#define
EPSILON 1E-6

//
3层的神经网络结构
typedef
struct
tag_bpnnt

...
{
int in_n; //输入层神经元数
int hidd_n; //隐层神经元数
int out_n; //输出层神经元
double *in_unit; //输入层神经元
double *hidd_unit; //隐层神经元
double *out_unit; //输出层神经元
double *hidd_delta; //隐层误差
double *out_delta; //输出层误差
double *hidd_dfda;
double *out_dfda;
double *target; //目标向量
double **in_w; //输入层权值
double **hidd_w; //隐层权值
//前一次结果(用于迭代)
double **prev_in_w;
double **prev_hidd_w;
}
BPNN_t;

//
分配1d内存
double
*
bpnn_malloc1d(
int
n);

//
分配2d内存
double
**
bpnn_malloc2d(
int
m,
int
n);

//
销毁2d内存
void
bpnn_mfree2d(
double
**
pmem,
int
m);

//
计算sigmoid函数
double
sigmoid(
double
x);

//
建立神经网络
BPNN_t
*
bpnn_create(
int
nIn,
int
nHidden,
int
nOut);

//
销毁网络
void
bpnn_destroy(BPNN_t
*
pNet);

//
初始化权值
void
bpnn_init_weight(
double
**
w,
int
m,
int
n,
int
flag);

//
前向计算本层输出
void
bpnn_layerforward(
double
*
layer1,
double
*
layer2,
double
**
conn,
int
n1,
int
n2);

//
计算输出层反传误差
void
bpnn_out_error(
double
*
delta,
double
*
dfda,
double
*
target,
double
*
output,
int
nj,
double
*
err);

//
计算隐层反传误差
void
bpnn_hidd_error(
double
*
delta_h,
double
*
delta_o,
double
*
dfda_h,
double
*
dfda_o,
int
nh,
int
nout,
double
**
w_ho,
double
*
h_unit,
double
*
err);

//
计算整个网络输出
void
bpnn_nnforward(BPNN_t
*
pNet);

//
最速下降法训练一次
double
bpnn_train_steepest(BPNN_t
*
pNet,
double
eta,
double
**
indata,
double
**
targetdata,
int
np);


//
Levenberg-Marquardt训练
double
bpnn_train_lm(BPNN_t
*
pNet,
double
**
indata,
double
**
targetdata,
int
np,
double
*
lamda);

//
gauss-jordan消元法解线性方程组
void
gauss_jordan(
double
*
a,
double
*
b,
int
n);
#include
<
stdlib.h
>
#include
<
string
.h
>
#include
<
math.h
>
#include
<
time.h
>

#include
"
bpnn.h
"

//
交换
#define
SWAP(x,y) if((x)!=(y))

...
{ x = x+y;
y = x-y;
x = x-y; }

//
设置单位矩阵
static
void
SetEye(
double
*
mat,
int
n);

//
分配1d内存
double
*
bpnn_malloc1d(
int
n)

...
{
double *pout;
pout = (double*)malloc(n*sizeof(double));
return pout;
}

//
分配2d内存
//
m为行数(组数), n为列数(每组个数)
double
**
bpnn_malloc2d(
int
m,
int
n)

...
{
double **pout;
int i;
pout = (double**)malloc(m * sizeof(double*));
for(i=0; i<m; i++)

...{
pout[i] = (double*)malloc(n*sizeof(double));
}
return pout;
}

//
销毁2d内存
void
bpnn_mfree2d(
double
**
pmem,
int
m)

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

...{
free(pmem[i]);
}
free(pmem);
pmem = NULL;
}



/**/
/
//
初始化权值
//
参数
//
flag -- 1 随机初始化 0 全部清0
//
m -- 上一层神经元数目
//
n -- 下一层神经元数目

/**/
////
void
bpnn_init_weight(
double
**
w,
int
m,
int
n,
int
flag)

...
{
int i,j;
srand((unsigned int)time(NULL));
if(flag) //随机生成

...{
for(i=0; i<m+1; i++)
for(j=0; j<n+1; j++)

...{
//-1.0 ~ 1.0的随机值
w[i][j] = (double)(rand()%2000) / 1000.0 - 1;
}

}
else //全部清0

...{
for(i=0; i<m+1; i++)
for(j=0; j<n+1; j++)

...{
w[i][j] = 0.0;
}
}

}

//
计算sigmoid函数
double
sigmoid(
double
x)

...
{
return 1.0 / (1.0+exp(-x));
}


/**/
/