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. iOS开源加密相册Agony的实现(五)

    简介 虽然目前市面上有一些不错的加密相册App,但不是内置广告,就是对上传的张数有所限制.本文介绍了一个加密相册的制作过程,该加密相册将包括多密码(输入不同的密码即可访问不同的空间,可掩人耳目).Wi ...

  2. SQL实例整理

    本文适合将w3school的SQL教程(http://www.w3school.com.cn/sql/sql_create_table.asp)都基本看过一遍的猿友阅读. 说说博主的情况吧.毕业找工作 ...

  3. springMVC源码分析--AbstractHandlerMapping(二)

    上一篇博客springMVC源码分析--HandlerMapping(一)中我们简单的介绍了HandlerMapping,接下来我们介绍一下它的抽象实现类AbstractHandlerMapping

  4. github pages + Hexo + 域名绑定搭建个人博客

    环境 Windows 10(64 位) Git-2.7.4-64-bit node-v4.4.7-x64 如果上述软件已经安装的,跳过,没有安装的下载安装. 1,git下载安装(https://git ...

  5. 手动添加SSH支持、使用c3p0

    之前做的笔记,现在整理一下:大家有耐心的跟着做就能成功: SSH(struts2.spring.hibernate) *  struts2      *  充当mvc的角色 *  hibernate ...

  6. ERP各个模块的缩写

    财务系统模块: Oracle 总帐管理(GL) Oracle 应付帐管理(AP) Oracle 固定资产管理(FA) Oracle 应收帐管理(AR) Oracle 现金管理(CE) Oracle 项 ...

  7. C控制台实现模拟平抛运动算法

    平抛运动这个相信读了高中物理都知道这个概念了,详细的我就不说了,不明白的看看百度: 平抛运动 接下来看看用控制台实现的平抛运动算法: #include <stdio.h> #include ...

  8. gitlab的搭建及问题的解决

    gitlab则是类似于github的一个工具,github无法免费建立私有仓库,并且为了代码安全,于是在内网安装了一个自己实验室的一个git服务器,gitlab有很多依赖,而bitnami制作了一键安 ...

  9. Android动态加载入坑指南

    曾几何时,国内各大公司掀起了一股研究Android动态加载的技术,两年多过去了,动态加载技术俨然成了Android开发中必须掌握的技术.那么动态加载技术是什么呢,这里谈谈我的个人看法,如有雷同,纯属偶 ...

  10. 高仿腾讯QQ即时通讯IM项目

    前言:其实这个项目早就开发完成了,在本人的github上,本来没打算写成博客的形式,因为一个项目要写出来要花很久,但是最近看到很多 人在我的github上download后随意发布到网上,本来上传到g ...