Package org.encog.neural.thermal

Source Code of org.encog.neural.thermal.BoltzmannMachine

/*
* Encog(tm) Core v3.0 - Java Version
* http://www.heatonresearch.com/encog/
* http://code.google.com/p/encog-java/
* Copyright 2008-2011 Heaton Research, Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
*     http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*  
* For more information on Heaton Research copyrights, licenses
* and trademarks visit:
* http://www.heatonresearch.com/copyright
*/
package org.encog.neural.thermal;

import org.encog.mathutil.BoundMath;
import org.encog.mathutil.randomize.RangeRandomizer;
import org.encog.ml.data.MLData;
import org.encog.ml.data.specific.BiPolarNeuralData;
import org.encog.util.EngineArray;

/**
* Implements a Boltzmann machine.
*
*/
public class BoltzmannMachine extends ThermalNetwork {

  /**
   * Serial id.
   */
  private static final long serialVersionUID = 1L;

  /**
   * The property for run cycles.
   */
  public static final String RUN_CYCLES = "runCycles";
 
  /**
   * The property for anneal cycles.
   */
  public static final String ANNEAL_CYCLES = "annealCycles";

  /**
   * The current temperature of the neural network. The higher the
   * temperature, the more random the network will behave.
   */
  private double temperature;

  /**
   * The thresholds.
   */
  private double[] threshold;

  /**
   * Count used to internally determine if a neuron is "on".
   */
  private transient int[] on;

  /**
   * Count used to internally determine if a neuron is "off".
   */
  private transient int[] off;

  /**
   * The number of cycles to anneal for.
   */
  private int annealCycles = 100;

  /**
   * The number of cycles to run the network through before annealing.
   */
  private int runCycles = 1000;

  /**
   * Default constructors.
   */
  public BoltzmannMachine() {
    super();
  }

  /**
   * Construct a Boltzmann machine with the specified number of neurons.
   * @param neuronCount The number of neurons.
   */
  public BoltzmannMachine(final int neuronCount) {
    super(neuronCount);

    this.threshold = new double[neuronCount];
  }

  /**
   * Note: for Boltzmann networks, you will usually want to call the "run"
   * method to compute the output.
   *
   * This method can be used to copy the input data to the current state. A
   * single iteration is then run, and the new current state is returned.
   *
   * @param input
   *            The input pattern.
   * @return The new current state.
   */
  @Override
  public final MLData compute(final MLData input) {
    final BiPolarNeuralData result = new BiPolarNeuralData(input.size());
    EngineArray.arrayCopy(input.getData(), getCurrentState().getData());
    run();
    EngineArray.arrayCopy(getCurrentState().getData(), result.getData());
    return result;
  }

  /**
   * Decrease the temperature by the specified amount.
   *
   * @param d
   *            The amount to decrease by.
   */
  public final void decreaseTemperature(final double d) {
    this.temperature *= d;
  }

  /**
   * Run the network until thermal equilibrium is established.
   */
  public final void establishEquilibrium() {
    final int count = getNeuronCount();

    if (this.on == null) {
      this.on = new int[count];
      this.off = new int[count];
    }

    for (int i = 0; i < count; i++) {
      this.on[i] = 0;
      this.off[i] = 0;
    }

    for (int n = 0; n < this.runCycles * count; n++) {
      run((int) RangeRandomizer.randomize(0, count - 1));
    }
    for (int n = 0; n < this.annealCycles * count; n++) {
      final int i = (int) RangeRandomizer.randomize(0, count - 1);
      run(i);
      if (getCurrentState().getBoolean(i)) {
        this.on[i]++;
      } else {
        this.off[i]++;
      }
    }

    for (int i = 0; i < count; i++) {
      getCurrentState().setData(i, this.on[i] > this.off[i]);
    }
  }

  /**
   * @return the annealCycles
   */
  public final int getAnnealCycles() {
    return this.annealCycles;
  }

  /**
   * {@inheritDoc}
   */
  @Override
  public int getInputCount() {
    return getNeuronCount();
  }

  /**
   * {@inheritDoc}
   */
  @Override
  public final int getOutputCount() {
    return getNeuronCount();
  }

  /**
   * @return the runCycles
   */
  public final int getRunCycles() {
    return this.runCycles;
  }

  /**
   * @return The temperature the network is currently operating at.
   */
  public final double getTemperature() {
    return this.temperature;
  }

  /**
   * @return the threshold
   */
  public final double[] getThreshold() {
    return this.threshold;
  }

  /**
   * Run the network for all neurons present.
   */
  public final void run() {
    final int count = getNeuronCount();
    for (int i = 0; i < count; i++) {
      run(i);
    }
  }

  /**
   * Run the network for the specified neuron.
   *
   * @param i
   *            The neuron to run for.
   */
  public final void run(final int i) {
    int j;
    double sum, probability;

    final int count = getNeuronCount();

    sum = 0;
    for (j = 0; j < count; j++) {
      sum += getWeight(i, j) * (getCurrentState().getBoolean(j) ? 1 : 0);
    }
    sum -= this.threshold[i];
    probability = 1 / (1 + BoundMath.exp(-sum / this.temperature));
    if (RangeRandomizer.randomize(0, 1) <= probability) {
      getCurrentState().setData(i, true);
    } else {
      getCurrentState().setData(i, false);
    }
  }

  /**
   * @param annealCycles
   *            the annealCycles to set
   */
  public final void setAnnealCycles(final int annealCycles) {
    this.annealCycles = annealCycles;
  }

  /**
   * @param runCycles
   *            the runCycles to set
   */
  public final void setRunCycles(final int runCycles) {
    this.runCycles = runCycles;
  }

  /**
   * Set the network temperature.
   *
   * @param temperature
   *            The temperature to operate the network at.
   */
  public final void setTemperature(final double temperature) {
    this.temperature = temperature;
  }

  /**
   * Set the thresholds.
   * @param t The thresholds.
   */
  public final void setThreshold(final double[] t) {
    this.threshold = t;

  }

  /**
   * {@inheritDoc}
   */
  @Override
  public void updateProperties() {
    // nothing needed here
  }

}
TOP

Related Classes of org.encog.neural.thermal.BoltzmannMachine

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.