bp神经网络

这里写图片描述
这是一个三层的神经网络模型,Input输入数据的特征,Output层输出结果,中间层是隐藏层。

bp算法是最小化均方误差,即E=1/2Ssigma(f(xi)-yi)^2

我们用梯度下降法优化,这里求偏导用到了链式原则。

下面给出随机梯度下降版本。
标准梯度版本就是考虑所以样本,而随机梯度下降就考虑当前数据,可以自行推导标准梯度下降的公式。

#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <math.h>
#include <conio.h>
#define S_BP_LEN 16
#define x_bp_BP_LEN 4
#define O_BP_LEN 2
#define H_BP_LEN 4
#define S 0.001
double v[x_bp_BP_LEN][H_BP_LEN],bp_w[H_BP_LEN][O_BP_LEN];
double bp_b[H_BP_LEN],y_bp[S_BP_LEN][O_BP_LEN],o[O_BP_LEN],x_bp[S_BP_LEN][x_bp_BP_LEN];
double b_pre[H_BP_LEN],o_pre[O_BP_LEN],p1[H_BP_LEN],p2[O_BP_LEN];
double nex_bpt_bp_w[H_BP_LEN][O_BP_LEN],nex_bpt_v[x_bp_BP_LEN][H_BP_LEN],nex_bpt_p2[O_BP_LEN],nex_bpt_p1[H_BP_LEN];

double sigmoid(double x)
{
    return 1/(1+exp(-x));
}

void init()
{
    for(int i = 0;i<x_bp_BP_LEN;i++)
    {
        for(int j = 0;j<H_BP_LEN;j++)
        {
            v[i][j] = 0;
        }
    }
    for(int i = 0;i<H_BP_LEN;i++)
    {
        p1[i] = 0;
    }
    for(int i = 0;i<H_BP_LEN;i++)
    {
        for(int j = 0;j<O_BP_LEN;j++)
        {
            bp_w[i][j] = 0;
        }
    }
    for(int i = 0;i<O_BP_LEN;i++)
    {
        p2[i] = 0;
    }
    int cnt  = 0;
    for(int i = 0;i<=1;i++)
    {
        for(int j = 0;j<=1;j++)
        {
            for(int k = 0;k<=1;k++)
            {
                for(int kk = 0;kk<=1;kk++)
                {
                    x_bp[cnt][0] = i;
                    x_bp[cnt][1] = j;
                    x_bp[cnt][2] = k;
                    x_bp[cnt][3] = kk;
                    if((i+j+k+kk)%2==0) y_bp[cnt][0] = 1,y_bp[cnt][1] = 0;
                    else y_bp[cnt][0] = 1,y_bp[cnt][1] = 0;
                    cnt++;

                }
            }
        }
    }
}

void cal_bp_res(int now)
{
    for(int i = 0;i<H_BP_LEN;i++)
    {
        b_pre[i] = 0;
        for(int j = 0;j<x_bp_BP_LEN;j++)
        {
            b_pre[i]+=v[j][i]*x_bp[now][j];

        }
        b_pre[i]+=p1[i];
        bp_b[i] = sigmoid(b_pre[i]);
    }
    for(int i = 0;i<O_BP_LEN;i++)
    {
        o_pre[i] = 0;
        for(int j = 0;j<H_BP_LEN;j++)
        {
            o_pre[i]+=bp_w[j][i]*bp_b[j];
        }
        o_pre[i]+=p2[i];
        o[i] = sigmoid(o_pre[i]);
    }

}
double cal_mis()
{
    double sum = 0;
    for(int i = 0;i<S_BP_LEN;i++)
    {
        sum+=(o[0]-y_bp[i][0])*(o[0]-y_bp[i][0]);
        sum+=(o[1]-y_bp[i][1])*(o[1]-y_bp[i][1]);
    }
    sum*=0.5;
    return sum;
}
void bp(int now)
{
    cal_bp_res(now);
    double temp[O_BP_LEN];
    for(int i = 0;i<O_BP_LEN;i++)
    {
        temp[i] = (o[i]-y_bp[now][i])*o[i]*(1-o[i]);
    }

    for(int i = 0;i<H_BP_LEN;i++)
    {
        for(int j = 0;j<O_BP_LEN;j++)
        {
            nex_bpt_bp_w[i][j] = temp[j]*bp_b[i];
        }
    }
    for(int j = 0;j<O_BP_LEN;j++)
    {
        nex_bpt_p2[j] = temp[j];
    }

    for(int i = 0;i<x_bp_BP_LEN;i++)
    {
        for(int j = 0;j<H_BP_LEN;j++)
        {
            nex_bpt_v[i][j] = 0;
            for(int k = 0;k<O_BP_LEN;k++)
            {
                nex_bpt_v[i][j] += temp[k]*bp_w[j][k]*bp_b[j]*(1-bp_b[j])*x_bp[now][i]; 
            }
        }
    }

    for(int j = 0;j<H_BP_LEN;j++)
    {
        nex_bpt_p1[j] = 0;
        for(int k =0;k<O_BP_LEN;k++)
        {
            nex_bpt_p1[j]+=temp[k]+bp_w[j][k]*bp_b[j]*(1-bp_b[j]);
        }
    }

    for(int i = 0;i<x_bp_BP_LEN;i++)
    {
        for(int j = 0;j<H_BP_LEN;j++)
        {
            v[i][j]+=-S*nex_bpt_v[i][j];
        }
    }
    for(int i = 0;i<H_BP_LEN;i++)
    {
        p1[i]+=-S*nex_bpt_p1[i];
    }
    for(int i = 0;i<H_BP_LEN;i++)
    {
        for(int j =0;j<O_BP_LEN;j++)
        {
            bp_w[i][j]+=-S*nex_bpt_bp_w[i][j];
        }
    }
    for(int i = 0;i<O_BP_LEN;i++)
    {
        p2[i]+=-S*nex_bpt_p2[i];
    }
}

void test_bp()
{
    init();
    int train = 100000;
    while(train--)
    {
        for(int i = 0;i<S_BP_LEN;i++)
        {
            bp(i);
        }

    }
    printf("%lf\n",cal_mis());
    getch();
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值