Discusión sobre el artículo "Neuroredes profundas (Parte V). Optimización bayesiana de los hiperparámetros de las DNN" - página 2

 

Interesantes resultados de la optimización: ¡el error en la muestra de validación fue menor que en la muestra de entrenamiento!

En otras palabras, el modelo entrenado en algunos datos, aprendió a trabajar en otros datos, es decir, extrajo más información de los datos de entrenamiento de la que realmente había - ¿es esto ciencia ficción o aventura...?

Hago un llamamiento al autor - dejar de shtukarstva y falsificación, finalmente escribir un Asesor Experto y mostrar algunos resultados, al menos en demo.

 
revers45:

En otras palabras, el modelo entrenado con unos datos aprendió a funcionar con otros, es decir, extrajo de los datos de entrenamiento más información de la que realmente había... ¿es esto ciencia ficción o aventura?

Todos los modelos se entrenaron en la parcela de entrenamiento, es decir, intentaron minimizar el error en la parcela de entrenamiento, pero al final la selección se hizo en la parcela de prueba, y si el modelo no encontraba un patrón en los datos, los resultados habrían sido muy malos en la parcela de entrenamiento o en la parcela posterior a la parcela de prueba. Pero tal y como mostraron los resultados tanto allí como allí no son muy diferentes de la parcela de prueba en la que se hizo la selección.
Es decir, el NS no aprendió del otro, sino que encontró patrones comunes en ambos conjuntos de datos.
Si los resultados fueran menos estables, entonces la selección en el gráfico de prueba (sin tener en cuenta el error del entrenador) podría haber llevado a ajustarse a él. En este caso no lo hizo, pero en otros datos (si no se encontraron patrones) podría hacerlo. Y entonces sería mejor buscar un equilibrio entre errores como Err = (ErrLeran * 0,37 + ErrValid * 0,63)

 
elibrarius:

Hola, Vladimir,

No entiendo muy bien por qué tu NS se entrena con datos de entrenamiento y su evaluación se hace con datos de prueba (si no me equivoco los usas como validación).

¿No resultaría esto en un ajuste a la gráfica de prueba, es decir, se elegirá el modelo que mejor funcionó en la gráfica de prueba?
También hay que tener en cuenta que la parcela de prueba es bastante pequeña y se puede ajustar a uno de los patrones temporales, que puede dejar de funcionar muy rápidamente.
Tal vez sea mejor estimar sobre la parcela de entrenamiento, o sobre la suma de parcelas, o como en Darch, (con los datos de validación presentados) sobre Err = (ErrLeran * 0.37 + ErrValid * 0.63) - estos coeficientes son por defecto, pero se pueden cambiar.

Hay muchas opciones y no está claro cuál es la mejor. Tus argumentos a favor del test plot son interesantes.

Buenas tardes.

Seamos más concretos. El conjunto de datos X consta de 4 subconjuntos preptrain = 4001, train = 1000, test = 500 y test1= 100 barras. Para el preentrenamiento utilizamos el conjunto de entrenamiento - pretrain, el conjunto de validación - train.

#  SRBM + upper Layer (backpropagation)
 pretrainSRBM_topLayer <- function(Ln, fact1, fact2, dr1, dr2, Lr.rbm, Lr.top) #  SRBM + upper Layer (backpropagation)
  {
    darch( x = X$pretrain$x, y = X$pretrain$y,
          xValid = X$train$x, 
          yValid = X$train$y,
          #=====constant======================
......................................................

Para el ajuste fino, se utiliza el conjunto de preentrenamiento como conjunto de entrenamiento y el conjunto de validación para los primeros 250 compases del conjunto de prueba.

fineTuneRP <- function(Ln, fact1, fact2, dr1, dr2, Dnn) #  rpropagation
  {
    darch( x = X$train$x, y = X$train$y,
           #xValid = X$test$x, yValid = X$test$y,
           xValid = X$test$x %>% head(250), 
           yValid = X$test$y %>% head(250),
           #=====constant========
................................................

Por lo tanto, para determinar la calidad final, utilizamos los últimos 250 compases del conjunto de prueba como conjunto de prueba. código

#---SRBM + upperLayer + RP----
  fitnes4.DNN <- function(n1, n2, fact1, fact2, dr1, dr2, Lr.rbm, Lr.top)
  {
    Ln <- c(0, 2*n1, 2*n2, 0)
    #--
     pretrainSRBM_topLayer(Ln, fact1, fact2, dr1, dr2, Lr.rbm, Lr.top) -> Dnn
    fineTuneRP(Ln, fact1, fact2, dr1, dr2, Dnn) -> Dnn
    predict(Dnn, newdata = X$test$x %>% tail(250) , type = "class") -> Ypred
    yTest <- X$test$y[ ,1] %>% tail(250)
    #numIncorrect <- sum(Ypred != yTest)
    #Score <- 1 - round(numIncorrect/nrow(xTest), 2)
    Score <- Evaluate(actual = yTest, predicted = Ypred)$Metrics$F1 %>%
      mean() 
    return(list(Score = Score, Pred = Ypred)
  }

No veo ninguna contradicción. ¿Está de acuerdo?

Suerte

 
elibrarius:

Todos los modelos se entrenaron en la parcela de entrenamiento, es decir, intentaron minimizar el error en esta parcela, pero al final la selección se hizo en la parcela de prueba, y si el modelo no encontraba un patrón en los datos, los resultados serían muy malos en la parcela de entrenamiento o en la parcela posterior a la de prueba. Pero como mostraron los resultados tanto allí como allí no son muy diferentes de la parcela de prueba en la que se hizo la selección.
Es decir, el NS no aprendió del otro, sino que encontró patrones comunes en ambos conjuntos de datos.
Si los resultados fueran menos estables, entonces la selección en el gráfico de prueba (sin tener en cuenta el error del entrenador) podría haber llevado a ajustarse a él. En este caso no lo hizo, pero en otros datos (si no se encontraron patrones) podría hacerlo. Y entonces sería mejor buscar un equilibrio entre errores como Err = (ErrLeran * 0,37 + ErrValid * 0,63).

En cualquier caso, las regularidades generales en el gráfico de entrenamiento no deberían ser menores que en el gráfico de prueba, ya que se encontraron allí junto con todas las demás, y por lo tanto el NS no debería funcionar peor en él.

En mi opinión, es obvio, así como el hecho de que los conocimientos del profesor no deberían ser menores que los del alumno, aunque el autor del artículo, aparentemente, intenta refutarlo, porque escribió en los comentarios que él no es científico ni programador, pero persiste en enseñarnos a programar redes neuronales.

Por supuesto, ya ha publicado un montón de código R, pero me gustaría ver los resultados adecuados, y lo más importante, entender cuántos artículos más escribirá hasta que aparezca al menos un Asesor Experto normal.

 
Vladimir Perervenko:

Buenas tardes.

Aclaremos. El conjunto de datos X consta de 4 subconjuntos preptrain = 4001, train = 1000, test = 500 y test1= 100 barras. Para el preentrenamiento utilizamos el conjunto de entrenamiento - pretrain, conjunto de validación - train.

Para el ajuste fino, el conjunto preentrenamiento se utiliza como conjunto de entrenamiento y el conjunto de validación se utiliza para los 250 primeros compases del conjunto de prueba.

Por lo tanto, para determinar la calidad final, utilizamos los últimos 250 compases del conjunto de prueba como conjunto de prueba. código

No veo ninguna contradicción. ¿Está de acuerdo?

Suerte

Técnicamente todo está bien hecho, esa no es la cuestión.
Creo que 250 bar no es suficiente para evaluar el modelo, por eso me preguntaba por qué sólo se selecciona esta sección.
Sí, funciona en un caso particular (obtuviste buenos resultados en todos los sitios), pero creo que no es universal.

Al fin y al cabo, podría haber datos que no fueran tan buenos. Por ejemplo, el modelo podría estar entrenado para un 40% de error en el gráfico de entrenamiento y, por pura casualidad, mostrar un 30% en el gráfico de prueba. Y el segundo modelo, digamos, entrenado al 35% en ambos gráficos. Obviamente, el segundo es mejor. Pero si se elige sólo el gráfico de prueba, se seleccionará el primero. Para comparar, existen las siguientes opciones de evaluación del modelo:
evaluación sólo en la parcela de entrenamiento,
o en la suma de todas las parcelas,
o como en Darch, (con datos de validación presentados) en Err = (ErrLeran * 0.37 + ErrValid * 0.63) - estos coeficientes son por defecto, pero pueden ser cambiados.

La última variante es la más interesante, porque tiene en cuenta ambos errores, pero con un mayor peso del apartado de validación.
En principio, se puede ampliar la fórmula, por ejemplo, a Err = (ErrLeran * 0,25 + ErrValid * 0,35 + ErrTest * 0,4).

Tal vez incluso por deltas de error es necesario hacer la selección, por ejemplo, si ErrLeran y ErrTest difieren en más del 5% - entonces rechazar tal modelo. Y hacer una selección entre los restantes.

He hecho un experimento.

Aquí están algunos resultados de 30 sesiones de entrenamiento: (el modelo no es el mismo que el original, todo es perfecto en él, así que quité el pre-entrenamiento para que hubiera malos resultados)

Decodificación: V1 = 1-ErrLearn; V2= 1-ErrOOC; Valor = 1 - (ErrLeran * 0.37 + ErrOOC * 0.63); en el OOS he pegado los datos de Valid y Test.

Valor V1 V2

0.5712 0.4988 0.6138 - OOS es bueno, pero aleatorio, ya que Learn = 50%.

0,5002 0,5047 0,4975 - esto era más común

0.6719 0.6911 0.6606 - y así un par de veces. Ordenar por Valor = 1 - (ErrLeran * 0.37 + ErrOOC * 0.63) hace que estos patrones suban

 
revers45:
Por supuesto, ya ha publicado una gran cantidad de código R, pero me gustaría ver los resultados adecuados, y lo más importante, para entender cuántos artículos más va a escribir hasta que haya al menos un EA normal.

En uno de los artículos había un Asesor Experto, lo reescribí en un par de días para la nueva versión de Darch - técnicamente todo funciona perfectamente. El Asesor Experto es simple - leer OHLC y lanzarlo en R y ejecutar la función de cálculo en R. Al final, después de haber recibido órdenes de la NS, envía órdenes de comercio al servidor. Eso es todo. El resto - trailing, stops, MM - a su gusto.
Lo más difícil es exactamente lo que se describe en los artículos - para encontrar buenos datos y entrenar adecuadamente el NS en él. Vladimir muestra todo tipo de variantes de modelos, ensembles, optimizaciones, selección y procesamiento de predictores..., no puedo seguirle el ritmo)))

 

¿Qué opinas,
tal vez deberíamos excluir de la enumeración de hiperparámetros las variantes con el número de neuronas en capas donde n2 > n1 ?

Por ejemplo la red 10 - 20 - 100 - 2 o 10 - 8 - 100 - 2

Si n2 > n1, obtendrá compresión a n1, luego descompresión a n2 y luego compresión de nuevo a 1 o 2 neuronas de la capa de salida. Si todavía tenemos 2 neuronas al final, entonces la descompresión en el medio no debería dar ninguna perimutación después de comprimir los datos en la capa n1. Pero consumirá mucho tiempo calcular las variantes obviamente peores.
Creo que se puede hacer en la función de aptitud de la siguiente manera: n1 es el número de neuronas, y n2 es el % de n1, luego redondear hacia arriba y *2 para maxout.

Actualización:
lo hice yo mismo, espero que el poder computacional se gastará de manera más eficiente.
 
elibrarius:

¿Qué opinas,
tal vez deberíamos excluir de la enumeración de hiperparámetros las variantes con el número de neuronas en capas donde n2 > n1 ?

Por ejemplo la red 10 - 20 - 100 - 2 o 10 - 8 - 100 - 2

Si n2 > n1, obtendrá compresión a n1, luego descompresión a n2 y luego compresión de nuevo a 1 o 2 neuronas de la capa de salida. Si todavía tenemos 2 neuronas al final, entonces la descompresión en el medio no debería dar ninguna perimutación después de comprimir los datos en la capa n1. Pero consumirá mucho tiempo calcular las variantes obviamente peores.
Creo que se puede hacer en la función de aptitud de la siguiente manera: n1 debe ser enumerado como el número de neuronas, y n2 como % de n1, luego redondeado y *2 para maxout.

Saludos.

De mis largos experimentos con los parámetros sólo unas pocas peculiaridades notado:

- a menudo mejores resultados con hecho = 2

- o cuando ambas capas ocultas tienen la misma función de activación.

No limité la proporción de neuronas en las capas ocultas. Las proporciones no óptimas salen de consideración muy rápidamente. Pero puedes probar esta idea. Puede que encuentre tiempo y compruebe la optimización con rgenoud.

Suerte

 
Vladimir Perervenko:

No he limitado la proporción de neuronas en las capas ocultas. Las proporciones no óptimas dejan de tenerse en cuenta muy rápidamente. Pero se puede probar esta idea. Puede que encuentre tiempo y compruebe la optimización con rgenoud.

He hecho que la capa siguiente se cuente en % de la anterior. Pero no hay ningún deseo de comparar en particular. Puramente teóricamente espero tener razón, que la descompresión dentro de la red no le dará nueva información, después de la compresión en las capas anteriores.

Probé la genética en GA:ga. Corrió NS 200-300 veces para el cálculo. Eso es mucho. Y no hay ninguna mejora en los resultados.

Aunque para la optimización bayesiana supongo que necesitamos más pasadas, no 20-30, pero tal vez hasta 100. Porque a menudo ocurre que el mejor resultado es una de las 10 variantes iniciales aleatorias, y en las siguientes 10-20 pasadas del optimizador no se encuentra nada mejor. Puede que durante 100 pasadas haya mejoras....

Vladimir Perervenko:

- a menudo los mejores resultados con hecho = 2

- o cuando ambas capas ocultas tienen la misma función de activación

Esto es diferente para mí. Relu es a menudo bueno.

 
elibrarius:

He hecho que la siguiente capa cuente como un % de la anterior. Pero no hay ningún deseo de compararlo. Puramente teóricamente espero tener razón, que la descompresión dentro de la red no le dará nueva información después de la compresión en las capas anteriores.

Probé la genética en GA:ga. Corrió NS 200-300 veces para el cálculo. Eso es mucho. Y no hay ninguna mejora en los resultados.

Aunque para la optimización bayesiana supongo que necesitamos más pasadas, no 20-30, pero tal vez hasta 100. Porque a menudo ocurre que el mejor resultado es una de las 10 variantes iniciales aleatorias, y en las siguientes 10-20 pasadas del optimizador no se encuentra nada mejor. Tal vez para 100 pases habrá mejoras....

Ahí es donde varía para mí. Relu es a menudo bueno.

Genetics tampoco me ha encontrado las mejores opciones.

Para Bayesiano tienes que jugar no sólo con el número de pasadas sino también con el número de puntos. Hay que buscar una opción más rápida. Esto es muy tedioso de tratar.

Suerte

PD. ¿No estás cambiando a TensorFlow? Es sólo un nivel superior.