Discussão do artigo "Redes Neurais Profundas (Parte V). Otimização Bayesiana de hiperparâmetros de uma DNN" - página 2

 

Resultados interessantes da otimização - o erro na amostra de validação foi menor do que na amostra de treinamento!

Em outras palavras, o modelo treinado em alguns dados aprendeu a trabalhar em outros dados, ou seja, extraiu mais informações dos dados de treinamento do que realmente havia - isso é ficção científica ou aventura...?

Faço um apelo ao autor: pare com o shtukarstva e a falsificação, finalmente escreva um Expert Advisor e mostre alguns resultados, pelo menos na demonstração.

 
revers45:

Em outras palavras, o modelo treinado em alguns dados aprendeu a trabalhar em outros dados, ou seja, extraiu mais informações dos dados de treinamento do que realmente havia - isso é ficção científica ou aventura...?

Todos os modelos foram treinados no gráfico de treinamento, ou seja, eles tentaram minimizar o erro no gráfico de treinamento, mas, no final, a seleção foi feita no gráfico de teste e, se o modelo não encontrasse um padrão nos dados, os resultados teriam sido muito ruins no gráfico de treinamento ou no gráfico após o gráfico de teste. Mas, como os resultados mostraram, tanto lá quanto cá, eles não são muito diferentes do gráfico de teste no qual a seleção foi feita.
Ou seja, o NS não aprendeu com o outro, mas encontrou padrões comuns em ambos os conjuntos de dados.
Se os resultados fossem menos estáveis, a seleção no gráfico de teste (sem levar em conta o erro do instrutor) poderia ter levado à adaptação a ele. Nesse caso, isso não aconteceu, mas em outros dados (se nenhum padrão fosse encontrado), poderia. E então seria melhor procurar um equilíbrio entre erros como Err = (ErrLeran * 0,37 + ErrValid * 0,63)

 
elibrarius:

Olá, Vladimir,

Não entendo muito bem por que seu NS é treinado em dados de treinamento e sua avaliação é feita em dados de teste (se não me engano, você os usa como validação).

Nesse caso, você não obterá um ajuste ao gráfico de teste, ou seja, você escolherá o modelo que funcionou melhor no gráfico de teste?
Você também deve levar em conta que o gráfico de teste é bem pequeno e você pode ajustar um dos padrões temporais, o que pode parar de funcionar muito rapidamente.
Talvez seja melhor estimar no gráfico de treinamento, ou na soma dos gráficos, ou como no Darch, (com dados de validação enviados) em Err = (ErrLeran * 0,37 + ErrValid * 0,63) - esses coeficientes são padrão, mas podem ser alterados.

Há muitas opções e não está claro qual é a melhor. Seus argumentos a favor do gráfico de teste são interessantes.

Boa tarde.

Vamos ser mais específicos. O conjunto de dados X consiste em 4 subconjuntos: pré-treinamento = 4001, treinamento = 1000, teste = 500 e teste1 = 100 barras. Para o pré-treinamento, usamos o conjunto de treinamento - pretrain, conjunto de validação - 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 o ajuste fino, o conjunto de pré-treinamento é usado como o conjunto de treinamento e o conjunto de validação é usado para as primeiras 250 barras do conjunto de teste.

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========
................................................

Portanto, para determinar a qualidade final, usamos as últimas 250 barras do conjunto de teste como conjunto de teste. 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)
  }

Não vejo nenhuma contradição. Você concorda?

Boa sorte

 
elibrarius:

Todos os modelos foram treinados no gráfico de treinamento, ou seja, eles tentaram minimizar o erro nesse gráfico, mas, no final, a seleção foi feita no gráfico de teste e, se o modelo não encontrasse um padrão nos dados, os resultados seriam muito ruins no gráfico de treinamento ou no gráfico após o gráfico de teste. Mas, como os resultados mostraram, tanto lá quanto cá, eles não são muito diferentes do gráfico de teste no qual a seleção foi feita.
Ou seja, o NS não aprendeu com o outro, mas encontrou padrões comuns em ambos os conjuntos de dados.
Se os resultados fossem menos estáveis, a seleção no gráfico de teste (sem levar em conta o erro do instrutor) poderia ter levado à adaptação a ele. Nesse caso, isso não aconteceu, mas em outros dados (se nenhum padrão fosse encontrado), poderia. E, nesse caso, seria melhor procurar um equilíbrio entre erros como Err = (ErrLeran * 0,37 + ErrValid * 0,63).

De qualquer forma, as regularidades gerais no gráfico de treinamento não devem ser menores do que no gráfico de teste, uma vez que foram encontradas lá junto com todas as outras e, portanto, o NS não deve funcionar pior nele.

Em minha opinião, isso é óbvio, assim como o conhecimento do professor não deve ser menor do que o do aluno, embora o autor do artigo aparentemente tente refutar isso, pois escreveu nos comentários que não é cientista nem programador, mas persiste em nos ensinar a programar redes neurais.

É claro que ele já publicou muitos códigos R, mas eu gostaria de ver os resultados adequados e, mais importante, saber quantos artigos mais ele escreverá até que apareça pelo menos um Expert Advisor normal.

 
Vladimir Perervenko:

Boa tarde.

Vamos esclarecer. O conjunto de dados X consiste em 4 subconjuntos: pré-treinamento = 4001, treinamento = 1000, teste = 500 e teste1 = 100 barras. Para o pré-treinamento, usamos o conjunto de treinamento - pretrain, conjunto de validação - train.

Para o ajuste fino, o conjunto de pré-treinamento é usado como o conjunto de treinamento e o conjunto de validação são as primeiras 250 barras do conjunto de teste.

Portanto, para determinar a qualidade final, usamos as últimas 250 barras do conjunto de teste como conjunto de teste. código

Não vejo nenhuma contradição. Você concorda?

Boa sorte

Tecnicamente, tudo está bem feito, mas essa não é a questão.
Acho que 250 barras não são suficientes para avaliar o modelo, por isso me perguntei por que apenas essa seção foi selecionada.
Sim, ele funciona em um caso específico (você obteve bons resultados em todos os locais), mas acho que não é universal.

Afinal de contas, pode haver dados que não sejam tão bons. Por exemplo, o modelo poderia ser treinado com 40% de erro no gráfico de treinamento e, por puro acaso, mostrar 30% no gráfico de teste. E o segundo modelo, digamos, treinado para 35% em ambos os gráficos. O segundo é obviamente melhor. Mas ao escolher apenas o gráfico de teste, o primeiro será selecionado. Para comparação, há as seguintes opções de avaliação do modelo:
avaliação somente no gráfico de treinamento,
ou na soma de todos os gráficos,
ou como em Darch, (com dados de validação enviados) em Err = (ErrLeran * 0,37 + ErrValid * 0,63) - esses coeficientes são padrão, mas podem ser alterados.

A última variante é a mais interessante, pois leva em conta os dois erros, mas com um peso maior da seção de validação.
Em princípio, é possível estender a fórmula, por exemplo, para Err = (ErrLeran * 0,25 + ErrValid * 0,35 + ErrTest * 0,4).

Talvez até mesmo por deltas de erro seja necessário fazer uma seleção, por exemplo, se ErrLeran e ErrTest diferirem em mais de 5%, então rejeite esse modelo. E faça uma escolha entre os modelos restantes.

Fiz um experimento.

Aqui estão alguns resultados de 30 sessões de treinamento: (o modelo não é o mesmo que o original, tudo está perfeito nele, então removi o pré-treinamento para que não houvesse resultados ruins)

Decodificação: V1 = 1-ErrLearn; V2= 1-ErrOOC; Valor = 1 - (ErrLeran * 0.37 + ErrOOC * 0,63); no OOS, colei os dados de Valid e Test.

Valor V1 V2

0,5712 0,4988 0,6138 - OOS é bom, mas aleatório, pois Learn = 50%

0,5002 0,5047 0,4975 - isso foi mais comum

0,6719 0,6911 0,6606 - e assim algumas vezes. A classificação por Value = 1 - (ErrLeran * 0,37 + ErrOOC * 0,63) puxa esses padrões para cima

 
revers45:
É claro que ele já publicou muitos códigos R, mas eu gostaria de ver os resultados adequados e, o mais importante, saber quantos artigos mais ele escreverá até que haja pelo menos um EA normal.

Em um dos artigos, havia um Expert Advisor, que reescrevi em alguns dias para a nova versão do Darch - tecnicamente, tudo funciona perfeitamente. O Expert Advisor é simples - leia o OHLC e jogue-o no R e execute a função de cálculo no R. No final, depois de receber comandos do NS, enviar comandos de negociação para o servidor. Isso é tudo. O resto - trailing, stops, MM - fica a seu gosto.
O mais difícil é exatamente o que está descrito nos artigos - encontrar bons dados e treinar adequadamente o NS com eles. Vladimir mostra todos os tipos de variantes de modelos, conjuntos, otimizações, seleção e processamento de preditores..., não consigo acompanhá-lo)))

 

O que você acha,
? Talvez devêssemos excluir da enumeração de hiperparâmetros as variantes com o número de neurônios em camadas em que n2 > n1?

Por exemplo, a rede 10 - 20 - 100 - 2 ou 10 - 8 - 100 - 2

Se n2 > n1, você terá compressão para n1, depois descompressão para n2 e, em seguida, compressão novamente para 1 ou 2 neurônios da camada de saída. Se ainda tivermos 2 neurônios no final, a descompressão no meio não deverá gerar nenhuma perimutação após a compressão dos dados na camada n1. Mas isso consumirá muito tempo para calcular as variantes obviamente piores.
Acho que isso pode ser feito na função de aptidão da seguinte maneira: n1 é o número de neurônios e n2 é a % de n1, depois arredondar para cima e *2 para o máximo.

Atualização:
eu mesmo fiz isso, espero que o poder computacional seja gasto de forma mais eficiente.
 
elibrarius:

O que você acha,
? Talvez devêssemos excluir da enumeração de hiperparâmetros as variantes com o número de neurônios em camadas em que n2 > n1?

Por exemplo, a rede 10 - 20 - 100 - 2 ou 10 - 8 - 100 - 2

Se n2 > n1, você terá compressão para n1, depois descompressão para n2 e, em seguida, compressão novamente para 1 ou 2 neurônios da camada de saída. Se ainda tivermos 2 neurônios no final, a descompressão no meio não deverá gerar nenhuma perimutação após a compressão dos dados na camada n1. Mas isso consumirá muito tempo para calcular as variantes obviamente piores.
Acho que isso pode ser feito na função de aptidão da seguinte maneira: n1 deve ser enumerado como o número de neurônios e n2 como % de n1, depois arredondado e *2 para o máximo.

Saudações.

Em meus longos experimentos com parâmetros, notei apenas algumas peculiaridades:

- geralmente melhores resultados com fato = 2

- ou quando as duas camadas ocultas têm a mesma função de ativação.

Não limitei a proporção de neurônios nas camadas ocultas. As proporções não ideais deixam de ser consideradas muito rapidamente. Mas você pode testar essa ideia. Talvez eu encontre tempo e verifique a otimização com o rgenoud.

Boa sorte

 
Vladimir Perervenko:

Não limitei a proporção de neurônios nas camadas ocultas. As proporções não ideais deixam de ser consideradas muito rapidamente. Mas você pode testar essa ideia. Talvez eu encontre tempo e verifique a otimização com o rgenoud.

Fiz com que a próxima camada fosse contada em % da anterior. Mas não há desejo de comparar particularmente. Teoricamente, espero estar certo de que a descompressão dentro da rede não fornecerá novas informações, após a compressão nas camadas anteriores.

Experimentei a genética no GA:ga. Ele executou o NS 200 a 300 vezes para computação. Isso é muito. E não houve melhora nos resultados.

Embora para a otimização bayesiana eu presuma que precisamos de mais passagens, não 20-30, mas talvez até 100. Porque muitas vezes acontece que o melhor resultado é uma das 10 variantes iniciais aleatórias e, nas próximas 10 a 20 passagens do otimizador, nada melhor é encontrado. Talvez em 100 passagens haja melhorias....

Vladimir Perervenko:

- Frequentemente os melhores resultados com fato = 2

- ou quando as duas camadas ocultas têm a mesma função de ativação

Isso é diferente para mim. O Relu geralmente é bom.

 
elibrarius:

Fiz com que a próxima camada contasse como uma porcentagem da anterior. Mas não há desejo de compará-las. Teoricamente, espero estar certo, pois a descompressão dentro da rede não fornecerá novas informações após a compressão nas camadas anteriores.

Experimentei a genética no GA:ga. Ele executou o NS 200 a 300 vezes para computação. Isso é muito. E não houve melhora nos resultados.

Embora para a otimização bayesiana eu presuma que precisamos de mais passagens, não 20-30, mas talvez até 100. Porque muitas vezes acontece que o melhor resultado é uma das 10 variantes iniciais aleatórias e, nas próximas 10 a 20 passagens do otimizador, nada melhor é encontrado. Talvez em 100 passagens haja melhorias....

É aí que as coisas variam para mim. O Relu geralmente é bom.

O Genetics também não encontrou as melhores opções para mim.

Para o Bayesian, você precisa jogar não apenas com o número de passagens, mas também com o número de pontos. Você precisa procurar uma opção mais rápida. É muito tedioso lidar com isso.

Boa sorte

PS. Você não está mudando para o TensorFlow? É apenas um nível mais alto.