EDIT: Code updated, Comments, performance info
I'm trying to code K-means|| in Java. (http://vldb.org/pvldb/vol5/p622_bahmanbahmani_vldb2012.pdf)
However, it doesn't work well. I wasn't surprised that the running time increases compared to standard K-means. I'm much more wondering why the detection rate of my program trained with K-means|| is lower compared to a training with standard K-means. How could choosen clusterpoints be worse than ones picked by chance?
UPDATE: If've found some errors while my internet was down, k-means|| performs now as good as k-means standard - however not a bit better.
I'm quite sure that my code is wrong, but after hours of searching I've got no idea where I've done a mistake (frankly, I'm quite new to this topic).
So I hope you see what I've done wrong. Here is my code for both seeding options:
public void training(int stop, int numberIt, double epsilon, boolean advanced){
double d=Double.MAX_VALUE,s=0;
int nearestprototype=0;
int [] myprototype=new int[trainingsSet.size()];
Random random=new Random();
//
long t1=System.currentTimeMillis();
if(!advanced){//standard random k-means seeding; random datapoints are choosen as prototypes
for(int i=0; i<k; i++){
int rand = random.nextInt(trainingsSet.size());
prototypes[i]=trainingsSet.getVectorAtIndex(rand);
}
}else{ //state-of-the-art k-means|| a.k.a k-means++ scalable seeding; explanation here: http://vldb.org/pvldb/vol5/p622_bahmanbahmani_vldb2012.pdf
prototypes[0]=trainingsSet.getVectorAtIndex(random.nextInt(trainingsSet.size())); //first protoype, chosen randomly
Vector<DataVector>kproto=new Vector<DataVector>(); //saves the prototypes
kproto.add(prototypes[0]);
for(int i=0;i<trainingsSet.size();i++){ //gets distance to all data points, sum it up
s+=trainingsSet.getVectorAtIndex(i).distance2(kproto.elementAt(0));
}
double it=Math.floor(Math.log(s)); // calculates how often the loop for step 4 and 5 is executed
for(int c=0; c<it; c++){
int[]psi=new int[trainingsSet.size()];//saves minimum distance to a protoype for every element
for(int i=0; i<trainingsSet.size();i++){
double min=Double.POSITIVE_INFINITY;
for(int j=0;j<kproto.size();j++){
double dist=trainingsSet.getVectorAtIndex(i).distance2(kproto.elementAt(j));
if(min>dist){
min=dist;
}
}
psi[i]=(int) min;
}
double phi_c=0;
for(int i=0; i<trainingsSet.size();i++)
phi_c+=psi[i]; //sums up squared distances
for(int f=0; f<trainingsSet.size();f++){
double p_x=5*psi[f]/phi_c; //oversampling factor 0.1*k (k is 50 in my case)
if(p_x>random.nextDouble()){
kproto.addElement(trainingsSet.getVectorAtIndex(f));//adds data point to the prototype set with a probability
//depending on its distance to the next prototype
}
}
}
int[]w=new int[kproto.size()]; //every prototype gets a value in w; the value is increased if the prototype has a minimum distance to a data point
for(int i=0; i<trainingsSet.size();i++){
double min=trainingsSet.getVectorAtIndex(i).distance2(kproto.elementAt(0));
if(min==0)
continue;
int index=0;
for(int j=1; j<kproto.size();j++){
double save=trainingsSet.getVectorAtIndex(i).distance2(kproto.elementAt(j));
if(min>save){
min=save;
index=j;
}
}
w[index]++;
}
int[]wtotal=new int[kproto.size()]; //wtotal sums the w values up
for(int i=0;i<kproto.size();i++){
for(int st=0; st<=i;st++){
wtotal[i]+=w[st];
}
}
int[]cselect=new int[k];//cselect saves the final prototypes
int stoppoint=0;
boolean repeat=false; //repeat lets the choosing process repeat if the prototype has already been selected
for(int kk=0;kk<k;kk++){
do{
repeat=false;
int stopper=random.nextInt(wtotal[kproto.size()-1]);//randomly choose a int and check in which interval it lies
for(int st=wtotal.length-1;st>=0;st--){
if(stopper>=wtotal[st]){
stoppoint=wtotal.length-st-1;
break;
}
}
for(int i=0; i<kk;i++){
if(cselect[i]==stoppoint)
repeat=true;
}
}while(repeat);
//are all prototypes overwritten?
prototypes[kk]=kproto.get(stoppoint);//the number of the interval is connected to a prototype; the prototype is added to the final set of prototypes "prototypes"
cselect[kk]=stoppoint;
}
}
long t2=System.currentTimeMillis();
System.out.println(advanced+" Init time: "+(t2-t1));
The performance shows that both options (standard, k-means||) reach the same level of correct clustering (around 85%). However, the running time for initalisation differs.
The seeding is quasi-immediatly for standard k-means, whereas k-means|| needs 600-900ms (for 1000 data points). The convergence afterwards with standard maximazation/expectation needs the same time for both (around 1900-2500ms). This is irritation because k-means|| should converge much faster.
I hope you spot some error or maybe explain me if I expect something else than k-means|| can deliver.
Thanks for your help!
Related
I have the following uni assignment that's been puzzling me. I have to implement a genetic algorithm that allocates processes into processors. More specifically the problem is the following:
"You have a program that is computed in parallel processor system. The program is made up of a N number of processes that need to be allocated on a n number of processors (where n is way smaller than N). The communication of processes during this whole process can be quite time consuming, so the best practice would be to assign processes that need intercommunication with one another to same processor.
In order to reduce the communication time between processes you could allocate of these processes to the same processor but this would negate the parallel processing idea that every processor needs to contribute to the whole process.
Consider the following: Let's say that Cij is the total amount of communication between process i and process j. Assume that every process needs the same amount of computing power so that the limitations of the processing process can be handled by assigning the same amount of processes to a processor. Use a genetic algorithm to assign N processes to n processors."
The above is roughly translated the description of the problem. Now I have the following question that puzzle me.
1) What would be the best viable solution in order to for the genetic algorithm to run. I have the theory behind them and I have deduced that you need a best possible solution in order to check each generation of the produced population.
2) How can I properly design the whole problem in order to be handled by a program.
I am planning to implement this in Java but any other recommendations for other programming languages would be welcome.
The Dude abides. Or El Duderino if you're not into the whole brevity thing.
What you're asking is really a two part question, but the Genetic Algorithm part can be easily illustrated in concept. I find that giving a basic start can be helpful, but this problem as a "whole" is too complicated to address here.
Genetic Algorithms (GA) can be used as an optimizer, as you note. In order to apply a GA to a process execution plan, you need to be able to score an execution plan, then clone and mutate the best plans. A GA works by running several plans, cloning the best, and then mutating some of them slightly to see if the offspring (cloned) plans are improved or worsened.
In this example, I created a array of 100 random Integers. Each Integer is a "process" to be run and the value of the Integer is the "cost" of running that individual process.
List<Integer> processes = new ArrayList<Integer>();
The processes are then added to an ExecutionPlan, which is a List<List<Integer>>. This List of List of Integers will be used to represent 4 processors doing 25 rounds of processing:
class ExecutionPlan implements Comparable<ExecutionPlan> {
List<List<Integer>> plan;
int cost;
The total cost of an execution plan will be computed by taking the highest process cost per round (the greatest Integer) and summing the costs of all the rounds. Thus, the goal of the optimizer is to distribute the initial 100 integers (processes) into 25 rounds of "processing" on 4 "processors" such that total cost is as low as possible.
// make 10 execution plans of 25 execution rounds running on 4 processors;
List<ExecutionPlan> executionPlans = createAndIntializePlans(processes);
// Loop on generationCount
for ( int generation = 0; generation < GENERATIONCOUNT; ++generation) {
computeCostOfPlans(executionPlans);
// sort plans by cost
Collections.sort(executionPlans);
// print execution plan costs
System.out.println(generation + " = " + executionPlans);
// clone 5 better plans over 5 worse plans
// i.e., kill off the least fit and reproduce the best fit.
cloneBetterPlansOverWorsePlans(executionPlans);
// mutate 5 cloned plans
mutateClones(executionPlans);
}
When the program is run, the cost is initially randomly determined, but with each generation it improves. If you run it for 1000 generations and plot the results, a typical run will look like this:
The purpose of the GA is to Optimize or attempt to determine the best possible solution. The reason it can be applied to you problem is that your ExecutionPlan can be scored, cloned and mutated. The path to success, therefore, is to separate the problems in your mind. First, figure out how you can make an execution plan that can be scored as to what the cost will be to actually run it on an assumed set of hardware. Add rountines to clone and mutate an ExecutionPlan. Once you have that plug it into this GA example. Good luck and stay cool dude.
public class Optimize {
private static int GENERATIONCOUNT = 1000;
private static int PROCESSCOUNT = 100;
private static int MUTATIONCOUNT = PROCESSCOUNT/10;
public static void main(String...strings) {
new Optimize().run();
}
// define an execution plan as 25 runs on 4 processors
class ExecutionPlan implements Comparable<ExecutionPlan> {
List<List<Integer>> plan;
int cost;
public ExecutionPlan(List<List<Integer>> plan) {
this.plan = plan;
}
#Override
public int compareTo(ExecutionPlan o) {
return cost-o.cost;
}
#Override
public String toString() {
return Integer.toString(cost);
}
}
private void run() {
// make 100 processes to be completed
List<Integer> processes = new ArrayList<Integer>();
// assign them a random cost between 1 and 100;
for ( int index = 0; index < PROCESSCOUNT; ++index) {
processes.add( new Integer((int)(Math.random() * 99.0)+1));
}
// make 10 execution plans of 25 execution rounds running on 4 processors;
List<ExecutionPlan> executionPlans = createAndIntializePlans(processes);
// Loop on generationCount
for ( int generation = 0; generation < GENERATIONCOUNT; ++generation) {
computeCostOfPlans(executionPlans);
// sort plans by cost
Collections.sort(executionPlans);
// print execution plan costs
System.out.println(generation + " = " + executionPlans);
// clone 5 better plans over 5 worse plans
cloneBetterPlansOverWorsePlans(executionPlans);
// mutate 5 cloned plans
mutateClones(executionPlans);
}
}
private void mutateClones(List<ExecutionPlan> executionPlans) {
for ( int index = 0; index < executionPlans.size()/2; ++index) {
ExecutionPlan execution = executionPlans.get(index);
// mutate 10 different location swaps, maybe the plan improves
for ( int mutationCount = 0; mutationCount < MUTATIONCOUNT ; ++mutationCount) {
int location1 = (int)(Math.random() * 100.0);
int location2 = (int)(Math.random() * 100.0);
// swap two locations
Integer processCostTemp = execution.plan.get(location1/4).get(location1%4);
execution.plan.get(location1/4).set(location1%4, execution.plan.get(location2/4).get(location2%4));
execution.plan.get(location2/4).set(location2%4, processCostTemp);
}
}
}
private void cloneBetterPlansOverWorsePlans(List<ExecutionPlan> executionPlans) {
for ( int index = 0; index < executionPlans.size()/2; ++index) {
ExecutionPlan execution = executionPlans.get(index);
List<List<Integer>> clonePlan = new ArrayList<List<Integer>>();
for ( int roundNumber = 0; roundNumber < 25; ++roundNumber) {
clonePlan.add( new ArrayList<Integer>(execution.plan.get(roundNumber)) );
}
executionPlans.set( index + executionPlans.size()/2, new ExecutionPlan(clonePlan) );
}
}
private void computeCostOfPlans(List<ExecutionPlan> executionPlans) {
for ( ExecutionPlan execution: executionPlans) {
execution.cost = 0;
for ( int roundNumber = 0; roundNumber < 25; ++roundNumber) {
// cost of a round is greatest "communication time".
List<Integer> round = execution.plan.get(roundNumber);
int roundCost = round.get(0)>round.get(1)?round.get(0):round.get(1);
roundCost = execution.cost>round.get(2)?roundCost:round.get(2);
roundCost = execution.cost>round.get(3)?roundCost:round.get(3);
// add all the round costs' to determine total plan cost
execution.cost += roundCost;
}
}
}
private List<ExecutionPlan> createAndIntializePlans(List<Integer> processes) {
List<ExecutionPlan> executionPlans = new ArrayList<ExecutionPlan>();
for ( int planNumber = 0; planNumber < 10; ++planNumber) {
// randomize the processes for this plan
Collections.shuffle(processes);
// and make the plan
List<List<Integer>> currentPlan = new ArrayList<List<Integer>>();
for ( int roundNumber = 0; roundNumber < 25; ++roundNumber) {
List<Integer> round = new ArrayList<Integer>();
round.add(processes.get(4*roundNumber+0));
round.add(processes.get(4*roundNumber+1));
round.add(processes.get(4*roundNumber+2));
round.add(processes.get(4*roundNumber+3));
currentPlan.add(round);
}
executionPlans.add(new ExecutionPlan(currentPlan));
}
return executionPlans;
}
}
I was inspired by this question XOR Neural Network in Java
Briefly, a XOR neural network is trained and the number of iterations required to complete the training depends on seven parameters (alpha, gamma3_min_cutoff, gamma3_max_cutoff, gamma4_min_cutoff, gamma4_max_cutoff, gamma4_min_cutoff, gamma4_max_cutoff). I would like to minimize number of iterations required for training by tweaking these parameters.
So, I want to rewrite program from
private static double alpha=0.1, g3min=0.2, g3max=0.8;
int iteration= 0;
loop {
do_something;
iteration++;
if (error < threshold){break}
}
System.out.println( "iterations: " + iteration)
to
for (double alpha = 0.01; alpha < 10; alpha+=0.01){
for (double g3min = 0.01; g3min < 0.4; g3min += 0.01){
//Add five more loops to optimize other parameters
int iteration = 1;
loop {
do_something;
iteration++;
if (error < threshold){break}
}
System.out.println( inputs );
//number of iterations, alpha, cutoffs,etc
//Close five more loops here
}
}
But this brute forcing method is not going to be efficient. Given 7 parameters and hundreds of iterations for each calculation even with 10 points for each parameter translates in billions of operations. Nonlinear fit should do, but those typically require partial derivatives which I wouldn't have in this case.
Is there a Java package for this sort of optimizations?
Thank you in advance,
Stepan
You have some alternatives - depending on the equations that govern the error parameter.
Pick a point in parameter space and use an iterative process to walk towards a minimum. Essentially, add a delta to each parameter and pick whichever reduces the error by the most - rince - repeat.
Pick each pareameter and perform a binary-chop search between its limits to find it's minimum. Will only work if the parameter's effect is linear.
Solve the system using some form of Operations-Research technique to track down a minimum.
I've built a model of the solar system in Java. In order to determine the position of a planet it does do a whole lot of computations which give a very exact value. However I am often satisfied with the approximate position, if that could make it go faster. Because I'm using it in a simulation speed is important, as the position of the planet will be requested millions of times.
Currently I try to cache the position of a planet throughout its orbit and then use those coordinates over and over. If a position in between two values is requested I perform a linear interpolation. This is how I store values:
for(int t=0; t<tp; t++) {
listCoordinates[t]=super.coordinates(ti+t);
}
interpolator = new PlanetOrbit(listCoordinates,tp);
PlanetOrbit has the interpolation code:
package cometsim;
import org.apache.commons.math3.util.FastMath;
public class PlanetOrbit {
final double[][] coordinates;
double tp;
public PlanetOrbit(double[][] coordinates, double tp) {
this.coordinates = coordinates;
this.tp = tp;
}
public double[] coordinates(double julian) {
double T = julian % FastMath.floor(tp);
if(coordinates.length == 1 || coordinates.length == 0) return coordinates[0];
if(FastMath.round(T) == T) return coordinates[(int) T];
int floor = (int) FastMath.floor(T);
if(floor>=coordinates.length) floor=coordinates.length-5;
double[] f = coordinates[floor];
double[] c = coordinates[floor+1];
double[] retval = f;
retval[0] += (T-FastMath.floor(T))*(c[0]-f[0]);
retval[1] += (T-FastMath.floor(T))*(c[1]-f[1]);
retval[2] += (T-FastMath.floor(T))*(c[2]-f[2]);
return retval;
}
}
You can think of FastMath as Math but faster. However, this code is not much of a speed improvement over calculating the exact value every time. Do you have any ideas for how to make it faster?
There are a few issues I can see, the main ones I can see are as follows
PlanetOrbit#coordinates seems to actually change the values in the variable coordinates. As this method is supposed to only interpolate I expect that your orbit will actually corrupt slightly everytime you run though it (because it is a linear interpolation the orbit will actually degrade towards its centre).
You do the same thing several times, most clearly T-FastMath.floor(T) occures 3 seperate times in the code.
Not a question of efficiency or accuracy but the variable and method names are very opaque, use real words for variable names.
My proposed method would be as follows
public double[] getInterpolatedCoordinates(double julian){ //julian calendar? This variable name needs to be something else, like day, or time, or whatever it actually means
int startIndex=(int)julian;
int endIndex=(startIndex+1>=coordinates.length?1:startIndex+1); //wrap around
double nonIntegerPortion=julian-startIndex;
double[] start = coordinates[startIndex];
double[] end = coordinates[endIndex];
double[] returnPosition= new double[3];
for(int i=0;i< start.length;i++){
returnPosition[i]=start[i]*(1-nonIntegerPortion)+end[i]*nonIntegerPortion;
}
return returnPosition;
}
This avoids corrupting the coordinates array and avoids repeating the same floor several times (1-nonIntegerPortion is still done several times and could be removed if needs be but I expect profiling will show it isn't significant). However, it does create a new double[] each time which may be inefficient if you only need the array temporarily. This can be corrected using a store object (an object you used previously but no longer need, usually from the previous loop)
public double[] getInterpolatedCoordinates(double julian, double[] store){
int startIndex=(int)julian;
int endIndex=(startIndex+1>=coordinates.length?1:startIndex+1); //wrap around
double nonIntegerPortion=julian-startIndex;
double[] start = coordinates[startIndex];
double[] end = coordinates[endIndex];
double[] returnPosition= store;
for(int i=0;i< start.length;i++){
returnPosition[i]=start[i]*(1-nonIntegerPortion)+end[i]*nonIntegerPortion;
}
return returnPosition; //store is returned
}
I'm getting wrong frequency, I don't understand why i'm getting wrong values.since i have calculating as per instructions followed by stackoverflow.
I've used FFT from
http://introcs.cs.princeton.edu/java/97data/FFT.java.html
and complex from
http://introcs.cs.princeton.edu/java/97data/Complex.java.html
audioRec.startRecording();
audioRec.read(bufferByte, 0,bufferSize);
for(int i=0;i<bufferSize;i++){
bufferDouble[i]=(double)bufferByte[i];
}
Complex[] fftArray = new Complex[bufferSize];
for(int i=0;i<bufferSize;i++){
fftArray[i]=new Complex(bufferDouble[i],0);
}
FFT.fft(fftArray);
double[] magnitude=new double[bufferSize];
for(int i=0;i<bufferSize;i++){
magnitude[i] = Math.sqrt((fftArray[i].re()*fftArray[i].re()) + (fftArray[i].im()*fftArray[i].im()));
}
double max = 0.0;
int index = -1;
for(int j=0;j<bufferSize;j++){
if(max < magnitude[j]){
max = magnitude[j];
index = j;
}
}
final int peak=index * sampleRate/bufferSize;
Log.v(TAG2, "Peak Frequency = " + index * sampleRate/bufferSize);
handler.post(new Runnable() {
public void run() {
textView.append("---"+peak+"---");
}
});
i'm getting values like 21000,18976,40222,30283 etc...
Please help me.....
Thank you..
Your source code is almost fine. The only problem is that you search for the peaks through the full spectrum, i.e. from 0 via Fs/2 to Fs.
For any real-valued input signal (which you have) the spectrum between Fs/2 and Fs (=sample frequency) is an exact mirror of the spectrum between 0 and Fs/2 (I found this nice background explanation). Thus, for each frequency there exist two peaks with almost identical amplitude. I'm writing 'almost' because due to limited machine precision they are not necessarily exactly identical. So, you randomly find the peak in the first half of the spectrum which contains the frequencies below the Nyquist frequency (=Fs/2) or in the second half of the spectrum with the frequencies above the Nyquist frequency.
If you want to correct the mistake yourself, stop reading here. Otherwise continue:
Just replace
for(int j=0;j<bufferSize;j++){
with
for(int j=0;j<=bufferSize/2;j++){
in the source code you presented.
P.S.: Typically, it is better to apply a window function to the analysis buffer (e.g. a Hamming window) but for your application of peak picking it won't change results very much.
I tried to implement Neural Network backpropagation using JAVA, I already code it, but the result is unsatifying. the error is decreasing too slow. Below are the example of train result:
epoch:1 current error:0.5051166876846451
epoch:2 current error:0.4982484527652138
epoch:3 current error:0.4965995467118879
epoch:4 current error:0.49585659139683363
epoch:5 current error:0.4953426236386938
epoch:6 current error:0.4948766985413233
epoch:7 current error:0.49441754405152294
epoch:8 current error:0.4939551661406868
epoch:9 current error:0.49348601614718984
epoch:10 current error:0.4930078119902486
epoch:11 current error:0.49251846766886453
Based on this I started to doubt my code and its algorithm. The activation function used are sigmoid. Below are The sample code of the training.
public void learning(int epoch,double learningRateTemp,double desiredErrorTemp,DataSet ds,double momentum){
int processEpoch=0;
double sumSquaredError=0;
DataSetRow dsr;
Connector conTemp;
double sumError=0;
double errorInformation=0;
double activationValue;
double partialDerivative;
do{
processEpoch++;
sumSquaredError=0;
System.out.println("epoch:"+processEpoch);
//data training set
for(int a=0;a<ds.countRows();a++){
dsr=ds.getSpecificRow(a);
sumError=0;
double[]input=dsr.getInput();
double[]output=dsr.getdesiredOutput();
double sumDeltaInput=0;
double weightTempValue=0;
//forward calculation
this.forwardCalculation(input);
//backpropagateofError
//for output unit
for(int k=0;k<NeuralLayers[totalLayer-1].getTotalNode();k++){
activationValue=NeuralLayers[totalLayer-1].getNeuron(k).getValue();
partialDerivative=(activationValue)*(1-activationValue);
Neuron Temp=NeuralLayers[totalLayer-1].getNeuron(k);
errorInformation=(output[k]-Temp.getValue())*partialDerivative;
Temp.SetErrorInformationTerm(errorInformation);
sumError+=Math.pow((output[k]-Temp.getValue()),2);
NeuralLayers[totalLayer-1].setNeuron(k, Temp);
}
//end of output unit
//for hidden Unit
for(int l=totalLayer-2;l>0;l--){
for(int j=1;j<NeuralLayers[l].getTotalNode();j++){
sumDeltaInput=0;
for(int k=0;k<NeuralLayers[l+1].getTotalNode();k++){
conTemp=NeuralLayers[l+1].getConnector(k, j);
if(conTemp.getStatusFrom()==false){
weightTempValue=conTemp.getWeight().getValue();
sumDeltaInput+=(NeuralLayers[l+1].getNeuron(k).GetErrorInformationTerm()*weightTempValue);
}
}
activationValue=NeuralLayers[l].getNeuron(j).getValue();
partialDerivative=(activationValue)*(1-activationValue);
errorInformation= sumDeltaInput*partialDerivative;
Neuron neuTemp=NeuralLayers[l].getNeuron(j);
neuTemp.SetErrorInformationTerm(errorInformation);
NeuralLayers[l].setNeuron(j, neuTemp);
}
}
updateWeight(learningRateTemp,momentum);
sumSquaredError+=sumError;
}
sumSquaredError/=(double)(ds.countRows()*NeuralLayers[totalLayer-1].getTotalNode());
sumSquaredError=Math.sqrt(sumSquaredError);
System.out.println("current error:"+sumSquaredError);
} while(processEpoch<epoch && sumSquaredError>desiredErrorTemp);
}
}
for the forward calculation
private void forwardCalculation(double[] inputValue){
Connector Contemp;
double SumNodeWeight=0;
int start=1;
int count=0;
setNodeValue(inputValue,0);
do{
count++;
if("output".equals(NeuralLayers[count].statusLayer))
start=0;
else start=1;
//get sum of all input
for(int j=start;j<NeuralLayers[count].getTotalNode();j++){
for(int i=0;i<NeuralLayers[count].sizeConnector(j);i++){
Contemp=NeuralLayers[count].getConnector(j, i);
SumNodeWeight+=Contemp.getCombinedweightInput();
}
SumNodeWeight=(1/(1+Math.exp(-SumNodeWeight)));
NeuralLayers[count].setNeuronValue(j, SumNodeWeight);
SumNodeWeight=0;
}
}while(!"output".equals(NeuralLayers[count].statusLayer));
}
and to update the weights
private void updateWeight(double learningRateTemp,double momentum){
double newWeight;
double errorInformation;
Connector conTemp;
for(int LayerPosition=totalLayer-1;LayerPosition>0;LayerPosition--){
for(int node=1;node<NeuralLayers[LayerPosition].getTotalNode();node++){
errorInformation=NeuralLayers[LayerPosition].getNeuron(node).GetErrorInformationTerm();
//for bias weight
newWeight=learningRateTemp*errorInformation;
conTemp=NeuralLayers[LayerPosition].getConnector(node, 0);
conTemp.updateWeight(newWeight,false,0);
NeuralLayers[LayerPosition].updateConnector(conTemp, node, 0);
/////////////////////
//for other node weight
for(int From=1;From<NeuralLayers[LayerPosition].sizeConnector(node);From++){
conTemp=NeuralLayers[LayerPosition].getConnector(node, From);
double weightCorrection=learningRateTemp*errorInformation*NeuralLayers[LayerPosition-1].getNeuron(From).getValue();
conTemp.updateWeight(weightCorrection,true,momentum);
NeuralLayers[LayerPosition].updateConnector(conTemp,node,From);
}
}
}
}
am I on the right Track? I already searched for the bugs in few days, and it still nothing. Does my formula to calculate the error is correct? thank you very much!
Well I'm not any kind of expert on this, nor Java programming, but It might be affecting, you put you variable sumError declared as 0 at the beggining, then you add the error from the outputs, and then in the for cycle of the hidden layers it appears again added to sumSquaredError variable, but if you are going to calc the error of training, why is it inside the "hidden layer cucle"?
for(int l=totalLayer-2;l>0;l--){
for(int j=1;j<NeuralLayers[l].getTotalNode();j++){
}
updateWeight(learningRateTemp,momentum);
sumSquaredError+=sumError;
}
Shouldn't it be outside?
I´ll make reference to the pseudocode of someone who answered me before.
link
Hope this helps!