计算智能 -- BP神经网络(1)

本文实现的是对张军等编写的《计算智能》第二章中的2.4.3引用举例的code实现。

图一
计算智能

图二
应用举例

import java.util.Scanner;

public class Bp {

    private int InputLayer = 3;         //输入层
    private int HiddenLayer = 2;        //隐含层
    private int OutputLayer = 1;        //输出层
    private double LearningRate = 0.9;  //学习率
    private double ExpectedValue = 1;   //预期值
    double [][] Input_Hidden_weights = new double [InputLayer][HiddenLayer];    //输入层到隐含层的权重
    double [][] Hidden_Output_weights = new double [HiddenLayer][OutputLayer];  //隐含层到输出层的权重
    double [] Hidden_polarization = new double[HiddenLayer];    //隐含层的偏置
    double [] Output_polarization = new double[OutputLayer];    //输出层的偏置
    double [] HiddenInputValues = new double[HiddenLayer];      //隐含层的输入值
    double [] HiddenOutputValues = new double[HiddenLayer];     //隐含层的输出值
    double [] OutputInputValues = new double[OutputLayer];      //输出层的输入值
    double [] OutputOutputValues = new double[OutputLayer];     //输出层的输出值
    double [] ErrorHiddenValues = new double[HiddenLayer];      //隐含层的误差值
    double [] ErrorOutputValues = new double[OutputLayer];      //输出层的误差值
    double [][] Adjustment_Input_Hidden_weights = new double [InputLayer][HiddenLayer];  //调整输入层到隐含层的权重
    double [][] Adjustment_Hidden_Output_weights = new double [HiddenLayer][OutputLayer]; //调整隐含层到输出层的权重
    double [] Adjustment_Hidden_polarization = new double [HiddenLayer];  //调整隐含层的偏置
    double [] Adjustment_Output_polarization = new double [OutputLayer]; //调整输出层的偏置


    //一、初始化网络权重和偏置
    void initialize(){

        Scanner in = new Scanner(System.in);

        //(1)输入层到隐含层的连接权重
        System.out.println("请输入输出层到隐含层的连接权重:");
        for (int i = 0 ; i < InputLayer ; i++ ){
            for ( int j = 0 ; j < HiddenLayer; j++ ){
                Input_Hidden_weights[i][j]= in.nextDouble();
            }
        }

        //(2)隐含层到输出层的连接权重
        System.out.println("请输入隐含层到输出层的连接权重:");
        for (int i = 0 ; i < HiddenLayer ; i++ ){
            for ( int j = 0 ; j < OutputLayer; j++ ){
                Hidden_Output_weights[i][j]= in.nextDouble();
            }
        }

        //(3)隐含层的偏置
        System.out.println("请输入隐含层的偏置:");
        for (int i = 0 ; i < HiddenLayer ; i++ ){
            Hidden_polarization[i] = in.nextDouble(); 
        }

        //(4)输出层的偏置
        System.out.println("请输入输出层的偏置:");
        for (int i = 0 ; i < OutputLayer ; i++ ){
            Output_polarization[i] = in.nextDouble(); 
        }   

        System.out.println("*********************************");  
    }

    //二、创建激活函数
    double ActivationFunction(double x){
        return 1/( 1 + Math.pow(Math.E,-x));
    }

    //三、向前传播输入(前馈型网络)
    void Forward( double[] TrainingSamples ){

        //隐含层的总输入和输出
        for(int i = 0; i < HiddenInputValues.length ; i++ ){
            double OutputSumTemp = 0; //临时存放数据
            for(int j = 0; j < TrainingSamples.length; j++ ){
                OutputSumTemp += TrainingSamples[j]*Input_Hidden_weights[j][i];
            }
            HiddenInputValues[i]= OutputSumTemp + Hidden_polarization[i];
            System.out.println("神经元"+(i+4)+"的总输入:");
            System.out.println(HiddenInputValues[i]);
            HiddenOutputValues[i] = ActivationFunction(HiddenInputValues[i]);
            System.out.println("神经元"+(i+4)+"的总输出:");
            System.out.println(HiddenOutputValues[i]);
        }

        //输出层的总输入和输出
        for( int i = 0 ; i < OutputLayer ; i++ ){
            double OutputSumTemp = 0; //临时存放数据
            for(int j = 0; j < HiddenLayer ; j++ ){
                OutputSumTemp += HiddenOutputValues[j]*Hidden_Output_weights[j][i];
            }
            OutputInputValues[i]= OutputSumTemp + Output_polarization[i];
            System.out.println("神经元"+(i+6)+"的总输入:");
            System.out.println(OutputInputValues[i]);
            OutputOutputValues[i] = ActivationFunction(OutputInputValues[i]);
            System.out.println("神经元"+(i+6)+"的总输出:");
            System.out.println(OutputOutputValues[i]);
        }
        System.out.println("*********************************");
    }

    //三、反向误差传播
    void BackWard(){

        //输出层的误差
        for(int i = 0 ; i < OutputLayer ; i++ ){
            ErrorOutputValues[i] = OutputOutputValues[i]*( 1 - OutputOutputValues[i])*( ExpectedValue - OutputOutputValues[i] );
            System.out.println("神经元"+(i+6)+"的误差:");
            System.out.println(ErrorOutputValues[i]);
        }

        //隐含层的误差
        for(int i = HiddenLayer - 1 ; i >= 0 ; i-- ){
            double ErrorTemp = 0; //临时存放数据
            for(int j = 0 ; j < OutputLayer ; j++ ){
                ErrorTemp = HiddenOutputValues[i]*( 1-HiddenOutputValues[i])*ErrorOutputValues[j]*Hidden_Output_weights[i][j];
            }
            ErrorHiddenValues[i] = ErrorTemp;
            System.out.println("神经元"+(i+4)+"的误差:");
            System.out.println(ErrorHiddenValues[i]);
        }

        System.out.println("*********************************");
    }

    //四、网络连接权重和偏置的调整
    void Adjustment(double[] TrainingSamples){

        //(1)调整隐含层到输出层的权重值
        System.out.println("调整隐含层到输出层的连接权重:");
        for(int i = 0 ; i < HiddenLayer ; i++ ){
            double TempWeights = 0; //临时存放数据
            for(int j = 0  ; j < OutputLayer ; j++ ){
                TempWeights = Hidden_Output_weights[i][j]+LearningRate*ErrorOutputValues[j]*HiddenOutputValues[i];
                Adjustment_Hidden_Output_weights[i][j] = TempWeights;
                System.out.println(Adjustment_Hidden_Output_weights[i][j]);
            }
        }

        //(2)调整输入层到隐含层的权重值
        System.out.println("调整输入层到隐含层的权重值:");
        for(int i = 0 ; i < InputLayer ; i++ ){
            double TempWeights = 0; //临时存放数据
            for(int j = 0 ; j < HiddenLayer; j++ ){
                TempWeights = Input_Hidden_weights[i][j]+LearningRate*ErrorHiddenValues[j]*TrainingSamples[i];
                Adjustment_Input_Hidden_weights[i][j] = TempWeights;
                System.out.println(Adjustment_Input_Hidden_weights[i][j]);
            }
        }

        //(3)调整输出层的偏置
        System.out.println("调整输出层的偏置:");
        for(int i = 0; i < OutputLayer; i++ ){
            Adjustment_Output_polarization[i] = Output_polarization[i] + LearningRate * ErrorOutputValues[i];
            System.out.println(Adjustment_Output_polarization[i]);
        }

        //(4)调整隐含层的偏置
        System.out.println("调整隐含层的偏置:");
        for(int i = HiddenLayer - 1 ; i >= 0; i-- ){
            Adjustment_Hidden_polarization[i] = Hidden_polarization[i] + LearningRate * ErrorHiddenValues[i];
            System.out.println(Adjustment_Hidden_polarization[i]);
        }
    }

    //五、判断结束
    void Judge(){

    }

    public static void main(String[] args) {
        // TODO Auto-generated method stub
        Bp bpnn = new Bp();
        bpnn.initialize();
        double[] TrainData = {1,0,1};
        bpnn.Forward(TrainData);
        bpnn.BackWard();
        //如果误差不在容忍的范围内则进行调整
        bpnn.Adjustment(TrainData);
    }
}

运行截图:

运行截图

注意点:
这个code实现的是一次计算,由于判断函数没有去实现。书中对判断结束描述如下:对于每个样本,如果最终的输出误差小于可接受的范围或者迭代次数t达到了一定的阈值,则选取下一个样本,转到步骤二继续执行;否则,迭代次数加1,然后向步骤2继续使用当前样本训练。

参考资料:
(1)woodbean – BP神经网络实现(Java代码):http://blog.csdn.net/woodbean/article/details/7175378
(2)ACdreamers – BP神经网络:http://blog.csdn.net/acdreamers/article/details/44657439
(3)https://zhidao.baidu.com/question/320522363.html
(4)http://www.cnblogs.com/hesi/p/7218602.html
(5)刀客123 – BP神经网络的数据分类 : http://blog.csdn.net/dingyahui123/article/details/72809153?locationNum=1&fps=1
(6)zhc0822 – BP神经网络的Java实现 : http://fantasticinblur.iteye.com/blog/1465497

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值