用C语言构建了一个简单的神经网络

用C语言构建了一个非常简单的神经网络,用来理解NN工作的基本原理。

1. 模块说明:
    NVCELL:   单个神经元结构,包含输入向量和权重向量,并指定了对应的传递/激活函数。
    NVLAYER:  单层神经网络,包含若干个NVCELL结构
    各结构对应的方法函数包括:NVCELL和NVLAYER的产生/销毁函数,向前/向后传导函数,权重和偏置系数的随机产生函数等。

2. 应用例子:
    构建一个3层神经网络,通过一组数据来学习3数逻辑:当3个数字和大于等于2时输出为1。

   具体代码见附。

   将https://github.com/midaszhou/nnc代码clone下来,然后执行make.

3.参考资料:
    《机器学习与深度学习 通过C语言模拟》  小高知宏 著

 

应用例子程序如下:

/*------------------------  test_nnc. -----------------------------------
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License version 2 as
published by the Free Software Foundation.
Midas Zhou
[email protected]
-----------------------------------------------------------------------*/
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <math.h>
#include <string.h>
#include "nnc.h"

#define ERR_LIMIT	0.0001   /* 允许误差值 */

int main(void)
{

	int i,j;
	int count=0;

	int wi_cellnum=3; /* wi layer cell number */
	int wm_cellnum=3; /* wm layer cell number */
	int wo_cellnum=1; /* wo layer cell number */

	int wi_inpnum=3; /* number of input data for each input/hidden nvcell */
	int wm_inpnum=3; /* number of input data for each middle nvcell */
	int wo_inpnum=3; /* number of input data for each output nvcell */

	double err;
	int ns=8; /* input sample number + teacher value */

	double pin[8*4]= /* 3 input + 1 teacher value */
{
1,1,1,1,
1,1,0,1,
1,0,1,1,
1,0,0,0,
0,1,1,1,
0,1,0,0,
0,0,1,0,
0,0,0,0,
};

	double data_input[3];

/*  <<<<<<<<<<<<<<<<<  Create Neuron Net 构建神经网络  >>>>>>>>>>>>>  */
	/* 1. creat an input nvlayer 建立输入层 */
	NVCELL *wi_tempcell=new_nvcell(wi_inpnum,NULL,data_input,NULL,0,func_sigmoid);
	nvcell_rand_dwv(wi_tempcell);
        NVLAYER *wi_layer=new_nvlayer(wi_cellnum,wi_tempcell);

	/* 2. creat a mid nvlayer 建立中间层 */
	NVCELL *wm_tempcell=new_nvcell(wm_inpnum,wi_layer->nvcells,NULL,NULL,0,func_sigmoid); 
	nvcell_rand_dwv(wm_tempcell);
        NVLAYER *wm_layer=new_nvlayer(wm_cellnum,wm_tempcell);

	/* 3. creat an output nvlayer 建立输出层 */
	NVCELL *wo_tempcell=new_nvcell(wo_inpnum, wm_layer->nvcells,          NULL,NULL,0,func_sigmoid); 
	nvcell_rand_dwv(wo_tempcell);
        NVLAYER *wo_layer=new_nvlayer(wo_cellnum,wo_tempcell);

/*  <<<<<<<<<<<<<<<<<  NNC Learning Process 网络的学习过程  >>>>>>>>>>>>>  */
	nnc_set_param(2.0); /* set learn rate 设置学习系数 */
	err=10; /* give an init value to trigger while() */

  	printf("NN model starts learning ...\n");
  	while(err>ERR_LIMIT)
  	{
		/* reset err */
		err=0.0;

		/* batch learning */
		for(i=0;i<ns;i++)
    		{
			/* 1. update data_input  */
			memcpy(data_input, pin+4*i,3*sizeof(double));

			/* 2. feed forward wi->wm->wo layer 向前传导 */
			nvlayer_feed_forward(wi_layer);
			nvlayer_feed_forward(wm_layer);
			nvlayer_feed_forward(wo_layer);

			/* 3. get err sum up */
			err += (wo_layer->nvcells[0]->dout - pin[3+i*4])
				 * (wo_layer->nvcells[0]->dout - pin[3+i*4]);

			/* 4. feed backward wo->wm->wi, 向后传导并自更新系数 */
			nvlayer_feed_backward(wo_layer,pin+(3+i*4));
		        nvlayer_feed_backward(wm_layer,NULL);
		        nvlayer_feed_backward(wi_layer,NULL);
		}
		count++;

		if( (count&255) == 0)
			printf("	%dth learning, err=%0.8f \n",count, err);
  	}
	printf("	%dth learning, err=%0.8f \n",count, err);
	printf("Finish %d times batch learning!. \n\n",count);

/*  <<<<<<<<<<<<<<<<<  Test Learned NN Model 测试学习完成的神经网络模型  >>>>>>>>>>>>>  */
	printf("----------- Test learned NN Model -----------\n");
	for(i=0;i<ns;i++)
    	{
		/* update data_input */
		memcpy(data_input, pin+4*i,wi_inpnum*sizeof(double));

		/* feed forward wi->wm->wo layer */
		nvlayer_feed_forward(wi_layer);
		nvlayer_feed_forward(wm_layer);
		nvlayer_feed_forward(wo_layer);

		/* print result */
		printf("Input: ");
		for(j=0;j<wi_inpnum;j++)
			printf("%lf ",data_input[j]);
		printf("\n");
		printf("output: %lf \n",wo_layer->nvcells[0]->dout);
	}

/*  <<<<<<<<<<<<<<<<<  Destroy NN Model 销毁神经网络 >>>>>>>>>>>>>  */

	free_nvcell(wi_tempcell);
	free_nvcell(wm_tempcell);
	free_nvcell(wo_tempcell);

	free_nvlayer(wi_layer);
	free_nvlayer(wm_layer);
	free_nvlayer(wo_layer);

	usleep(100000);


	return 0;
}

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章