Java实现JOONE的模式识别

目前主要用到的有【java神经网络组件Joone、Encog和Neuroph】

Joone的实现:

算法:我自己感受不干什么算法变成都不是那么困难那学习,最重要的是你要有一套合理简洁的数学方法,让机器很容易就领会到它;joone是早期的一个模式识别的算法框架,里面是用了BP神经网络的算法实现。分为文件训练神经网络和内训训练神经网络。

JOONE 主要有三个大的模块:

  • joone-engine:joone的核心模块
  • joone-editor:joone的GUI开发环境。图形界面建立神经网络模型,可以进行训练和验证。 JOONE中提供了一个用joone-editor建立XOR网络模型的例子。
  • joone-distributed-environment:joone 用于支持分布式计算的模块。

具体代码实现:

import java.io.*;
import org.joone.engine.*;
import org.joone.engine.learning.TeachingSynapse;
import org.joone.io.*;
import org.joone.net.*;

/**BPNN类,实现了神经网络初始化,训练,测试等方法
 * 输入为0~1之间的double数(组)
 * 输出为0~1之间的double数(组)
 * 使用的接口方法可自定义执行内容
 * */
public class BPNN  implements NeuralNetListener,Serializable {
    //序列号用于检查兼容性
    private static final long serialVersionUID = -3472219226214066504L;
    //神经网络成员
    private NeuralNet nnet = null;
    //神经网络保存路径
    private String NNet_Path = null;

    /**初始化神经网络
     * String NNet_Path 神经网络存放路径
     * int InputNum     输入层神经元个数
     * int HiddenNum    隐藏层神经元个数
     * int OutputNum    输出层神经元个数
     * */
    public void Init_BPNN(String NNet_Path,int InputNum,int HiddenNum,int OutputNum) {
        //设置新网络的保存路径
        this.NNet_Path = NNet_Path;
        //新建三个Layer,分别作为输入层,隐藏层,输出层
        LinearLayer input = new LinearLayer();
        SigmoidLayer hidden = new SigmoidLayer();
        SigmoidLayer output = new SigmoidLayer();
        //设置每个Layer包含的神经元个数
        input.setRows(InputNum);
        hidden.setRows(HiddenNum);
        output.setRows(OutputNum);
        //新建两条突触,用于连接各层
        FullSynapse synapse_IH = new FullSynapse();
        FullSynapse synapse_HO = new FullSynapse();
        //连接输入-隐藏,隐藏-输出各层
        input.addOutputSynapse(synapse_IH);
        hidden.addInputSynapse(synapse_IH);
        hidden.addOutputSynapse(synapse_HO);
        output.addInputSynapse(synapse_HO);
        //新建一个神经网络,并添加输入层,隐藏层,输出层
        nnet = new NeuralNet();
        nnet.addLayer(input, NeuralNet.INPUT_LAYER);
        nnet.addLayer(hidden, NeuralNet.HIDDEN_LAYER);
        nnet.addLayer(output, NeuralNet.OUTPUT_LAYER);
    }
    /**使用磁盘文件训练新建的神经网络,需与Init_BPNN搭配使用
     * String TrainFile 训练文件存放路径
     * int TrainLength  训练文件的行数
     * double Rate      神经网络训练速度
     * double Momentum  神经网络训练动量
     * int TrainCicles  神经网络训练次数
     * */
    public void Train_BPNN(String TrainFile,int TrainLength,double Rate,double Momentum,int TrainCicles){
        //获取输入层
        Layer input = nnet.getInputLayer();
        //新建输入突触
        FileInputSynapse trains = new FileInputSynapse();
        //设置输入文件
        trains.setInputFile(new File(TrainFile));
        //设置使用的列数,文件第1,2,3,4列作为训练的输入
        trains.setAdvancedColumnSelector("1,2,3,4");

        //获取输出层
        Layer output = nnet.getOutputLayer();
        //新建输入突触
        FileInputSynapse target = new FileInputSynapse();
        //设置输入文件
        target.setInputFile(new File(TrainFile));
        //设置使用的列数,文件第5,6列作为训练的目标
        target.setAdvancedColumnSelector("5,6");

        //新建训练突触
        TeachingSynapse trainer = new TeachingSynapse();
        //设置训练目标
        trainer.setDesired(target);

        //添加输入层的输入突触
        input.addInputSynapse(trains);
        //添加输出层的输出突触
        output.addOutputSynapse(trainer);
        //设置神经网络的训练突触
        nnet.setTeacher(trainer);

        //获取神经网络的监视器
        Monitor monitor = nnet.getMonitor();
        //设置训练速率
        monitor.setLearningRate(Rate);
        //设置训练动量
        monitor.setMomentum(Momentum);
        //新增监听者
        monitor.addNeuralNetListener(this);// 输入流
        //设置训练数据个数(行数)
        monitor.setTrainingPatterns(TrainLength);
        //设置训练次数
        monitor.setTotCicles(TrainCicles);
        //打开训练模式
        monitor.setLearning(true);
        //开始训练
        nnet.go();
    }
    /**使用内存数据训练新建的神经网络,需与Init_BPNN搭配使用
     * double[][] TrainData 训练文件存放路径
     * double Rate      神经网络训练速度
     * double Momentum  神经网络训练动量
     * int TrainCicles  神经网络训练次数
     * */
    public void Train_BPNN(double[][] TrainData,double Rate,double Momentum,int TrainCicles){

        Layer input = nnet.getInputLayer();
        //设置输入数组
        MemoryInputSynapse trains = new MemoryInputSynapse();
        trains.setInputArray(TrainData);
        trains.setAdvancedColumnSelector("1,2,3,4");

        Layer output = nnet.getOutputLayer();
        //设置输出数组
        MemoryInputSynapse target = new MemoryInputSynapse();
        target.setInputArray(TrainData);
        target.setAdvancedColumnSelector("5,6");

        TeachingSynapse trainer = new TeachingSynapse();
        trainer.setDesired(target);
        input.addInputSynapse(trains);
        output.addOutputSynapse(trainer);
        nnet.setTeacher(trainer);

        Monitor monitor = nnet.getMonitor();
        monitor.setLearningRate(Rate);
        monitor.setMomentum(Momentum);
        monitor.addNeuralNetListener(this);
        monitor.setTrainingPatterns(TrainData.length);
        monitor.setTotCicles(TrainCicles);
        monitor.setLearning(true);
        nnet.go();
    }
    /**使用磁盘文件再次训练已有的神经网络
     * String NNet_Path 神经网络存放路径
     * String TrainFile 训练文件存放路径
     * int TrainLength  训练文件的行数
     * double Rate      神经网络训练速度
     * double Momentum  神经网络训练动量
     * int TrainCicles  神经网络训练次数
     * */
    public void Train_BPNN(String NNet_Path,String TrainFile,int TrainLength,double Rate,double Momentum,int TrainCicles){
        //初始化神经网络的保存路径
        this.NNet_Path = NNet_Path;
        //获取保存的神经网络
        this.nnet = this.Get_BPNN(NNet_Path);

        Monitor monitor = this.nnet.getMonitor();
        monitor.setLearningRate(Rate);
        monitor.setMomentum(Momentum);
        monitor.addNeuralNetListener(this);
        monitor.setTrainingPatterns(TrainLength);
        monitor.setTotCicles(TrainCicles);
        monitor.setLearning(true);
        this.nnet.go();
    }
    /**使用磁盘文件测试训练过的神经网络
     * String NNet_Path 神经网络存放路径
     * String OutFile   测试结果存放路径
     * String TestFile  训练文件存放路径
     * int TestLength   训练文件的行数
     * */
    public void Test_BPNN(String NNet_Path,String OutFile,String TestFile,int TestLength){
        NeuralNet testBPNN = this.Get_BPNN(NNet_Path);
        if (testBPNN != null) {

            Layer input = testBPNN.getInputLayer();
            /**采用文件输入测试 */
            FileInputSynapse inputStream = new FileInputSynapse();
            inputStream.setInputFile(new File(TestFile));
            inputStream.setAdvancedColumnSelector("1,2,3,4");
            input.removeAllInputs();
            input.addInputSynapse(inputStream);

            Layer output = testBPNN.getOutputLayer();
            //设置输出突触
            FileOutputSynapse fileOutput = new FileOutputSynapse();
            //设置输出文件保存路径
            fileOutput.setFileName(OutFile);
            output.addOutputSynapse(fileOutput);

            Monitor monitor = testBPNN.getMonitor();
            monitor.setTrainingPatterns(TestLength);
            monitor.setTotCicles(1);
            //关闭训练模式
            monitor.setLearning(false);

            //开始测试
            testBPNN.go();
            System.out.println("test");
        }
    }
    /**使用内存矩阵测试训练过的神经网络
     * String NNet_Path 神经网络存放路径
     * String OutFile   测试结果存放路径
     * double[][] TestData  测试矩阵
     * */
    public void Test_BPNN(String NNet_Path,String OutFile,double[][] TestData){
        NeuralNet testBPNN = this.Get_BPNN(NNet_Path);
        if (testBPNN != null) {

            Layer input = testBPNN.getInputLayer();
            /**采用矩阵输入测试*/
            MemoryInputSynapse inputStream = new MemoryInputSynapse();
            input.removeAllInputs();
            input.addInputSynapse(inputStream);
            inputStream.setInputArray(TestData);
            inputStream.setAdvancedColumnSelector("1,2,3,4");

            Layer output = testBPNN.getOutputLayer();
            FileOutputSynapse fileOutput = new FileOutputSynapse();
            fileOutput.setFileName(OutFile);
            output.addOutputSynapse(fileOutput);

            Monitor monitor = testBPNN.getMonitor();
            monitor.setTrainingPatterns(TestData.length);
            monitor.setTotCicles(1);
            monitor.setLearning(false);

            testBPNN.go();
            System.out.println("test");
        }
    }
    /**使用内存矩阵测试训练过的神经网络
     * String NNet_Path 神经网络存放路径
     * double[][] TestData  测试矩阵
     * int[][] result   返回的测试结果
     * */
    public int[][] Test_BPNN(String NNet_Path,double[][] TestData){
        NeuralNet testBPNN = this.Get_BPNN(NNet_Path);
        int[][] result = new int[TestData.length][2];
        if (testBPNN != null) {
            double[] temp = new double[2];

            Layer input = testBPNN.getInputLayer();
            /**采用矩阵输入测试*/
            MemoryInputSynapse inputStream = new MemoryInputSynapse();
            input.removeAllInputs();
            input.addInputSynapse(inputStream);
            inputStream.setInputArray(TestData);
            inputStream.setAdvancedColumnSelector("1,2,3,4");

            Layer output = testBPNN.getOutputLayer();
            MemoryOutputSynapse fileOutput = new MemoryOutputSynapse();
            output.addOutputSynapse(fileOutput);

            Monitor monitor = testBPNN.getMonitor();
            monitor.setTrainingPatterns(TestData.length);
            monitor.setTotCicles(1);
            monitor.setLearning(false);
            testBPNN.go();

            for(int i = 0;i<result.length;i++){
                temp = fileOutput.getNextPattern();
                result[i][0] = temp[0] < 0.5 ? 0 : 1;
                result[i][1] = temp[1] < 0.5 ? 0 : 1;
                System.out.println(result[i][0]+"---------"+result[i][1]);
            }
            return result;
        }
        return result;
    }
    /**读入已有的神经网络
     * String NNet_Path 神经网络存放路径
     * */
    NeuralNet Get_BPNN(String NNet_Path) {
        NeuralNetLoader loader = new NeuralNetLoader(NNet_Path);
        NeuralNet nnet = loader.getNeuralNet();
        return nnet;
    }

    /**具体实现所用接口的方法
     * */
    @Override
    public void cicleTerminated(NeuralNetEvent arg0) {
        // TODO 自动生成的方法存根
        //获取监视器
        Monitor mon = (Monitor)arg0.getSource();
        //获取总的训练次数
        long totalcicles = mon.getTotCicles();
        //获取当前要做的训练次数
        long currentcicle = mon.getCurrentCicle();

        //按照一定规律减小训练速率
        int t1 = (int) ((totalcicles*0.3)/100);
        int t2 = (int) ((totalcicles*0.5)/100);
        int t3 = (int) ((totalcicles*0.8)/100);
        if (currentcicle == t1*100){
            double rate = mon.getLearningRate();
            mon.setLearningRate(rate*0.5);
            System.out.println(1);
        }
        else if (currentcicle == t2*100){
            double rate = mon.getLearningRate();
            mon.setLearningRate(rate*0.5);
            System.out.println(2);
        }
        else if (currentcicle == t3*100){
            double rate = mon.getLearningRate();
            mon.setLearningRate(rate*0.5);
            System.out.println(3);
        }

        //获取误差并输出
        double err = mon.getGlobalError();
        if (currentcicle % 100 == 0)
            System.out.println(currentcicle + " epochs remaining - RMSE = " + err);
    }

    @Override
    public void netStarted(NeuralNetEvent arg0) {
        // TODO 自动生成的方法存根
        System.out.println("start");
    }

    @Override
    public void netStopped(NeuralNetEvent arg0) {
        // TODO 自动生成的方法存根
        System.out.println("Training Stopped...");
        //保存训练完的网络
        try {
            FileOutputStream stream = new FileOutputStream(NNet_Path);
            ObjectOutputStream out = new ObjectOutputStream(stream);
            out.writeObject(nnet);// 写入nnet对象
            out.close();
            System.out.println("Save in "+NNet_Path);
        } catch (Exception excp) {
            excp.printStackTrace();
        }
    }

    @Override
    public void errorChanged(NeuralNetEvent arg0)
    {
        // TODO 自动生成的方法存根

    }


    @Override
    public void netStoppedError(NeuralNetEvent arg0, String arg1)
    {
        // TODO 自动生成的方法存根

    }

}

以上代码主要是创建神经网络,分别创建内存和文件训练神经网络的方法工具类

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;

public class Main {

    public static void main(String[] args) {
      testone();
    }
    private static void testone() {
        String NNet_Path = "E:\\nnet.snet";
        String TrainFile = "E:\\train.txt";
        String TestFile = "E:\\test.txt";
        String OutputFile = "E:\\test_output.txt";

        double[][] TestData = new double[][] {
                {0.505320600272851, 0.304556354916067,0.252767052767053,0.544487015751384,  1,1},
                {0.494679399727149, 0.264816718054128,0.245817245817246,0.442315879097488,  1,1},
                {0.312960436562074, 0.645083932853717,0.194337194337194,0.200085142613878,  1,1},
                {0.277216916780355, 0.382322713257965,0.286229086229086,0.441890166028097,  1,0},
                {0.315688949522510, 0.322028091812265,0.218532818532819,0.494252873563218,  1,0},
                {0.683492496589359, 0.302843439534087,0.218275418275418,0.429118773946360,  1,0},
                {0.0141882673942701,0.289140116478246,0.219305019305019,0.440613026819923,  0,1},
                {0.0141882673942701,0.303871188763275,0.250707850707851,0.438910174542359,  0,1},
                {0.0144611186903138,0.290853031860226,0.221106821106821,0.437633035334185,  0,1},
                {0.0643929058663029,0.292908530318602,0.254826254826255,0.0770540655598127, 0,0},
                {0.0643929058663029,0.309695101062008,0.255341055341055,0.0706683695189442, 0,0},
                {0.0663028649386085,0.303871188763275,0.255598455598456,0.0706683695189442, 0,0}
        };
        double[][] HttData = new double[][] {
                {0.05, 0.2,0.2,0.06}
        };
        BPNN myBPNN = new BPNN();

    }

    /**
     * 内存训练神经网络(调试)
     * @param myBPNN
     * @param NNet_Path
     * @param TestData
     */
    public static void TrainData(BPNN myBPNN ,String NNet_Path,double[][] TestData){
        myBPNN.Init_BPNN(NNet_Path, 4, 16, 2);
        myBPNN.Train_BPNN(TestData, 0.8, 0.3, 1000);
    }

    /**
     * 通过内存和文件完成神经网络的学习(调试结果)
     * @param myBPNN
     * @param HttData
     * @param NNet_Path
     */
    public static void getResult(BPNN myBPNN ,double[][] HttData,String NNet_Path){
        int[][] result = myBPNN.Test_BPNN(NNet_Path,HttData);
    }

    /**
     * 内存训练神经网络(正式的工具类)
     * @param myBPNN
     * @param NNet_Path
     */
    public static void BaseTrainData(BPNN myBPNN ,String NNet_Path,List<Double> list){
        //首先把数据传进到这个方法,进行逐条训练
        double[][] wavePlus=new double[list.size()][30];
        myBPNN.Init_BPNN(NNet_Path, 26, 30, 4);
        myBPNN.Train_BPNN(wavePlus, 0.8, 0.3, 5000);
    }
}

通过调试和测试数据,初始化圣经网络

BPNN myBPNN = new BPNN();

/**
     * 内存训练神经网络(调试)
     * @param myBPNN
     * @param NNet_Path
     * @param TestData
     */
    public static void TrainData(BPNN myBPNN ,String NNet_Path,double[][] TestData){
        myBPNN.Init_BPNN(NNet_Path, 4, 16, 2);
        myBPNN.Train_BPNN(TestData, 0.8, 0.3, 1000);
    }

把测试的数据准备好,然后训练出来一个神经网络文件,方便以后识别其他的模式。

/**
     * 通过内存和文件完成神经网络的学习(调试结果)
     * @param myBPNN
     * @param HttData
     * @param NNet_Path
     */
    public static void getResult(BPNN myBPNN ,double[][] HttData,String NNet_Path){
        int[][] result = myBPNN.Test_BPNN(NNet_Path,HttData);
    }
上面的方法进行完成,进行下面的测试,看看我们输入的数据是否可以返回来机器学习的结果,然后看看这个误差到底在哪里,然后来回调整。

这里面的nnet.snet就是我们的神经网络训练出来的文件,joone是文件训练神经网络的文件夹。

到此我们的JOONE的神经网络就可以运行了

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值