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. Redis之(二)数据类型及存储结构

    Redis支持五中数据类型:String(字符串),Hash(哈希),List(列表),Set(集合)及zset(sortedset:有序集合). Redis定义了丰富的原语命令,可以直接与Redis ...

  2. Android Multimedia框架总结(二十)MediaCodec状态周期及Codec与输入/输出Buffer过程(附实例)

    转载请把头部出处链接和尾部二维码一起转载,本文出自逆流的鱼yuiop:http://blog.csdn.net/hejjunlin/article/details/53183718 前言:前面几节都是 ...

  3. [Vim]vim学习笔记--多个文件打开,切换,关闭

    一种情况是在shell中用vim打开多个文件,另一种是在vim编辑器中打开多个文件 同时打开多个文件 vim file1 file2  打开文件并水平窗口显示 vim -o file1 file2 打 ...

  4. FFmpeg的HEVC解码器源代码简单分析:解码器主干部分

    ===================================================== HEVC源代码分析文章列表: [解码 -libavcodec HEVC 解码器] FFmpe ...

  5. Java集合-----java集合框架常见问题

    1什么是Java集合API Java集合框架API是用来表示和操作集合的统一框架,它包含接口.实现类.以及帮助程序员完成一些编程的算法. 简言之,API在上层完成以下几件事: ● 编程更加省力,提高城 ...

  6. 详解EBS接口开发之供应商导入补充-供应商地点增加实例

    DECLARE --v_org_id number; v_vendor_interface_id NUMBER; v_vendor_site_interface_id NUMBER; --接口表的id ...

  7. iOS开发之使用block块进行数据遍历的方法

    看了一篇文章,发现遍历数组.字典中的数据时,除了使用for循环外,还可以使用block块进行操作,瞬间感觉iOS的语言代码确实有点高大上的感觉,下面就简单的介绍一下这个方法. 首先是最基本的运用形式, ...

  8. UNIX网络编程——epoll 系列函数简介、与select、poll 的区别

    前面博客<<UNIX环境高级编程--epoll函数使用详解>>有关于epoll函数的讲解. 一.epoll 系列函数简介 #include <sys/epoll.h> ...

  9. FFmpeg示例程序合集-批量编译脚本

    此前做了一系列有关FFmpeg的示例程序,组成了<最简单的FFmpeg示例程序合集>,其中包含了如下项目:simplest ffmpeg player:                   ...

  10. 【一天一道LeetCode】#349. Intersection of Two Arrays

    一天一道LeetCode 本系列文章已全部上传至我的github,地址:ZeeCoder's Github 欢迎大家关注我的新浪微博,我的新浪微博 欢迎转载,转载请注明出处 (一)题目 Given t ...