2016-07-19 20 views
6

Vấn đề

Tôi có một tập lệnh Python sử dụng TensorFlow để tạo một mạng lưới perceptron đa lớp (có bỏ học) để phân loại nhị phân. Mặc dù tôi đã cẩn thận để đặt cả hạt Python và TensorFlow, tôi nhận được kết quả không lặp lại được. Nếu tôi chạy một lần và sau đó chạy lại, tôi nhận được kết quả khác nhau. Tôi thậm chí có thể chạy một lần, bỏ Python, khởi động lại Python, chạy lại và nhận được kết quả khác nhau.TensorFlow: Kết quả không lặp lại

Những gì tôi đã cố gắng

Tôi biết một số người gửi câu hỏi về việc nhận kết quả không thể lặp lại trong TensorFlow (ví dụ: "How to get stable results...", "set_random_seed not working...", "How to get reproducible result in TensorFlow"), và câu trả lời thường bật ra được một sử dụng không đúng/sự hiểu biết của tf.set_random_seed(). Tôi đã thực hiện chắc chắn để thực hiện các giải pháp được đưa ra nhưng điều đó đã không giải quyết được vấn đề của tôi.

Lỗi thường gặp là không nhận ra rằng tf.set_random_seed() chỉ là hạt giống cấp đồ thị và chạy tập lệnh nhiều lần sẽ làm thay đổi biểu đồ, giải thích kết quả không lặp lại được. Tôi đã sử dụng câu lệnh sau đây để in toàn bộ biểu đồ và xác minh (thông qua khác) rằng biểu đồ giống nhau ngay cả khi kết quả khác nhau.

print [n.name for n in tf.get_default_graph().as_graph_def().node] 

Tôi cũng đã sử dụng chức năng gọi như tf.reset_default_graph()tf.get_default_graph().finalize() để tránh bất kỳ thay đổi đồ thị mặc dù đây có lẽ là quá mức cần thiết.

The (có liên quan) Mã

kịch bản của tôi là ~ 360 đường dài vì vậy đây là những dòng có liên quan (với mã Snipped chỉ). Bất kỳ mục nào trong ALL_CAPS là các hằng số được xác định trong khối Parameters của tôi bên dưới.

import numpy as np 
import tensorflow as tf 

from copy import deepcopy 
from tqdm import tqdm # Progress bar 

# --------------------------------- Parameters --------------------------------- 
(snip) 

# --------------------------------- Functions --------------------------------- 
(snip) 

# ------------------------------ Obtain Train Data ----------------------------- 
(snip) 

# ------------------------------ Obtain Test Data ----------------------------- 
(snip) 

random.seed(12345) 
tf.set_random_seed(12345) 

(snip) 

# ------------------------- Build the TensorFlow Graph ------------------------- 

tf.reset_default_graph() 

with tf.Graph().as_default(): 

    x = tf.placeholder("float", shape=[None, N_INPUT]) 
    y_ = tf.placeholder("float", shape=[None, N_CLASSES]) 

    # Store layers weight & bias 
    weights = { 
     'h1': tf.Variable(tf.random_normal([N_INPUT, N_HIDDEN_1])), 
     'h2': tf.Variable(tf.random_normal([N_HIDDEN_1, N_HIDDEN_2])), 
     'h3': tf.Variable(tf.random_normal([N_HIDDEN_2, N_HIDDEN_3])), 
     'out': tf.Variable(tf.random_normal([N_HIDDEN_3, N_CLASSES])) 
    } 

    biases = { 
     'b1': tf.Variable(tf.random_normal([N_HIDDEN_1])), 
     'b2': tf.Variable(tf.random_normal([N_HIDDEN_2])), 
     'b3': tf.Variable(tf.random_normal([N_HIDDEN_3])), 
     'out': tf.Variable(tf.random_normal([N_CLASSES])) 
    } 

# Construct model 
    pred = multilayer_perceptron(x, weights, biases, USE_DROP_LAYERS, DROP_KEEP_PROB) 

    mean1 = tf.reduce_mean(weights['h1']) 
    mean2 = tf.reduce_mean(weights['h2']) 
    mean3 = tf.reduce_mean(weights['h3']) 

    cost = tf.reduce_mean(tf.nn.softmax_cross_entropy_with_logits(pred, y_)) 

    regularizers = (tf.nn.l2_loss(weights['h1']) + tf.nn.l2_loss(biases['b1']) + 
        tf.nn.l2_loss(weights['h2']) + tf.nn.l2_loss(biases['b2']) + 
        tf.nn.l2_loss(weights['h3']) + tf.nn.l2_loss(biases['b3'])) 

    cost += COEFF_REGULAR * regularizers 

    optimizer = tf.train.GradientDescentOptimizer(LEARNING_RATE).minimize(cost) 

    out_labels = tf.nn.softmax(pred) 

    sess = tf.InteractiveSession() 
    sess.run(tf.initialize_all_variables()) 

    tf.get_default_graph().finalize() # Lock the graph as read-only 

    #Print the default graph in text form  
    print [n.name for n in tf.get_default_graph().as_graph_def().node] 

    # --------------------------------- Training ---------------------------------- 

    print "Start Training" 
    pbar = tqdm(total = TRAINING_EPOCHS) 
    for epoch in range(TRAINING_EPOCHS): 
     avg_cost = 0.0 
     batch_iter = 0 

     train_outfile.write(str(epoch)) 

     while batch_iter < BATCH_SIZE: 
      train_features = [] 
      train_labels = [] 
      batch_segments = random.sample(train_segments, 20) 
      for segment in batch_segments: 
       train_features.append(segment[0]) 
       train_labels.append(segment[1]) 
      sess.run(optimizer, feed_dict={x: train_features, y_: train_labels}) 
      line_out = "," + str(batch_iter) + "\n" 
      train_outfile.write(line_out) 
      line_out = ",," + str(sess.run(mean1, feed_dict={x: train_features, y_: train_labels})) 
      line_out += "," + str(sess.run(mean2, feed_dict={x: train_features, y_: train_labels})) 
      line_out += "," + str(sess.run(mean3, feed_dict={x: train_features, y_: train_labels})) + "\n" 
      train_outfile.write(line_out) 
      avg_cost += sess.run(cost, feed_dict={x: train_features, y_: train_labels})/BATCH_SIZE 
      batch_iter += 1 

     line_out = ",,,,," + str(avg_cost) + "\n" 
     train_outfile.write(line_out) 
     pbar.update(1) # Increment the progress bar by one 

    train_outfile.close() 
    print "Completed training" 


# ------------------------------ Testing & Output ------------------------------ 

keep_prob = 1.0 # Do not use dropout when testing 

print "now reducing mean" 
print(sess.run(mean1, feed_dict={x: test_features, y_: test_labels})) 

print "TRUE LABELS" 
print(test_labels) 
print "PREDICTED LABELS" 
pred_labels = sess.run(out_labels, feed_dict={x: test_features}) 
print(pred_labels) 

output_accuracy_results(pred_labels, test_labels) 

sess.close() 

Có gì không lặp lại

Như bạn thấy, tôi xuất ra kết quả trong mỗi thời đại vào một tập tin và cũng có thể in ra số chính xác ở cuối. Không ai trong số này phù hợp với từ chạy để chạy, mặc dù tôi tin rằng tôi đã thiết lập các hạt giống (s) một cách chính xác. Tôi đã sử dụng cả hai random.seed(12345)tf.set_random_seed(12345)

Vui lòng cho tôi biết nếu tôi cần cung cấp thêm thông tin. Và cảm ơn trước vì sự giúp đỡ nào.

-DG

Set-up chi tiết

phiên bản TensorFlow 0.8.0 (CPU chỉ)
Enthought Canopy phiên bản 1.7.2 (Python 2.7, không 3. +)
phiên bản Mac OS X 10.11.3

Trả lời

5

Bạn cần phải thiết lập hạt mức hoạt động, thêm vào đồ thị cấp hạt giống, tức là

tf.reset_default_graph() 
a = tf.constant([1, 1, 1, 1, 1], dtype=tf.float32) 
graph_level_seed = 1 
operation_level_seed = 1 
tf.set_random_seed(graph_level_seed) 
b = tf.nn.dropout(a, 0.5, seed=operation_level_seed) 
+0

Wow. Bạn có cần thiết lập một hạt giống cấp hoạt động cho hoạt động _every_ không? Tất cả 'tf.placeholder',' tf.Variable', 'tf.reduce_mean', v.v ...? – DojoGojira

+2

Không, chỉ những cái có độ ngẫu nhiên –

+1

@Yaroslav Tôi không hiểu: Tôi cho rằng mục đích của 'tf.set_random_seed()' là ảnh hưởng đến tất cả các hoạt động ngẫu nhiên trong biểu đồ, vì vậy bạn không phải đặt bằng tay một hạt giống cho mỗi toán tử ngẫu nhiên. Việc sử dụng nó là gì? Và từ ví dụ trong [doc] (https://www.tensorflow.org/versions/r0.11/api_docs/python/constant_op.html#set_random_seed), chúng chỉ đặt hạt giống toàn cầu để có được kết quả có thể lặp lại. – toto2

5

Xem lưu lượng này github issue. Một số thao tác trên GPU không hoàn toàn xác định (tốc độ so với độ chính xác).

Tôi cũng quan sát thấy rằng để hạt giống có hiệu lực, tf.set_random_seed(...) phải được gọi là trướcSession được tạo.Và bạn cũng nên khởi động lại hoàn toàn trình thông dịch python mỗi lần bạn chạy mã của bạn, hoặc gọi tf.reset_default_graph() khi bắt đầu.

0

Chỉ cần thêm vào câu trả lời của câu trả lời là Yaroslav, bạn cũng nên đặt hạt numpy ngoài hạt giống hoạt động và mức đồ thị, vì một số hoạt động phụ trợ phụ thuộc vào khối u. Điều này đã làm cho các trick cho tôi np.random.seed() với Tensorflow V 1.1.0

Các vấn đề liên quan