tf.session.run()單函數運行和多函數運行區別
覺得有用的話,歡迎一起討論相互學習~




problem introduction
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 |