Pesquisa por hiperparâmetro para LSTM-RNN usando Keras (Python)

18

Do tutorial da Keras RNN: "RNNs são complicadas. A escolha do tamanho do lote é importante, a escolha da perda e do otimizador é crítica, etc. Algumas configurações não convergirão."

Portanto, essa é uma pergunta mais geral sobre o ajuste dos hiperparâmetros de um LSTM-RNN no Keras. Gostaria de saber sobre uma abordagem para encontrar os melhores parâmetros para o seu RNN.

Comecei com o exemplo do IMDB no Github de Keras .

o modelo principal fica assim:

(X_train, y_train), (X_test, y_test) = imdb.load_data(nb_words=max_features,
                                                      test_split=0.2)

max_features = 20000
maxlen = 100  # cut texts after this number of words (among top max_features most common words)
batch_size = 32

model = Sequential()
model.add(Embedding(max_features, 128, input_length=maxlen))
model.add(LSTM(128))  
model.add(Dropout(0.5))
model.add(Dense(1))
model.add(Activation('sigmoid'))

# try using different optimizers and different optimizer configs
model.compile(loss='binary_crossentropy',
          optimizer='adam',
          class_mode="binary")

print("Train...")
model.fit(X_train, y_train, batch_size=batch_size, nb_epoch=3,
      validation_data=(X_test, y_test), show_accuracy=True)
score, acc = model.evaluate(X_test, y_test,
                        batch_size=batch_size,
                        show_accuracy=True)

print('Test accuracy:', acc)
Test accuracy:81.54321846

81.5 é uma pontuação justa e, mais importante, significa que o modelo, mesmo não totalmente otimizado, funciona.

Meus dados são Séries temporais e a tarefa é previsão binária, igual ao exemplo. E agora meu problema é assim:

#Training Data
train = genfromtxt(os.getcwd() + "/Data/trainMatrix.csv", delimiter=',', skip_header=1)
validation = genfromtxt(os.getcwd() + "/Data/validationMatrix.csv", delimiter=',', skip_header=1)

#Targets
miniTrainTargets = [int(x) for x in genfromtxt(os.getcwd() + "/Data/trainTarget.csv", delimiter=',', skip_header=1)]
validationTargets = [int(x) for x in genfromtxt(os.getcwd() + "/Data/validationTarget.csv", delimiter=',', skip_header=1)]

#LSTM
model = Sequential()
model.add(Embedding(train.shape[0], 64, input_length=train.shape[1]))
model.add(LSTM(64)) 
model.add(Dropout(0.5))
model.add(Dense(1))
model.add(Activation('sigmoid'))

# try using different optimizers and different optimizer configs
model.compile(loss='binary_crossentropy',
          optimizer='adam',
          class_mode="binary")

model.fit(train, miniTrainTargets, batch_size=batch_size, nb_epoch=5,
      validation_data=(validation, validationTargets), show_accuracy=True)
valid_preds = model.predict_proba(validation, verbose=0)
roc = metrics.roc_auc_score(validationTargets, valid_preds)
print("ROC:", roc)
ROC:0.5006526

O modelo é basicamente o mesmo que o IMDB. Embora o resultado signifique que não está aprendendo nada. No entanto, quando uso um MLP-NN de baunilha, não tenho o mesmo problema, o modelo aprende e a pontuação aumenta. Tentei aumentar o número de épocas e aumentar - diminuindo o número de unidades LTSM, mas a pontuação não aumentará.

Então, eu gostaria de conhecer uma abordagem padrão para ajustar a rede porque, em teoria, o algoritmo deve ter um desempenho melhor do que uma rede perceptron multicamada, especialmente para os dados desta série temporal.

wacax
fonte
1
Quantos dados você tem? Qual é o comprimento das suas sequências? Os LSTMs são realmente úteis apenas para problemas com muitos dados e dependências de longo prazo.
quer
Busca aleatória ou otimização Bayesiana são formas padronizadas de encontrar hiperparâmetros :)
pir
1
Tem certeza de que precisa da camada de incorporação? Muitos conjuntos de dados de séries temporais não precisariam disso.
pir
Eu tenho quase 100k pontos de dados e o dobro de recursos do exemplo do IMDB, então não acho que esse seja o problema. Quanto à camada de incorporação, como exatamente você conectaria a camada LSTM à entrada? De acordo com a documentação keras.io/layers/recurrent/#lstm, o LSTM do Keras usa apenas inicializações, ativações e output_dim como argumentos. Se essa é a fonte do erro, o código que descreve como eliminar a camada de incorporação será muito apreciado.
Wacax
Por favor, veja minha resposta. Parece que você não precisa da camada de incorporação.
pir

Respostas:

5

Uma camada de incorporação transforma números inteiros positivos (índices) em vetores densos de tamanho fixo. Por exemplo [[4], [20]] -> [[0.25, 0.1], [0.6, -0.2]],. Essa conversão de representação é aprendida automaticamente com a camada de incorporação no Keras (consulte a documentação ).

No entanto, parece que seus dados não precisam dessa camada de incorporação para realizar uma conversão. Ter uma camada de incorporação desnecessária é provavelmente o motivo pelo qual o LSTM não pode funcionar corretamente. Se for esse o caso, você deve simplesmente remover a camada de incorporação.

A primeira camada da sua rede deve ter o input_shape argumento adicionado com informações sobre as dimensões dos seus dados (veja exemplos ). Observe que você pode adicionar esse argumento a qualquer camada - ele não estará presente na documentação de nenhuma camada específica.


A propósito, os hiperparâmetros são frequentemente ajustados usando pesquisa aleatória ou otimização bayesiana. Eu usaria o RMSProp e focaria no tamanho do lote de ajuste (tamanhos como 32, 64, 128, 256 e 512), recorte de gradiente (no intervalo 0,1-10) e desistência (no intervalo 0,1-0,6). As especificidades do curso dependem dos dados e da arquitetura do modelo.

pir
fonte
Com o que você propõe substituir a camada de incorporação? Tentei simplesmente remover a camada de incorporação, mas isso não funciona.
wacax 29/03
1
Veja os outros exemplos - comece, por exemplo, diretamente com a camada Densa. Lembre-se de definir o parâmetro input_shape.
pir
5

Eu recomendaria a otimização bayesiana para busca de hiper parâmetros e teve bons resultados com o Spearmint. https://github.com/HIPS/Spearmint Talvez você precise usar uma versão mais antiga para uso comercial.

Mutian Zhai
fonte
2

Eu sugeriria o uso de hyperopt ( https://github.com/hyperopt/hyperopt ), que usa um tipo de otimização bayesiana para pesquisar valores ótimos de hiperparâmetros, dada a função objetivo. É mais intuitivo de usar que o Hortelã.

PS: Existe um invólucro de hyperopt especificamente para keras, hyperas ( https://github.com/maxpumperla/hyperas ). Você também pode usá-lo.

SHASHANK GUPTA
fonte
2

Talos é exatamente o que você está procurando; uma solução automatizada para pesquisar combinações de hiperparâmetros nos modelos Keras. Talvez eu não seja objetivo, pois sou o autor, mas a intenção tem sido fornecer uma alternativa com a menor curva de aprendizado possível, expondo completamente a funcionalidade Keras.

Como alternativa, como já foi mencionado, você pode procurar no Hyperas , ou então no SKlearn ou no AutoKeras . Que eu saiba, no momento da redação deste artigo, essas 4 são as opções especificamente para os usuários do Keras.

mikkokotila
fonte