前面講了製作tfrecord需要的基礎功能,今天會把迴圈部分的邏輯講完。
build_voc2012_data.py
(cont.)107行就是迴圈的開始,_NUM_SHARDS
設4表示shard_id
從0到3跑4圈。因為是用迴圈去使用shard,所以4個tfrecord分到的example並不是像玩撲克牌那樣,繞圈發牌,而是一個tfrecord發完num_per_shard
張後,再開下一個tfrecord。
108-110行則是設定tfrecord要叫什麼,假設output_dir是./result
,且假設list dir底下的txt檔叫voc2012_train.txt
,那tfrecord名稱就是voc2012_train-00000-of-00004.tfrecord
。
這樣的話4個tfrecord分別叫:0/4,1/4,2/4,3/4。
感覺把shard_id + 1比較符合直覺(1/4~4/4)。
112-114行,是在處理每個tfrecord會存放當初放在filenames
中編號幾到幾的資料。我覺得這裡的寫法可以記,像我就不會馬上想到這樣處理。
不明白不用print()的原因。
read byte
模式,之後再用read轉換。實際上應該可以直接用'r'就好。順便查一下為什麼他要這樣寫,跑去看官網的gfile沒有相關說明,那就看一下原始碼,這裡我就沒有切換branch,因為感覺不會差別太大。
然後看到super(),代表得去查_FileIO
的寫法,
就去github的.../python/lib/io/file_io.py找東西
發現看無就放棄。
build_data.py:
82行呼叫自定義的decode_image()
看到97行,session.sun()裡面的程式是_decode
,後面的feed_dict的前面是存放在變數self._decode_data
的placeholder,冒號(:)後面是還沒decode的data
67行:因為data reader是jpg格式,所以_decode
用的是decode_jpeg(),他接的tensor是self._decode_data
這個placeholder,然後在97行run的時候這個placeholder被丟入了當前還沒decode的data。