TF Boys (TensorFlow Boys ) 養成記(二): TensorFlow 數據讀取
1. 變數:創建,初始化,保存,載入,共享;
2. TensorFlow 的可視化學習,(r0.12版本後,加入了Embedding Visualization)
3. 數據的讀取;
4. 線程和隊列;
5. 分散式的TensorFlow;
6. 增加新的Ops;
7. 自定義數據讀取;
由於各種原因,本人只看了前5個部分,剩下的2個部分還沒來得及看,時間緊任務重,所以匆匆發車了,以後如果有用到的地方,再回過頭來研究。學習過程中深感官方文檔的繁雜冗餘極多多,特別是第三部分數據讀取,又臭又長,花了我好久時間,所以我想把第三部分整理如下,方便乘客們。
TensorFlow 有三種方法讀取數據:1)供給數據,用placeholder;2)從文件讀取;3)用常量或者是變數來預載入數據,適用於數據規模比較小的情況。供給數據沒什麼好說的,前面已經見過了,不難理解,我們就簡單的說一下從文件讀取數據。
官方的文檔里,從文件讀取數據是一段很長的描述,鏈接層出不窮,看完這個鏈接還沒看幾個字,就出現了下一個鏈接。
自己花了很久才認識路,所以想把這部分總結一下,帶帶我的乘客們。其實很簡單,首先要知道你要讀取的文件的格式,選擇對應的文件讀取器;然後,定位到數據文件夾下,用
["file0", "file1"] # or n[("file%d" % i) for i in range(2)]) # or ntf.train.match_filenames_oncen
選擇要讀取的文件的名字,用 tf.train.string_input_producer 函數來生成文件名隊列,這個函數可以設置shuffle = Ture,來打亂隊列,可以設置epoch = 5,過5遍訓練數據。
最後,選擇的文件讀取器,讀取文件名隊列並解碼,輸入 tf.train.shuffle_batch 函數中,生成 batch 隊列,傳遞給下一層。
1)假如你要讀取的文件是像 CSV 那樣的文本文件,用的文件讀取器和解碼器就是 TextLineReader 和 decode_csv 。
2)假如你要讀取的數據是像 cifar10 那樣的 .bin 格式的二進位文件,就用 tf.FixedLengthRecordReader 和 tf.decode_raw 讀取固定長度的文件讀取器和解碼器。如下列出了我的參考代碼:
class cifar10_data(object):n def __init__(self, filename_queue):n self.height = 32n self.width = 32n self.depth = 3n self.label_bytes = 1n self.image_bytes = self.height * self.width * self.depthn self.record_bytes = self.label_bytes + self.image_bytesn self.label, self.image = self.read_cifar10(filename_queue)n n def read_cifar10(self, filename_queue):n reader = tf.FixedLengthRecordReader(record_bytes = self.record_bytes)n key, value = reader.read(filename_queue)n record_bytes = tf.decode_raw(value, tf.uint8)n label=tf.cast(tf.slice(record_bytes,[0],[self.label_bytes]),tf.int32)n image_raw=tf.slice(record_bytes,[self.label_bytes],self.image_bytes])n image_raw=tf.reshape(image_raw,[self.depth, self.height,self.width])n image = tf.transpose(image_raw, (1,2,0)) n image = tf.cast(image, tf.float32)n return label, imagen ndef inputs(data_dir, batch_size, train = True, name = input):nn with tf.name_scope(name):n if train: n filenames = [os.path.join(data_dir,data_batch_%d.bin % ii) n for ii in range(1,6)]n for f in filenames:n if not tf.gfile.Exists(f):n raise ValueError(Failed to find file: + f)n n filename_queue = tf.train.string_input_producer(filenames)n read_input = cifar10_data(filename_queue)n images = read_input.imagen images = tf.image.per_image_whitening(images)n labels = read_input.labeln num_preprocess_threads = 16n image, label = tf.train.shuffle_batch(n [images,labels], batch_size = batch_size, n num_threads = num_preprocess_threads, n min_after_dequeue = 20000, n capacity = 20192)n n n return image, tf.reshape(label, [batch_size])n else:n ...n
3)如果你要讀取的數據是圖片,或者是其他類型的格式,那麼可以先把數據轉換成 TensorFlow 的標準支持格式 tfrecords ,它其實是一種二進位文件,通過修改 tf.train.Example 的Features,將 protocol buffer 序列化為一個字元串,再通過 tf.python_io.TFRecordWriter 將序列化的字元串寫入 tfrecords,然後再用跟上面一樣的方式讀取tfrecords,只是讀取器變成了tf.TFRecordReader,之後通過一個解析器tf.parse_single_example ,然後用解碼器 tf.decode_raw 解碼。
例如,對於生成式對抗網路GAN,我採用了這個形式進行輸入,部分代碼如下:
def _int64_feature(value):n return tf.train.Feature(int64_list = tf.train.Int64List(value = [value]))ndef _bytes_feature(value):n return tf.train.Feature(bytes_list = tf.train.BytesList(value = [value]))n ndef convert_to(data_path, name):n """n Converts s dataset to tfrecordsn """n rows = 64n cols = 64n depth = DEPTHn for ii in range(12):n writer = tf.python_io.TFRecordWriter(name + str(ii) + .tfrecords)n for img_name in os.listdir(data_path)[ii*16384 : (ii+1)*16384]:n img_path = data_path + img_namen img = Image.open(img_path)n h, w = img.size[:2]n j, k = (h - OUTPUT_SIZE) / 2, (w - OUTPUT_SIZE) / 2n box = (j, k, j + OUTPUT_SIZE, k+ OUTPUT_SIZE)n n img = img.crop(box = box)n img = img.resize((rows,cols))n img_raw = img.tobytes()n example = tf.train.Example(features = tf.train.Features(feature={n height: _int64_feature(rows),n weight: _int64_feature(cols),n depth: _int64_feature(depth),n image_raw: _bytes_feature(img_raw)}))n writer.write(example.SerializeToString())n writer.close()nnndef read_and_decode(filename_queue):n n """n read and decode tfrecordsn """n n reader = tf.TFRecordReader()n _, serialized_example = reader.read(filename_queue)n n features = tf.parse_single_example(serialized_example,features = {n image_raw:tf.FixedLenFeature([], tf.string)})n image = tf.decode_raw(features[image_raw], tf.uint8)n n return imagen
這裡,我的data_path下面有16384*12張圖,通過12次寫入Example操作,把圖片數據轉化成了12個tfrecords,每個tfrecords裡面有16384張圖。
4)如果想定義自己的讀取數據操作,請參考https://www.tensorflow.org/how_tos/new_data_formats/。
好了,今天的車到站了,請帶好隨身物品準備下車,明天老司機還有一趟車,請記得準時乘坐,車不等人。
參考文獻:
1. https://www.tensorflow.org/how_tos/
2. 沒了
推薦閱讀:
※需要一個「隨機梯度下降」的詳細教程?
※怎樣看待地平線機器人以深度強化學習演算法為切入點?
※請問如何將深度學習Caffe做成一個動態庫,方便在其他應用程序中調用?
※如何評價人們對電腦在圍棋上戰勝人類的時間預測?
※大家如何看待最近Kaggle的賓士比賽最後排名嚴重波動?
TAG:TensorFlow | 深度学习DeepLearning |