神经网络

    实验过程中要用到神经网络,于是自己按照书上的算法写了一个,虽然能够跑异或问题,但是在大数据量上却没有办法运行。而且有一个问题,有些时候收敛的特别慢,查了两遍没有找出问题来。上网上找了一个别人的神经网络,发现还是不能用在大数据上(收敛特别慢);无奈又用了JOONE,收敛还是有问题。最后,只好调用weka了。下面把所有的4个神经网络都贴上来,算是个总结吧。第四个稍后补上。
    如果谁发现我写的神经网络有问题,请指点一二,先谢过了。
    javaeye无法添加检索关键字,很伤心。

1.自己写的神经网络。算法参考《神经网络原理》,author: simon Haykin。
/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */

/**
 *
 * @author KingSlayer
 */
public class InputLayer {

    public InputLayer(int aInputD) {
        System.out.println("input layer: " + aInputD);
        inputD = aInputD;
        input = new double[inputD];
        output = new double[inputD];
    }

    public void setInput(double[] aInput) {
        for (int i = 0; i < aInput.length; i++) {
            input[i] = output[i] = aInput[i];
            /*
            output[i] = f_x(input[i]);
            //*/
        }
    }
    public double[] getOutput() {
        return output;
    }

    private double f_x(double x) {
        /* function f(x) */
        return 1 / (1 + Math.exp(0-x));
    }
    
    private int inputD;
    private double[] input;
    private double[] output;
}


/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */

/**
 *
 * @author KingSlayer
 */
public class HiddenLayer {
    public HiddenLayer(int aInputD, int aOutputD, double aEta){
        System.out.println("hidden layer: " +aInputD+" "+aOutputD);
        inputD = aInputD;
        outputD = aOutputD;
        weight = new double[inputD][outputD];
        delta_weight = new double[inputD][outputD];
        for(int i=0;i<inputD;i++){
            for(int j=0;j<outputD;j++){
                weight[i][j] = Math.random()-0.5;
            }
        }

        weight_input = new double[outputD];
        output = new double[outputD];
        delta = new double[outputD];

        eta = aEta;
    }
    public void forward(double aInput[]){
        for(int i=0;i < outputD; i++){
            //System.out.println(weight_input[0]);
            weight_input[i] = 0;
            for(int j=0; j<inputD; j++){
                weight_input[i] += weight[j][i]*aInput[j];
            }
            output[i] = f_x(weight_input[i]);
        }
    }
    public void backward(double[] delta_next, double[][] weight_next, double[] output_pre){
        //output_pre是来自上一层结点的输入
        for(int i = 0; i < outputD; i++){
            double sum = 0;
            for(int j=0; j< delta_next.length; j ++){
                sum += delta_next[j]*weight_next[i][j];
            }
            delta[i] = output[i] * (1 - output[i]) * sum;
        }
        for(int i=0;i<inputD;i++){
            for(int j=0;j<outputD;j++){
                delta_weight[i][j] += eta * delta[j] * output_pre[i];
            }
        }
    }
    public void init_d_weight(){
        for(int i=0;i<inputD;i++){
            for(int j=0;j<outputD;j++){
                delta_weight[i][j] = 0;
            }
        }
    }
    public void setWeight(int aTimes){
        for(int i=0; i< inputD; i++){
            for(int j=0; j< outputD; j++){
                weight[i][j] += delta_weight[i][j]/aTimes;
                //System.out.print("delta_weight = " +delta_weight[i][j]);
            }
        }
    }
    public double[] getDelta(){
        return delta;
    }
    public double[] getOutput(){
        return output;
    }
    private double f_x(double x) {
        /* function f(x) */
        return 1 / (1 + Math.exp(0-x));
    }
    private int inputD;
    private int outputD;            //前面一层数目inputD,本层数目outputD
    private double[][] weight;      //权值
    private double[][] delta_weight;//将要改动的权值的累加和
    private double[] weight_input;  //加权之后的输入
    private double[] output;        //经过fx的输入
    private double[] delta;         //delta局域梯度

    private final double eta;
}

/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */

/**
 *
 * @author KingSlayer
 */
public class OutputLayer {
    public OutputLayer(int aInputD, int aOutputD, double aEta){
        System.out.println("output layer: "+aInputD+" "+aOutputD);
        inputD = aInputD;
        outputD = aOutputD;
        
        weight = new double[inputD][outputD];
        delta_weight = new double[inputD][outputD];
        for(int i=0;i<inputD;i++){
            for(int j=0;j<outputD;j++){
                weight[i][j] = Math.random()-0.5;
                delta_weight[i][j] = 0;
            }
        }
        weight_input = new double[outputD];
        output = new double[outputD];
        delta = new double[outputD];
        expectation = new double[outputD];
        error = new double[outputD];
        eta = aEta;
    }
    public void setExpectation(double[] aExpectation){
        if(aExpectation.length!= outputD){
            System.out.println("error");
        }
        for(int i = 0; i < outputD; i++){
            expectation[i] = aExpectation[i];
        }
    }
    public void forward(double[] aInput){
        for(int i=0;i < outputD; i++){
            weight_input[i] = 0;
            for(int j=0; j<inputD; j++){
                weight_input[i] += weight[j][i]*aInput[j];
            }
            output[i] = f_x(weight_input[i]);
        }
    }
    public void backward(double[] output_pre){
        //output_pre是来自上一层结点的输入
        for(int i=0; i<outputD; i++){
            error[i] = expectation[i] - output[i];
            delta[i] = output[i]*(1-output[i])*error[i];
        }
        for(int i=0;i<inputD;i++){
            for(int j=0;j<outputD;j++){
                delta_weight[i][j] += eta * delta[j] * output_pre[i];
            }
        }
    }
    public void init_d_weight(){
        for(int i=0;i<inputD;i++){
            for(int j=0;j<outputD;j++){
                delta_weight[i][j] = 0;
            }
        }
    }
    public double[] getDelta(){
        return delta;
    }
    public double[] getOutput(){
        return output;
    }
    public double getError(){
        double sum = 0;
        for(int i= 0 ;i < error.length;i ++){
            sum += error[i]*error[i];
        }
        return sum*0.5;
    }
    public double[][] getWeight(){
        return weight;
    }
    public void setWeight(int aTimes){
        for(int i=0; i< inputD; i++){
            for(int j=0; j< outputD; j++){
                weight[i][j] += delta_weight[i][j]/aTimes;
            }
        }
    }
    private double f_x(double x) {
        /* function f(x) */
        return 1 / (1 + Math.exp(0-x));
    }
    private int inputD;
    private int outputD;            //前面一层数目inputD,本层数目outputD
    private double[][] weight;      //权值
    private double[][] delta_weight;
    private double[] weight_input;  //加权之后的输入
    private double[] output;        //经过fx的输入
    private double[] delta;         //delta局域梯度
    private double[] expectation;   //期望结果
    private double[] error;         //每次的误差

    private final double eta;
}


import java.util.Scanner;

/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
/**
 *
 * @author KingSlayer
 */
public class MultilayerPerceptron {

    /**
     * @param args the command line arguments
     */
    public MultilayerPerceptron(int[] dimension, double aEta) {
        //dimension数组代表了各层的结点数目,第0代表input层,length-1代表output层
        //dimension.length-2 即为隐层结点数目;
        inputL = new InputLayer(dimension[0]);

        hiddenL = new HiddenLayer[dimension.length - 2];
        for (int i = 0; i < hiddenL.length; i++) {
            hiddenL[i] = new HiddenLayer(dimension[i], dimension[i + 1], aEta);
        }

        outputL = new OutputLayer(dimension[dimension.length - 2], dimension[dimension.length - 1], aEta);
    }

    public void test(double[][] input, double[][] result) {
        double sum;
        for (int i = 0; i < input.length; i++) {
            inputL.setInput(input[i]);
            //前向
            for (int j = 0; j < hiddenL.length; j++) {
                //double[] outputBuf ;
                if (j == 0) {
                    hiddenL[j].forward(inputL.getOutput());
                } else {
                    hiddenL[j].forward(hiddenL[j - 1].getOutput());
                }
            }
            outputL.forward(hiddenL[hiddenL.length - 1].getOutput());
        
            System.out.println("第"+i+"个测试样本的结果:");
            for(int j = 0 ; j< result[0].length; j++){
                System.out.print(result[i][j]+"    ");
            }
            System.out.println();
            for(int j = 0 ; j< outputL.getOutput().length; j++){
                System.out.print(outputL.getOutput()[j]+"    ");
            }
            System.out.println();
        }
    }

    public static void main(String[] args) {
        // TODO code application logic here
        int[] dimension = {2, 2, 1};
        MultilayerPerceptron mlp = new MultilayerPerceptron(dimension, eta);
        //Scanner in = new Scanner(System.in);
        
        double[][] input = {{0, 0}, {1, 1}, {1, 0}, {0, 1}};
        double[][] expectation = {{0}, {0}, {1}, {1}};
//        double[][] input={{0,0,0},{5,1,4},{5,3,3},
//	{5,5,2},{5,3,3},{5,3,2},
//	{5,3,2},{5,5,1},{5,1,2},
//	{5,3,3},{5,5,4},{5,5,2},
//	{5,1,3},{5,3,4},{5,5,5},
//	{5,1,4},{5,1,4},{5,3,5},
//	{5,5,4},{5,1,3},{5,3,2},
//	{1,3,1},{1,5,2},{1,1,3},
//	{1,3,4},{1,5,5},{1,5,3},
//	{1,1,4},{1,3,5},{1,5,4},
//	{1,1,3},{1,1,5},{1,3,4},
//	{1,5,3},{1,1,2},{1,3,1},
//	{1,3,3},{1,5,2},{1,1,1},
//	{1,3,2},{1,5,3}
//	};
//        double[][] expectation = {{0},{19.02},{14.150},
//        {14.360},{14.150},{15.390},
//        {15.390},{19.680},{21.060},
//        {14.150},{12.680},{14.360},
//        {19.610},{13.650},{12.430},
//        {19.020},{19.020},{13.390},
//        {12.680},{19.610},{15.390},
//        {11.110},{6.521},{10.190},
//        {6.043},{5.242},{5.724},
//        {9.766},{5.870},{5.406},
//        {10.190},{9.545},{6.043},
//        {5.724},{11.250},{11.110},
//        {6.380},{6.521},{16.000},
//        {7.219},{5.724}};
        int times = input.length;
        System.out.println("一共" + times + "个样本");
        do {
            mlp.error = 0;
            for(int i = 0 ; i< mlp.hiddenL.length; i++){
                mlp.hiddenL[i].init_d_weight();
            }
            mlp.outputL.init_d_weight();
            for (int i = 0; i < times; i++) {
                mlp.inputL.setInput(input[i]);
                mlp.outputL.setExpectation(expectation[i]);
                /*前向和后向*/
                //前向
                for (int j = 0; j < mlp.hiddenL.length; j++) {
                    if (j == 0) {
                        mlp.hiddenL[j].forward(mlp.inputL.getOutput());
                    } else {
                        mlp.hiddenL[j].forward(mlp.hiddenL[j - 1].getOutput());
                    }
                }
                mlp.outputL.forward(mlp.hiddenL[mlp.hiddenL.length - 1].getOutput());

                //后向
                mlp.outputL.backward(mlp.hiddenL[mlp.hiddenL.length - 1].getOutput());
                for (int j = mlp.hiddenL.length - 1; j >= 0; j--) {
                    if (mlp.hiddenL.length == 1) {
                        mlp.hiddenL[j].backward(mlp.outputL.getDelta(), mlp.outputL.getWeight(), mlp.inputL.getOutput());
                    } else {
                        System.out.println("隐层结点数目为:" + mlp.hiddenL.length + "目前算法只针对三层");
                    }
                }
                //计算累加的误差
                mlp.error += mlp.outputL.getError();
            }//批量样本循环一次
            //权值调整
            mlp.outputL.setWeight(times);
            for (int i = 0; i < mlp.hiddenL.length; i++) {
                mlp.hiddenL[i].setWeight(times);
            }
           System.out.println("现在误差为: "+Math.abs(mlp.error / times));
        } while (Math.abs(mlp.error / times) > 0.01); //&&Math.abs(mlp.error / times)!=0.25
        mlp.test(input, expectation);
    }
    private InputLayer inputL;
    private HiddenLayer[] hiddenL;
    private OutputLayer outputL;
    private double error;
    private static final double eta = 1;
}


这个例子是别人的:
/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */

/**
 *
 * @author KingSlayer
 */

import java.util.HashMap;
import java.util.Random;
import java.util.Set;
import java.util.Map.Entry;

/**
 * JAVA 反向传输神经网络
 * @author kj021320  , codeby 2008.12.10
 *
 */
public class JavaBackPropagationNeuralNetwork {
    /**
     * 神经元
     */
    public class Neuron {
        HashMap<Integer, Link> target = new HashMap<Integer, Link>();// 连接其他神经元的
        HashMap<Integer, Link> source = new HashMap<Integer, Link>();// 被其他神经元连接的
        double data = 0.0;
        public Link sourceGet(int index) {
            return source.get(index);
        }
        public Link targetGet(int index) {
            return target.get(index);
        }
        public boolean targetContains(Link l) {
            return target.containsValue(l);
        }
        public boolean sourceContains(Link l) {
            return source.containsValue(l);
        }
        public Link sourceLink(int index, Link l) {
            if (l.linker != this) {
                l.setLinker(this);
            }
            return source.put(index, l);
        }
        public Link targetLink(int index, Link l) {
            if (l.owner != this) {
                l.setOwner(this);
            }
            return target.put(index, l);
        }
    }

    /**
     * 神经链
     */
    public class Link {
        Neuron owner;
        public void setOwner(Neuron o) {
            owner = o;
            if (!o.targetContains(this)) {
                o.targetLink(o.target.size(), this);
            }
        }
        public Link() {
            weight = rand(-1, 1);
        }
        public void setLinker(Neuron o) {
            linker = o;
            if (!o.sourceContains(this)) {
                o.sourceLink(o.source.size(), this);
            }
        }
        @Override
        public String toString(){
            return super.toString()+" weight:"+weight;
        }
        Neuron linker;
        double weight;
    }

    Random random = new Random();
    {
        random.setSeed(System.nanoTime());
    }
    Neuron[] inputnode;    //输入层神经元
    Neuron[] hiddennode;    //隐含层神经元
    Neuron[] outputnode;    //输出层神经元
    double learnrate;// 学习速度
    double threshold;// 阀值,误差允许度

    private final int inputCount;
    private final int hiddenCount;
    private final int outputCount;
    /**
     *
     * @param input        输入层的神经元个数
     * @param hidden    隐含层的神经元个数
     * @param output    输出层的神经元的个数
     */
    public JavaBackPropagationNeuralNetwork(int input, int hidden, int output) {
        inputCount = input;
        hiddenCount = hidden;
        outputCount = output;
        build();
    }
    public void reBuildNeuralNetwork(){
        build();
    }
    private void build(){
        inputnode = new Neuron[inputCount+1];
        hiddennode = new Neuron[hiddenCount];
        outputnode = new Neuron[outputCount];
        initNeurons(inputnode);
        initNeurons(hiddennode);
        initNeurons(outputnode);
        makeLink(inputnode, hiddennode);
        makeLink(hiddennode, outputnode);
    }
    /**
     * 思考方法
     * @param inputs    前馈层神经个数相符的浮点数    -1~1之间
     * @return            思考后的结果,个数与后端的神经个数相符,每个浮点为-1~1之间
     */
    public double[] thinking(double[] inputs) {
        /**把数据映射到前馈层的神经元里面*/
        makeNeuron(inputnode, inputs);
        /**通过每个神经链的权重 从隐藏层计算到最终输出层的值*/
        thinking();
        /**把输出层的值映为return的double数组*/
        return makeMatrix();
    }
    public double[][] batchThinking(double[][] inputs){
        double[][] ret = new double[inputs.length][];
        for(int i = 0; i< inputs.length ; i++){
            makeNeuron(inputnode, inputs[i]);
            thinking();
            ret[i]=makeMatrix();
        }
        return ret;
    }
    /**
     * 总体训练
     * @param inputs
     * @param outputs
     * @param learnrate        学习精细度
     * @param error            容许误差
     * @param maxlearn        最大学习次数
     * @return 是否完成训练
     */
    public boolean train(double[][] inputs, double[][] outputs, double learnrate,
            double error,int maxlearn) {
        this.learnrate = learnrate;
        this.threshold = error;
        boolean complete = false;
        int count = 0;
        double e =0;
        while (!complete) {
            count++;
            e = 0;
            complete = true;
            for (int size = 0; size < inputs.length; size++) {
                e += learn(inputs[size], outputs[size]);
                if (e > threshold) {
                    complete = false;
                }
            }
            if(count>=maxlearn){
                System.err.println("convergence fail  error:"+e);
                return false;
            }
        }
        System.out.println("convergence success    error:"+e);
        return true;
    }

    /**
     * 单次学习
     *
     * @param input
     * @param output
     * @return 误差
     */
    private double learn(double[] input, double[] output) {
        /**把数据映射到前馈层的神经元里面*/
        makeNeuron(inputnode, input);
        /**通过每个神经链的权重 从隐藏层计算到最终输出层的值*/
        thinking();
        /**误差计算*/
        return evolutionComputing(output);
    }

    private void thinking() {
        transmitComputing(hiddennode);
        transmitComputing(outputnode);
    }

    /**
     * 神经元传输计算
     *
     * @param ns
     */
    private void transmitComputing(Neuron[] ns) {
        for (Neuron ne : ns) {
            double sum = 0.0;
            Set<Entry<Integer, Link>> linkset = ne.source.entrySet();
            for (Entry<Integer, Link> ent : linkset) {
                Link l = ent.getValue();
                Neuron n = l.owner;
                // 这里是重点,计算神经元*神经权重
                sum += n.data * l.weight;
            }
            // 计算完毕后通过 S型激活函数把数据存储在隐藏层的神经节点上
            ne.data = sigmoid(sum);
        }
    }
    /**
     * 最速梯度下降法 来计算 delta规则
     * @param datas
     * @return
     */
    private double evolutionComputing(double[] datas) {
        double[] output_deltaDatas = new double[outputnode.length];
        double totalError = 0.0;
        for (int i = 0; i < outputnode.length; i++) {
            /**
             * Erri = Ti – Oi O is the predicted output T is the correct output
             * Δi = Erri * g’(ini) g’ is the derivative of the activation
             * function g
             */
            output_deltaDatas[i] = (datas[i] - outputnode[i].data)
                    * sigmoidDerivative(datas[i]);
        }

        double[] hidden_deltaDatas = new double[hiddennode.length];
        for (int i = 0; i < hiddennode.length; i++) {
            /**
             * Δj = g’(inj) * Σi(Wj,i * Δi)
             */
            double error = 0.0;
            Set<Entry<Integer, Link>> linkSet = hiddennode[i].target.entrySet();
            for (Entry<Integer, Link> ent : linkSet) {
                error += output_deltaDatas[ent.getKey()]
                        * ent.getValue().weight;
            }
            hidden_deltaDatas[i] = sigmoidDerivative(hiddennode[i].data)
                    * error;
        }
        /**
         * Wj,i = Wj,i + α * Hj * Δi    Hj is the activation of the hidden unit
         */
        for (int i = 0; i < hiddennode.length; i++) {
            Set<Entry<Integer, Link>> linkSet = hiddennode[i].target.entrySet();
            for (Entry<Integer, Link> ent : linkSet) {
                Link hidden2output = ent.getValue();
                hidden2output.weight += output_deltaDatas[ent.getKey()]
                        * hiddennode[ent.getKey()].data * learnrate;
                //System.out.println("hidden2output:"+hidden2output);
            }
        }
        //System.out.println();
        /**
         * Wk,j = Wk,j + α * Ik * Δj Ik is the activation of the input unit
         */
        for (int i = 0; i < inputnode.length; i++) {
            Set<Entry<Integer, Link>> linkSet = inputnode[i].target.entrySet();
            for (Entry<Integer, Link> ent : linkSet) {
                Link input2hidden = ent.getValue();
                input2hidden.weight += hidden_deltaDatas[ent.getKey()]
                        * inputnode[i].data * learnrate;
                //System.out.println("inputnode[i].data:"+inputnode[i].data+"input2hidden:"+input2hidden);
            }
        }
        //System.out.println();
        /**
         * E = 1/2 Σi((Ti – Oi)^2)
         */
        for (int i = 0; i < outputnode.length; i++) {
            double temp = outputnode[i].data - datas[i];
            totalError +=  temp * temp;
        }
        return totalError * 0.5;
    }

    /**
     * 把数据映射到每个神经元里面
     *
     * @param neurons
     * @param datas
     */
    private void makeNeuron(Neuron[] neurons, double[] datas) {
        for (int len = 0; len < neurons.length; len++) {
            if(len >= datas.length){
                neurons[len].data = 1.0;
            }else{
                neurons[len].data = datas[len];
            }
        }
    }

    /**
     * 把output的神经元数据映射为矩阵
     *
     * @return
     */
    private double[] makeMatrix() {
        double[] temp = new double[outputnode.length];
        for (int i = 0; i < outputnode.length; i++) {
            temp[i] = outputnode[i].data;
        }
        return temp;
    }

    private void initNeurons(Neuron[] startns) {
        for (int lenN = 0; lenN < startns.length; lenN++) {
            if (startns[lenN] == null) {
                startns[lenN] = new Neuron();
            }
        }
    }

    /**
     * 这里是互相交叉连接
     *
     * @param startns
     * @param endns
     */
    private void makeLink(Neuron[] startns, Neuron[] endns) {
        for (int lenN = 0; lenN < startns.length; lenN++) {
            for (int len = 0; len < endns.length; len++) {
                Link target = startns[lenN].targetGet(len);
                if (target == null) {
                    target = new Link();
                    startns[lenN].targetLink(len, target);
                }
                target.setLinker(endns[len]);
            }
        }
    }

    /**
     * 这里是S型激活函数.最终目的是把所有数据都2值化
     *
     * @param x
     * @return
     */
    private double sigmoid(double x) {
        return Math.tanh(x);
    }

    /*
     * calculate a random number where: a <= rand < b def rand(a, b): return
     * (b-a)*random.random() + a
     */
    private double rand(double min, double max) {
        return (max - min) * random.nextDouble() + min;
    }

    // derivative of our sigmoid function
    private double sigmoidDerivative(double y) {
        // return (1.0 - sigmoid(y)) * sigmoid(y);
        // return 1.0-y*y;
        return 1.0 - sigmoid(y) * y;
    }

    /**
     * @param args
     * @throws Throwable
     */
    public static void main(String[] args) throws Throwable {
        //创建一个 反向传输神经网络
        JavaBackPropagationNeuralNetwork jbpn = new JavaBackPropagationNeuralNetwork(2, 4, 1);

        //训练XOR
        while(!jbpn.train(
                new double[][] { new double[] { -1, -1 },new double[] { 1, 1 }, new double[] { -1, 1 },new double[] { 1, -1 } },//这个为输入值
                new double[][] { new double[] {-1},new double[] {-1},new double[] {1},new double[] {1} },//这个是监督指导结果
                0.3, 0.05,1000)){
            jbpn.reBuildNeuralNetwork();
        }
        //思考
        double[] res = jbpn.thinking(new double[] { -1, -1 });
        for(double s:res){
            System.out.println("thinking:"+s);
        }
        //批量思考
        double[][] ress = jbpn.batchThinking(new double[][] { new double[] { -0.8, -0.9 },new double[] { 0.7, 0.3 }, new double[] { -.6, .85 },new double[] { 1, -1 } });
        for(double[] s:ress){
            for(double d:s){
                System.out.print("batchThinking:"+d+"    ");
            }
            System.out.println();
        }

    }

}


参照joone里面的异或例子,自己加了如何保存训练模型,如何load训练模型
/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */

/**
 *
 * @author KingSlayer
 */
//public class NN_JOONE {
//
//    /**
//     * @param args the command line arguments
//     */
//    public static void main(String[] args) {
//        // TODO code application logic here
//
//    }
//
//}
/*
 * JOONE - Java Object Oriented Neural Engine
 * http://joone.sourceforge.net
 *
 * XOR_using_NeuralNet.java
 *
 */
//package org.joone.samples.engine.xor;
//nnet=JooneTools.load(nnOutput)
//JOONE从存储在你的系统中的文本文件中取得输入。这些文本文件通过使用一种称为FileInputSynapse的非凡触角来读取
//下面是从文件中读取神经网络的代码:
//
//ObjectInputStream ois = new ObjectInputStream(new FileInputStream("D:/work/homework/ANN/final/3.snet"));
//Object o = ois.readObject();
//System.out.println("o is " + o);
//ois.close();
//NeuralNet net = (NeuralNet) o;
//FileInputSynapse
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.io.Serializable;
import org.joone.engine.*;
import org.joone.engine.learning.*;
import org.joone.io.*;
import org.joone.net.*;
import java.util.Vector;

/**
 * Sample class to demostrate the use of the MemoryInputSynapse
 *
 * @author Jos�?Rodriguez
 */
public class NN_JOONE implements NeuralNetListener, Serializable {

    private NeuralNet nnet = null;
    private MemoryInputSynapse inputSynapse, desiredOutputSynapse;
    LinearLayer input;
    SigmoidLayer hidden, output;
    boolean singleThreadMode = true;
    // XOR input
//    private double[][] inputArray = new double[][]{
//        {0.0, 0.0},
//        {0.0, 1.0},
//        {1.0, 0.0},
//        {1.0, 1.0}
//    };
//    // XOR desired output
//    private double[][] desiredOutputArray = new double[][]{
//        {0.0},
//        {1.0},
//        {1.0},
//        {0.0}
//    };
        double[][] inputA={{0,0,0},{5,1,4},{5,3,3},
	{5,5,2},{5,3,3},{5,3,2},
	{5,3,2},{5,5,1},{5,1,2},
	{5,3,3},{5,5,4},{5,5,2},
	{5,1,3},{5,3,4},{5,5,5},
	{5,1,4},{5,1,4},{5,3,5},
	{5,5,4},{5,1,3},{5,3,2},
	{1,3,1},{1,5,2},{1,1,3},
	{1,3,4},{1,5,5},{1,5,3},
	{1,1,4},{1,3,5},{1,5,4},
	{1,1,3},{1,1,5},{1,3,4},
	{1,5,3},{1,1,2},{1,3,1},
	{1,3,3},{1,5,2},{1,1,1},
	{1,3,2},{1,5,3}
	};
        double[][] expectation = {{0},{19.02},{14.150},
        {14.360},{14.150},{15.390},
        {15.390},{19.680},{21.060},
        {14.150},{12.680},{14.360},
        {19.610},{13.650},{12.430},
        {19.020},{19.020},{13.390},
        {12.680},{19.610},{15.390},
        {11.110},{6.521},{10.190},
        {6.043},{5.242},{5.724},
        {9.766},{5.870},{5.406},
        {10.190},{9.545},{6.043},
        {5.724},{11.250},{11.110},
        {6.380},{6.521},{16.000},
        {7.219},{5.724}};
    /**
     * @param args the command line arguments
     */
    public static void main(String args[]) {
        NN_JOONE xor = new NN_JOONE();
        xor.initNeuralNet();
        xor.train();
//        xor.initNeuralNet("model.snet");
//        System.out.print("here");
        
        xor.interrogate();//测试

    }

    /**
     * Method declaration
     */
    public void train() {

        // set the inputs
        inputSynapse.setInputArray(inputA);
        inputSynapse.setAdvancedColumnSelector("1,2,3");
        // set the desired outputs
        desiredOutputSynapse.setInputArray(expectation);
        desiredOutputSynapse.setAdvancedColumnSelector("1");

        // get the monitor object to train or feed forward
        Monitor monitor = nnet.getMonitor();

        // set the monitor parameters
        monitor.setLearningRate(0.8);
        monitor.setMomentum(0.3);
        monitor.setTrainingPatterns(inputA.length);
        monitor.setTotCicles(500000);
        monitor.setLearning(true);

        long initms = System.currentTimeMillis();
        // Run the network in single-thread, synchronized mode
        nnet.getMonitor().setSingleThreadMode(singleThreadMode);
        nnet.go(true);
        System.out.println("Total time= " + (System.currentTimeMillis() - initms) + " ms");
        saveNeuralNet("model.snet");
    }

    private void interrogate() {
        // set the inputs
        inputSynapse.setInputArray(inputA);
        inputSynapse.setAdvancedColumnSelector("1,2,3");
        Monitor monitor = nnet.getMonitor();
        monitor.setTrainingPatterns(inputA.length);
        monitor.setTotCicles(1);
        monitor.setLearning(false);
        FileOutputSynapse foutput = new FileOutputSynapse();
        // set the output synapse to write the output of the net
        
        foutput.setFileName("tmp/xorOut.txt");
        if (nnet != null) {
            nnet.addOutputSynapse(foutput);
            System.out.println(nnet.check());
            nnet.getMonitor().setSingleThreadMode(singleThreadMode);
            nnet.go();
        }
    }

    /**
     * Method declaration
     */
    public void initNeuralNet(String name){
        NeuralNetLoader netLoader = new NeuralNetLoader(name);
        nnet = netLoader.getNeuralNet();
        Layer input = nnet.getInputLayer();
        input.removeAllInputs();
        inputSynapse = new MemoryInputSynapse();
        input.addInputSynapse(inputSynapse);

        // The Trainer and its desired output
//        Layer output = nnet.getOutputLayer();
//        desiredOutputSynapse = new MemoryInputSynapse();
//        output.addOutputSynapse(desiredOutputSynapse);

    }
    protected void initNeuralNet() {

        // First create the three layers
        input = new LinearLayer();
        hidden = new SigmoidLayer();
        output = new SigmoidLayer();

        // set the dimensions of the layers
        input.setRows(2);
        hidden.setRows(3);
        output.setRows(1);

        input.setLayerName("L.input");
        hidden.setLayerName("L.hidden");
        output.setLayerName("L.output");

        // Now create the two Synapses
        FullSynapse synapse_IH = new FullSynapse();	/* input -> hidden conn. */

        FullSynapse synapse_HO = new FullSynapse();	/* hidden -> output conn. */

        // Connect the input layer whit the hidden layer
        input.addOutputSynapse(synapse_IH);
        hidden.addInputSynapse(synapse_IH);

        // Connect the hidden layer whit the output layer
        hidden.addOutputSynapse(synapse_HO);
        output.addInputSynapse(synapse_HO);

        // the input to the neural net
        inputSynapse = new MemoryInputSynapse();

        input.addInputSynapse(inputSynapse);

        // The Trainer and its desired output
        desiredOutputSynapse = new MemoryInputSynapse();

        TeachingSynapse trainer = new TeachingSynapse();

        trainer.setDesired(desiredOutputSynapse);

        // Now we add this structure to a NeuralNet object
        nnet = new NeuralNet();

        nnet.addLayer(input, NeuralNet.INPUT_LAYER);
        nnet.addLayer(hidden, NeuralNet.HIDDEN_LAYER);
        nnet.addLayer(output, NeuralNet.OUTPUT_LAYER);
        nnet.setTeacher(trainer);
        output.addOutputSynapse(trainer);
        nnet.addNeuralNetListener(this);
    }

    public void saveNeuralNet(String fileName) {
        try {
            FileOutputStream stream = new FileOutputStream(fileName);
            ObjectOutputStream out = new ObjectOutputStream(stream);
            out.writeObject(nnet);
            out.close();
        } catch (Exception excp) {
            excp.printStackTrace();
        }
    }
    public void load(String filename){

    }
    public NeuralNet restoreNeuralNet(String filename) {
        try {
            FileInputStream stream = new FileInputStream(filename);
            ObjectInputStream inp = new ObjectInputStream(stream);
            return (NeuralNet) inp.readObject();
        } catch (Exception excp) {
            excp.printStackTrace();
            return null;
        }
    }

    public void cicleTerminated(NeuralNetEvent e) {
    }

    public void errorChanged(NeuralNetEvent e) {
        Monitor mon = (Monitor) e.getSource();
        if (mon.getCurrentCicle() % 100 == 0) {
            System.out.println("Epoch: " + (mon.getTotCicles() - mon.getCurrentCicle()) + " RMSE:" + mon.getGlobalError());
        }
    }

    public void netStarted(NeuralNetEvent e) {
        Monitor mon = (Monitor) e.getSource();
        System.out.print("Network started for ");
        if (mon.isLearning()) {
            System.out.println("training.");
        } else {
            System.out.println("interrogation.");
        }
    }

    public void netStopped(NeuralNetEvent e) {
        Monitor mon = (Monitor) e.getSource();
        System.out.println("Network stopped. Last RMSE=" + mon.getGlobalError());
    }

    public void netStoppedError(NeuralNetEvent e, String error) {
        System.out.println("Network stopped due the following error: " + error);
    }
}

你可能感兴趣的:(算法,.net,J#,360,Go)