<ul id="qxxfc"><fieldset id="qxxfc"><tr id="qxxfc"></tr></fieldset></ul>


      首先看一下運行效果:



      下面是項目整體目錄:


      0.實現(xiàn)神經(jīng)網(wǎng)絡(luò)總覽

      神經(jīng)網(wǎng)絡(luò)由層、神經(jīng)元、權(quán)重、激活函數(shù)和偏置組成。每層都有一個或者多個神經(jīng)元,每一個神經(jīng)元都和神經(jīng)輸入/輸出連接,這些連接就是權(quán)重。
      需要重點強調(diào)一下,一個神經(jīng)網(wǎng)絡(luò)可能有很多隱含層,也可能一個沒有,因為每層的神經(jīng)元數(shù)目也可能不同。然而,輸入輸出層的神經(jīng)元個數(shù)分別等于神經(jīng)輸入/輸出的個數(shù)。
      我們?yōu)榱藢崿F(xiàn),需要定義以下的類:

      * Neuron: 定義人工神經(jīng)元
      * NeuralLayer: 抽象類,定義一個神經(jīng)元層。
      * InputLayer: 定義神經(jīng)輸入層
      * HiddenLayer:定義輸入層和輸出層之間的層
      * OutputLayer: 定義神經(jīng)輸出層。
      * InputNeuron: 定義神經(jīng)網(wǎng)絡(luò)輸入中出現(xiàn)的神經(jīng)元。
      * NeuralNet:將前面定義的所有類組成一個ANN結(jié)構(gòu)。

      除了以上的類,我們還需要為激活函數(shù)定義一個IActivationFunction接口。這是必要的,因為激活函數(shù)與方法類似,需要作為神經(jīng)元的一個屬性進行分配。所以要為激活函數(shù)定義類,這些類需要實現(xiàn)IActivationFunction接口:

      * Linear
      * Sigmoid
      * Step
      * HyperTan

      第一章的編碼基本完成。除此之外,還需要定義倆個類。一個用于異常處理(NeuralException),另一個用于產(chǎn)生隨機數(shù)(RandomNumberGenerator)。最后,將這些類分別放到倆個包。

      1.神經(jīng)元Neuron類

      神經(jīng)元類是本章代碼的基礎(chǔ)類。根據(jù)理論,人工神經(jīng)元有如下屬性

      * 輸入
      * 權(quán)重
      * 偏置
      * 激活函數(shù)
      * 輸出
      首先定義神經(jīng)元的各種屬性:
      public class Neuron { //神經(jīng)元相關(guān)的權(quán)重 protected ArrayList<Double> weight; //神經(jīng)元的輸入
      private ArrayList<Double> input; //這個神經(jīng)元的輸出,由激活函數(shù)產(chǎn)生 private Double output;
      //傳遞給激活函數(shù)的值 private Double outputBeforeActivation; //輸入的數(shù)量。如果為0,則表示神經(jīng)元尚未初始化。
      private int numberOfInputs = 0; //神經(jīng)元的偏差。除了第一層,其他都應(yīng)該是1.0。 protected Double bias
      = 1.0; //神經(jīng)元的激活函數(shù) private IActivationFunction activationFunction; }
      當(dāng)實例化神經(jīng)元時,需要指定輸入數(shù)據(jù)的個數(shù)以及激活函數(shù)。構(gòu)造函數(shù)如下:
      public Neuron(int numberofinputs,IActivationFunction iaf){
      numberOfInputs=numberofinputs; weight=new ArrayList<>(numberofinputs+1);
      input=new ArrayList<>(numberofinputs); activationFunction=iaf; }

      注意,為偏置定義另一個權(quán)重。一個重要的步驟是初始化神經(jīng)元,也就是為權(quán)重賦初始值。這主要在init()方法中完成,通過隨機數(shù)生成器靜態(tài)類RandomNumberGenerator生成隨機數(shù),賦值權(quán)重。注意:設(shè)置權(quán)重值時需要防止權(quán)重數(shù)組越界。
      public void init(){ if(numberOfInputs>0){ for(int i=0;i<=numberOfInputs;i++){
      double newWeight = RandomNumberGenerator.GenerateNext(); try{
      this.weight.set(i, newWeight); } catch(IndexOutOfBoundsException iobe){
      this.weight.add(newWeight); } } } }
      最后,在calc()方法中計算輸出值:
      public void calc(){ outputBeforeActivation=0.0; if(numberOfInputs>0){
      if(input!=null && weight!=null){ for(int i=0;i<=numberOfInputs;i++){
      outputBeforeActivation+=(i==numberOfInputs?bias:input.get(i))*weight.get(i); }
      } } output=activationFunction.calc(outputBeforeActivation); }

      首先需要對所有輸入和權(quán)重的成績進行求和(偏置乘最后一個權(quán)重,i==Number-OfInputs),然后將得出的結(jié)果保存在屬性outputBeforeActivation中。激活函數(shù)用這個值計算神經(jīng)元的輸出。

      總代碼如下:
      package neuralnet; import java.util.ArrayList; public class Neuron {
      //神經(jīng)元相關(guān)的權(quán)重 protected ArrayList<Double> weight; //神經(jīng)元的輸入 private
      ArrayList<Double> input; //這個神經(jīng)元的輸出,由激活函數(shù)產(chǎn)生 private Double output; //傳遞給激活函數(shù)的值
      private Double outputBeforeActivation; //輸入的數(shù)量。如果為0,則表示神經(jīng)元尚未初始化。 private int
      numberOfInputs = 0; //神經(jīng)元的偏差。除了第一層,其他都應(yīng)該是1.0。 protected Double bias = 1.0;
      //神經(jīng)元的激活函數(shù) private IActivationFunction activationFunction; public Neuron(){ }
      public Neuron(int numberofinputs){ numberOfInputs=numberofinputs; weight=new
      ArrayList<>(numberofinputs+1); input=new ArrayList<>(numberofinputs); } public
      Neuron(int numberofinputs,IActivationFunction iaf){
      numberOfInputs=numberofinputs; weight=new ArrayList<>(numberofinputs+1);
      input=new ArrayList<>(numberofinputs); activationFunction=iaf; } public void
      init(){ if(numberOfInputs>0){ for(int i=0;i<=numberOfInputs;i++){ double
      newWeight = RandomNumberGenerator.GenerateNext(); try{ this.weight.set(i,
      newWeight); } catch(IndexOutOfBoundsException iobe){
      this.weight.add(newWeight); } } } } public void setInputs(double [] values){
      if(values.length==numberOfInputs){ for(int i=0;i<numberOfInputs;i++){ try{
      input.set(i, values[i]); } catch(IndexOutOfBoundsException iobe){
      input.add(values[i]); } } } } public void setInputs(ArrayList<Double> values){
      if(values.size()==numberOfInputs){ input=values; } } public ArrayList<Double>
      getArrayInputs(){ return input; } public double[] getInputs(){ double[] inputs
      = new double[numberOfInputs]; for (int i=0;i<numberOfInputs;i++){
      inputs[i]=this.input.get(i); } return inputs; } public void setInput(int
      i,double value){ if(i>=0 && i<numberOfInputs){ try{ input.set(i, value); }
      catch(IndexOutOfBoundsException iobe){ input.add(value); } } } public double
      getInput(int i){ return input.get(i); } public double[] getWeights(){ double[]
      weights = new double[numberOfInputs+1]; for(int i=0;i<=numberOfInputs;i++){
      weights[i]=weight.get(i); } return weights; } public ArrayList<Double>
      getArrayWeights(){ return weight; } public void updateWeight(int i, double
      value){ if(i>=0 && i<=numberOfInputs){ weight.set(i, value); } } public int
      getNumberOfInputs(){ return this.numberOfInputs; } public void setWeight(int
      i,double value) throws NeuralException{ if(i>=0 && i<numberOfInputs){
      this.weight.set(i, value); } else{ throw new NeuralException("Invalid weight
      index"); } } public double getOutput(){ return output; } public void calc(){
      outputBeforeActivation=0.0; if(numberOfInputs>0){ if(input!=null &&
      weight!=null){ for(int i=0;i<=numberOfInputs;i++){
      outputBeforeActivation+=(i==numberOfInputs?bias:input.get(i))*weight.get(i); }
      } } output=activationFunction.calc(outputBeforeActivation); } public void
      setActivationFunction(IActivationFunction iaf){ this.activationFunction=iaf; }
      public double getOutputBeforeActivation(){ return outputBeforeActivation; } }
      2.NeuralLayer類

      在這個類中,將把在同一層中對齊的神經(jīng)元分成一組。因為一層需要將值傳遞給另一層,也需要定義層與層之間的連接。類的屬性定義如下:
      //這一層的神經(jīng)元數(shù)量 protected int numberOfNeuronsInLayer; //這一層的神經(jīng)元 private
      ArrayList<Neuron> neuron; //激勵函數(shù) protected IActivationFunction activationFnc;
      //將值提供給此層的前一層 protected NeuralLayer previousLayer; protected NeuralLayer
      nextLayer; protected ArrayList<Double> input; protected ArrayList<Double>
      output; protected int numberOfInputs;

      這個類是抽象的,整整可實例化的層類是InputLayer、HiddenLayer和Outp-utLayer。創(chuàng)建一個類是,必須使用另一個類的構(gòu)造函數(shù),這幾個類具有相似的構(gòu)造函數(shù)。

      而層的初始化和計算都和神經(jīng)元一樣,他們也實現(xiàn)了init()方法和calc() 方法。生命欸protected類型,確保了只有子類可以調(diào)用或覆蓋這些方法。

      全部的代碼如下:
      package neuralnet; import java.util.ArrayList; public abstract class
      NeuralLayer { //這一層的神經(jīng)元數(shù)量 protected int numberOfNeuronsInLayer; //這一層的神經(jīng)元
      private ArrayList<Neuron> neuron; //激勵函數(shù) protected IActivationFunction
      activationFnc; //將值提供給此層的前一層 protected NeuralLayer previousLayer; protected
      NeuralLayer nextLayer; protected ArrayList<Double> input; protected
      ArrayList<Double> output; protected int numberOfInputs; public NeuralLayer(int
      numberofneurons){ this.numberOfNeuronsInLayer=numberofneurons; neuron = new
      ArrayList<>(numberofneurons); output = new ArrayList<>(numberofneurons); }
      public NeuralLayer(int numberofneurons,IActivationFunction iaf){
      this.numberOfNeuronsInLayer=numberofneurons; this.activationFnc=iaf; neuron =
      new ArrayList<>(numberofneurons); output = new ArrayList<>(numberofneurons); }
      public int getNumberOfNeuronsInLayer(){ return numberOfNeuronsInLayer; } public
      ArrayList<Neuron> getListOfNeurons(){ return neuron; } protected NeuralLayer
      getPreviousLayer(){ return previousLayer; } protected NeuralLayer
      getNextLayer(){ return nextLayer; } protected void setPreviousLayer(NeuralLayer
      layer){ previousLayer=layer; } protected void setNextLayer(NeuralLayer layer){
      nextLayer=layer; } protected void init(){ if(numberOfNeuronsInLayer>=0){
      for(int i=0;i<numberOfNeuronsInLayer;i++){ try{
      neuron.get(i).setActivationFunction(activationFnc); neuron.get(i).init(); }
      catch(IndexOutOfBoundsException iobe){ neuron.add(new
      Neuron(numberOfInputs,activationFnc)); neuron.get(i).init(); } } } } protected
      void setInputs(ArrayList<Double> inputs){ this.numberOfInputs=inputs.size();
      this.input=inputs; } protected void calc(){ if(input!=null && neuron!=null){
      for(int i=0;i<numberOfNeuronsInLayer;i++){ neuron.get(i).setInputs(this.input);
      neuron.get(i).calc(); try{ output.set(i,neuron.get(i).getOutput()); }
      catch(IndexOutOfBoundsException iobe){ output.add(neuron.get(i).getOutput()); }
      } } } protected ArrayList<Double> getOutputs(){ return output; } protected
      Neuron getNeuron(int i){ return neuron.get(i); } protected void setNeuron(int
      i, Neuron _neuron){ try{ this.neuron.set(i, _neuron); }
      catch(IndexOutOfBoundsException iobe){ this.neuron.add(_neuron); } } }
      3.ActivationFunction接口

      在定義NeerualNetwork類之前,先看接口的Java代碼示例:
      public interface IActivationFunction { double calc(double x); public enum
      ActivationFunctionENUM { STEP, LINEAR, SIGMOID, HYPERTAN } }
      其中calc()方法屬于實現(xiàn)IActivationFunction接口的特定的激活函數(shù)類,例如Sigmoid函數(shù)。
      public class Sigmoid implements IActivationFunction { private double a=1.0;
      public Sigmoid(){ } public Sigmoid(double value){ this.setA(value); } public
      void setA(double value){ this.a=value; } @Override public double calc(double
      x){ return 1.0/(1.0+Math.exp(-a*x)); } }
      這也是多態(tài)性的一個示例,即在相同的函數(shù)名下,類和方法呈現(xiàn)不同的行為,產(chǎn)生靈活的應(yīng)用。

      4.神經(jīng)網(wǎng)絡(luò)(NeuralNet)類


      最后,定義神經(jīng)網(wǎng)絡(luò)類。到目前為止,我們已經(jīng)知道,神經(jīng)網(wǎng)絡(luò)在神經(jīng)層中組織神經(jīng)元,且每個神經(jīng)網(wǎng)絡(luò)至少有倆層,一個用來接收收入,一個用來處理輸出,還有一個數(shù)量可變的隱含層。因此,除了具有和神經(jīng)元以及NeuralLary類相似的屬性之外,Neural還將擁有這幾個屬性,如numberOfInputs,numberOfOutputs等。
      private InputLayer inputLayer; private ArrayList<HiddenLayer> hiddenLayer;
      private OutputLayer outputLayer; private int numberOfHiddenLayers; private int
      numberOfInputs; private int numberOfOutputs; private ArrayList<Double> input;
      private ArrayList<Double> output;
      這個類的構(gòu)造函數(shù)比前面類的參數(shù)更多:
      public NeuralNet(int numberofinputs,int numberofoutputs, int []
      numberofhiddenneurons,IActivationFunction[] hiddenAcFnc, IActivationFunction
      outputAcFnc)

      如果隱含層的數(shù)量是可變的,我們還應(yīng)該考慮到可能有多個隱含層或0個隱含層,且對每個隱含層來說,隱藏神經(jīng)元的數(shù)量也是可變的。處理這種可變性的最好方法就是把每個隱含層中的神經(jīng)元數(shù)量表示為一個整數(shù)向量(參數(shù)
      numberofhiddenlayers)。此外,需要為每個隱含層定義激活函數(shù),包括輸出層,完成這個目標(biāo)所需要的參數(shù)分別為hiddenActivationFnc和outputAcFnc。
      完整實現(xiàn)如下:
      public NeuralNet(int numberofinputs,int numberofoutputs, int []
      numberofhiddenneurons,IActivationFunction[] hiddenAcFnc, IActivationFunction
      outputAcFnc){ numberOfHiddenLayers=numberofhiddenneurons.length;
      numberOfInputs=numberofinputs; numberOfOutputs=numberofoutputs;
      if(numberOfHiddenLayers==hiddenAcFnc.length){ input=new
      ArrayList<>(numberofinputs); inputLayer=new InputLayer(numberofinputs);
      if(numberOfHiddenLayers>0){ hiddenLayer=new ArrayList<>(numberOfHiddenLayers);
      } for(int i=0;i<numberOfHiddenLayers;i++){ if(i==0){ try{ hiddenLayer.set(i,new
      HiddenLayer(numberofhiddenneurons[i], hiddenAcFnc[i],
      inputLayer.getNumberOfNeuronsInLayer())); } catch(IndexOutOfBoundsException
      iobe){ hiddenLayer.add(new HiddenLayer(numberofhiddenneurons[i],
      hiddenAcFnc[i], inputLayer.getNumberOfNeuronsInLayer())); }
      inputLayer.setNextLayer(hiddenLayer.get(i)); } else{ try{ hiddenLayer.set(i,
      new HiddenLayer(numberofhiddenneurons[i], hiddenAcFnc[i],hiddenLayer.get(i-1)
      .getNumberOfNeuronsInLayer() )); } catch(IndexOutOfBoundsException iobe){
      hiddenLayer.add(new HiddenLayer(numberofhiddenneurons[i],
      hiddenAcFnc[i],hiddenLayer.get(i-1) .getNumberOfNeuronsInLayer() )); }
      hiddenLayer.get(i-1).setNextLayer(hiddenLayer.get(i)); } }
      if(numberOfHiddenLayers>0){ outputLayer=new
      OutputLayer(numberofoutputs,outputAcFnc,
      hiddenLayer.get(numberOfHiddenLayers-1) .getNumberOfNeuronsInLayer() );
      hiddenLayer.get(numberOfHiddenLayers-1).setNextLayer(outputLayer); } else{
      outputLayer=new OutputLayer(numberofinputs, outputAcFnc, numberofoutputs);
      inputLayer.setNextLayer(outputLayer); } } }
      5.運行程序

      代碼如下:
      package neuralnet; import neuralnet.math.IActivationFunction; import
      neuralnet.math.Linear; import neuralnet.math.RandomNumberGenerator; import
      neuralnet.math.Sigmoid; public class NeuralNetConsoleTest { public static void
      main(String[] args){ RandomNumberGenerator.seed=0; int numberOfInputs=2; int
      numberOfOutputs=1; int[] numberOfHiddenNeurons= { 3 }; IActivationFunction[]
      hiddenAcFnc = { new Sigmoid(1.0) } ; Linear outputAcFnc = new Linear(1.0);
      System.out.println("Creating Neural Netword..."); NeuralNet nn = new
      NeuralNet(numberOfInputs,numberOfOutputs,
      numberOfHiddenNeurons,hiddenAcFnc,outputAcFnc); System.out.println("Neural
      Network Network..."); double [] neuralInput = { 1.5 , 0.5 };
      System.out.println("Feeding the values {1.5;0.5} to the neural network");
      double [] neuralOutput; nn.setInputs(neuralInput); nn.calc();
      neuralOutput=nn.getOutputs(); System.out.println("OutPut 1:" +
      neuralOutput[0]); neuralInput[0] = 1.0; neuralInput[1] = 2.1;
      System.out.println("Feeding the values {1.0;2.1} to the neural network");
      nn.setInputs(neuralInput); nn.calc(); neuralOutput=nn.getOutputs();
      System.out.println("OutPut 2:" + neuralOutput[0]); } }
      到此就完成了我們神經(jīng)網(wǎng)絡(luò)的全部代碼:下面是源代碼壓縮包。有需要的同學(xué)可以下載運行。

      下載鏈接 <https://files-cdn.cnblogs.com/files/godoforange/neuralnet.zip>

      友情鏈接
      ioDraw流程圖
      API參考文檔
      OK工具箱
      云服務(wù)器優(yōu)惠
      阿里云優(yōu)惠券
      騰訊云優(yōu)惠券
      京東云優(yōu)惠券
      站點信息
      問題反饋
      郵箱:[email protected]
      QQ群:637538335
      關(guān)注微信

        <ul id="qxxfc"><fieldset id="qxxfc"><tr id="qxxfc"></tr></fieldset></ul>
          亚洲综合欧美 | 亚洲国产成人精品综合99 | AV黄色网 | 国产伦精品一区二区三区四区视频 | 99精品热 | 久久国产成人免费视频 | 阿娇双腿岔开实干13分钟 | 操鼻视频素材大网站 | 自拍偷拍国内 | 免费黄色操片 |