Agregar varias capas a TensorFlow hace que la función de pérdida se convierta en Nan

Estoy escribiendo un clasificador de neural network en TensorFlow / Python para el conjunto de datos notMNIST . He implementado l2 regularización y abandono en las capas ocultas. Funciona bien siempre que solo haya una capa oculta, pero cuando agregué más capas (para mejorar la precisión), la función de pérdida aumenta rápidamente en cada paso, convirtiéndose en NaN en el paso 5. Intenté desactivar temporalmente la regularización de Dropout y L2, pero Tengo el mismo comportamiento siempre que haya más de 2 capas. Incluso reescribí mi código desde cero (haciendo una refactorización para hacerlo más flexible), pero con los mismos resultados. El número y el tamaño de las capas están controlados por hidden_layer_spec . ¿Qué me estoy perdiendo?

 #works for np.array([1024]) with about 96.1% accuracy hidden_layer_spec = np.array([1024, 300]) num_hidden_layers = hidden_layer_spec.shape[0] batch_size = 256 beta = 0.0005 epochs = 100 stepsPerEpoch = float(train_dataset.shape[0]) / batch_size num_steps = int(math.ceil(float(epochs) * stepsPerEpoch)) l2Graph = tf.Graph() with l2Graph.as_default(): #with tf.device('/cpu:0'): # Input data. For the training data, we use a placeholder that will be fed # at run time with a training minibatch. tf_train_dataset = tf.placeholder(tf.float32, shape=(batch_size, image_size * image_size)) tf_train_labels = tf.placeholder(tf.float32, shape=(batch_size, num_labels)) tf_valid_dataset = tf.constant(valid_dataset) tf_test_dataset = tf.constant(test_dataset) weights = [] biases = [] for hi in range(0, num_hidden_layers + 1): width = image_size * image_size if hi == 0 else hidden_layer_spec[hi - 1] height = num_labels if hi == num_hidden_layers else hidden_layer_spec[hi] weights.append(tf.Variable(tf.truncated_normal([width, height]), name = "w" + `hi + 1`)) biases.append(tf.Variable(tf.zeros([height]), name = "b" + `hi + 1`)) print(`width` + 'x' + `height`) def logits(input, addDropoutLayer = False): previous_layer = input for hi in range(0, hidden_layer_spec.shape[0]): previous_layer = tf.nn.relu(tf.matmul(previous_layer, weights[hi]) + biases[hi]) if addDropoutLayer: previous_layer = tf.nn.dropout(previous_layer, 0.5) return tf.matmul(previous_layer, weights[num_hidden_layers]) + biases[num_hidden_layers] # Training computation. train_logits = logits(tf_train_dataset, True) l2 = tf.nn.l2_loss(weights[0]) for hi in range(1, len(weights)): l2 = l2 + tf.nn.l2_loss(weights[0]) loss = tf.reduce_mean(tf.nn.softmax_cross_entropy_with_logits(train_logits, tf_train_labels)) + beta * l2 # Optimizer. global_step = tf.Variable(0) # count the number of steps taken. learning_rate = tf.train.exponential_decay(0.5, global_step, int(stepsPerEpoch) * 2, 0.96, staircase = True) optimizer = tf.train.GradientDescentOptimizer(learning_rate).minimize(loss, global_step=global_step) # Predictions for the training, validation, and test data. train_prediction = tf.nn.softmax(train_logits) valid_prediction = tf.nn.softmax(logits(tf_valid_dataset)) test_prediction = tf.nn.softmax(logits(tf_test_dataset)) saver = tf.train.Saver() with tf.Session(graph=l2Graph) as session: tf.initialize_all_variables().run() print("Initialized") for step in range(num_steps): # Pick an offset within the training data, which has been randomized. # Note: we could use better randomization across epochs. offset = (step * batch_size) % (train_labels.shape[0] - batch_size) # Generate a minibatch. batch_data = train_dataset[offset:(offset + batch_size), :] batch_labels = train_labels[offset:(offset + batch_size), :] # Prepare a dictionary telling the session where to feed the minibatch. # The key of the dictionary is the placeholder node of the graph to be fed, # and the value is the numpy array to feed to it. feed_dict = {tf_train_dataset : batch_data, tf_train_labels : batch_labels} _, l, predictions = session.run( [optimizer, loss, train_prediction], feed_dict=feed_dict) if (step % 500 == 0): print("Minibatch loss at step %d: %f" % (step, l)) print("Learning rate: " % learning_rate) print("Minibatch accuracy: %.1f%%" % accuracy(predictions, batch_labels)) print("Validation accuracy: %.1f%%" % accuracy( valid_prediction.eval(), valid_labels)) print("Test accuracy: %.1f%%" % accuracy(test_prediction.eval(), test_labels)) save_path = saver.save(session, "l2_degrade.ckpt") print("Model save to " + `save_path`) 

Resulta que esto no era tanto un problema de encoding como un problema de aprendizaje profundo. La capa adicional hizo que los gradientes fueran demasiado inestables, y eso llevó a que la función de pérdida se convirtiera rápidamente en NaN. La mejor manera de solucionar esto es usar la inicialización de Xavier . De lo contrario, la varianza de los valores iniciales tenderá a ser demasiado alta, causando inestabilidad. Además, disminuir la tasa de aprendizaje puede ayudar.

Tuve el mismo problema y al reducir el tamaño del lote y la velocidad de aprendizaje funcionó para mí.