franyack / IMachineApp

This Android application uses the CIEngine module to automatically manage the photos and images on the device. Then you will be able to manage the result according to your criteria, by moving or erasing images as you want.
1 stars 0 forks source link

Duda sobre la normalización de Matriz clase MCLDenseEJML.java #13

Closed franyack closed 6 years ago

franyack commented 6 years ago

Buenas! A raíz de estar haciendo pruebas en mi celular, cuando voy aumentando la cantidad de imágenes a procesar, siempre uno de los cluster me queda con muchísimas mas imágenes que no tienen mucha relación unas con otra, por ejemplo: imágenes tomadas al monitor de la pc con fotos de un paisaje. Revisando un poco el código que me paso Lea no entiendo una parte en la función que normaliza la matriz:

public void normalize(DMatrixRMaj M) {
        // TODO: similar method that returns a matrix, avoiding modifications on the given one
        // TODO: handle division by zero when having rows with all zeros
        Equation eq = new Equation();
        eq.alias(M, "M");

        for(int i=0; i < M.numRows; i++){
            eq.alias(i, "i");
            eq.process("M(i,:) = M(i,:) / sum(M(i,:))");

        }

    }

Especialmente acá: eq.process("M(i,:) = M(i,:) / sum(M(i,:))"); No se estaría dividiendo todos los elementos de la fila i por la suma de los elementos de la columna i?

Quizás yo no entiendo bien la manera en que opera ese proceso y es simplemente un error de interpretación mía! Intenté resolverlo de esta manera:

public void normalize(DMatrixRMaj M) {
        double suma=0;
        Equation eq = new Equation();
        eq.alias(M, "M");
        eq.alias(suma,"s");

        for (int i=0;i<M.numRows;i++) {
            for (int j = 0; j < M.numCols; j++) {
                eq.alias(i, "i");
                eq.alias(j, "j");
                eq.process("s = s + M(i,j)");
            }
        }
        for(int i=0; i < M.numRows; i++){
            eq.alias(i, "i");
//          eq.process("M(i,:) = M(i,:) / sum(M(i,:))");
            eq.process("M(i,:) = M(i,:) / s");
        }
    }

Pero no funciona, por algún motivo casi todos (solo quedan uno o dos valores dependiendo del tamaño) los valores de la matriz se vuelven 0

leferrad commented 6 years ago

La idea ahí es normalizar la matriz por filas, entonces por cada fila i de la matriz, cada uno de sus elementos es dividido por la suma de todos los elementos en esa fila. Como resultado, se puede chequear que al sumar todos los elementos de cada fila en la matriz resulta en un vector de 1s. La formula para lograr eso parece correcta, pero lo que me entra en duda al respecto es si habría que normalizar por filas o por columnas. Puede ser que sea el segundo caso, ya que luego el clustering se hace por columnas, pero la verdad que no estoy seguro y debería chequearlo bien. Mientras, si querés hacé la prueba, y sólo cambiá la linea con la fórmula por esta: eq.process("M(:,i) = M(:,i) / sum(M(:,i))");.

Otra razón posible, es que las afinidades entre elementos sean realmente chicas, por lo que al aplicar el prune se anulen quizás, y por ende no se logra discriminación al hacer el clustering. Entonces, podrías decir a partir de cuántas imágenes ves el problema, y tratar de pegar una matriz de entrada de ejemplo?

ldvignolo commented 6 years ago

Buenas, La normalización, según el caso, puede convenir por filas o por columnas, ambas formas están bien. En este caso, yo me inclinaría más a hacerlo por columnas pero lo mejor es probar de las dos formas y comparar resultados. Al hacerlo por columnas estás normalizando cada característica según los valores que va tomando esta en todos los ejemplos de la base, en cambio, al hacerlo por filas te asegurás que todos los valores están entre 0 y 1 pero al tener en cuenta distintas características estás normalizando peras con manzanas y además perdés la relación que existía entre el valor de una característica determinada de un ejemplo y de otro. También incluso mejor que normalizar podría ser estandarizar. Saludos!

Dr. Leandro Daniel Vignolo Assistant Professor | Assistant Research Scientist sinc(i), FICH-UNL/CONICET, Santa Fe, Argentina www.sinc.unl.edu.ar | Tel: +54 (342) 4575233 ext 117

2018-05-10 23:39 GMT-03:00 Leandro Ferrado notifications@github.com:

La idea ahí es normalizar la matriz por filas, entonces por cada fila i de la matriz, cada uno de sus elementos es dividido por la suma de todos los elementos en esa fila. Como resultado, se puede chequear que al sumar todos los elementos de cada fila en la matriz resulta en un vector de 1s. La formula para lograr eso parece correcta, pero lo que me entra en duda al respecto es si habría que normalizar por filas o por columnas. Puede ser que sea el segundo caso, ya que luego el clustering se hace por columnas, pero la verdad que no estoy seguro y debería chequearlo bien. Mientras, si querés hacé la prueba, y sólo cambiá la linea con la fórmula por esta: eq.process("M(:,i) = M(:,i) / sum(M(:,i))");.

Otra razón posible, es que las afinidades entre elementos sean realmente chicas, por lo que al aplicar el prune se anulen quizás, y por ende no se logra discriminación al hacer el clustering. Entonces, podrías decir a partir de cuántas imágenes ves el problema, y tratar de pegar una matriz de entrada de ejemplo?

— You are receiving this because you are subscribed to this thread. Reply to this email directly, view it on GitHub https://github.com/franyack/IMachineApp/issues/13#issuecomment-388242610, or mute the thread https://github.com/notifications/unsubscribe-auth/APJ-G5909et5Lz2tJ7cyKFakjMQnWAEmks5txPnHgaJpZM4T6rma .

franyack commented 6 years ago

Buenas! Estuve haciendo pruebas, sobre todo cambiando el size de las imágenes a procesar, también cambiando el código como me dijiste que pruebe Lea, pero no obtengo cambios significativos en los resultados. A partir de las 50 imágenes, empiezo a notar como se pierde el sentido del agrupamiento. Fui aumentando de diez en diez y, si bien con 30 o 40 imágenes quedan algunos clusters muy chicos (1 o 2 imágenes), los cuales deberemos pensar que hacer con ellos, los clusters grandes para mí no arrojan malos resultados (totalmente subjetivo). En el siguiente link se encuentra un archivo de texto y uno de excel con la matriz de entrada al algoritmo de cluster.

https://drive.google.com/open?id=1iMmycolWbhj7sG-g9huGBB8mtP8r4MSp

leferrad commented 6 years ago

Por las dudas probaste cambiar los parámetros del clustering? En tal caso, ya no es problema de la implementación quizás sino que es parte de la configuración del experimento. En un momento teníamos que llegar a ese punto en el cual se determina la mejor config para una entrada dada, así que fijate si cambiando estos valores se llega a un clustering "mejor" en terminos subjetivos. En tal caso abrimos otro issue para discutir acerca de la config ideal

leferrad commented 6 years ago

Otra cosa a probar es tocar el parámetro de pruning bajándolo, o bien desactivarlo (igual a 0.0) para ver si no es que está removiendo afinidades importantes.

leferrad commented 6 years ago

Revisando un poco el código, veo que al armar la matriz de afinidad se están filtrando las correlaciones menores a 0.65 (https://github.com/franyack/IMachineApp/blob/manageActivities/app/src/main/java/com/example/fran/imachineapp/Working.java#L349) y por ello la matriz de afinidad de entrada queda tan sparse y con valores altos. Deberíamos variar este valor de threshold como para entender también cómo afecta al clustering. A su vez, no veo nada raro en la normalización de las matrices aún, por lo cual recomiendo cerrar este issue por el momento y seguir en otro la discusión de cómo manejar los parámetros para que el clustering cambie (que de hecho es el problema inicial de este issue)

franyack commented 6 years ago

Se cierra este issue y se sigue en #17 .