J'ai écrit ma première implémentation TensorFlow d'un RNN qui prend en entrée des séquences aléatoires qui augmentent ou diminuent. Les étiquettes d'apprentissage sont un entier unique correspondant à chaque séquence, 1 étant une séquence croissante et 0 décroissant. Comme mon modèle s'entraîne, il se penche rapidement vers la classification de chaque séquence comme étant décroissante et je n'arrive pas à comprendre pourquoi. Voici mon code:Pourquoi mon RNN apprend-il à classer toutes les entrées comme étant seulement une des deux classifications possibles?
from __future__ import print_function
import tensorflow as tf
from tensorflow.contrib import rnn
import random
sequenceLength = 5 # Input Dimension
maxNum = 1000 # Must be >= than (sequenceLength - 1)
outputDim = 1
hiddenDim = 16
learningRate = 0.1
trainingIterations = 10000
batchSize = 10
displayStep = 1000
def generateData():
data = []
labels = []
for _ in range(batchSize):
type = (1 if random.random() < 0.5 else 0)
temp = []
if type == 1:
labels.append([1])
temp.append(random.randint(0, maxNum - sequenceLength + 1))
for i in range(1, sequenceLength):
temp.append(random.randint(temp[i - 1] + 1, maxNum - sequenceLength + i + 1))
data.append(temp)
if type == 0:
labels.append([0])
temp.append(random.randint(0 + sequenceLength - 1, maxNum))
for i in range(1, sequenceLength):
temp.append(random.randint(0 + sequenceLength - i - 1, temp[i - 1] - 1))
data.append(temp)
return data, labels
x = tf.placeholder(tf.float32, [batchSize, sequenceLength], name="input")
y = tf.placeholder(tf.float32, [batchSize, outputDim], name="label")
W = tf.Variable(tf.random_normal([hiddenDim, outputDim]))
b = tf.Variable(tf.random_normal([outputDim]))
cell = rnn.BasicRNNCell(hiddenDim)
outputs, states = tf.nn.static_rnn(cell, [x], dtype=tf.float32)
prediction = tf.sigmoid(tf.matmul(outputs[0], W + b))
loss = tf.reduce_mean(tf.nn.sigmoid_cross_entropy_with_logits(logits=prediction, labels=y))
optimiser = tf.train.AdamOptimizer(learning_rate=learningRate).minimize(loss)
correctPrediction = tf.equal(tf.round(prediction), y)
accuracy = tf.reduce_mean(tf.cast(correctPrediction, tf.float32))
with tf.Session() as session:
session.run(tf.global_variables_initializer())
for i in range(trainingIterations):
batchX, batchY = generateData()
dict = {x: batchX, y : batchY}
session.run(optimiser, feed_dict=dict)
if i % displayStep == 0:
print("Predictions:\t" + str(session.run(tf.transpose(tf.round(prediction)), dict)))
print("Labels:\t\t" + str(session.run(tf.transpose(y), dict)) + "\n")
# batchAccuracy = session.run(accuracy, feed_dict=dict)
# batchLoss = session.run(loss, feed_dict=dict)
# print("Iteration: " + str(i) + "\nAccuracy: " + str(batchAccuracy) + "\nLoss: " + str(batchLoss) + "\n")
Comme je l'ai dit, ceci est ma première mise en œuvre en utilisant tensorflow, bien que je suis bien conscient de la façon dont fonctionne un RNN, je suis encore tout à fait perdu avec l'abstraction de haut niveau que nous interagir avec TensorFLow. Ce sont mes calculs de prediction
, loss
, correctPrediction
et accuracy
dont je ne suis pas sûr. Est-ce que la façon dont j'utilise la fonction sigmoïde est double? Une fois pour produire une probabilité pour ma prédiction, et encore pour calculer l'entropie croisée entre ma prédiction (comme la probabilité) et l'étiquette.
EDIT
Je viens de remarquer que, dans de très rares occasions, sans modifier le code, le RNN apprend rapidement à classer les séquences correctement.
Pour toute question portant spécifiquement sur le processus de conception et de la formation des modèles d'apprentissage de la machine, envisager de demander plutôt sur [Science Data SE] (https: //datascience.stackexchange.com) ou [Cross Validated] (https://stats.stackexchange.com). –