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. 理解性能的奥秘——应用程序中慢,SSMS中快(4)——收集解决参数嗅探问题的信息

    本文属于<理解性能的奥秘--应用程序中慢,SSMS中快>系列 接上文:理解性能的奥秘--应用程序中慢,SSMS中快(3)--不总是参数嗅探的错 前面已经提到过关于存储过程在SSMS中运行很 ...

  2. EBS业务学习之应付INVOICE类型

    INVOICE类型 类      型 描           述 标准INVOICE 是指由于采购货物或接受劳务,从供应商处取得的INVOICE (标准INVOICE,既可以和订单匹配,也可以不匹配) ...

  3. EBS业务学习之应收管理

    Oracle Receivable 是功能完备地应收款管理系统,它能够有效地管理客户.发票和收帐过程,因此是财务模块的重要组成部分,是财务系统中较为核心的模块之一.对于一个公司来说,是否能够与客户保持 ...

  4. RxJava操作符(03-变换操作)

    转载请标明出处: http://blog.csdn.net/xmxkf/article/details/51649975 本文出自:[openXu的博客] 目录: Buffer FlatMap fla ...

  5. 为什么选择C++

    为什么选择C++,怎么不选其它语言呢? 为什么不选择C? 因为C++比C简单点~ 为什么不选择C#? 因为C++可以在所有操作系统上使用. 为什么不选择JAVA? 因为C++的性能好一点~ 还有其他的 ...

  6. UIKit视图动画的微扩展

    大熊猫猪·侯佩原创或翻译作品.欢迎转载,转载请注明出处. 如果觉得写的不好请多提意见,如果觉得不错请多多支持点赞.谢谢! hopy ;) 好久没写blog了,还不快快写来- ;] 我们知道在UIKit ...

  7. Dynamics CRM 插件注册时报Assembly must be registered in isolation的解决方法

    在插件注册的时候经常会遇到"Assembly must be registered in isolation"的问题导致无法注册,之前经常会被同事或者朋友问到这个问题,遇到这个问题 ...

  8. Linux--DNS服务器

     DNS是Internet上使用最普遍,也是最重要的服务之一,通过DNS我们才可以访 问丰富多彩的网络,而DNS服务器就是为了实现域名解析功能而搭建的. 域名系统采用层次结构,按地理区域或机构区域 ...

  9. Spark技术内幕之任务调度:从SparkContext开始

    SparkContext是开发Spark应用的入口,它负责和整个集群的交互,包括创建RDD,accumulators and broadcast variables.理解Spark的架构,需要从这个入 ...

  10. unix下快速混淆源代码

    只能算雕虫小技,但可以快速简单的做混淆,如下: #vapyhqr <fgqvb.u> #vapyhqr <fgqyvo.u> #vapyhqr <fgqobby.u> ...