java - tipos - tomar el promedio de cada índice en un mapa doble
tipos de html (1)
Quiero implementar el algoritmo de perceptrón promediado, de acuerdo con esta descripción (página 48, completo con psuedocode).
Creo que estoy bastante cerca, pero estoy teniendo problemas para tratar de descubrir el último paso en el que necesito calcular el promedio de los pesos calculados durante cada iteración para cada índice en particular, y luego asignar ese valor a una matriz final de pesas ¿Cómo implementaría eso?
La estructura del hashmap es int
que es el número de iteraciones, y luego una matriz de double[]
con los pesos para esa iteración. así que supongo que la salida sería algo así como
For all the hashmap keys
for the length of the hashmap value at this key index
...something
Entonces, si cada iteración, el primer peso fue 2
, 4
,, 3
, quiero asignar el peso de 3
a la matriz double[]
final double[]
para ese índice, y así sucesivamente para todas las instancias.
A continuación se muestra el código pertinente. El código completo está aquí en mi GitHub en caso de que quiera verificarlo.
//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;
}
aquí está la parte que mencioné arriba
//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
}
Creo que algo como esto funcionaría:
//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 ];
}
Pero luego, debe hacer un término para dividir por el número de iteraciones al final, supongo
al igual que si la clave está al final de la clave, no hay iteraciones más grandes, si ese es el caso, luego divida por eso, algo así.
¿tal vez esto?
//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;
}
}