HNAS 2020-06-08 12:04 采纳率: 0%
浏览 179
已结题

Bp算法结果值与预期不符,结果值很平均

本人小白,通过学习网上的Bp算法的定义和公式,自己写了一个自己的Bp算法。
但是写完,运算 后发现其计算学习后的预测值与实际想要的不太相符,预测的数值非常平均。
平均现象如下:
图片说明

麻烦各位大佬帮忙看看··这已经是我写的第三个版本了··出现的预测值还是很平均,不清楚到底是哪里出错了......真心求助
有任何疑问可以que我

我用的是java实现的。
总共有4个class

Bp.class :主类

import java.util.ArrayList;
import java.util.List;
import java.util.Random;

public class Bp{
    int length;//层数长度
    List<Layer> mLayer;
    void setlen(int len){ //设置层数
        length = len;
    }
    void setin(double[] in){//输入初始化
        mLayer.get(0).setin(in);
    }
    void settarget(double[] target){//输出初始化 
        mLayer.get(length -1).settarget(target);
    }
    void init(int len,double[] in ,int nelen,double[] out){//初始化权值和偏置  
        //随机生成
        //len 总层数
        //in 输入值数组
        //nelen 层中总neural个数
        //out 目标输出

        setlen(len);
        mLayer = new ArrayList<>();
        Layer inlayer = new Layer();
        inlayer.addcount();
        mLayer.add(inlayer);
        for(int i = 0; i < len -1;i++){
            Layer l = new Layer();
            l.addcount();
            l.randomWeight(len);
            mLayer.add(l);
        }
        for(int j =0; j < mLayer.size();j++){
            if(j == 0)
                mLayer.get(j).Next =  mLayer.get(j+1);
            else if(j == length -1)
                mLayer.get(j).pre =  mLayer.get(j-1);
            else{
                mLayer.get(j).pre = mLayer.get(j-1);
                mLayer.get(j).Next =  mLayer.get(j+1);
            }
        }
        setin(in);
        settarget(out);

    }


    void feedward(){
        for(int i =0;i< length;i++)
            mLayer.get(i).feedward();
    }

    void backward(){
        for(int i =length -1;i >= 0 ;i--)
            mLayer.get(i).backward();
    }
    void printConstruction(){
        System.out.println("输入值:");
        for( int i =0; i < mLayer.get(0).length;i ++)
                System.out.println("第"+i+"层:"+mLayer.get(0).lin[i]);
        System.out.println("目标输出值:");
        for( int i =0; i < mLayer.get(length-1).length ;i ++)
                System.out.println("第"+i+"层:"+mLayer.get(length-1).lout[i]);
        System.out.println("真实输出值:");
        for( int i =0; i < mLayer.get(length-1).length ;i ++)
                System.out.println("第"+i+"层:"+mLayer.get(length-1).realout[i]);
    }
    void printError(){
        double sum = 0;
        for( int i =0; i < mLayer.get(length-1).length ;i ++)
            sum += mLayer.get(length-1).realout[i] - mLayer.get(length-1).lout[i];
        sum = sum /(length -1);
        System.out.println("误差:"+sum);
    }
    public static void main(String[] args) {
        Bp backfeed = new Bp();
        double[] in = {1,0,0};
        double[] out = {1,0,0};
        backfeed.init(3,in,3,out);
        for (int i =0;i <3000;i++){
            double[] in1 = {1,0,0};
            double[] out1 = {1,0,0};
            //Random r = new Random();
            int y =0;
            y = i%3;
            if (y ==0){
                in1 = new double[] {1,0,0};
                out1 = new double[] {1,0,0};
            }
            if (y ==1){
                in1 = new double[] {0,1,0};
                out1 = new double[] {0,1,0};
            }
            if (y ==2){
                in1 = new double[] {0,0,1};
                out1 = new double[] {0,0,1};
            }
            backfeed.setin(in1);
            backfeed.settarget(out1);
            backfeed.feedward();
            backfeed.backward();
            backfeed.printError();
        }
        double[] in1 = {1,0,0};
        System.out.println("当: {1,0,0}时");
        in1 = new double[] {1,0,0};
        backfeed.setin(in1);
        backfeed.feedward();
        backfeed.printConstruction();
        System.out.println("当: {0,1,0}时");
        in1 = new double[] {0,1,0};
        backfeed.setin(in1);
        backfeed.feedward();
        backfeed.printConstruction();
    }
}


//Layer.class

import java.util.*;
import java.lang.Math;


public class Layer{
    static int _layercount = 0;//总层数
    int layercount;//该层数
    int length;
    Neural[] neurals;
    double[] lin;
    double[] lout;//目标输出点
    double[] net;
    double[] realout;//真实输出点
    Layer pre;
    Layer Next;
    double[] delta;//误差
    double meu = Settings.meu;
    void setin(double[] in){
        length = in.length;
        if(lin == null)
            lin = new double[length];
        if(net == null)
            net = new double[length];
        lin = in;
    }
    void settarget(double[] out){
        length = out.length;
        if(lout == null)
            lout = new double[length];
        lout = out;
    }
    void randomWeight(int len){
        Random r = new Random();
        length = len;
        if(neurals ==null)
            neurals = new Neural[length];
        for(int i = 0; i < neurals.length; i++){
            if (neurals[i] ==null){
                neurals[i] = new Neural();
                neurals[i].length = len;
            }

            if (neurals[i].Weight ==null)
                neurals[i].Weight = new double[length];
            for(int j = 0; j< neurals[i].Weight.length;j++){
                neurals[i].Weight[j] = r.nextDouble();
            }

        }
    }


    void feedward(){
        if(realout == null)
            realout = new double[length]; 
        if(net == null)
            net = new double[length];
        if(layercount == 1)
            for (int i =0;i < length ;i++){
                realout[i] = lin[i];    //输入层的输出 = 输入
            }
        else{
            for (int i =0;i < length ;i++){ //这一层细胞数
                double sum = 0;
                for(int j =0;j< neurals[i].length;j++)//细胞数的weight总数
                    sum += neurals[i].Weight[j] * pre.realout[i]; //前者所有细胞的输出分别与该层这个细胞的权值相乘。

                net[i] = sum;
                realout[i] = sigmoid(net[i]);
            }

        }

        //初始化


    }

    void calc_deta(){//计算误差delta δ
        if (delta == null){
            delta = new double[length];
        }
        if (layercount == _layercount)
            for(int i = 0;i < length;i++){
                double aj = realout[i];
                delta[i] = aj * (1-aj)*(lout[i] -aj);
                //该层下这个细胞对应delta误差 
            }
        else{
            for(int i =0; i < length;i++){
                double sum  =0;
                double aj = realout[i];
                for(int j =0; j > Next.neurals[i].Weight.length;j++){
                    sum += Next.delta[i] * Next.neurals[j].Weight[i];//下一层细胞的对应权值 * 通用误差δ 之和
                }

                delta[i] = sum * aj * (1-aj);
            }

        }
    }
    void updatew(){
        if(layercount == 1)
            return;
        if(layercount == _layercount){
            for(int i =0; i< length; i++)
                for(int j =0; j < neurals[i].Weight.length;j++)
                    neurals[i].Weight[j] = neurals[i].Weight[j] + (delta[i] * pre.realout[i] * meu);
            return;
        }else{
            for(int i =0; i< length; i++)
            for(int j =0; j < neurals[i].Weight.length;j++)
                neurals[i].Weight[j] = neurals[i].Weight[j] + (delta[i] * pre.realout[i] * meu);
        }

    //这一层的Δw = 这一层权值 - (上一层 与 权值 相对应的细胞输出值 * 学习率 * δ)
    }
    void backward(){
        calc_deta();
        updatew(); 
    }
    void addcount(){
        _layercount++;
        layercount = _layercount;
    }
    double sigmoid(double mnet){
        return 1 / (1 + Math.exp(-mnet));
    }
}
//Neurals.class

public class Neural{
    int length;
    double[] Weight;
}
//Settings.class

class Settings{
    static double meu = 0.5;
}
  • 写回答

2条回答 默认 最新

报告相同问题?

悬赏问题

  • ¥15 shape_predictor_68_face_landmarks.dat
  • ¥15 slam rangenet++配置
  • ¥15 有没有研究水声通信方面的帮我改俩matlab代码
  • ¥15 对于相关问题的求解与代码
  • ¥15 ubuntu子系统密码忘记
  • ¥15 信号傅里叶变换在matlab上遇到的小问题请求帮助
  • ¥15 保护模式-系统加载-段寄存器
  • ¥15 电脑桌面设定一个区域禁止鼠标操作
  • ¥15 求NPF226060磁芯的详细资料
  • ¥15 使用R语言marginaleffects包进行边际效应图绘制