2016-04-12 7 views
13

बनने का कारण बनता है। मैं notMNIST डेटासेट के लिए टेंसरफ्लो/पायथन में एक तंत्रिका-नेटवर्क वर्गीकरण लिख रहा हूं। मैंने छुपा परतों पर एल 2 नियमितकरण और ड्रॉपआउट लागू किया है। यह तब तक ठीक काम करता है जब तक केवल एक छिपी हुई परत होती है, लेकिन जब मैंने अधिक परतें (सटीकता में सुधार करने के लिए) जोड़ दिया, तो प्रत्येक चरण में हानि फ़ंक्शन तेजी से बढ़ता है, चरण 5 तक NaN बन जाता है। मैंने अस्थायी रूप से ड्रॉपआउट और एल 2 नियमितकरण को अक्षम करने की कोशिश की, लेकिन जब तक 2+ परतें होती हैं तब तक मुझे वही व्यवहार मिलता है। मैं स्क्रैच से भी अपना कोड दोबारा लिखता हूं (इसे और अधिक लचीला बनाने के लिए कुछ रिफैक्टरिंग कर रहा हूं), लेकिन एक ही परिणाम के साथ। परतों की संख्या और आकार hidden_layer_spec द्वारा नियंत्रित किया जाता है। मैं क्या खो रहा हूँ?टेंसरफ्लो में कई परतों को जोड़ना हानि फ़ंक्शन को नैन

#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`) 

उत्तर

17

यह पता चला कि यह एक गहरी सीखने के मुद्दे के रूप में कोडिंग समस्या इतनी ज्यादा नहीं थी। अतिरिक्त परत ने ग्रेडियेंट को बहुत अस्थिर बना दिया, और इससे नाक के लिए जल्दी से हानि समारोह का कारण बन गया। इसे ठीक करने का सबसे अच्छा तरीका Xavier initialization का उपयोग करना है। अन्यथा, शुरुआती मूल्यों का भिन्नता बहुत अधिक हो जाएगा, अस्थिरता का कारण बनता है। इसके अलावा, सीखने की दर में कमी से मदद मिल सकती है।

+1

मुझे एहसास हुआ कि यह कुछ समय पहले था, लेकिन आप कुछ नियमितकरण विधियों और विशेष रूप से [बैच सामान्यीकरण] (https://arxiv.org/pdf/1502.03167.pdf) में भी देखना चाहते हैं। यदि आप इसे महान काम कर रहे हैं, लेकिन बीएन अन्य चीजों के साथ शुरुआती वजन वितरण के लिए नेटवर्क संवेदनशीलता के साथ मदद करता है। – Engineero

+0

'truncated_normal' के लिए, 'stddev = sqrt (2/N)' सेट करने का प्रयास करें, जहां वजन मैट्रिक्स में पंक्तियों की संख्या' N' है। या बस 'stddev' को एक [निचले मान] पर सेट करें (https://discussions.udacity.com/t/problem-3-3-dropout-does-not-improve-test-accuarcy/46286/13)। यहां एक [उदाहरण] है (http://www.ritchieng.com/machine-learning/deep-learning/tensorflow/regularization/), हालांकि कुछ गलतियाँ हैं, जैसे मूल्यांकन चरण में ड्रॉपआउट शामिल हैं। – orodbhen

+0

वास्तव में, यहां मूल [पेपर] (https://arxiv.org/pdf/1502.01852v1.pdf) है कि 'sqrt (2/N)' से आता है। – orodbhen

8

मुझे एक ही समस्या थी और बैच आकार और सीखने की दर को कम करने के लिए मेरे लिए काम किया।

+0

हां। मेरी सीखने की दर एक निश्चित 0.5 पर थी और इसे जाने के लिए मुझे इसे 0.06 तक कम करना पड़ा। – scipilot

संबंधित मुद्दे