De Keras RNN Tutorial: "Les RNN sont difficiles. Le choix de la taille des lots est important, le choix de la perte et de l'optimiseur est critique, etc. Certaines configurations ne convergent pas."
Il s'agit donc plus d'une question générale sur le réglage des hyperparamètres d'un LSTM-RNN sur Keras. Je voudrais connaître une approche pour trouver les meilleurs paramètres pour votre RNN.
J'ai commencé avec l' exemple IMDB sur le Github de Keras .
le modèle principal ressemble à ceci:
(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 est un bon score et plus important encore, cela signifie que le modèle, même s'il n'est pas entièrement optimisé, fonctionne.
Mes données sont des séries temporelles et la tâche est une prédiction binaire, la même que l'exemple. Et maintenant mon problème ressemble à ceci:
#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
Le modèle est fondamentalement le même que celui de l'IMDB. Bien que le résultat signifie qu'il n'apprend rien. Cependant, lorsque j'utilise un MLP-NN vanille, je n'ai pas le même problème, le modèle apprend et le score augmente. J'ai essayé d'augmenter le nombre d'époques et d'augmenter-diminuer le nombre d'unités LTSM mais le score n'augmentera pas.
Je voudrais donc connaître une approche standard pour régler le réseau car, en théorie, l'algorithme devrait être plus performant qu'un réseau perceptron multicouche spécialement pour ces données de série chronologique.
Réponses:
Une couche d'intégration transforme les entiers positifs (index) en vecteurs denses de taille fixe. Par exemple,
[[4], [20]] -> [[0.25, 0.1], [0.6, -0.2]]
. Cette conversion de représentation est apprise automatiquement avec la couche d'intégration dans Keras (voir la documentation ).Cependant, il semble que vos données n'aient pas besoin d'une telle couche d'intégration pour effectuer une conversion. Avoir une couche d'intégration inutile est probablement la raison pour laquelle vous ne pouvez pas faire fonctionner correctement votre LSTM. Si tel est le cas, vous devez simplement supprimer la couche d'intégration.
La première couche de votre réseau devrait alors avoir l'
input_shape
argument ajouté avec des informations sur les dimensions de vos données (voir exemples ). Notez que vous pouvez ajouter cet argument à n'importe quelle couche - il ne sera présent dans la documentation d'aucune couche spécifique.Soit dit en passant, les hyperparamètres sont souvent réglés à l'aide d'une recherche aléatoire ou d'une optimisation bayésienne. J'utiliserais RMSProp et me concentrerais sur le réglage de la taille des lots (tailles comme 32, 64, 128, 256 et 512), l'écrêtage du gradient (sur l'intervalle 0,1-10) et le décrochage (sur l'intervalle 0,1-0,6). Les spécificités dépendent bien sûr de vos données et de l'architecture du modèle.
la source
Je recommanderais l'optimisation bayésienne pour la recherche d'hyperparamètres et j'ai obtenu de bons résultats avec Spearmint. https://github.com/HIPS/Spearmint Vous devrez peut-être utiliser une ancienne version à des fins commerciales.
la source
Je suggérerais d'utiliser hyperopt ( https://github.com/hyperopt/hyperopt ), qui utilise une sorte d'optimisation bayésienne pour rechercher des valeurs optimales d'hyperparamètres étant donné la fonction objectif. Il est plus intuitif à utiliser que Spearmint.
PS: Il existe un wrapper d'hyperopt spécifiquement pour les keras, les hyperas ( https://github.com/maxpumperla/hyperas ). Vous pouvez également l'utiliser.
la source
Talos est exactement ce que vous recherchez; une solution automatisée de recherche de combinaisons d'hyperparamètres pour les modèles Keras. Je ne suis peut-être pas objectif car je suis l'auteur, mais l'intention était de fournir une alternative avec la courbe d'apprentissage la plus basse possible tout en exposant entièrement la fonctionnalité Keras.
Alternativement, comme cela avait déjà été mentionné, vous pouvez regarder dans Hyperas , ou ensuite SKlearn ou AutoKeras . À ma connaissance, au moment de la rédaction de ce document, ces quatre options sont spécifiquement destinées aux utilisateurs de Keras.
la source