zoukankan      html  css  js  c++  java
  • 简单易学的机器学习算法——神经网络之BP神经网络

    一、BP神经网络的概念

        BP神经网络是一种多层的前馈神经网络,其基本的特点是:信号是前向传播的,而误差是反向传播的。详细来说。对于例如以下的仅仅含一个隐层的神经网络模型:

    (三层BP神经网络模型)
    BP神经网络的过程主要分为两个阶段。第一阶段是信号的前向传播,从输入层经过隐含层。最后到达输出层;第二阶段是误差的反向传播,从输出层到隐含层。最后到输入层,依次调节隐含层到输出层的权重和偏置,输入层到隐含层的权重和偏置。

    二、BP神经网络的流程

        在知道了BP神经网络的特点后,我们须要根据信号的前向传播和误差的反向传播来构建整个网络。

    1、网络的初始化

        如果输入层的节点个数为,隐含层的节点个数为,输出层的节点个数为

    输入层到隐含层的权重,隐含层到输出层的权重为,输入层到隐含层的偏置为,隐含层到输出层的偏置为。学习速率为,激励函数为。当中激励函数为取Sigmoid函数。形式为:


    2、隐含层的输出

        如上面的三层BP网络所看到的,隐含层的输出

    3、输出层的输出


    4、误差的计算

        我们取误差公式为:

    当中为期望输出。

    我们记,则能够表示为


    以上公式中。

    5、权值的更新

        权值的更新公式为:

    这里须要解释一下公式的由来:
    这是误差反向传播的过程,我们的目标是使得误差函数达到最小值。即。我们使用梯度下降法:
    • 隐含层到输出层的权重更新
    则权重的更新公式为:

    • 输入层到隐含层的权重更新
    当中



    则权重的更新公式为:

    6、偏置的更新

        偏置的更新公式为:

    • 隐含层到输出层的偏置更新
    则偏置的更新公式为:

    • 输入层到隐含层的偏置更新
    当中



    则偏置的更新公式为:

    7、推断算法迭代是否结束

        有非常多的方法能够推断算法是否已经收敛,常见的有指定迭代的代数,推断相邻的两次误差之间的区别是否小于指定的值等等。

    三、实验的仿真

        在本试验中。我们利用BP神经网络处理一个四分类问题,终于的分类结果为:

    MATLAB代码

    主程序
    %% BP的主函数
    
    % 清空
    clear all;
    clc;
    
    % 导入数据
    load data;
    
    %从1到2000间随机排序
    k=rand(1,2000);
    [m,n]=sort(k);
    
    %输入输出数据
    input=data(:,2:25);
    output1 =data(:,1);
    
    %把输出从1维变成4维
    for i=1:2000
        switch output1(i)
            case 1
                output(i,:)=[1 0 0 0];
            case 2
                output(i,:)=[0 1 0 0];
            case 3
                output(i,:)=[0 0 1 0];
            case 4
                output(i,:)=[0 0 0 1];
        end
    end
    
    %随机提取1500个样本为训练样本,500个样本为预測样本
    trainCharacter=input(n(1:1600),:);
    trainOutput=output(n(1:1600),:);
    testCharacter=input(n(1601:2000),:);
    testOutput=output(n(1601:2000),:);
    
    % 对训练的特征进行归一化
    [trainInput,inputps]=mapminmax(trainCharacter');
    
    %% 參数的初始化
    
    % 參数的初始化
    inputNum = 24;%输入层的节点数
    hiddenNum = 50;%隐含层的节点数
    outputNum = 4;%输出层的节点数
    
    % 权重和偏置的初始化
    w1 = rands(inputNum,hiddenNum);
    b1 = rands(hiddenNum,1);
    w2 = rands(hiddenNum,outputNum);
    b2 = rands(outputNum,1);
    
    % 学习率
    yita = 0.1;
    
    %% 网络的训练
    for r = 1:30
        E(r) = 0;% 统计误差
        for m = 1:1600
            % 信息的正向流动
            x = trainInput(:,m);
            % 隐含层的输出
            for j = 1:hiddenNum
                hidden(j,:) = w1(:,j)'*x+b1(j,:);
                hiddenOutput(j,:) = g(hidden(j,:));
            end
            % 输出层的输出
            outputOutput = w2'*hiddenOutput+b2;
            
            % 计算误差
            e = trainOutput(m,:)'-outputOutput;
            E(r) = E(r) + sum(abs(e));
            
            % 改动权重和偏置
            % 隐含层到输出层的权重和偏置调整
            dw2 = hiddenOutput*e';
            db2 = e;
            
            % 输入层到隐含层的权重和偏置调整
            for j = 1:hiddenNum
                partOne(j) = hiddenOutput(j)*(1-hiddenOutput(j));
                partTwo(j) = w2(j,:)*e;
            end
            
            for i = 1:inputNum
                for j = 1:hiddenNum
                    dw1(i,j) = partOne(j)*x(i,:)*partTwo(j);
                    db1(j,:) = partOne(j)*partTwo(j);
                end
            end
            
            w1 = w1 + yita*dw1;
            w2 = w2 + yita*dw2;
            b1 = b1 + yita*db1;
            b2 = b2 + yita*db2;  
        end
    end
    
    %% 语音特征信号分类
    testInput=mapminmax('apply',testCharacter',inputps);
    
    for m = 1:400
        for j = 1:hiddenNum
            hiddenTest(j,:) = w1(:,j)'*testInput(:,m)+b1(j,:);
            hiddenTestOutput(j,:) = g(hiddenTest(j,:));
        end
        outputOfTest(:,m) = w2'*hiddenTestOutput+b2;
    end
    
    %% 结果分析
    %根据网络输出找出数据属于哪类
    for m=1:400
        output_fore(m)=find(outputOfTest(:,m)==max(outputOfTest(:,m)));
    end
    
    %BP网络预測误差
    error=output_fore-output1(n(1601:2000))';
    
    k=zeros(1,4);  
    %找出推断错误的分类属于哪一类
    for i=1:400
        if error(i)~=0
            [b,c]=max(testOutput(i,:));
            switch c
                case 1 
                    k(1)=k(1)+1;
                case 2 
                    k(2)=k(2)+1;
                case 3 
                    k(3)=k(3)+1;
                case 4 
                    k(4)=k(4)+1;
            end
        end
    end
    
    %找出每类的个体和
    kk=zeros(1,4);
    for i=1:400
        [b,c]=max(testOutput(i,:));
        switch c
            case 1
                kk(1)=kk(1)+1;
            case 2
                kk(2)=kk(2)+1;
            case 3
                kk(3)=kk(3)+1;
            case 4
                kk(4)=kk(4)+1;
        end
    end
    
    %正确率
    rightridio=(kk-k)./kk

    激活函数
    %% 激活函数
    function [ y ] = g( x )
        y = 1./(1+exp(-x));
    end
    


  • 相关阅读:
    php 获取上上个月数据 使用 strtotime('-1 months')的一个bug
    mysql ON DUPLICATE KEY UPDATE 用法
    在WAMPSERVER下增加多版本的PHP(PHP5.3,PHP5.4,PHP5.5 ,PHP5.6)支持。
    Window7 环境下 MariaDB 的安装 及使用
    memcache和memcached之间的区别和联系
    基于bootstrap + php +ajax datatable 插件的使用
    daterangepicker+ bootstrap +php +ajax +datatable双日历的使用
    基于bootstrap 的datatable插件的使用2(php版)
    CI 框架导出文件
    MYSQL中replace into的用法
  • 原文地址:https://www.cnblogs.com/gccbuaa/p/6905590.html
Copyright © 2011-2022 走看看