1. 程式人生 > >tf.sesstion.run()單函式執行和多函式執行區別

tf.sesstion.run()單函式執行和多函式執行區別

tf.session.run()單函式執行和多函式執行區別

覺得有用的話,歡迎一起討論相互學習~Follow Me

problem instruction

sess.run([a,b]) # (1)同時執行a,b兩個函式
sess.run(a)
sess.run(b) # (2)執行完a函式後再執行b函式
  • 這兩個語句初看時沒有任何區別,但是如果a,b函式恰好是讀取example_batch和label_batch這種需要使用到 資料批次輸入輸出函式時 例如(tf.train.shuffle_batch.tf.reader.read).
  • (1)式只會呼叫一次輸入資料函式,則得到的example_batch和label_batch來自同一批次。 (2)式會單獨呼叫兩次輸入資料函式,則得到的example_batch來自上一批次而label_batch來自下一批次。
  • 這個需要十分注意,因為如果我們想要實時打印出label_batch和inference(example_batch)時,即將輸入資料的標籤和經過模型預測推斷的結果進行比較時.如果我們使用(2)中的寫法,則label_batch和inference(example_batch)並不是來自與同一批次資料。

example code

這裡我們分別使用兩種不同的程式碼,讀取csv檔案中的資料。我們觀察這兩種方式讀取的資料有什麼不同。
源程式檔案下載
test_tf_train_batch.csv

import tensorflow as tf

BATCH_SIZE = 400
NUM_THREADS = 2
MAX_NUM = 5 def read_data(file_queue): reader = tf.TextLineReader(skip_header_lines=1) key, value = reader.read(file_queue) defaults = [[0], [0.], [0.]] NUM, C, Tensile = tf.decode_csv(value, defaults) vertor_example = tf.stack([C]) vertor_label = tf.stack([Tensile]) vertor_num = tf.stack([NUM]) return
vertor_example, vertor_label, vertor_num def create_pipeline(filename, batch_size, num_threads): file_queue = tf.train.string_input_producer([filename]) # 設定檔名佇列 example, label, no = read_data(file_queue) # 讀取資料和標籤 example_batch, label_batch, no_batch = tf.train.batch( [example, label, no], batch_size=batch_size, num_threads=num_threads, capacity=MAX_NUM) return example_batch, label_batch, no_batch x_train_batch, y_train_batch, no_train_batch = create_pipeline('test_tf_train_batch.csv', batch_size=BATCH_SIZE, num_threads=NUM_THREADS) init_op = tf.global_variables_initializer() local_init_op = tf.local_variables_initializer() with tf.Session() as sess: sess.run(local_init_op) sess.run(init_op) coord = tf.train.Coordinator() threads = tf.train.start_queue_runners(coord=coord) # 同時執行的方式 example, label, num = sess.run([x_train_batch, y_train_batch, no_train_batch]) print('The first mode to load data') print('example', example) print('label', label) print('num', num) # 分別執行的方式 # example = sess.run(x_train_batch) # label = sess.run(y_train_batch) # num = sess.run(no_train_batch) # print('The second mode to load data') # print('example', example) # print('label', label) # print('num', num) coord.request_stop() coord.join(threads)

Result

Run at the same time

example, label, num = sess.run([x_train_batch, y_train_batch, no_train_batch])
print('The first mode to load data')
print('example', example)
print('label', label)
print('num', num)
example label num
[ 0.294 ] [ 0.59821427] [1]
[ 0.31 ] [ 0.51785713] [2]
[ 0.2 ] [ 0.79464287] [3]
[ 0.30000001] [ 0.4732143 ] [4]
[ 0.36000001] [ 0.6964286 ] [5]

Run respectively

   example = sess.run(x_train_batch)
   label = sess.run(y_train_batch)
   num = sess.run(no_train_batch)
   print('The second mode to load data')
   print('example\n', example)
   print('label\n', label)
   print('num\n', num)

經過對比原始資料,我們發現採用單獨執行的方式讀取的example來自第一個batch,label來自下一個batch,而num來自第三個batch.也就是說其實我們單獨運行了三次檔案輸入的程式。雖然是個小事,但是有些方面不注意,我們會釀成大錯

example label num
[ 0.294 ] [ 0.5625 ] [11]
[ 0.31 ] [ 0.3482143 ] [13]
[ 0.2 ] [ 0.5535714 ] [12]
[ 0.30000001] [ 0.5714286 ] [14]
[ 0.36000001] [ 0.48214287] [15]

* 原始資料

C tensile NUM
0.294 0.598214286 1
0.31 0.517857143 2
0.2 0.794642857 3
0.3 0.473214286 4
0.36 0.696428571 5
0.28 0.5625 6
0.2 0.348214286 7
0.284 0.553571429 8
0.38 0.482142857 9
0.44 0.571428571 10
0.214 0.660714286 11
0.72 0.589285714 12
0.38 0.616071429 13
0.266 0.5 14
0.46 0.642857143 15