【小白學(xué)PyTorch】17.TFrec文件的創(chuàng)建與讀取
小白學(xué)PyTorch | 16 TF2讀取圖片的方法
小白學(xué)PyTorch | 15 TF2實現(xiàn)一個簡單的服裝分類任務(wù)
小白學(xué)PyTorch | 14 tensorboardX可視化教程
小白學(xué)PyTorch | 13 EfficientNet詳解及PyTorch實現(xiàn)
小白學(xué)PyTorch | 12 SENet詳解及PyTorch實現(xiàn)
小白學(xué)PyTorch | 11 MobileNet詳解及PyTorch實現(xiàn)
小白學(xué)PyTorch | 10 pytorch常見運算詳解
小白學(xué)PyTorch | 9 tensor數(shù)據(jù)結(jié)構(gòu)與存儲結(jié)構(gòu)
小白學(xué)PyTorch | 8 實戰(zhàn)之MNIST小試牛刀
小白學(xué)PyTorch | 7 最新版本torchvision.transforms常用API翻譯與講解
小白學(xué)PyTorch | 6 模型的構(gòu)建訪問遍歷存儲(附代碼)
小白學(xué)PyTorch | 5 torchvision預(yù)訓(xùn)練模型與數(shù)據(jù)集全覽
小白學(xué)PyTorch | 4 構(gòu)建模型三要素與權(quán)重初始化
小白學(xué)PyTorch | 3 淺談Dataset和Dataloader
小白學(xué)PyTorch | 2 淺談訓(xùn)練集驗證集和測試集
小白學(xué)PyTorch | 1 搭建一個超簡單的網(wǎng)絡(luò)
小白學(xué)PyTorch | 動態(tài)圖與靜態(tài)圖的淺顯理解
參考目錄:
1 為什么用tfrec文件
2 tfrec文件的內(nèi)部結(jié)構(gòu)
3 制作tfrec文件
4 讀取tfrec文件
本文的代碼已經(jīng)上傳公眾號后臺,回復(fù)【PyTorch】獲取。?
第一次接觸到TFrec文件,我也是比較蒙蔽的其實:
可以看到文件是.tfrec后綴的,而且先記住這個文件是186.72MB大小的。
1 為什么用tfrec文件
正常情況下我們用于訓(xùn)練的文件夾內(nèi)部往往會存著成千上萬的圖片或文本等文件,這些文件通常被散列存放。這種存儲方式有一些缺點:
占用磁盤空間; 一個一個讀取文件消耗時間
而tfrec格式的文件存儲形式會很合理的幫我們存儲數(shù)據(jù),核心就是tfrec內(nèi)部使用Protocol Buffer的二進制數(shù)據(jù)編碼方案,這個方案可以極大的壓縮存儲空間。
之前我們知道一個tfrec文件100多M,這是因為這個tfrec文件內(nèi)存儲了很多的圖片,類似于壓縮,對tfrec解壓縮后可以獲取到一部分的數(shù)據(jù)集,當(dāng)我們把全部的rfrec文件都解壓縮后,可以獲取到全部的數(shù)據(jù)集。
值得一提的是,rfrec文件內(nèi)除了可以存儲圖片,還可以存儲其他的數(shù)據(jù),比方說圖片的label。字符串,float類型等都可以轉(zhuǎn)換成二進制的方法,所以什么數(shù)據(jù)類型基本上都可以存儲到rfrec文件內(nèi),從而簡化讀取數(shù)據(jù)的過程。
2 tfrec文件的內(nèi)部結(jié)構(gòu)
tfrec文件時tensorflow的數(shù)據(jù)集存儲格式,tensorflow可以高效的讀取和處理這些數(shù)據(jù)集,因此我見過有的數(shù)據(jù)集因為是tfrec文件,所以用TF讀取數(shù)據(jù)集,然后用pytorch訓(xùn)練模型。
之前提到了tfrec文件里面是有多個樣本的,所以tfrec可以為是多個tf.train.Example文件組成的序列(每一個example是一個樣本),然后每一個tf.train.Example又是由若干個tf.train.Features字典組成。這個Features可以理解為這個樣本的一些信息,如果是圖片樣本,那么肯定有一個Features是圖片像素值數(shù)據(jù),一個Features是圖片的標(biāo)簽值;如果是預(yù)測任務(wù),那么這個Feature可能就是一些字符串類型的特征
3 制作tfrec文件
import?tensorflow?as?tf
import?glob
#?先記錄一下要保存的tfrec文件的名字
tfrecord_file?=?'./train.tfrec'
#?獲取指定目錄的所有以jpeg結(jié)尾的文件list
images?=?glob.glob('./*.jpeg')
with?tf.io.TFRecordWriter(tfrecord_file)?as?writer:
????for?filename?in?images:
????????image?=?open(filename,?'rb').read()??#?讀取數(shù)據(jù)集圖片到內(nèi)存,image?為一個?Byte?類型的字符串
????????feature?=?{??#?建立?tf.train.Feature?字典
????????????'image':?tf.train.Feature(bytes_list=tf.train.BytesList(value=[image])),??#?圖片是一個?Bytes?對象
????????????'label':?tf.train.Feature(int64_list=tf.train.Int64List(value=[1])),
????????????'float':tf.train.Feature(float_list=tf.train.FloatList(value=[1.0,2.0])),
????????????'name':tf.train.Feature(bytes_list=tf.train.BytesList(value=[str.encode(filename)]))
????????}
????????#?tf.train.Example?在?tf.train.Features?外面又多了一層封裝
????????example?=?tf.train.Example(features=tf.train.Features(feature=feature))??#?通過字典建立?Example
????????writer.write(example.SerializeToString())??#?將?Example?序列化并寫入?TFRecord?文件
代碼中我們需要注意的地方是:
先讀取圖片,然后構(gòu)建一個字典來作為這個example的格式; 上面代碼中,字典中有四個屬性,首先是image圖片本身的像素值,然后有一個標(biāo)簽,標(biāo)簽是int類型,然后有一個float浮點類型,name是一個字符串類型,這個string類型的需要轉(zhuǎn)換成byte字節(jié)類型的才能進行存儲,所以這里使用 str.encode來把字符串轉(zhuǎn)換成字節(jié);然后這個features再經(jīng)過Example的封裝,再然后把這個example寫進這個tfrec文件中。
這一段代碼建議保存下來,方便以后的直接參考和復(fù)制。構(gòu)建tfrec文件對于tensorflow處理圖片來說,應(yīng)該是繞不過的一個步驟。
4 讀取tfrec文件
現(xiàn)在,我們運行完上面的代碼,應(yīng)該生成了一個./train.tfrec文件,下面我們再對這個文件進行讀取。
import?tensorflow?as?tf
dataset?=?tf.data.TFRecordDataset('./train.tfrec')
def?decode(example):
????feature_description?=?{
????????'image':?tf.io.FixedLenFeature([],?tf.string),
????????'label':?tf.io.FixedLenFeature([],?tf.int64),
????????'float':?tf.io.FixedLenFeature([1,?2],?tf.float32),
????????'name':?tf.io.FixedLenFeature([],?tf.string)
????}
????feature_dict?=?tf.io.parse_single_example(example,?feature_description)
????feature_dict['image']?=?tf.io.decode_jpeg(feature_dict['image'])??#?解碼?JEPG?圖片
????return?feature_dict
dataset?=?dataset.map(decode).batch(4)
for?i?in?dataset.take(1):
????print(i['image'].shape)
????print(i['label'].shape)
????print(i['float'].shape)
????print(bytes.decode(i['name'][0].numpy()))
首先使用專門用來讀取tfrec文件的方法 tf.data.TFRecordDataset,進行讀取,創(chuàng)建了一個dataset,但是這個dataset并不能直接使用,需要對tfrec中的example進行一些解碼;自己寫一個解碼函數(shù)decode,首先寫一個特征描述,我們知道在保存tfrec的時候每一個example有四個特征,這里需要對每一個特征確定他的類型,是string還是int還是float這樣的。 然后通過這個特征描述和 tf.io.parse_single_example方法,從example中提取到對應(yīng)的特征;因為image是一個圖片張量,而我們讀取的時候是讀取的tf.string的類型,所以使用 tf.io.decode_jpeg()來把字符串解碼成一個tensor張量。最后使用上節(jié)課講過的 .batch(4)把數(shù)據(jù)集每一個batch包含四個樣本。
上面代碼輸出的結(jié)果為:
需要注意的是這個如何把name轉(zhuǎn)換成string類型的,如果已經(jīng)在本地跑完了上面的代碼,可以自己看看i['name']是一個什么類型的,然后自己試試如何轉(zhuǎn)換成string類型的。上面的代碼是能成功轉(zhuǎn)換的。
下一次的內(nèi)容就是如何構(gòu)建模型,然后怎么把數(shù)據(jù)集喂給模型。
- END -往期精彩回顧
獲取一折本站知識星球優(yōu)惠券,復(fù)制鏈接直接打開:
https://t.zsxq.com/662nyZF
本站qq群704220115。
加入微信群請掃碼進群(如果是博士或者準(zhǔn)備讀博士請說明):
