內容概要:
單一數據讀取方式:
第一種:slice_input_producer()
# 返回值可以直接通過 Session.run([images, labels])查看,且第一個參數必須放在列表中,如[...]
[images, labels] = tf.train.slice_input_producer([images, labels], num_epochs=None, shuffle=True)
第二種:string_input_producer()
# 需要定義文件讀取器,然後通過讀取器中的 read()方法來獲取數據(返回值類型 key,value),再通過 Session.run(value)查看
file_queue = tf.train.string_input_producer(filename, num_epochs=None, shuffle=True)
reader = tf.WholeFileReader() # 定義文件讀取器key, value = reader.read(file_queue) # key:文件名;value:文件中的內容
!!!num_epochs=None,不指定迭代次數,這樣文件隊列中元素個數也不限定(None*數據集大小)。
!!!如果它
不是None
,則此函數創建本地計數器 epochs
,需要使用local_variables_initializer()
初始化局部變數
!!!以上兩種方法都可以生成文件名隊列。
(隨機)批量數據讀取方式:
batchsize=2 # 每次讀取的樣本數量tf.train.batch(tensors, batch_size=batchsize)
tf.train.shuffle_batch(tensors, batch_size=batchsize, capacity=batchsize*10, min_after_dequeue=batchsize*5) # capacity > min_after_dequeue
!!!以上所有讀取數據的方法,在Session.run()之前必須開啟文件隊列執行緒 tf.train.start_queue_runners()
TFRecord文件的打包與讀取
一、單一數據讀取方式
第一種:slice_input_producer()
def slice_input_producer(tensor_list, num_epochs=None, shuffle=True, seed=None, capacity=32, shared_name=None, name=None)
案例1:
import tensorflow as tf images = ['image1.jpg', 'image2.jpg', 'image3.jpg', 'image4.jpg'] labels = [1, 2, 3, 4] # [images, labels] = tf.train.slice_input_producer([images, labels], num_epochs=None, shuffle=True) # 當num_epochs=2時,此時文件隊列中只有 2*4=8個樣本,所有在取第9個樣本時會出錯 # [images, labels] = tf.train.slice_input_producer([images, labels], num_epochs=2, shuffle=True) data = tf.train.slice_input_producer([images, labels], num_epochs=None, shuffle=True) print(type(data)) # <class 'list'> with tf.Session() as sess: # sess.run(tf.local_variables_initializer()) sess.run(tf.local_variables_initializer()) coord = tf.train.Coordinator() # 執行緒的協調器 threads = tf.train.start_queue_runners(sess, coord) # 開始在圖表中收集隊列運行器 for i in range(10): print(sess.run(data)) coord.request_stop() coord.join(threads) """ 運行結果: [b'image2.jpg', 2] [b'image1.jpg', 1] [b'image3.jpg', 3] [b'image4.jpg', 4] [b'image2.jpg', 2] [b'image1.jpg', 1] [b'image3.jpg', 3] [b'image4.jpg', 4] [b'image2.jpg', 2] [b'image3.jpg', 3] """
!!!slice_input_producer() 中的第一個參數需要放在一個列表中,列表中的每個元素可以是 List 或 Tensor,如 [images,labels],
!!!num_epochs設置
第二種:string_input_producer()
def string_input_producer(string_tensor, num_epochs=None, shuffle=True, seed=None, capacity=32, shared_name=None, name=None, cancel_op=None)
文件讀取器
不同類型的文件對應不同的文件讀取器,我們稱為 reader對象;
該對象的 read 方法自動讀取文件,並創建數據隊列,輸出key/文件名,value/文件內容;
reader = tf.TextLineReader() ### 一行一行讀取,適用於所有文本文件
reader = tf.TFRecordReader() ### A Reader that outputs the records from a TFRecords file
reader = tf.WholeFileReader() ### 一次讀取整個文件,適用圖片
案例2:讀取csv文件
iimport tensorflow as tf filename = ['data/A.csv', 'data/B.csv', 'data/C.csv'] file_queue = tf.train.string_input_producer(filename, shuffle=True, num_epochs=2) # 生成文件名隊列 reader = tf.WholeFileReader() # 定義文件讀取器(一次讀取整個文件) # reader = tf.TextLineReader() # 定義文件讀取器(一行一行的讀) key, value = reader.read(file_queue) # key:文件名;value:文件中的內容 print(type(file_queue)) init = [tf.global_variables_initializer(), tf.local_variables_initializer()] with tf.Session() as sess: sess.run(init) coord = tf.train.Coordinator() threads = tf.train.start_queue_runners(sess=sess, coord=coord) try: while not coord.should_stop(): for i in range(6): print(sess.run([key, value])) break except tf.errors.OutOfRangeError: print('read done') finally: coord.request_stop() coord.join(threads) """ reader = tf.WholeFileReader() # 定義文件讀取器(一次讀取整個文件) 運行結果: [b'data/C.csv', b'7.jpg,7\n8.jpg,8\n9.jpg,9\n'] [b'data/B.csv', b'4.jpg,4\n5.jpg,5\n6.jpg,6\n'] [b'data/A.csv', b'1.jpg,1\n2.jpg,2\n3.jpg,3\n'] [b'data/A.csv', b'1.jpg,1\n2.jpg,2\n3.jpg,3\n'] [b'data/B.csv', b'4.jpg,4\n5.jpg,5\n6.jpg,6\n'] [b'data/C.csv', b'7.jpg,7\n8.jpg,8\n9.jpg,9\n'] """ """ reader = tf.TextLineReader() # 定義文件讀取器(一行一行的讀) 運行結果: [b'data/B.csv:1', b'4.jpg,4'] [b'data/B.csv:2', b'5.jpg,5'] [b'data/B.csv:3', b'6.jpg,6'] [b'data/C.csv:1', b'7.jpg,7'] [b'data/C.csv:2', b'8.jpg,8'] [b'data/C.csv:3', b'9.jpg,9'] """
案例3:讀取圖片(每次讀取全部圖片內容,不是一行一行)
import tensorflow as tf filename = ['1.jpg', '2.jpg'] filename_queue = tf.train.string_input_producer(filename, shuffle=False, num_epochs=1) reader = tf.WholeFileReader() # 文件讀取器 key, value = reader.read(filename_queue) # 讀取文件 key:文件名;value:圖片數據,bytes with tf.Session() as sess: tf.local_variables_initializer().run() coord = tf.train.Coordinator() # 執行緒的協調器 threads = tf.train.start_queue_runners(sess, coord) for i in range(filename.__len__()): image_data = sess.run(value) with open('img_%d.jpg' % i, 'wb') as f: f.write(image_data) coord.request_stop() coord.join(threads)
二、(隨機)批量數據讀取方式:
功能:shuffle_batch() 和 batch() 這兩個API都是從文件隊列中批量獲取數據,使用方式類似;
案例4:slice_input_producer() 與 batch()
import tensorflow as tf import numpy as np images = np.arange(20).reshape([10, 2]) label = np.asarray(range(0, 10)) images = tf.cast(images, tf.float32) # 可以注釋掉,不影響運行結果 label = tf.cast(label, tf.int32) # 可以注釋掉,不影響運行結果 batchsize = 6 # 每次獲取元素的數量 input_queue = tf.train.slice_input_producer([images, label], num_epochs=None, shuffle=False) image_batch, label_batch = tf.train.batch(input_queue, batch_size=batchsize) # 隨機獲取 batchsize個元素,其中,capacity:隊列容量,這個參數一定要比 min_after_dequeue 大 # image_batch, label_batch = tf.train.shuffle_batch(input_queue, batch_size=batchsize, capacity=64, min_after_dequeue=10) with tf.Session() as sess: coord = tf.train.Coordinator() # 執行緒的協調器 threads = tf.train.start_queue_runners(sess, coord) # 開始在圖表中收集隊列運行器 for cnt in range(2): print("第{}次獲取數據,每次batch={}...".format(cnt+1, batchsize)) image_batch_v, label_batch_v = sess.run([image_batch, label_batch]) print(image_batch_v, label_batch_v, label_batch_v.__len__()) coord.request_stop() coord.join(threads) """ 運行結果: 第1次獲取數據,每次batch=6... [[ 0. 1.] [ 2. 3.] [ 4. 5.] [ 6. 7.] [ 8. 9.] [10. 11.]] [0 1 2 3 4 5] 6 第2次獲取數據,每次batch=6... [[12. 13.] [14. 15.] [16. 17.] [18. 19.] [ 0. 1.] [ 2. 3.]] [6 7 8 9 0 1] 6 """
案例5:從本地批量的讀取圖片 — string_input_producer() 與 batch()


1 import tensorflow as tf 2 import glob 3 import cv2 as cv 4 5 def read_imgs(filename, picture_format, input_image_shape, batch_size=1): 6 """ 7 從本地批量的讀取圖片 8 :param filename: 圖片路徑(包括圖片的文件名),[] 9 :param picture_format: 圖片的格式,如 bmp,jpg,png等; string 10 :param input_image_shape: 輸入影像的大小; (h,w,c)或[] 11 :param batch_size: 每次從文件隊列中載入圖片的數量; int 12 :return: batch_size張圖片數據, Tensor 13 """ 14 global new_img 15 # 創建文件隊列 16 file_queue = tf.train.string_input_producer(filename, num_epochs=1, shuffle=True) 17 # 創建文件讀取器 18 reader = tf.WholeFileReader() 19 # 讀取文件隊列中的文件 20 _, img_bytes = reader.read(file_queue) 21 # print(img_bytes) # Tensor("ReaderReadV2_19:1", shape=(), dtype=string) 22 # 對圖片進行解碼 23 if picture_format == ".bmp": 24 new_img = tf.image.decode_bmp(img_bytes, channels=1) 25 elif picture_format == ".jpg": 26 new_img = tf.image.decode_jpeg(img_bytes, channels=3) 27 else: 28 pass 29 # 重新設置圖片的大小 30 # new_img = tf.image.resize_images(new_img, input_image_shape) 31 new_img = tf.reshape(new_img, input_image_shape) 32 # 設置圖片的數據類型 33 new_img = tf.image.convert_image_dtype(new_img, tf.uint8) 34 35 # return new_img 36 return tf.train.batch([new_img], batch_size) 37 38 39 def main(): 40 image_path = glob.glob(r'F:\demo\FaceRecognition\人臉庫\ORL\*.bmp') 41 image_batch = read_imgs(image_path, ".bmp", (112, 92, 1), 5) 42 print(type(image_batch)) 43 # image_path = glob.glob(r'.\*.jpg') 44 # image_batch = read_imgs(image_path, ".jpg", (313, 500, 3), 1) 45 46 sess = tf.Session() 47 sess.run(tf.local_variables_initializer()) 48 tf.train.start_queue_runners(sess=sess) 49 50 image_batch = sess.run(image_batch) 51 print(type(image_batch)) # <class 'numpy.ndarray'> 52 53 for i in range(image_batch.__len__()): 54 cv.imshow("win_"+str(i), image_batch[i]) 55 cv.waitKey() 56 cv.destroyAllWindows() 57 58 def start(): 59 image_path = glob.glob(r'F:\demo\FaceRecognition\人臉庫\ORL\*.bmp') 60 image_batch = read_imgs(image_path, ".bmp", (112, 92, 1), 5) 61 print(type(image_batch)) # <class 'tensorflow.python.framework.ops.Tensor'> 62 63 64 with tf.Session() as sess: 65 sess.run(tf.local_variables_initializer()) 66 coord = tf.train.Coordinator() # 執行緒的協調器 67 threads = tf.train.start_queue_runners(sess, coord) # 開始在圖表中收集隊列運行器 68 image_batch = sess.run(image_batch) 69 print(type(image_batch)) # <class 'numpy.ndarray'> 70 71 for i in range(image_batch.__len__()): 72 cv.imshow("win_"+str(i), image_batch[i]) 73 cv.waitKey() 74 cv.destroyAllWindows() 75 76 # 若使用 with 方式打開 Session,且沒加如下2行語句,則會出錯 77 # ERROR:tensorflow:Exception in QueueRunner: Enqueue operation was cancelled; 78 # 原因:文件隊列執行緒還處於工作狀態(隊列中還有圖片數據),而載入完batch_size張圖片會話就會自動關閉,同時關閉文件隊列執行緒 79 coord.request_stop() 80 coord.join(threads) 81 82 83 if __name__ == "__main__": 84 # main() 85 start()
從本地批量的讀取圖片案例
案列6:TFRecord文件打包與讀取


1 def write_TFRecord(filename, data, labels, is_shuffler=True): 2 """ 3 將數據打包成TFRecord格式 4 :param filename: 打包後路徑名,默認在工程目錄下創建該文件;String 5 :param data: 需要打包的文件路徑名;list 6 :param labels: 對應文件的標籤;list 7 :param is_shuffler:是否隨機初始化打包後的數據,默認:True;Bool 8 :return: None 9 """ 10 im_data = list(data) 11 im_labels = list(labels) 12 13 index = [i for i in range(im_data.__len__())] 14 if is_shuffler: 15 np.random.shuffle(index) 16 17 # 創建寫入器,然後使用該對象寫入樣本example 18 writer = tf.python_io.TFRecordWriter(filename) 19 for i in range(im_data.__len__()): 20 im_d = im_data[index[i]] # im_d:存放著第index[i]張圖片的路徑資訊 21 im_l = im_labels[index[i]] # im_l:存放著對應圖片的標籤資訊 22 23 # # 獲取當前的圖片數據 方式一: 24 # data = cv2.imread(im_d) 25 # # 創建樣本 26 # ex = tf.train.Example( 27 # features=tf.train.Features( 28 # feature={ 29 # "image": tf.train.Feature( 30 # bytes_list=tf.train.BytesList( 31 # value=[data.tobytes()])), # 需要打包成bytes類型 32 # "label": tf.train.Feature( 33 # int64_list=tf.train.Int64List( 34 # value=[im_l])), 35 # } 36 # ) 37 # ) 38 # 獲取當前的圖片數據 方式二:相對於方式一,打包文件佔用空間小了一半多 39 data = tf.gfile.FastGFile(im_d, "rb").read() 40 ex = tf.train.Example( 41 features=tf.train.Features( 42 feature={ 43 "image": tf.train.Feature( 44 bytes_list=tf.train.BytesList( 45 value=[data])), # 此時的data已經是bytes類型 46 "label": tf.train.Feature( 47 int64_list=tf.train.Int64List( 48 value=[im_l])), 49 } 50 ) 51 ) 52 53 # 寫入將序列化之後的樣本 54 writer.write(ex.SerializeToString()) 55 # 關閉寫入器 56 writer.close()
TFRecord文件打包案列


1 import tensorflow as tf 2 import cv2 3 4 def read_TFRecord(file_list, batch_size=10): 5 """ 6 讀取TFRecord文件 7 :param file_list: 存放TFRecord的文件名,List 8 :param batch_size: 每次讀取圖片的數量 9 :return: 解析後圖片及對應的標籤 10 """ 11 file_queue = tf.train.string_input_producer(file_list, num_epochs=None, shuffle=True) 12 reader = tf.TFRecordReader() 13 _, ex = reader.read(file_queue) 14 batch = tf.train.shuffle_batch([ex], batch_size, capacity=batch_size * 10, min_after_dequeue=batch_size * 5) 15 16 feature = { 17 'image': tf.FixedLenFeature([], tf.string), 18 'label': tf.FixedLenFeature([], tf.int64) 19 } 20 example = tf.parse_example(batch, features=feature) 21 22 images = tf.decode_raw(example['image'], tf.uint8) 23 images = tf.reshape(images, [-1, 32, 32, 3]) 24 25 return images, example['label'] 26 27 28 29 def main(): 30 # filelist = ['data/train.tfrecord'] 31 filelist = ['data/test.tfrecord'] 32 images, labels = read_TFRecord(filelist, 2) 33 with tf.Session() as sess: 34 sess.run(tf.local_variables_initializer()) 35 coord = tf.train.Coordinator() 36 threads = tf.train.start_queue_runners(sess=sess, coord=coord) 37 38 try: 39 while not coord.should_stop(): 40 for i in range(1): 41 image_bth, _ = sess.run([images, labels]) 42 print(_) 43 44 cv2.imshow("image_0", image_bth[0]) 45 cv2.imshow("image_1", image_bth[1]) 46 break 47 except tf.errors.OutOfRangeError: 48 print('read done') 49 finally: 50 coord.request_stop() 51 coord.join(threads) 52 cv2.waitKey(0) 53 cv2.destroyAllWindows() 54 55 if __name__ == "__main__": 56 main()
TFReord文件的讀取案列