Package aima.core.learning.neural

Source Code of aima.core.learning.neural.Layer

package aima.core.learning.neural;

import aima.core.util.Util;
import aima.core.util.math.Matrix;
import aima.core.util.math.Vector;

/**
* Artificial Intelligence A Modern Approach (3rd Edition): page 729<br>
* <br>
*
* Feed-forward networks are usually arranged in layers, such that each unit
* receives input only from units in the immediately preceding layer.
*
* @author Ravi Mohan
* @author Mike Stampone
*/
public class Layer {
  // vectors are represented by n * 1 matrices;
  private final Matrix weightMatrix;

  Vector biasVector, lastBiasUpdateVector;

  private final ActivationFunction activationFunction;

  private Vector lastActivationValues, lastInducedField;

  private Matrix lastWeightUpdateMatrix;

  private Matrix penultimateWeightUpdateMatrix;

  private Vector penultimateBiasUpdateVector;

  private Vector lastInput;

  public Layer(Matrix weightMatrix, Vector biasVector, ActivationFunction af) {

    activationFunction = af;
    this.weightMatrix = weightMatrix;
    lastWeightUpdateMatrix = new Matrix(weightMatrix.getRowDimension(),
        weightMatrix.getColumnDimension());
    penultimateWeightUpdateMatrix = new Matrix(
        weightMatrix.getRowDimension(),
        weightMatrix.getColumnDimension());

    this.biasVector = biasVector;
    lastBiasUpdateVector = new Vector(biasVector.getRowDimension());
    penultimateBiasUpdateVector = new Vector(biasVector.getRowDimension());
  }

  public Layer(int numberOfNeurons, int numberOfInputs,
      double lowerLimitForWeights, double upperLimitForWeights,
      ActivationFunction af) {

    activationFunction = af;
    this.weightMatrix = new Matrix(numberOfNeurons, numberOfInputs);
    lastWeightUpdateMatrix = new Matrix(weightMatrix.getRowDimension(),
        weightMatrix.getColumnDimension());
    penultimateWeightUpdateMatrix = new Matrix(
        weightMatrix.getRowDimension(),
        weightMatrix.getColumnDimension());

    this.biasVector = new Vector(numberOfNeurons);
    lastBiasUpdateVector = new Vector(biasVector.getRowDimension());
    penultimateBiasUpdateVector = new Vector(biasVector.getRowDimension());

    initializeMatrix(weightMatrix, lowerLimitForWeights,
        upperLimitForWeights);
    initializeVector(biasVector, lowerLimitForWeights, upperLimitForWeights);
  }

  public Vector feedForward(Vector inputVector) {
    lastInput = inputVector;
    Matrix inducedField = weightMatrix.times(inputVector).plus(biasVector);

    Vector inducedFieldVector = new Vector(numberOfNeurons());
    for (int i = 0; i < numberOfNeurons(); i++) {
      inducedFieldVector.setValue(i, inducedField.get(i, 0));
    }

    lastInducedField = inducedFieldVector.copyVector();
    Vector resultVector = new Vector(numberOfNeurons());
    for (int i = 0; i < numberOfNeurons(); i++) {
      resultVector.setValue(i, activationFunction
          .activation(inducedFieldVector.getValue(i)));
    }
    // set the result as the last activation value
    lastActivationValues = resultVector.copyVector();
    return resultVector;
  }

  public Matrix getWeightMatrix() {
    return weightMatrix;
  }

  public Vector getBiasVector() {
    return biasVector;
  }

  public int numberOfNeurons() {
    return weightMatrix.getRowDimension();
  }

  public int numberOfInputs() {
    return weightMatrix.getColumnDimension();
  }

  public Vector getLastActivationValues() {
    return lastActivationValues;
  }

  public Vector getLastInducedField() {
    return lastInducedField;
  }

  public Matrix getLastWeightUpdateMatrix() {
    return lastWeightUpdateMatrix;
  }

  public void setLastWeightUpdateMatrix(Matrix m) {
    lastWeightUpdateMatrix = m;
  }

  public Matrix getPenultimateWeightUpdateMatrix() {
    return penultimateWeightUpdateMatrix;
  }

  public void setPenultimateWeightUpdateMatrix(Matrix m) {
    penultimateWeightUpdateMatrix = m;
  }

  public Vector getLastBiasUpdateVector() {
    return lastBiasUpdateVector;
  }

  public void setLastBiasUpdateVector(Vector v) {
    lastBiasUpdateVector = v;
  }

  public Vector getPenultimateBiasUpdateVector() {
    return penultimateBiasUpdateVector;
  }

  public void setPenultimateBiasUpdateVector(Vector v) {
    penultimateBiasUpdateVector = v;
  }

  public void updateWeights() {
    weightMatrix.plusEquals(lastWeightUpdateMatrix);
  }

  public void updateBiases() {
    Matrix biasMatrix = biasVector.plusEquals(lastBiasUpdateVector);
    Vector result = new Vector(biasMatrix.getRowDimension());
    for (int i = 0; i < biasMatrix.getRowDimension(); i++) {
      result.setValue(i, biasMatrix.get(i, 0));
    }
    biasVector = result;
  }

  public Vector getLastInputValues() {

    return lastInput;

  }

  public ActivationFunction getActivationFunction() {

    return activationFunction;
  }

  public void acceptNewWeightUpdate(Matrix weightUpdate) {
    /*
     * penultimate weightupdates maintained only to implement VLBP later
     */
    setPenultimateWeightUpdateMatrix(getLastWeightUpdateMatrix());
    setLastWeightUpdateMatrix(weightUpdate);
  }

  public void acceptNewBiasUpdate(Vector biasUpdate) {
    setPenultimateBiasUpdateVector(getLastBiasUpdateVector());
    setLastBiasUpdateVector(biasUpdate);
  }

  public Vector errorVectorFrom(Vector target) {
    return target.minus(getLastActivationValues());

  }

  //
  // PRIVATE METHODS
  //
  private static void initializeMatrix(Matrix aMatrix, double lowerLimit,
      double upperLimit) {
    for (int i = 0; i < aMatrix.getRowDimension(); i++) {
      for (int j = 0; j < aMatrix.getColumnDimension(); j++) {
        double random = Util.generateRandomDoubleBetween(lowerLimit,
            upperLimit);
        aMatrix.set(i, j, random);
      }
    }

  }

  private static void initializeVector(Vector aVector, double lowerLimit,
      double upperLimit) {
    for (int i = 0; i < aVector.size(); i++) {

      double random = Util.generateRandomDoubleBetween(lowerLimit,
          upperLimit);
      aVector.setValue(i, random);
    }
  }
}
TOP

Related Classes of aima.core.learning.neural.Layer

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.