¿Es posible utilizar la correlación de clasificación como función de costo en TensorFlow?

Estoy trabajando con datos extremadamente ruidosos ocasionalmente salpicados de valores atípicos, por lo que confío principalmente en la correlación como medida de precisión en mi NN.

¿Es posible usar explícitamente algo como la correlación de rango (el coeficiente de correlación de Spearman) como mi función de costo? Hasta ahora, me he basado principalmente en MSE como un proxy para la correlación.

Tengo tres grandes obstáculos en este momento:

1) La noción de clasificación se vuelve mucho más difusa con los mini lotes.

2) ¿Cómo realiza dinámicamente los rankings? ¿TensorFlow no tendrá un error de gradiente / no podrá hacer un seguimiento de cómo un cambio en un peso / sesgo afecta el costo?

3) ¿Cómo determina el tamaño de los tensores que está viendo durante el tiempo de ejecución?

Por ejemplo, el código que aparece a continuación es lo que me gustaría hacer aproximadamente si solo utilizara la correlación. En la práctica, la longitud debe pasarse en lugar de determinarse en el tiempo de ejecución.

length = tf.shape(x)[1] ## Example code. This line not meant to work. original_loss = -1 * length * tf.reduce_sum(tf.mul(x, y)) - (tf.reduce_sum(x) * tf.reduce_sum(y)) divisor = tf.sqrt( (length * tf.reduce_sum(tf.square(x)) - tf.square(tf.reduce_sum(x))) * (length * tf.reduce_sum(tf.square(y)) - tf.square(tf.reduce_sum(y))) ) original_loss = tf.truediv(original_loss, divisor) 

Aquí está el código para la correlación de Spearman:

 predictions_rank = tf.nn.top_k(predictions_batch, k=samples, sorted=True, name='prediction_rank').indices real_rank = tf.nn.top_k(real_outputs_batch, k=samples, sorted=True, name='real_rank').indices rank_diffs = predictions_rank - real_rank rank_diffs_squared_sum = tf.reduce_sum(rank_diffs * rank_diffs) six = tf.constant(6) one = tf.constant(1.0) numerator = tf.cast(six * rank_diffs_squared_sum, dtype=tf.float32) divider = tf.cast(samples * samples * samples - samples, dtype=tf.float32) spearman_batch = one - numerator / divider 

El problema con la correlación de Spearman es que necesitas usar un algoritmo de clasificación ( top_k en mi código). Y no hay manera de traducirlo a un valor de pérdida. No hay derivada de un algoritmo de clasificación. Puedes usar una correlación normal, pero creo que no hay una diferencia matemática para usar el error cuadrático medio.

Estoy trabajando en esto ahora mismo para imágenes. Lo que he leído en artículos que usan para agregar la clasificación a la función de pérdida es comparar 2 o 3 imágenes (donde digo imágenes, puedes decir cualquier cosa que quieras clasificar).

Comparando dos elementos:

introduzca la descripción de la imagen aquí

introduzca la descripción de la imagen aquí

Donde N es el número total de elementos y α un valor de margen. Obtuve esta ecuación de Photo Aesthetics Ranking Network con atributos y adaptación de contenido

También puede usar las pérdidas con 3 elementos en los que compara dos de ellos con una clasificación similar con otro con uno diferente:

introduzca la descripción de la imagen aquí

Pero en esta ecuación también debe agregar la dirección del ranking, más detalles en ¿Le gustará a la gente su imagen? . En el caso de este documento, utilizan una encoding vectorial en lugar de un valor real, pero también puede hacerlo por un número.

En el caso de las imágenes, la comparación entre imágenes tiene más sentido cuando esas imágenes están relacionadas. Por lo tanto, es una buena idea ejecutar un algoritmo de agrupación en clúster para crear (¿quizás?) 10 agrupaciones, de modo que pueda usar elementos de la misma agrupación para hacer comparaciones en lugar de cosas muy diferentes. Esto ayudará a la red, ya que las entradas están relacionadas de alguna manera y no son completamente diferentes.

Como nota al margen, debe saber qué es más importante para usted, si es el orden de clasificación final o el valor de clasificación. Si es el valor que debe usar con error cuadrático medio, si es el orden de clasificación, puede usar las pérdidas que escribí antes. O incluso puedes combinarlos.

¿Cómo determina el tamaño de los tensores que está viendo durante el tiempo de ejecución?

tf.shape(tensor) devuelve un tensor con la forma. Luego puede usar tf.gather(tensor,index) para obtener el valor que desea.