声振论坛

 找回密码
 我要加入

QQ登录

只需一步,快速开始

查看: 3829|回复: 6

[人工智能] BP神经网络的VC程序语言实现

[复制链接]
发表于 2006-11-15 09:51 | 显示全部楼层 |阅读模式

马上注册,结交更多好友,享用更多功能,让你轻松玩转社区。

您需要 登录 才可以下载或查看,没有账号?我要加入

x
  1. /*
  2. ******************************************************************
  3. * backprop.cpp
  4. ******************************************************************
  5. */

  6. #include "StdAfx.h"
  7. #include <stdio.h>
  8. #include "backprop.h"
  9. #include <math.h>
  10. #include <stdlib.h>

  11. #define ABS(x)          (((x) > 0.0) ? (x) : (-(x)))

  12. /* 宏定义:快速拷贝 */
  13. #define fastcopy(to,from,len)\
  14. {\
  15.         register char *_to,*_from;\
  16.         register int _i,_l;\
  17.         _to = (char *)(to);\
  18.         _from = (char *)(from);\
  19.         _l = (len);\
  20.         for (_i = 0; _i < _l; _i++) *_to++ = *_from++;\
  21. }

  22. /*** 返回0-1的双精度随机数 ***/
  23. double drnd()
  24. {
  25.         return ((double) rand() / (double) BIGRND);
  26. }

  27. /*** 返回-1.0到1.0之间的双精度随机数 ***/
  28. double dpn1()
  29. {
  30.         return ((drnd() * 2.0) - 1.0);
  31. }

  32. /*** 作用函数,目前是S型函数 ***/

  33. double squash(double x)
  34. {
  35.         return (1.0 / (1.0 + exp(-x)));
  36. }


  37. /*** 申请1维双精度实数数组 ***/

  38. double *alloc_1d_dbl(int n)
  39. {
  40.         double *new1;

  41.         new1 = (double *) malloc ((unsigned) (n * sizeof (double)));
  42.         if (new1 == NULL) {
  43.                 printf("ALLOC_1D_DBL: Couldn't allocate array of doubles\n");
  44.                 return (NULL);
  45.         }
  46.         return (new1);
  47. }


  48. /*** 申请2维双精度实数数组 ***/

  49. double **alloc_2d_dbl(int m, int n)
  50. {
  51.         int i;
  52.         double **new1;

  53.         new1 = (double **) malloc ((unsigned) (m * sizeof (double *)));
  54.         if (new1 == NULL) {
  55.                 printf("ALLOC_2D_DBL: Couldn't allocate array of dbl ptrs\n");
  56.                 return (NULL);
  57.         }

  58.         for (i = 0; i < m; i++) {
  59.                 new1[i] = alloc_1d_dbl(n);
  60.         }

  61.         return (new1);
  62. }

  63. /*** 随机初始化权值 ***/
  64. void bpnn_randomize_weights(double **w, int m, int n)
  65. {
  66.         int i, j;

  67.         for (i = 0; i <= m; i++) {
  68.                 for (j = 0; j <= n; j++) {
  69.                         w[i][j] = dpn1();
  70.                 }
  71.         }
  72. }

  73. /*** 0初始化权值 ***/
  74. void bpnn_zero_weights(double **w, int m, int n)
  75. {
  76.         int i, j;

  77.         for (i = 0; i <= m; i++) {
  78.                 for (j = 0; j <= n; j++) {
  79.                         w[i][j] = 0.0;
  80.                 }
  81.         }
  82. }

  83. /*** 设置随机数种子 ***/
  84. void bpnn_initialize(int seed)
  85. {
  86.         printf("Random number generator seed: %d\n", seed);
  87.         srand(seed);
  88. }

  89. /*** 创建BP网络 ***/
  90. BPNN *bpnn_internal_create(int n_in, int n_hidden, int n_out)
  91. {
  92.         BPNN *newnet;

  93.         newnet = (BPNN *) malloc (sizeof (BPNN));
  94.         if (newnet == NULL) {
  95.                 printf("BPNN_CREATE: Couldn't allocate neural network\n");
  96.                 return (NULL);
  97.         }

  98.         newnet->input_n = n_in;
  99.         newnet->hidden_n = n_hidden;
  100.         newnet->output_n = n_out;
  101.         newnet->input_units = alloc_1d_dbl(n_in + 1);
  102.         newnet->hidden_units = alloc_1d_dbl(n_hidden + 1);
  103.         newnet->output_units = alloc_1d_dbl(n_out + 1);

  104.         newnet->hidden_delta = alloc_1d_dbl(n_hidden + 1);
  105.         newnet->output_delta = alloc_1d_dbl(n_out + 1);
  106.         newnet->target = alloc_1d_dbl(n_out + 1);

  107.         newnet->input_weights = alloc_2d_dbl(n_in + 1, n_hidden + 1);
  108.         newnet->hidden_weights = alloc_2d_dbl(n_hidden + 1, n_out + 1);

  109.         newnet->input_prev_weights = alloc_2d_dbl(n_in + 1, n_hidden + 1);
  110.         newnet->hidden_prev_weights = alloc_2d_dbl(n_hidden + 1, n_out + 1);

  111.         return (newnet);
  112. }

  113. /* 释放BP网络所占地内存空间 */
  114. void bpnn_free(BPNN *net)
  115. {
  116.         int n1, n2, i;

  117.         n1 = net->input_n;
  118.         n2 = net->hidden_n;

  119.         free((char *) net->input_units);
  120.         free((char *) net->hidden_units);
  121.         free((char *) net->output_units);

  122.         free((char *) net->hidden_delta);
  123.         free((char *) net->output_delta);
  124.         free((char *) net->target);

  125.         for (i = 0; i <= n1; i++) {
  126.                 free((char *) net->input_weights[i]);
  127.                 free((char *) net->input_prev_weights[i]);
  128.         }
  129.         free((char *) net->input_weights);
  130.         free((char *) net->input_prev_weights);

  131.         for (i = 0; i <= n2; i++) {
  132.                 free((char *) net->hidden_weights[i]);
  133.                 free((char *) net->hidden_prev_weights[i]);
  134.         }
  135.         free((char *) net->hidden_weights);
  136.         free((char *) net->hidden_prev_weights);

  137.         free((char *) net);
  138. }


  139. /***
  140.          创建一个BP网络,并初始化权值
  141. ***/

  142. BPNN *bpnn_create(int n_in, int n_hidden, int n_out)
  143. {
  144.         BPNN *newnet;

  145.         newnet = bpnn_internal_create(n_in, n_hidden, n_out);

  146. #ifdef INITZERO
  147.         bpnn_zero_weights(newnet->input_weights, n_in, n_hidden);
  148. #else
  149.         bpnn_randomize_weights(newnet->input_weights, n_in, n_hidden);
  150. #endif
  151.         bpnn_randomize_weights(newnet->hidden_weights, n_hidden, n_out);
  152.         bpnn_zero_weights(newnet->input_prev_weights, n_in, n_hidden);
  153.         bpnn_zero_weights(newnet->hidden_prev_weights, n_hidden, n_out);

  154.         return (newnet);
  155. }



  156. void bpnn_layerforward(double *l1, double *l2, double **conn, int n1, int n2)
  157. {
  158.         double sum;
  159.         int j, k;

  160.         /*** 设置阈值 ***/
  161.         l1[0] = 1.0;

  162.         /*** 对于第二层的每个神经元 ***/
  163.         for (j = 1; j <= n2; j++) {

  164.                 /*** 计算输入的加权总和 ***/
  165.                 sum = 0.0;
  166.                 for (k = 0; k <= n1; k++) {
  167.                         sum += conn[k][j] * l1[k];
  168.                 }
  169.                 l2[j] = squash(sum);
  170.         }
  171. }

  172. /* 输出误差 */
  173. void bpnn_output_error(double *delta, double *target, double *output, int nj, double *err)
  174. {
  175.         int j;
  176.         double o, t, errsum;

  177.         errsum = 0.0;
  178.         for (j = 1; j <= nj; j++) {
  179.                 o = output[j];
  180.                 t = target[j];
  181.                 delta[j] = o * (1.0 - o) * (t - o);
  182.                 errsum += ABS(delta[j]);
  183.         }
  184.         *err = errsum;
  185. }

  186. /* 隐含层误差 */
  187. void bpnn_hidden_error(double* delta_h, int nh, double *delta_o, int no, double **who, double *hidden, double *err)
  188. {
  189.         int j, k;
  190.         double h, sum, errsum;

  191.         errsum = 0.0;
  192.         for (j = 1; j <= nh; j++) {
  193.                 h = hidden[j];
  194.                 sum = 0.0;
  195.                 for (k = 1; k <= no; k++) {
  196.                         sum += delta_o[k] * who[j][k];
  197.                 }
  198.                 delta_h[j] = h * (1.0 - h) * sum;
  199.                 errsum += ABS(delta_h[j]);
  200.         }
  201.         *err = errsum;
  202. }

  203. /* 调整权值 */
  204. void bpnn_adjust_weights(double *delta, int ndelta, double *ly, int nly, double** w, double **oldw, double eta, double momentum)
  205. {
  206.         double new_dw;
  207.         int k, j;

  208.         ly[0] = 1.0;
  209.         for (j = 1; j <= ndelta; j++) {
  210.                 for (k = 0; k <= nly; k++) {
  211.                         new_dw = ((eta * delta[j] * ly[k]) + (momentum * oldw[k][j]));
  212.                         w[k][j] += new_dw;
  213.                         oldw[k][j] = new_dw;
  214.                 }
  215.         }
  216. }

  217. /* 进行前向运算 */
  218. void bpnn_feedforward(BPNN* net)
  219. {
  220.         int in, hid, out;

  221.         in = net->input_n;
  222.         hid = net->hidden_n;
  223.         out = net->output_n;

  224.         /*** Feed forward input activations. ***/
  225.         bpnn_layerforward(net->input_units, net->hidden_units,
  226.                 net->input_weights, in, hid);
  227.         bpnn_layerforward(net->hidden_units, net->output_units,
  228.                 net->hidden_weights, hid, out);
  229. }

  230. /* 训练BP网络 */
  231. void bpnn_train(BPNN *net, double eta, double momentum, double *eo, double *eh)
  232. {
  233.         int in, hid, out;
  234.         double out_err, hid_err;

  235.         in = net->input_n;
  236.         hid = net->hidden_n;
  237.         out = net->output_n;

  238.         /*** 前向输入激活 ***/
  239.         bpnn_layerforward(net->input_units, net->hidden_units,
  240.                 net->input_weights, in, hid);
  241.         bpnn_layerforward(net->hidden_units, net->output_units,
  242.                 net->hidden_weights, hid, out);

  243.         /*** 计算隐含层和输出层误差 ***/
  244.         bpnn_output_error(net->output_delta, net->target, net->output_units,
  245.                 out, &out_err);
  246.         bpnn_hidden_error(net->hidden_delta, hid, net->output_delta, out,
  247.                 net->hidden_weights, net->hidden_units, &hid_err);
  248.         *eo = out_err;
  249.         *eh = hid_err;

  250.         /*** 调整输入层和隐含层权值 ***/
  251.         bpnn_adjust_weights(net->output_delta, out, net->hidden_units, hid,
  252.                 net->hidden_weights, net->hidden_prev_weights, eta, momentum);
  253.         bpnn_adjust_weights(net->hidden_delta, hid, net->input_units, in,
  254.                 net->input_weights, net->input_prev_weights, eta, momentum);
  255. }


  256. /* 保存BP网络 */
  257. void bpnn_save(BPNN *net, char *filename)
  258. {
  259.         int n1, n2, n3, i, j, memcnt;
  260.         double dvalue, **w;
  261.         char *mem;
  262.         FILE *fd;

  263.         if ((fd = fopen(filename, "w")) == NULL) {
  264.                 printf("BPNN_SAVE: Cannot create '%s'\n", filename);
  265.                 return;
  266.         }

  267.         n1 = net->input_n;  n2 = net->hidden_n;  n3 = net->output_n;
  268.         printf("Saving %dx%dx%d network to '%s'\n", n1, n2, n3, filename);
  269.         fflush(stdout);


  270.         fwrite((char *) &n1, sizeof(int), 1, fd);
  271.         fwrite((char *) &n2, sizeof(int), 1, fd);
  272.         fwrite((char *) &n3, sizeof(int), 1, fd);

  273.         memcnt = 0;
  274.         w = net->input_weights;
  275.         mem = (char *) malloc ((unsigned) ((n1+1) * (n2+1) * sizeof(double)));
  276.         for (i = 0; i <= n1; i++) {
  277.                 for (j = 0; j <= n2; j++) {
  278.                         dvalue = w[i][j];
  279.                         fastcopy(&mem[memcnt], &dvalue, sizeof(double));
  280.                         memcnt += sizeof(double);
  281.                 }
  282.         }

  283.         fwrite(mem, (n1+1) * (n2+1) * sizeof(double), 1, fd);
  284.         free(mem);

  285.         memcnt = 0;
  286.         w = net->hidden_weights;
  287.         mem = (char *) malloc ((unsigned) ((n2+1) * (n3+1) * sizeof(double)));
  288.         for (i = 0; i <= n2; i++) {
  289.                 for (j = 0; j <= n3; j++) {
  290.                         dvalue = w[i][j];
  291.                         fastcopy(&mem[memcnt], &dvalue, sizeof(double));
  292.                         memcnt += sizeof(double);
  293.                 }
  294.         }

  295.         fwrite(mem, (n2+1) * (n3+1) * sizeof(double), 1, fd);
  296.         free(mem);

  297.         fclose(fd);
  298.         return;
  299. }

  300. /* 从文件中读取BP网络 */
  301. BPNN *bpnn_read(char *filename)
  302. {
  303.         char *mem;
  304.         BPNN *new1;
  305.         int n1, n2, n3, i, j, memcnt;
  306.         FILE *fd;

  307.         if ((fd = fopen(filename, "r")) == NULL) {
  308.                 return (NULL);
  309.         }

  310.         printf("Reading '%s'\n", filename);  fflush(stdout);

  311.         fread((char *) &n1, sizeof(int), 1, fd);
  312.         fread((char *) &n2, sizeof(int), 1, fd);
  313.         fread((char *) &n3, sizeof(int), 1, fd);

  314.         new1 = bpnn_internal_create(n1, n2, n3);

  315.         printf("'%s' contains a %dx%dx%d network\n", filename, n1, n2, n3);
  316.         printf("Reading input weights...");  fflush(stdout);

  317.         memcnt = 0;
  318.         mem = (char *) malloc ((unsigned) ((n1+1) * (n2+1) * sizeof(double)));

  319.         fread( mem, (n1+1) * (n2+1) * sizeof(double), 1, fd);
  320.         for (i = 0; i <= n1; i++) {
  321.                 for (j = 0; j <= n2; j++) {
  322.                         fastcopy(&(new1->input_weights[i][j]), &mem[memcnt], sizeof(double));
  323.                         memcnt += sizeof(double);
  324.                 }
  325.         }
  326.         free(mem);

  327.         printf("Done\nReading hidden weights...");  fflush(stdout);

  328.         memcnt = 0;
  329.         mem = (char *) malloc ((unsigned) ((n2+1) * (n3+1) * sizeof(double)));

  330.         fread( mem, (n2+1) * (n3+1) * sizeof(double), 1, fd);
  331.         for (i = 0; i <= n2; i++) {
  332.                 for (j = 0; j <= n3; j++) {
  333.                         fastcopy(&(new1->hidden_weights[i][j]), &mem[memcnt], sizeof(double));
  334.                         memcnt += sizeof(double);
  335.                 }
  336.         }
  337.         free(mem);
  338.         fclose(fd);

  339.         printf("Done\n");  fflush(stdout);

  340.         bpnn_zero_weights(new1->input_prev_weights, n1, n2);
  341.         bpnn_zero_weights(new1->hidden_prev_weights, n2, n3);

  342.         return (new1);
  343. }
复制代码
回复
分享到:

使用道具 举报

 楼主| 发表于 2006-11-15 09:51 | 显示全部楼层
  1. /*
  2. ******************************************************************
  3. * backprop.h
  4. ******************************************************************
  5. */

  6. #ifndef _BACKPROP_H_

  7. #define _BACKPROP_H_

  8. #define BIGRND 0x7fffffff

  9. /*** 神经网络的数据结构。网络被假定为一个全连接的3层前向结构,
  10.          每层的单元0是阈值,这意味着真正的神经元编号为1-n
  11. ***/

  12. typedef struct {
  13.         int input_n;                  /* 输入层的神经元个数 */
  14.         int hidden_n;                 /* 隐含层的神经元个数 */
  15.         int output_n;                 /* 输出层的神经元个数 */

  16.         double *input_units;          /* 输入层的神经元 */
  17.         double *hidden_units;         /* 隐藏层的神经元 */
  18.         double *output_units;         /* 输出曾的神经元 */

  19.         double *hidden_delta;         /* 隐藏层的误差 */
  20.         double *output_delta;         /* 输出层的误差 */

  21.         double *target;               /* 目标向量 */

  22.         double **input_weights;       /* 输入层到隐藏层的连接权 */
  23.         double **hidden_weights;      /* 隐藏层到输出曾的连接权 */

  24.                                 /*** 下面两个在迭代时使用 ***/
  25.         double **input_prev_weights;  /* 前次输入层导隐藏层权值的改变 */
  26.         double **hidden_prev_weights; /* 前次隐藏层导输出层权值的改变 */
  27. } BPNN;


  28. /*** 用户接口 ***/

  29. /* 初始化随机数种子 */
  30. void bpnn_initialize(int seed);

  31. /* 创建BP网络 */
  32. BPNN *bpnn_create(int n_in, int n_hidden, int n_out);

  33. /* 释放BP网络所占地内存空间 */
  34. void bpnn_free(BPNN *net);

  35. /* 训练BP网络 */
  36. void bpnn_train(BPNN *net, double eta, double momentum, double *eo, double *eh);

  37. /* 前向运算 */
  38. void bpnn_feedforward(BPNN* net);

  39. /* 保存BP网络到文件中 */
  40. void bpnn_save(BPNN *net, char *filename);

  41. /* 从文件中读取BP网络参数 */
  42. BPNN *bpnn_read(char *filename);


  43. #endif
复制代码

评分

1

查看全部评分

发表于 2007-5-2 14:04 | 显示全部楼层

请教

你的QQ是多少啊?能请教遗传算法问题吗?你懂遗传算法在Qos路由中的应用吗
 楼主| 发表于 2007-5-5 20:39 | 显示全部楼层


本人不用QQ,另外也不懂Qos路由,请注意本论坛的主题,估计没几个人懂你的问题
发表于 2007-6-20 15:52 | 显示全部楼层
main 函数呢?
发表于 2007-7-21 13:44 | 显示全部楼层
楼主是个高手:victory:
辛苦了!:handshake
发表于 2008-4-1 15:29 | 显示全部楼层

main

main 函数呢?
想知道啊:)搂住
您需要登录后才可以回帖 登录 | 我要加入

本版积分规则

QQ|小黑屋|Archiver|手机版|联系我们|声振论坛

GMT+8, 2024-6-25 14:39 , Processed in 0.067562 second(s), 22 queries , Gzip On.

Powered by Discuz! X3.4

Copyright © 2001-2021, Tencent Cloud.

快速回复 返回顶部 返回列表