Package org.neuroph.nnet.learning

Source Code of org.neuroph.nnet.learning.KohonenLearning

/**
* Copyright 2010 Neuroph Project http://neuroph.sourceforge.net
*
* 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.
*/

package org.neuroph.nnet.learning;

import java.util.Iterator;

import org.neuroph.core.Connection;
import org.neuroph.core.Layer;
import org.neuroph.core.NeuralNetwork;
import org.neuroph.core.Neuron;
import org.neuroph.core.learning.LearningRule;
import org.neuroph.core.learning.TrainingElement;
import org.neuroph.core.learning.TrainingSet;
import org.neuroph.nnet.Kohonen;

/**
* Learning algorithm for Kohonen network.
*
* @author Zoran Sevarac <sevarac@gmail.com>
*/
public class KohonenLearning extends LearningRule {
 
  /**
   * The class fingerprint that is set to indicate serialization
   * compatibility with a previous version of the class.
   */ 
  private static final long serialVersionUID = 1L;
 
  double learningRate = 0.9d;
  int[] iterations = { 100, 0 };
  double decStep[] = new double[2];
  int mapSize = 0;
  int[] nR = { 1, 1 }; // neighborhood radius
  int currentIteration;

   
  public KohonenLearning() {
    super();
  }

  public void learn(TrainingSet trainingSet) {
               
    for (int phase = 0; phase < 2; phase++) {
      for (int k = 0; k < iterations[phase]; k++) {
        Iterator<TrainingElement> e = trainingSet.iterator();
        while (e.hasNext() && !isStopped()) {
          TrainingElement tE = e.next();
          learnPattern(tE, nR[phase]);       
        } // while
        currentIteration = k;
        this.notifyChange()
        if (isStopped()) return;
      } // for k
      learningRate = learningRate * 0.5;
    } // for phase
  }

  private void learnPattern(TrainingElement tE, int neighborhood) {
    neuralNetwork.setInput(tE.getInput());
    neuralNetwork.calculate();
    Neuron winner = getClosest();
    if (winner.getOutput() == 0)
      return; // ako je vec istrenirana jedna celija, izadji

    Layer mapLayer = neuralNetwork.getLayerAt(1);
    int winnerIdx = mapLayer.indexOf(winner);
    adjustCellWeights(winner, 0);

    int cellNum = mapLayer.getNeuronsCount();
    for (int p = 0; p < cellNum; p++) {
      if (p == winnerIdx)
        continue;
      if (isNeighbor(winnerIdx, p, neighborhood)) {
        Neuron cell = mapLayer.getNeuronAt(p);
        adjustCellWeights(cell, 1);
      } // if
    } // for

  }

  // get unit with closetst weight vector
  private Neuron getClosest() {
    Iterator<Neuron> i = this.neuralNetwork.getLayerAt(1)
        .getNeuronsIterator();
    Neuron winner = new Neuron();
    double minOutput = 100;
    while (i.hasNext()) {
      Neuron n = i.next();
      double out = n.getOutput();
      if (out < minOutput) {
        minOutput = out;
        winner = n;
      } // if
    } // while
    return winner;
  }

  private void adjustCellWeights(Neuron cell, int r) {
    Iterator<Connection> i = cell.getInputsIterator();
    while (i.hasNext()) {
      Connection conn = i.next();
      double dWeight = (learningRate / (r + 1))
          * (conn.getInput() - conn.getWeight().getValue());
      conn.getWeight().inc(dWeight);
    }// while
  }

  private boolean isNeighbor(int i, int j, int n) {
    // i - centralna celija
    // n - velicina susedstva
    // j - celija za proveru
    n = 1;
    int d = mapSize;

    // if (j<(i-n*d-n)||(j>(i+n*d+n))) return false;

    int rt = n; // broj celija ka gore
    while ((i - rt * d) < 0)
      rt--;

    int rb = n; // broj celija ka dole
    while ((i + rb * d) > (d * d - 1))
      rb--;

    for (int g = -rt; g <= rb; g++) {
      int rl = n; // broj celija u levu stranu
      int rl_mod = (i - rl) % d;
      int i_mod = i % d;
      while (rl_mod > i_mod) {
        rl--;
        rl_mod = (i - rl) % d;
      }

      int rd = n; // broj celija u desnu stranu
      int rd_mod = (i + rd) % d;
      while (rd_mod < i_mod) {
        rd--;
        rd_mod = (i + rd) % d;
      }

      if ((j >= (i + g * d - rl)) && (j <= (i + g * d + rd)))
        return true;
      // else if (j<(i+g*d-rl)) return false;
    } // for
    return false;
  }

  public double getLearningRate() {
    return learningRate;
  }

  public void setLearningRate(double learningRate) {
    this.learningRate = learningRate;
  }

  public void setIterations(int Iphase, int IIphase) {
    this.iterations[0] = Iphase;
    this.iterations[1] = IIphase;
  }

  public Integer getIteration() {
    return new Integer(currentIteration);
  }

  public int getMapSize() {
    return mapSize;
  }
       
        @Override
        public void setNeuralNetwork(NeuralNetwork neuralNetwork) {
            super.setNeuralNetwork(neuralNetwork);
            int neuronsNum = neuralNetwork.getLayerAt(1).getNeuronsCount();
            mapSize = (int) Math.sqrt(neuronsNum);
        }

}
TOP

Related Classes of org.neuroph.nnet.learning.KohonenLearning

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.