c语言 bp,BP网(C语言实现)

#include #include #include #include #include "utility.h"

#define NUM_IN     6 //输入层神经元数量I

#define NUM_MID    5 //中间层神经元数量J

#define NUM_OUT    4 //输出层神经元数量K

#define NUM_PATTERN 3 //输入的模式数量

#define CONSTANT 0.15  //η常量

#define MAX_COUNT 10000 //最大学习次数

double input_in[NUM_PATTERN][NUM_IN]; //输入层的输入值

double input_mid[NUM_MID]; //中间层的输入值

double output_mid[NUM_MID]; //中间层的输出值

double input_out[NUM_OUT]; //输出层的输入值

double output_out[NUM_OUT]; //输出层的输出值

double V[NUM_MID][NUM_IN]; //中间层神经元与输入层神经元的权值

double W[NUM_OUT][NUM_MID]; //输出层神经元与中间层神经元的权值

double v[NUM_MID];   //中间层阈值

double w[NUM_OUT];   //输出层阈值

double d[NUM_PATTERN][NUM_OUT];  //输出层的教师信号

double error_out[NUM_OUT];  //输出层各单元的一般化误差

double error_mid[NUM_MID];  //中间层各单元的一般化误差

int dirty[NUM_PATTERN];   //如果模式i未被访问过,则dirty[i] == TRUE

char *Filename = "1.PTN"; //学习模式文件

char *Filename1 = "1.TSIG"; //教师信号文件

char *Filename2 = "1.RESULT"; //结果文件

void process();    //主计算过程

int trainpattern(int pattern); //训练模式

void initialize();   //初始化函数

void init_weight();   //初始化权重、阈值

void load_patternfile(); //从文件加载学习模式

void load_techersig();  //从文件加载教师信号

void compute_midinput(int pattern); //计算中间层输入值

void compute_midoutput(); //计算中间层输出值

void compute_outinput(); //计算输出层输入值

void compute_outoutput(); //计算输出层输出值

void compute_outerror(int pattern); //计算输出层各单元的一般化误差

void compute_miderror(); //计算中间层各单元的一般化误差

void adjust_mid_out();  //调整中间层至输出层之间的连接权值及输出层各单元的阈值

void adjust_in_mid(int pattern); //调整输入层至中间层之间的连接权值,及中间层各单元的阈值

double Func(double net); //f() sigmoid函数

void print_all();   //打印所有数组

/********************************************************

程序入口

*********************************************************/

int main(int argc, char **args)

{

if(argc == 3){

Filename = args[1];

Filename1 = args[2];

}

initialize();

process();

print_all();

return(1);

}

/********************************************************

初始化

*********************************************************/

void initialize()

{

init_weight();

//print_all();

load_patternfile();

load_techersig();

setalldirty(NUM_PATTERN, dirty);

}

/********************************************************

从文件加载学习模式

*********************************************************/

void init_weight()

{

int i, j, k;

printf("\n开始初始化权值、阈值...");

//初始化中间层神经元与输入层神经元的权值

for(j = 0;j < NUM_MID;j++)

for(i = 0;i < NUM_IN;i++)

V[j][i] = gen_random();

//初始化输出层神经元与中间层神经元的权值

for(k = 0;k < NUM_OUT;k++)

for(j = 0;j < NUM_MID;j++)

W[k][j] = gen_random();

//初始化中间层阈值

for(j = 0;j < NUM_MID;j++)

v[j] = gen_random();

//初始化输出层阈值

for(k = 0;k < NUM_OUT;k++)

w[k] = gen_random();

printf("\n初始化权值、阈值完毕...");

}

/********************************************************

从文件加载学习模式

*********************************************************/

void load_patternfile()

{

FILE *PATTERNFILE;

double temp;

int i, j;

printf("\n开始加载学习模式...");

PATTERNFILE = fopen(Filename, "r");

if(PATTERNFILE == NULL){

printf("\n不能打开学习模式文件:%s\n", Filename);

exit(0);

}

for(i = 0;i < NUM_PATTERN;i++){

for(j = 0;j < NUM_IN;j++){

fscanf(PATTERNFILE, PREMISE, &temp);

input_in[i][j] = temp;

}

}

fclose(PATTERNFILE);

printf("\n加载学习模式完毕...");

}

/********************************************************

从文件加载教师信号

*********************************************************/

void load_techersig()

{

FILE *TSIGFILE;

double temp;

int i, j;

printf("\n开始加载教师信号...");

TSIGFILE = fopen(Filename1, "r");

if(TSIGFILE == NULL){

printf("\n不能打开学习教师信号文件:%s\n", Filename1);

exit(0);

}

for(i = 0;i < NUM_PATTERN;i++){

for(j = 0;j < NUM_OUT;j++){

fscanf(TSIGFILE, PREMISE, &temp);

d[i][j] = temp;

}

}

fclose(TSIGFILE);

printf("\n加载教师信号完毕...");

}

/********************************************************

主计算过程

*********************************************************/

void process()

{

int counter = 0; //学习次数计数器

int rand_pattern, ChngCount = 0;

printf("\n进行第1次学习\n");

while(counter < MAX_COUNT){

rand_pattern = random(NUM_PATTERN);

dirty[rand_pattern] = FALSE;

trainpattern(rand_pattern);

if(isallclean(NUM_PATTERN, dirty)){

setalldirty(NUM_PATTERN, dirty);

counter++;

printf("\n进行第%d次学习\n", counter);

}

}

}

/********************************************************

训练模式

*********************************************************/

int trainpattern(int pattern)

{

compute_midinput(pattern);

compute_midoutput();

compute_outinput();

compute_outoutput();

compute_outerror(pattern);

compute_miderror();

adjust_mid_out();

adjust_in_mid(pattern);

if(dirty[pattern] == TRUE)

return TRUE;

else

return FALSE;

}

/********************************************************

计算中间层输入值

*********************************************************/

void compute_midinput(int pattern)

{

int i, j;

for(j = 0;j < NUM_MID;j++){

input_mid[j] = 0;

for(i = 0;i < NUM_IN;i++){

input_mid[j] += V[j][i]*input_in[pattern][i];

}

input_mid[j] -= v[j];

}

}

/********************************************************

计算中间层输出值

*********************************************************/

void compute_midoutput()

{

int j;

for(j = 0;j < NUM_MID;j++)

output_mid[j] = Func(input_mid[j]);

}

/********************************************************

计算输出层输入值

*********************************************************/

void compute_outinput()

{

int j, k;

for(k = 0;k < NUM_OUT;k++){

input_out[k] = 0;

for(j = 0;j < NUM_MID;j++){

input_out[j] += W[k][j]*output_mid[j];

}

input_out[k] -= w[k];

}

}

/********************************************************

计算输出层输出值

*********************************************************/

void compute_outoutput()

{

int k;

for(k = 0;k < NUM_OUT;k++)

output_out[k] = Func(input_out[k]);

}

/********************************************************

计算输出层各单元的一般化误差

*********************************************************/

void compute_outerror(int pattern)

{

int k;

for(k = 0;k < NUM_OUT;k++){

error_out[k] = (d[pattern][k] - output_out[k])*output_out[k]*(1 - output_out[k]);

}

}

/********************************************************

计算中间层各单元的一般化误差

*********************************************************/

void compute_miderror()

{

int j, k;

for(j = 0;j < NUM_MID;j++){

error_mid[j] = 0;

for(k = 0;k < NUM_OUT;k++)

error_mid[j] += error_out[k]*W[k][j];

error_mid[j] = error_mid[j]*output_mid[j]*(1 - output_mid[j]);

}

}

/********************************************************

调整中间层至输出层之间的连接权值及输出层各单元的阈值

*********************************************************/

void adjust_mid_out()

{

int j, k;

for(k = 0;k < NUM_OUT;k++){

for(j = 0;j < NUM_MID;j++)

W[k][j] += CONSTANT*error_out[k]*output_mid[j];

w[k] -= CONSTANT*error_out[k];

}

}

/********************************************************

调整输入层至中间层之间的连接权值,及中间层各单元的阈值

*********************************************************/

void adjust_in_mid(int pattern)

{

int i, j;

for(j = 0;j < NUM_MID;j++){

for(i = 0;i < NUM_IN;i++)

V[j][i] += CONSTANT*error_mid[j]*input_in[pattern][i];

v[j] -= CONSTANT*error_mid[j];

}

}

/********************************************************

f()函数

*********************************************************/

double Func(double net)

{

return 1/(1 + exp(-net));

}

/********************************************************

打印所有数组

*********************************************************/

void print_all()

{

FILE *RESULTFILE = fopen(Filename2, "w");

if(RESULTFILE == NULL){

printf("不能打开结果文件: %s", Filename2);

exit(0);

}

printf("\n打印学习模式");

fprintf(RESULTFILE, "\n打印学习模式");

print_two(RESULTFILE, (double **)input_in, NUM_PATTERN, NUM_IN);

printf("\n打印中间层神经元与输入层神经元的权值");

fprintf(RESULTFILE, "\n打印中间层神经元与输入层神经元的权值");

print_two(RESULTFILE, (double **)V, NUM_MID, NUM_IN);

printf("\n打印输出层神经元与中间层神经元的权值");

fprintf(RESULTFILE, "\n打印输出层神经元与中间层神经元的权值");

print_two(RESULTFILE, (double **)W, NUM_OUT, NUM_MID);

printf("\n打印中间层阈值");

fprintf(RESULTFILE, "\n打印中间层阈值");

print_one(RESULTFILE, v, NUM_MID);

printf("\n打印输出层阈值");

fprintf(RESULTFILE, "\n打印输出层阈值");

print_one(RESULTFILE, w, NUM_OUT);

printf("\n打印期望输出值");

fprintf(RESULTFILE, "\n打印期望输出值");

print_one(RESULTFILE, d[0], NUM_OUT);

printf("\n打印最终输出值");

fprintf(RESULTFILE, "\n打印最终输出值");

print_one(RESULTFILE, output_out, NUM_OUT);

fclose(RESULTFILE);

}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值