Java 如何在Android studio中使用保存的neural network.ser

Java 如何在Android studio中使用保存的neural network.ser,java,android,netbeans,neural-network,Java,Android,Netbeans,Neural Network,我已经在NetBeans中训练了一个神经网络,并使用Serializable将其保存为neural_network.ser,“所有类都实现Serializable”,现在我想在我的android应用程序中使用它,但在加载网络时,会引发ClassNotFoundException java.lang.ClassNotFoundException:神经网络.反向传播 以下是课程: 反向传播类: public class BackPropagation extends Thread impleme

我已经在NetBeans中训练了一个神经网络,并使用Serializable将其保存为neural_network.ser,“所有类都实现Serializable”,现在我想在我的android应用程序中使用它,但在加载网络时,会引发ClassNotFoundException

java.lang.ClassNotFoundException:神经网络.反向传播

以下是课程:

反向传播类:

public class BackPropagation extends  Thread  implements  Serializable
 {
   private static final String TAG = "NetworkMessage";
   private static final long serialVersionUID = -8862858027413741101L;
   private double   OverallError;
   // The minimum Error Function defined by the user
   private double   MinimumError;
   // The user-defined expected output pattern for a set of samples
   private double   ExpectedOutput[][];
   // The user-defined input pattern for a set of samples
   private double   Input[][];
   // User defined learning rate - used for updating the network weights
   private double   LearningRate;
   // Users defined momentum - used for updating the network weights
   private double   Momentum;
   // Number of layers in the network 
   private  int NumberOfLayers;
   // Number of training sets
   private  int NumberOfSamples;
   // Current training set/sample that is used to train network
   private  int SampleNumber;
   // Maximum number of Epochs before the traing stops training 
   private long MaximumNumberOfIterations;
   // Public Variables
   public LAYER Layer[];
   public  double   ActualOutput[][];
   long delay = 0;
   boolean die = false;
   // Calculate the node activations
   public void FeedForward()
    {
      int i,j;
      // Since no weights contribute to the output
      // vector from the input layer,
      // assign the input vector from the input layer
      // to all the node in the first hidden layer
      for (i = 0; i < Layer[0].Node.length; i++)
         Layer[0].Node[i].Output = Layer[0].Input[i];
      Layer[1].Input = Layer[0].Input;
      for (i = 1; i < NumberOfLayers; i++)
       {
         Layer[i].FeedForward();
         // Unless we have reached the last layer, assign the layer i's    //output vector
        // to the (i+1) layer's input vector
        if (i != NumberOfLayers-1)
            Layer[i+1].Input = Layer[i].OutputVector();
       }
  }
  // FeedForward()
  // Back propagated the network outputy error through
  // the network to update the weight values
public void UpdateWeights()
{
    CalculateSignalErrors();
    BackPropagateError();
}
 private void CalculateSignalErrors()
  {
    int i,j,k,OutputLayer;
    double Sum;
    OutputLayer = NumberOfLayers-1;
    // Calculate all output signal error
   for (i = 0; i < Layer[OutputLayer].Node.length; i++)
    { 
      Layer[OutputLayer].Node[i].SignalError =   
      (ExpectedOutput[SampleNumber][i] -Layer[OutputLayer].Node[i].Output) * 
      Layer[OutputLayer].Node[i].Output *  
      (1-Layer[OutputLayer].Node[i].Output);
    }
  // Calculate signal error for all nodes in the hidden layer
  // (back propagate the errors
 for (i = NumberOfLayers-2; i > 0; i--)
  {
    for (j = 0; j < Layer[i].Node.length; j++) 
     {
       Sum = 0;
       for (k = 0; k < Layer[i+1].Node.length; k++)
          Sum = Sum + Layer[i+1].Node[k].Weight[j] * 
          Layer[i+1].Node[k].SignalError;
       Layer[i].Node[j].SignalError = Layer[i].Node[j].Output*(1 -  
       Layer[i].Node[j].Output)*Sum;
     }
  }
}

private void BackPropagateError() 
 {
    int i,j,k;
    // Update Weights
    for (i = NumberOfLayers-1; i > 0; i--) 
      {
        for (j = 0; j < Layer[i].Node.length; j++) 
          {
            // Calculate Bias weight difference to node j
            Layer[i].Node[j].ThresholdDiff = LearningRate *
                    Layer[i].Node[j].SignalError +
                    Momentum*Layer[i].Node[j].ThresholdDiff;
            // Update Bias weight to node j
            Layer[i].Node[j].Threshold =
                    Layer[i].Node[j].Threshold +
                            Layer[i].Node[j].ThresholdDiff;
             // Update Weights
            for (k = 0; k < Layer[i].Input.length; k++) 
               {
                 // Calculate weight difference between node j and k
                 Layer[i].Node[j].WeightDiff[k] =
                         LearningRate *
                         Layer[i].Node[j].SignalError*Layer[i-
                         1].Node[k].Output +
                         Momentum*Layer[i].Node[j].WeightDiff[k];
                 // Update weight between node j and k
                 Layer[i].Node[j].Weight[k] =
                        Layer[i].Node[j].Weight[k] + 
                        Layer[i].Node[j].WeightDiff[k];
               }
          }
       }
  }
private void CalculateOverallError()
 {
    int i,j;
    OverallError = 0;
    for (i = 0; i < NumberOfSamples; i++)
        for (j = 0; j < Layer[NumberOfLayers-1].Node.length; j++)
         {
            OverallError = OverallError +
                    0.5*( Math.pow(ExpectedOutput[i][j] - ActualOutput[i] 
                                                                   [j],2) );
        }
}
 public  BackPropagation(int NumberOfNodes[],
                        double InputSamples[][],
                        double OutputSamples[][],
                        double LearnRate,
                        double Moment,
                        double MinError,
                        long MaxIter
                        )
  {
    int i,j;
 // Initiate variables
    NumberOfSamples = InputSamples.length;
    MinimumError = MinError;
    LearningRate = LearnRate;
    Momentum = Moment;
    NumberOfLayers = NumberOfNodes.length;
    MaximumNumberOfIterations = MaxIter;
 // Create network layers
    Layer = new LAYER[NumberOfLayers];
 // Assign the number of node to the input layer
    Layer[0] = new LAYER(NumberOfNodes[0],NumberOfNodes[0]);
 // Assign number of nodes to each layer
    for (i = 1; i < NumberOfLayers; i++)
        Layer[i] = new LAYER(NumberOfNodes[i],NumberOfNodes[i-1]);
    Input = new double[NumberOfSamples][Layer[0].Node.length];
    ExpectedOutput = new double[NumberOfSamples][Layer[NumberOfLayers-
    1].Node.length];
    ActualOutput = new double[NumberOfSamples][Layer[NumberOfLayers-
   1].Node.length];
    // Assign input set
    for (i = 0; i < NumberOfSamples; i++)
        for (j = 0; j < Layer[0].Node.length; j++)
            Input[i][j] = InputSamples[i][j];
    // Assign output set
    for (i = 0; i < NumberOfSamples; i++)
        for (j = 0; j < Layer[NumberOfLayers-1].Node.length; j++)
            ExpectedOutput[i][j] = OutputSamples[i][j];
} 
 public void TrainNetwork() 
  {
   int i,j;
   long k=0;
   do
    {
      // For each pattern
      for (SampleNumber = 0; SampleNumber < NumberOfSamples; SampleNumber++) 
      {
          for (i = 0; i < Layer[0].Node.length; i++)
              Layer[0].Input[i] = Input[SampleNumber][i];
          FeedForward();
        // Assign calculated output vector from network to ActualOutput
          for (i = 0; i < Layer[NumberOfLayers-1].Node.length; i++)
              ActualOutput[SampleNumber][i] = Layer[NumberOfLayers-
             1].Node[i].Output;
          UpdateWeights();
          // if we've been told to stop training, then
          // stop thread execution
          if (die){
              return;
          }
          // if
      }
      k++;
     // Calculate Error Function
      CalculateOverallError();
      System.out.println("OverallError = 
      "+Double.toString(OverallError)+"\n");
      System.out.print("Epoch = "+Long.toString(k)+"\n");
  } while ((OverallError > MinimumError) &&(k < MaximumNumberOfIterations));
}
  public LAYER[] get_layers() { return Layer; }
  // called when testing the network.
  public double[] test(double[] input) 
   {
     int winner = 0;
     NODE[] output_nodes;
     for (int j = 0; j < Layer[0].Node.length; j++)
     { Layer[0].Input[j] = input[j];}
     FeedForward();
     // get the last layer of nodes (the outputs)
     output_nodes = (Layer[Layer.length - 1]).get_nodes();
     double[] actual_output  = new double[output_nodes.length];
     for (int k=0; k < output_nodes.length; k++)
      {
        actual_output[k]=output_nodes[k].Output;
      } // for
    return actual_output;
 }//test()
  public double get_error() 
  {
     CalculateOverallError(); 
     return OverallError;
  } // get_error()
// to change the delay in the network
 public void set_delay(long time) 
  {
    if (time >= 0) {
        delay = time;
    } // if
}
//save the trained network
public void save(String FileName)
{
    try{


       FileOutputStream fos = new FileOutputStream (new File(FileName), true);
       // Serialize data object to a file
        ObjectOutputStream os = new ObjectOutputStream(fos);
        os.writeObject(this);
        os.close();
        fos.close();
        System.out.println("Network Saved!!!!");
    }
    catch (IOException E){System.out.println(E.toString());}
    catch (Exception e){System.out.println(e.toString());}
}


public  BackPropagation load(String FileName)
{

    BackPropagation myclass= null;
    try
    {

        //File patternDirectory = new File(Environment.getExternalStorageDirectory().getAbsolutePath().toString()+"INDIAN_NUMBER_RECOGNITION.data");
        //patternDirectory.mkdirs();
        FileInputStream fis = new FileInputStream(new File(FileName));
        //FileInputStream fis =context.openFileInput(FileName);
        ObjectInputStream is = new ObjectInputStream(fis);
        myclass = (BackPropagation) is.readObject();
        System.out.println("Error After Reading = "+Double.toString(myclass.get_error())+"\n");
        is.close();
        fis.close();
        return myclass;


    }
    catch (Exception e){System.out.println(e.toString());}
    return myclass;
}

// needed to implement threading.
public void run() {
    TrainNetwork();
    File Net_File = new File(Environment.getExternalStorageDirectory(),"Number_Recognition_1.ser");
    save(Net_File.getAbsolutePath());
    System.out.println( "DONE TRAINING :) ^_^ ^_^ :) !\n");
    System.out.println("With Network ERROR = "+Double.toString(get_error())+"\n");
} // run()


// to notify the network to stop training.
public void kill() { die = true; }
公共类反向传播扩展线程实现可序列化
{
私有静态最终字符串TAG=“NetworkMessage”;
私有静态最终长serialVersionUID=-8862858027413741101L;
私人双套路;
//用户定义的最小误差函数
私有双极小误差;
//一组样本的用户定义的预期输出模式
专用双预期输出[];
//一组样本的用户定义输入模式
专用双输入[];
//用户定义的学习率-用于更新网络权重
私人双重学习率;
//用户定义的动量-用于更新网络权重
私人双动力;
//网络中的层数
私有整数层;
//训练集数目
私有整数样本;
//用于训练网络的当前训练集/样本
私人int SampleNumber;
//培训停止前的最大历元数
私有长最大迭代次数;
//公共变量
公共层[];
公共双执行器输出[];
长延时=0;
布尔模=假;
//计算节点激活
公共无效前馈()
{
int i,j;
//因为没有权重对输出有贡献
//来自输入层的向量,
//从输入层指定输入向量
//到第一个隐藏层中的所有节点
对于(i=0;i<层[0]。Node.length;i++)
层[0]。节点[i]。输出=层[0]。输入[i];
图层[1]。输入=图层[0]。输入;
对于(i=1;i0;i--)
{
对于(j=0;j0;i--)
{
对于(j=0;jpublic class LAYER implements Serializable
{
  private   double  Net;
  public    double  Input[];
  // Vector of inputs signals from previous
  // layer to the current layer
  public    NODE    Node[];
  // Vector of nodes in current layer
  // The FeedForward function is called so that
  // the outputs for all the nodes in the current
  // layer are calculated
public void FeedForward() {
    for (int i = 0; i < Node.length; i++) {
        Net = Node[i].Threshold;

        for (int j = 0; j < Node[i].Weight.length; j++)
        {Net = Net + Input[j] * Node[i].Weight[j];
            System.out.println("Net = "+Double.toString(Net)+"\n");
        }

        Node[i].Output = Sigmoid(Net);
        System.out.println("Node["+Integer.toString(i)+".Output = "+Double.toString(Node[i].Output)+"\n");
    }
}

// The Sigmoid function calculates the
// activation/output from the current node
private double Sigmoid (double Net) {
    return 1/(1+Math.exp(-Net));
}

// Return the output from all node in the layer
// in a vector form
public double[] OutputVector() {

    double Vector[];

    Vector = new double[Node.length];

    for (int i=0; i < Node.length; i++)
        Vector[i] = Node[i].Output;

    return (Vector);
}
public LAYER (int NumberOfNodes, int NumberOfInputs) {
    Node = new NODE[NumberOfNodes];

    for (int i = 0; i < NumberOfNodes; i++)
        Node[i] = new NODE(NumberOfInputs);

    Input = new double[NumberOfInputs];
}

// added by DSK
public NODE[] get_nodes() { return Node; }
}
 public class NODE implements  Serializable
{
  public    double  Output;
  // Output signal from current node
  public    double  Weight[];
  // Vector of weights from previous nodes to current node
  public    double  Threshold;
  // Node Threshold /Bias
  public    double  WeightDiff[];
  // Weight difference between the nth and the (n-1) iteration
  public    double  ThresholdDiff;
  // Threshold difference between the nth and the (n-1) iteration
  public    double  SignalError;
  // Output signal error
  // InitialiseWeights function assigns a randomly
  // generated number, between -1 and 1, to the
  // Threshold and Weights to the current node
  private void InitialiseWeights() {
    Threshold = -1+2*Math.random();
    // Initialise threshold nodes with a random
    // number between -1 and 1
    ThresholdDiff = 0;
    // Initially, ThresholdDiff is assigned to 0 so
    // that the Momentum term can work during the 1st
    // iteration
    for(int i = 0; i < Weight.length; i++) {
        Weight[i]= -1+2*Math.random();
        // Initialise all weight inputs with a
        // random number between -1 and 1
        WeightDiff[i] = 0;
        // Initially, WeightDiff is assigned to 0
        // so that the Momentum term can work during
        // the 1st iteration
    }
}

public NODE (int NumberOfNodes) {
    Weight = new double[NumberOfNodes];
    // Create an array of Weight with the same
    // size as the vector of inputs to the node

    WeightDiff = new double[NumberOfNodes];
    // Create an array of weightDiff with the same
    // size as the vector of inputs to the node

    InitialiseWeights();
    // Initialise the Weights and Thresholds to the node
}


public double[] get_weights() { return Weight; }
public double get_output() { return Output; }
}
  public void SaveToXML(String FileName)throws     
       ParserConfigurationException,     FileNotFoundException,  
        TransformerException, TransformerConfigurationException
     {
  DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
    DocumentBuilder parser = factory.newDocumentBuilder();
    Document doc = parser.newDocument();
    Element root = doc.createElement("neuralNetwork");
    Element layers = doc.createElement("structure");
    layers.setAttribute("numberOfLayers",Integer.toString(this.NumberOfLayers));
    for (int il=0; il<this.NumberOfLayers; il++){
        Element layer = doc.createElement("layer");
        layer.setAttribute("index",Integer.toString(il));
        layer.setAttribute("numberOfNeurons",Integer.toString(this.Layer[il].Node.length));
        if(il==0)
        {
            for(int in=0;in<this.Layer[il].Node.length;in++)
            {
                 Element neuron = doc.createElement("neuron");
                 neuron.setAttribute("index",Integer.toString(in));
                 neuron.setAttribute("NumberOfInputs",Integer.toString(1));
                 neuron.setAttribute("threshold",Double.toString(this.Layer[il].Node[in].Threshold));
                 Element input = doc.createElement("input");
                 double[] weights = this.Layer[il].Node[in].get_weights();
                 input.setAttribute("index",Integer.toString(in));
                input.setAttribute("weight",Double.toString(weights[in]));
                neuron.appendChild(input);
                layer.appendChild(neuron);
            }
            layers.appendChild(layer);

        }
        else
        {
         for (int in=0; in<this.Layer[il].Node.length;in++){
              Element neuron = doc.createElement("neuron");
            neuron.setAttribute("index",Integer.toString(in));
            neuron.setAttribute("NumberOfInputs",Integer.toString(this.Layer[il].Node[in].Weight.length));
            neuron.setAttribute("threshold",Double.toString(this.Layer[il].Node[in].Threshold));
            for (int ii=0; ii<this.Layer[il].Node[in].Weight.length;ii++) {
                 double[] weights = this.Layer[il].Node[in].get_weights();
                Element input = doc.createElement("input");
                input.setAttribute("index",Integer.toString(ii));
                input.setAttribute("weight",Double.toString(weights[ii]));
                 neuron.appendChild(input);                    
            }
            layer.appendChild(neuron);
            layers.appendChild(layer);
         }
    }
    }
    root.appendChild(layers);
    doc.appendChild(root);
    File xmlOutputFile = new File(FileName);
    FileOutputStream fos;
    Transformer transformer;
    fos = new FileOutputStream(xmlOutputFile);
    TransformerFactory transformerFactory = TransformerFactory.newInstance();
    transformer = transformerFactory.newTransformer();
    DOMSource source = new DOMSource(doc);
    StreamResult result = new StreamResult(fos);
    transformer.setOutputProperty("encoding","iso-8859-2");
    transformer.setOutputProperty("indent","yes");
    transformer.transform(source, result);

    }
   public  BackPropagation LoadFromXML(String FileName)throws 
     ParserConfigurationException, SAXException, IOException, ParseException 
    {
    BackPropagation myclass= new BackPropagation();
     DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
    DocumentBuilder parser = factory.newDocumentBuilder();
    File source = new File(FileName);
    Document doc = parser.parse(source);

    Node nodeNeuralNetwork = doc.getDocumentElement();
    if (!nodeNeuralNetwork.getNodeName().equals("neuralNetwork")) throw new ParseException("[Error] NN-Load: Parse error in XML file, neural network couldn't be loaded.",0);
    NodeList nodeNeuralNetworkContent = nodeNeuralNetwork.getChildNodes();
    System.out.print("<neuralNetwork>\n");
    for (int innc=0; innc<nodeNeuralNetworkContent.getLength(); innc++) 
    {
        Node nodeStructure = nodeNeuralNetworkContent.item(innc);
        if (nodeStructure.getNodeName().equals("structure")) 
        { 
            System.out.print("<stucture nuumberOfLayers = ");
            myclass.NumberOfLayers = Integer.parseInt(((Element)nodeStructure).getAttribute("numberOfLayers"));
            myclass.Layer  = new LAYER[myclass.NumberOfLayers];
            System.out.print(Integer.toString(myclass.NumberOfLayers)+">\n");
            NodeList nodeStructureContent = nodeStructure.getChildNodes();
             for (int isc=0; isc<nodeStructureContent.getLength();isc++)
             {
                 Node nodeLayer = nodeStructureContent.item(isc);

                 if (nodeLayer.getNodeName().equals("layer"))
                 {
                     int index = Integer.parseInt(((Element)nodeLayer).getAttribute("index"));
                     System.out.print("<layer index = "+Integer.toString(index)+" numberOfNeurons = ");
                     int number_of_N = Integer.parseInt(((Element)nodeLayer).getAttribute("numberOfNeurons"));
                     System.out.print(Integer.toString(number_of_N)+">\n");
                     if(index==0)
                     {
                         myclass.Layer[0]=new LAYER(number_of_N,800);

                     }
                     else
                     {
                         int j=index-1;
                         myclass.Layer[index]=new LAYER(number_of_N,myclass.Layer[j].Node.length);
                     }
                     NodeList nodeLayerContent = nodeLayer.getChildNodes();
                      for (int ilc=0; ilc<nodeLayerContent.getLength();ilc++)
                      {
                           Node nodeNeuron = nodeLayerContent.item(ilc);
                            if (nodeNeuron.getNodeName().equals("neuron"))
                            {
                                System.out.print("<neuron index = ");
                                int neuron_index = Integer.parseInt(((Element)nodeNeuron).getAttribute("index"));
                                myclass.Layer[index].Node[neuron_index].Threshold = Double.parseDouble(((Element)nodeNeuron).getAttribute("threshold"));
                                System.out.print(Integer.toString(neuron_index)+" threshold = "+Double.toString(myclass.Layer[index].Node[neuron_index].Threshold)+">\n");
                                NodeList nodeNeuronContent = nodeNeuron.getChildNodes();
                                  for (int inc=0; inc < nodeNeuronContent.getLength();inc++)
                                  {
                                      Node nodeNeuralInput = nodeNeuronContent.item(inc);                                    
                                      if (nodeNeuralInput.getNodeName().equals("input"))
                                      {
                                          System.out.print("<input index = ");
                                          int index_input = Integer.parseInt(((Element)nodeNeuralInput).getAttribute("index"));
                                          myclass.Layer[index].Node[neuron_index].Weight[index_input] = Double.parseDouble(((Element)nodeNeuralInput).getAttribute("weight"));
                                          System.out.print(Integer.toString(index_input)+" weight = "+Double.toString(myclass.Layer[index].Node[neuron_index].Weight[index_input])+">\n");
                                      }
                                  }
                            }
                      }


                 }
             }
             System.out.print("</structure");

        }
    }


   return myclass;
 }