ANN核心数据结构:

typedef struct 

{

    int input_n;                  /* number of input units */

    int hidden_n;                 /* number of hidden units */

    int output_n;                 /* number of output units */

    double *input_units;          /* the input units */

    double *hidden_units;         /* the hidden units */

    double *output_units;         /* the output units */

    double *hidden_delta;         /* storage for hidden unit error */

    double *output_delta;         /* storage for output unit error */

    double *target;               /* storage for target vector */

    double **input_weights;       /* weights from input to hidden layer */

    double **hidden_weights;      /* weights from hidden to output layer */

    /*** The next two are for momentum ***/

    double **input_prev_weights;  /* previous change on input to hidden wgt */

    double **hidden_prev_weights; /* previous change on hidden to output wgt */

} BPNN;

整个神经网络可以分成三层:输入层,隐藏层,输出层,通过加权线性变换,层与层之间的传递,最终得到输入层的实数值。

BPNN *bpnn_internal_create(int n_in, int n_hidden,int n_out;)

{//创建人工网络,参数分别指定输入层,隐藏层和输出层大小

    BPNN *newnet;

    newnet = (BPNN *) malloc (sizeof (BPNN));

    if (newnet == NULL)

    {

        printf("BPNN_CREATE: Couldn't allocate neural network/n");

        return (NULL);

    }

    newnet->input_n = n_in;//输入层

    newnet->hidden_n = n_hidden;//隐藏层

    newnet->output_n = n_out;//输出层

    newnet->input_units = alloc_1d_dbl(n_in + 1);

    newnet->hidden_units = alloc_1d_dbl(n_hidden + 1);

    newnet->output_units = alloc_1d_dbl(n_out + 1);

    newnet->hidden_delta = alloc_1d_dbl(n_hidden + 1);

    newnet->output_delta = alloc_1d_dbl(n_out + 1);

    newnet->target = alloc_1d_dbl(n_out + 1);//目标向量

    newnet->input_weights = alloc_2d_dbl(n_in + 1, n_hidden + 1);//输入层到隐藏层的权值

    newnet->hidden_weights = alloc_2d_dbl(n_hidden + 1, n_out + 1);//隐藏层到输出层的权值

    newnet->input_prev_weights = alloc_2d_dbl(n_in + 1, n_hidden + 1);

    newnet->hidden_prev_weights = alloc_2d_dbl(n_hidden + 1, n_out + 1);

    return (newnet);

}

下面代码段是ANN运行的核心部分:

if (train_n > 0)

{//提供了训练集

    printf("Creating new network '%s'/n", netname);

    iimg = trainlist->list[0];//指向训练集第一张图片

    imgsize = ROWS(iimg) * COLS(iimg);

    /* bthom ===========================

    make a net with:

    imgsize inputs, 4 hiden units, and 1 output unit

    */

    //输入层为图片大小,隐藏层为,输出层为

    net = bpnn_create(imgsize, 4, 1);

}



// 训练

/************** Train it *****************************/

for (epoch = 1; epoch <= epochs; epoch++) 

{

    printf("%d ", epoch);  fflush(stdout);

    sumerr = 0.0;

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

    {

        /** Set up input units on net with image i **/

        //为图像i在网络上建立输入单元

        load_input_with_image(trainlist->list[i], net);

        /** Set up target vector for image i **/

        //为图像i建立目标向量

        load_target(trainlist->list[i], net);

        /** Run backprop, learning rate 0.3, momentum 0.3 **/

        //学习速率.3,冲量.3

        bpnn_train(net, 0.3, 0.3, &out_err, &hid_err);

        sumerr += (out_err + hid_err);

    }

    进行性能评估:

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

        {

            /*** Load the image into the input layer. **/

            load_input_with_image(il->list[i], net);//加载图片到输入层中

            /*** Run the net on this input. **/

            bpnn_feedforward(net);//在当前输入上运行神经网络

            /*** Set up the target vector for this image. **/

            load_target(il->list[i], net);//为此图片建立目标向量

            /*** See if it got it right. ***/

            if (evaluate_performance(net, &val, 0)) 

            {//判断是否正确识别,

                correct++;

            }

            else if (list_errors) 

            {

                printf("%s - outputs ", NAME(il->list[i]));

                for (j = 1; j <= net->output_n; j++) 

                {

                    printf("%.3f ", net->output_units[j]);

                }

                putchar('/n');

            }

            err += val;

        }

        err = err / (double) n;

        if (!list_errors)

            /* bthom==================================

            this line prints part of the ouput line

            discussed in section 3.1.2 of homework

            */

            printf("%g %g ", ((double) correct / (double) n) * 100.0, err);

用到的性能评估函数:

evaluate_performance(BPNN *net,double *err)

{//性能评估

doubledelta;

delta =net->target[1] -net->output_units[1];

*err =(0.5 *delta *
delta);

/*** If thetarget unit is on... ***/

if (net->target[1]> 0.5)

{

/*** If theoutput unit is on, then we correctly recognized me! ***/

if (net->output_units[1]> 0.5)

{

return(1);

}

else

{

return(0);

}

/*** Else,the target unit is off... ***/

}

else

{

/*** If theoutput unit is on, then we mistakenly thought it was me ***/

if (net->output_units[1]> 0.5)

{

return(0);

/***else, we correctly realized that it wasn't me ***/

}

else

{

return(1);

}

}

}

辅助处理函数区:

load_input_with_image(IMAGE *img, BPNN *net)

{//输入图像

    double *units;

    int nr, nc, imgsize, i, j, k;



    nr = ROWS(img);// 行大小

    nc = COLS(img);//列大小

    imgsize = nr * nc;;

    if (imgsize != net->input_n) 

    {//确保输入单元数目设置为图片大小

        printf("LOAD_INPUT_WITH_IMAGE: This image has %d pixels,/n", imgsize);

        printf("   but your net has %d input units.  I give up./n", net->input_n);

        exit (-1);

    }

    //取图片的每个像素为输入单元

    units = net->input_units;

    k = 1;

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

    {

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

        {

            units[k] = ((double) img_getpixel(img, i, j)) / 255.0;

            k++;

        }

    }

}



load_target(IMAGE *img, BPNN *net)

{//加载目标值

    int scale;

    char userid[40], head[40], expression[40], eyes[40], photo[40];

    userid[0] = head[0] = expression[0] = eyes[0] = photo[0] = '/0';

    /*** scan in the image features ***/

    sscanf(NAME(img), "%[^_]_%[^_]_%[^_]_%[^_]_%d.%[^_]",

    userid, head, expression, eyes, &scale, photo);

    if (!strcmp(userid, "glickman")) 

    {

        net->target[1] = TARGET_HIGH;  /* it's me, set target to HIGH */

    } 

    else 

    {

        net->target[1] = TARGET_LOW;   /* not me, set it to LOW */

    }

}



void bpnn_train(BPNN *net, double eta, momentum *eo, momentum *eh)

{//人工神经网络训练

    int in, hid, out;

    double out_err, hid_err;

    in = net->input_n;

    hid = net->hidden_n;

    out = net->output_n;

    /*** Feed forward input activations. ***/

    bpnn_layerforward(net->input_units, net->hidden_units,

    net->input_weights, in, hid);

    bpnn_layerforward(net->hidden_units, net->output_units,

    net->hidden_weights, hid, out);

    /*** Compute error on output and hidden units. ***/

    bpnn_output_error(net->output_delta, net->target, net->output_units,out, &out_err);

    bpnn_hidden_error(net->hidden_delta, hid, net->output_delta, out,net->hidden_weights, net->hidden_units, &hid_err);

    *eo = out_err;

    *eh = hid_err;

    /*** Adjust input and hidden weights. ***/

    bpnn_adjust_weights(net->output_delta, out, net->hidden_units, hid,net->hidden_weights, net->hidden_prev_weights, eta, momentum);

    bpnn_adjust_weights(net->hidden_delta, hid, net->input_units, in,net->input_weights, net->input_prev_weights, eta, momentum);

}



void bpnn_feedforward(BPNN *net)

{//前向反馈

    int in, hid, out;

    in = net->input_n;//输入层大小

    hid = net->hidden_n;//隐藏层大小

    out = net->output_n;//输出层大小

    /*** Feed forward input activations. ***/

    bpnn_layerforward(net->input_units, net->hidden_units,net->input_weights, in, hid);

    bpnn_layerforward(net->hidden_units, net->output_units,net->hidden_weights, hid, out);

}



void bpnn_adjust_weights(double *delta, double *ly,double **w, double **oldw, double eta, double momentum)

{//调整权值

    double new_dw;

    int k, j;

    ly[0] = 1.0;

    for (j = 1; j <= ndelta; j++) 

    {

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

        {

            new_dw = ((eta * delta[j] * ly[k]) + (momentum * oldw[k][j]));

            w[k][j] += new_dw;

            oldw[k][j] = new_dw;

        }

    }

}

void bpnn_layerforward(double *l1, double *l2, double **conn,int n1,int n2)

{//层次前向输入

    double sum;

    int j, k;

    /*** Set up thresholding unit ***/

    l1[0] = 1.0;

    //加权线性变换

    /*** For each unit in second layer ***/

    for (j = 1; j <= n2; j++) 

    {

        /*** Compute weighted sum of its inputs ***/

        sum = 0.0;

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

        {

            sum += conn[k][j] * l1[k];

        }

        l2[j] = squash(sum);

    }

}

ANN实现的更多相关文章

  1. 从下往上看--新皮层资料的读后感 第三部分 70年前的逆向推演- 从NN到ANN

    第三部分 NN-ANN 70年前的逆向推演 从这部分开始,调整一下视角主要学习神经网络算法,将其与生物神经网络进行横向的比较,以窥探一二. 现在基于NN的AI应用几乎是满地都是,效果也不错,这种貌似神 ...

  2. 机器学习笔记之人工神经网络(ANN)

    人工神经网络(ANN)提供了一种普遍而且实际的方法从样例中学习值为实数.离散值或向量函数.人工神经网络由一系列简单的单元相互连接构成,其中每个单元有一定数量的实值输入,并产生单一的实值输出. 上面是一 ...

  3. Codeforces Round #311 (Div. 2) E. Ann and Half-Palindrome 字典树/半回文串

    E. Ann and Half-Palindrome Time Limit: 20 Sec Memory Limit: 256 MB 题目连接 http://codeforces.com/contes ...

  4. 利用Multi-Probe LSH构建ANN高维索引

    感谢大神们的无私奉献精神........因此笔者要坚持开源,专注开源,开源就像在HPU的考试中不像其他人作弊一样,长远来看,会有巨大收获. 一.背景介绍 1.1 相似性搜索简介 高维相似性搜索在音频. ...

  5. 【转】漫谈ANN(2):BP神经网络

    上一次我们讲了M-P模型,它实际上就是对单个神经元的一种建模,还不足以模拟人脑神经系统的功能.由这些人工神经元构建出来的网络,才能够具有学习.联想.记忆和模式识别的能力.BP网络就是一种简单的人工神经 ...

  6. Codeforces Round #311 (Div. 2) E - Ann and Half-Palindrome(字典树+dp)

    E. Ann and Half-Palindrome time limit per test 1.5 seconds memory limit per test 512 megabytes input ...

  7. OpenCV——ANN神经网络

    ANN-- Artificial Neural Networks 人工神经网络 //定义人工神经网络 CvANN_MLP bp; // Set up BPNetwork's parameters Cv ...

  8. 目前所有的ANN神经网络算法大全

    http://blog.sina.com.cn/s/blog_98238f850102w7ik.html 目前所有的ANN神经网络算法大全 (2016-01-20 10:34:17) 转载▼ 标签: ...

  9. 【机器学习】人工神经网络ANN

    神经网络是从生物领域自然的鬼斧神工中学习智慧的一种应用.人工神经网络(ANN)的发展经历的了几次高潮低谷,如今,随着数据爆发.硬件计算能力暴增.深度学习算法的优化,我们迎来了又一次的ANN雄起时代,以 ...

随机推荐

  1. Tomcat怎么实现异步Servlet

    有时Servlet在生成响应报文前必须等待某些耗时的操作,比如在等待一个可用的JDBC连接或等待一个远程Web服务的响应.对于这种情况servlet规范中定义了异步处理方式,由于Servlet中等待阻 ...

  2. Android TV开发总结(六)构建一个TV app的直播节目实例

    请尊重分享成果,转载请注明出处:http://blog.csdn.net/hejjunlin/article/details/52966319 近年来,Android TV的迅速发展,传统的有线电视受 ...

  3. RE模块疑问

    待处理: >>> re.findall(r'[-+]*\d+(?:\.\d+)?','-++++---+123.012') ['-++++---+123.012'] >> ...

  4. Swift中如何转换不同类型的Mutable指针

    在Swift中我们拥有强大高级逻辑抽象能力的同时,低级底层操作被刻意的限制了.但是有些情况下我们仍然想做一些在C语言中的hack工作,下面本猫就带大家看一看如何做这样的事. hacking is ha ...

  5. 【Netty源码分析】Reactor线程模型

    1. 背景 1.1. Java线程模型的演进 1.1.1. 单线程 时间回到十几年前,那时主流的CPU都还是单核(除了商用高性能的小机),CPU的核心频率是机器最重要的指标之一. 在Java领域当时比 ...

  6. Android 增量更新和升级

    在年初的时候,尝试了一把热修复技术,当时选择的是阿里的andfix,使用起来也很简单,这里就不在多少,如果你对andfix有兴趣请链接:点击打开链接.虽然网上将热修复的文章很多,不过我还是想说原理,然 ...

  7. Hibernate初体验及简单错误排除

    Hibernate是什么,有多少好处,想必查找这类博文的都知道,所以就不多说了.下面是我对Hibernate简单使用的一个小小的总结.与君(主要是刚入门的)共勉吧! 创建的顺序 创建Hibernate ...

  8. J2EE学习从菜鸟变大鸟之七 Servlet

    Servlet现在自己的理解是一个控制器,简单的可以理解为不同的JSP页面由用户发送过来的请求可以由Servlet控制器来控制其向下调用的方向(结合三层好理解),但它比较特殊,因为它通常会从外界接收数 ...

  9. nginx+uwsgi+django 部署原理

    python开发群里经常有同学问 nginx+uwsgi+django 着了教程部署,但是不知道他们之间怎么样的关系,于是我就google到了一个让我看起来很认同的图,大家看了也比较认同,于是就分享出 ...

  10. Mybatis执行ReuseExecutor(五)

    ReuseExecutor顾名思义就是重复使用执行,其定义了一个Map<String, Statement>,将执行的sql作为key,将执行的Statement作为value保存,这样执 ...