用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;
}