package ann; import java.util.Collection; import java.util.Vector; public class Node { private TransferFunc tfunc; private double inputValue; private double outputValue; private double gradient; private double learningRate; private int layerDepth; private int layerMaxDepth; private boolean bias; private Vector links; private double targetValue; private int id; private static int counter=0; public Node(int layerDepth, int layerMaxDepth, TransferFunc tfunc, double learningRate, boolean bias) { this.links=new Vector(); this.layerDepth=layerDepth; this.layerMaxDepth=layerMaxDepth; this.learningRate=learningRate; this.tfunc=tfunc; this.bias=bias; if(bias) outputValue=1; id=counter++; } public void connectToNode(Node n) { Link newLink=new Link(this,n); addLink(newLink); n.addLink(newLink); } public void addLink(Link newLink) { links.add(newLink); } public double getInputValue() { return inputValue; } public void setInputValue(double value) { this.inputValue=value; if(layerDepth != 0) this.outputValue=tfunc.f(value); else this.outputValue=inputValue; } public double getOutputValue() { return outputValue; } public void updateValue() { if(layerDepth !=0 && !bias) { inputValue=0; boolean gotLink=false; for(Link link: links) { if(link.getToNode().equals(this)) { inputValue+=link.getWeight()*link.getFromNode().getOutputValue(); gotLink=true; } } if(gotLink) outputValue=tfunc.f(inputValue); } } public void updateWeightChanges() { if(layerDepth!=0) { for(Link link: links) { if(link.getToNode().equals(this)) { link.setWeightChange(learningRate*gradient*link.getFromNode().getOutputValue()); } } } } public void updateGradient() { if(layerDepth==layerMaxDepth-1) { if(!bias) gradient=(targetValue-outputValue)*tfunc.fd(inputValue); } else if(layerDepth!=0) { double tmpSum=0; for(Link link:links) { if(link.getFromNode().equals(this)) { tmpSum+=link.getToNode().getGradient()*link.getWeight(); } } gradient=tfunc.fd(inputValue)*tmpSum; } System.out.println("new gradient for node "+id+" is "+gradient); } private double getGradient() { return gradient; } public String toString() { return Double.toString(outputValue); } public boolean isBiasNode() { return bias; } public void applyWeightChanges() { for(Link link:links) { if(link.getFromNode().equals(this)) link.applyWeightChange(); } } public void setTargetValue(double targetValue) { this.targetValue=targetValue; } public double getError() { return targetValue-outputValue; } public Vector getLinks() { Vector tmpLinks=new Vector(); for(int i=0;i