Reputation: 2889
I want to implement the averaged perceptron algorithm, in accordance with this description (page 48, complete with psuedocode).
I think I'm pretty close, but I'm having trouble trying to figure out the last step wherein I need to compute the average of the weights calculated during every iteration for each particular index, and then assign that value to a final array of weights. How would I implement that?
The structure of the hashmap is int
which is the number of iterations, and then an array of double[]
with the weights for that iteration. so i guess the output would be something like
For all the hashmap keys
for the length of the hashmap value at this key index
...something
So if each iteration the first weight was 2
, 4
, ,3
, I want to assign the weight of 3
to the final double[]
array for that index, and so on for all the instances.
Below is the pertinent code. The full code is here on my GitHub in case you'd like to check it out.
//store weights to be averaged.
Map<Integer,double[]> cached_weights = new HashMap<Integer,double[]>();
final int globoDictSize = globoDict.size(); // number of features
// weights total 32 (31 for input variables and one for bias)
double[] weights = new double[globoDictSize + 1];
for (int i = 0; i < weights.length; i++)
{
//weights[i] = Math.floor(Math.random() * 10000) / 10000;
//weights[i] = randomNumber(0,1);
weights[i] = 0.0;
}
int inputSize = trainingPerceptronInput.size();
double[] outputs = new double[inputSize];
final double[][] a = Prcptrn_InitOutpt.initializeOutput(trainingPerceptronInput, globoDictSize, outputs, LABEL);
double globalError;
int iteration = 0;
do
{
iteration++;
globalError = 0;
// loop through all instances (complete one epoch)
for (int p = 0; p < inputSize; p++)
{
// calculate predicted class
double output = Prcptrn_CalcOutpt.calculateOutput(THETA, weights, a, p);
// difference between predicted and actual class values
//always either zero or one
double localError = outputs[p] - output;
int i;
for (i = 0; i < a.length; i++)
{
weights[i] += LEARNING_RATE * localError * a[i][p];
}
weights[i] += LEARNING_RATE * localError;
// summation of squared error (error value for all instances)
globalError += localError * localError;
}
here's the part I was mentioning above
//calc averages
for (Entry<Integer, double[]> entry : cached_weights.entrySet())
{
int key = entry.getKey();
double[] value = entry.getValue();
// ...
}
/* Root Mean Squared Error */
//System.out.println("Iteration " + iteration + " : RMSE = " + Math.sqrt(globalError / inputSize));
}
while (globalError != 0 && iteration <= MAX_ITER);
//calc averages
Iterator it = cached_weights.entrySet().iterator();
while( it.hasNext() )
{
Map.Entry pair = (Map.Entry)it.next();
System.out.println(pair.getKey() + " = " + pair.getValue());
it.remove(); // avoids a ConcurrentModificationException
}
Upvotes: 0
Views: 156
Reputation:
I guess something like this would work:
//calc averages
for (Entry<Integer, double[]> entry : cached_weights.entrySet())
{
int key = entry.getKey();
double[] value = entry.getValue();
AVERAGED_WEIGHTS[ key - 1 ] += value[ key - 1 ];
}
But then, must make some term for dividing by the # of iterations at the end I guess
like if key is at the end of the key, there's no more bigger iterations, if that is the case, then divide by it, something like that.
maybe this?
//calc averages
for (Entry<Integer, double[]> entry : cached_weights.entrySet())
{
int key = entry.getKey();
double[] value = entry.getValue();
AVERAGED_WEIGHTS[ key - 1 ] += value[ key - 1 ];
if (key == iteration)
{
AVERAGED_WEIGHTS[ key - 1 ] /= key;
}
}
Upvotes: 1