tensorflow的數據輸入

tensorflow有兩種數據輸入方法,比較簡單的一種是使用feed_dict,這種方法在畫graph的時候使用placeholder來站位,在真正run的時候經過feed字典把真實的輸入傳進去。比較簡單再也不介紹。bash

比較惱火的是第二種方法,直接從文件中讀取數據(其實第一種也能夠咱們本身從文件中讀出來以後使用feed_dict傳進去,但方法二tf提供很完善的一套類和函數造成一個相似pipeline同樣的讀取線):
1.使用tf.train.string_input_producer函數把咱們須要的所有文件打包爲一個tf內部的queue類型,以後tf開文件就從這個queue中取目錄了,要注意一點的是這個函數的shuffle參數默認是True,也就是你傳給他文件順序是1234,可是到時候讀就不必定了,我一開始每次跑訓練第一次迭代的樣本都不同,還納悶了很久,就是這個緣由。網絡

files_in = ["./data/data_batch%d.bin" % i for i in range(1, 6)] files = tf.train.string_input_producer(files_in)

2.搞一個reader,不一樣reader對應不一樣的文件結構,好比度bin文件tf.FixedLengthRecordReader就比較好,由於每次讀等長的一段數據。若是要讀什麼別的結構也有相應的reader。dom

reader = tf.FixedLengthRecordReader(record_bytes=1+32*32*3)

3.用reader的read方法,這個方法須要一個IO類型的參數,就是咱們上邊string_input_producer輸出的那個queue了,reader從這個queue中取一個文件目錄,而後打開它經行一次讀取,reader的返回是一個tensor(這一點很重要,咱們如今寫的這些讀取代碼並非真的在讀數據,仍是在畫graph,和定義神經網絡是同樣的,這時候的操做在run以前都不會執行,這個返回的tensor也沒有值,他僅僅表明graph中的一個結點)。函數

key, value = reader.read(files)

4.對這個tensor作些數據與處理,好比CIFAR1-10中label和image數據是糅在一塊兒的,這裏用slice把他們切開,切成兩個tensor(注意這個兩個tensor是對應的,一個image對一個label,對叉了後便訓練就完了),而後對image的tensor作data augmentation。ui

data = tf.decode_raw(value, tf.uint8) label = tf.cast(tf.slice(data, [0], [1]), tf.int64) raw_image = tf.reshape(tf.slice(data, [1], [32*32*3]), [3, 32, 32]) image = tf.cast(tf.transpose(raw_image, [1, 2, 0]), tf.float32) lr_image = tf.image.random_flip_left_right(image) br_image = tf.image.random_brightness(lr_image, max_delta=63) rc_image = tf.image.random_contrast(br_image, lower=0.2, upper=1.8) std_image = tf.image.per_image_standardization(rc_image)

5.這時候能夠發現,這個tensor表明的是一個樣本([高管道]),可是訓練網絡的時候的輸入通常都是一推樣本([樣本數寬*管道]),咱們就要用tf.train.batch或者tf.train.shuffle_batch這個函數把一個一個小樣本的tensor打包成一個高一維度的樣本batch,這些函數的輸入是單個樣本,輸出就是4D的樣本batch了,其內部原理彷佛是建立了一個queue,而後不斷調用你的單樣本tensor得到樣本,直到queue裏邊有足夠的樣本,而後一次返回一堆樣本,組成樣本batch。spa

images, labels = tf.train.batch([std_image, label], batch_size=100, num_threads=16, capacity=int(50000* 0.4 + 3 * batch_size))

5.事實上一直到上一部的images這個tensor,都尚未真實的數據在裏邊,咱們必須用Session run一下這個4D的tensor,纔會真的有數據出來。這個原理就和咱們定義好的神經網絡run一下出結果同樣,你一run這個4D tensor,他就會順着本身的operator找本身依賴的其餘tensor,一路最後找到最開始reader那裏。code

除了上邊講的原理,其中還要注意幾點
1.tf.train.start_queue_runners(sess=sess)這一步必定要運行,且其位置要在定義好讀取graph以後,在真正run以前,其做用是把queue裏邊的內容初始化,不跑這句一開始string_input_producer那裏就沒用,整個讀取流水線都沒用了。server

training_images = tf.train.batch(XXXXXXXXXXXXXXX) tf.train.start_queue_runners(sess=self.sess) real_images = sess.run(training_images)

2.image和label必定要一塊兒run,要記清楚咱們的image和label是在一張graph裏邊的,跑一次那個graph,這兩個tensor都會出結果,且同一次跑出來的image和label纔是對應的,若是你run兩次,第一次爲了拿image第二次爲了拿label,那整個就叉了,由於第一次跑出來第0到100號image和0到100號label,第二次跑出來第100到200的image和第100到200的label,你拿到了0~100的image和100~200的label,整個樣本分類全不對,最後網絡確定跑不出結果。圖片

training_images, training_labels = read_image()
tf.train.start_queue_runners(sess=self.sess) real_images = sess.run(training_images) # 讀出來是真的圖片,可是和label對不上 real_labels = sess.run(training_labels) # 讀出來是真的label,可是和image對不上 # 正確調用方法,經過跑一次graph,將成套的label和image讀出來 real_images, real_labels = sess.run([training_images, training_labels])
相關文章
相關標籤/搜索