0
  • 聊天消息
  • 系統(tǒng)消息
  • 評(píng)論與回復(fù)
登錄后你可以
  • 下載海量資料
  • 學(xué)習(xí)在線(xiàn)課程
  • 觀看技術(shù)視頻
  • 寫(xiě)文章/發(fā)帖/加入社區(qū)
會(huì)員中心
創(chuàng)作中心

完善資料讓更多小伙伴認(rèn)識(shí)你,還能領(lǐng)取20積分哦,立即完善>

3天內(nèi)不再提示

構(gòu)建簡(jiǎn)單數(shù)據(jù)管道,為什么tf.data要比f(wàn)eed_dict更好?

zhKF_jqr_AI ? 來(lái)源:lq ? 2018-12-03 09:08 ? 次閱讀

在大多數(shù)面向初學(xué)者的TensorFlow教程里,作者通常會(huì)建議讀者在會(huì)話(huà)中用feed_dict為模型導(dǎo)入數(shù)據(jù)——feed_dict是一個(gè)字典,能為占位符饋送數(shù)據(jù)。但是,其實(shí)TF提供了另一種更好的、更簡(jiǎn)單的方法:只需使用tf.dataAPI,你就能用幾行代碼搞定高性能數(shù)據(jù)管道。

那么tf.data的優(yōu)勢(shì)具體在哪里呢?如下圖所示,雖然feed_dict的靈活性大家有目共睹,但每當(dāng)我們需要等待CPU把數(shù)據(jù)饋送進(jìn)來(lái)時(shí),GPU就一直處于閑置狀態(tài),也就是程序運(yùn)行效率太低。

而tf.data管道沒(méi)有這個(gè)問(wèn)題,它能提前抓取下個(gè)batch的數(shù)據(jù),降低總體閑置時(shí)間。在這個(gè)基礎(chǔ)上,如果我們采用并行數(shù)據(jù)導(dǎo)入,或者事先進(jìn)行數(shù)據(jù)預(yù)處理,整個(gè)過(guò)程就更快了。

在5分鐘內(nèi)實(shí)現(xiàn)小型圖像管道

要構(gòu)建一個(gè)簡(jiǎn)單數(shù)據(jù)管道,首先我們需要兩個(gè)對(duì)象:一個(gè)用于存儲(chǔ)數(shù)據(jù)集的tf.data.Dataset,以及一個(gè)允許我們逐個(gè)從數(shù)據(jù)集中提取樣本的tf.data.Iterator。

對(duì)于tf.data.Dataset,它在圖像管道中是這樣的:

[

[Tensor(image), Tensor(label)],

[Tensor(image), Tensor(label)],

...

]

之后我們就可以用tf.data.Iterator逐個(gè)檢索圖像標(biāo)簽對(duì)。在實(shí)踐中,多個(gè)圖像標(biāo)簽對(duì)通常會(huì)組成元素序列,方便迭代器進(jìn)行提取。

至于數(shù)據(jù)集,DatasetAPI有兩種創(chuàng)建數(shù)據(jù)集的方法,其一是從源(如Python中的文件名列表)創(chuàng)建數(shù)據(jù)集,其二是可以直接在現(xiàn)有數(shù)據(jù)集上應(yīng)用轉(zhuǎn)換,下面是一些示例:

Dataset(list of image files) → Dataset(actual images)

Dataset(6400 images) → Dataset(64 batches with 100 images each)

Dataset(list of audio files) → Dataset(shuffled list of audio files)

定義計(jì)算圖

小型圖像管道的大致情況如下圖所示:

所有代碼都和模型、損失、優(yōu)化器等一起放在我們的計(jì)算圖定義中。首先,我們要從文件列表中創(chuàng)建一個(gè)張量。

# define list of files

files = ['a.png', 'b.png', 'c.png', 'd.png']

# create a dataset from filenames

dataset = tf.data.Dataset.from_tensor_slices(files)

之后是定義一個(gè)函數(shù)來(lái)從其路徑加載圖像(作為張量),并調(diào)用tf.data.Dataset.map()把函數(shù)用于數(shù)據(jù)集中的所有元素(文件路徑)。如果想并行調(diào)用函數(shù),你也可以設(shè)置num_parallel_calls=n里的map()參數(shù)。

# Source

def load_image(path):

image_string = tf.read_file(path)

# Don't use tf.image.decode_image, or the output shape will be undefined

image = tf.image.decode_jpeg(image_string, channels=3)

# This will convert to float values in [0, 1]

image = tf.image.convert_image_dtype(image, tf.float32)

image = tf.image.resize_images(image, [image_size, image_size])

return image

# Apply the function load_image to each filename in the dataset

dataset = dataset.map(load_image, num_parallel_calls=8)

然后是用tf.data.Dataset.batch()創(chuàng)建batch:

# Create batches of 64 images each

dataset = dataset.batch(64)

如果想減少GPU閑置時(shí)間,我們可以在管道末尾添加tf.data.Dataset.prefetch(buffer_size),其中buffer_size這個(gè)參數(shù)表示預(yù)抓取的batch數(shù),我們一般設(shè)buffer_size=1,但在某些情況下,尤其是處理每個(gè)batch耗時(shí)不同時(shí),我們也可以適當(dāng)擴(kuò)大一點(diǎn)。

dataset = dataset.prefetch(buffer_size=1)

最后,我們?cè)賱?chuàng)建一個(gè)迭代器遍歷數(shù)據(jù)集。雖然迭代器的選擇有很多,但對(duì)于大多數(shù)任務(wù),我們還是建議選擇可以初始化的迭代器。

iterator = dataset.make_initializable_iterator()

調(diào)用tf.data.Iterator.get_next()創(chuàng)建占位符張量,每次評(píng)估時(shí),TensorFlow都會(huì)填充下一batch的圖像。

batch_of_images = iterator.get_next()

如果寫(xiě)到這里,你突然想換回feed_dict的方法,你可以用batch_of_images把之前的占位符全都替換掉。

運(yùn)行會(huì)話(huà)

現(xiàn)在,我們就可以向往常一樣運(yùn)行模型了。但在每個(gè)epoch前,記得先評(píng)估iterator.initializer的op和tf.errors.OutOfRangeError有沒(méi)有拋出異常。

with tf.Session() as session:

for i in range(epochs):

session.run(iterator.initializer)

try:

# Go through the entire dataset

whileTrue:

image_batch = session.run(batch_of_images)

except tf.errors.OutOfRangeError:

print('End of Epoch.')

nvidia-smi這個(gè)命令可以幫我們監(jiān)控GPU利用率,找到數(shù)據(jù)管道中的瓶頸。正常情況下,GPU的平均利用率應(yīng)該高于70%-80%。

更完整的數(shù)據(jù)管道

Shuffle

在Dataset里,tf.data.Dataset.shuffle()是一個(gè)比較常用的方法,它可以用來(lái)打亂數(shù)據(jù)集中的數(shù)據(jù)順序。它的參數(shù)buffer_size指定的是一次打亂的元素?cái)?shù)量,一般情況下,我們建議把這個(gè)參數(shù)值設(shè)大一點(diǎn),最好一次性就能把整個(gè)數(shù)據(jù)集洗牌,因?yàn)槿绻麉?shù)過(guò)小,它可能會(huì)造成意料之外的偏差。

dataset = tf.data.Dataset.from_tensor_slices(files)

dataset = dataset.shuffle(len(files))

數(shù)據(jù)增強(qiáng)

數(shù)據(jù)增強(qiáng)是擴(kuò)大數(shù)據(jù)集的一種常用方式,這方面常用的函數(shù)有tf.image.random_flip_left_right()、tf.image.random_brightness()和tf.image.random_saturation():

# Source

def train_preprocess(image):

image = tf.image.random_flip_left_right(image)

image = tf.image.random_brightness(image, max_delta=32.0 / 255.0)

image = tf.image.random_saturation(image, lower=0.5, upper=1.5)

# Make sure the image is still in [0, 1]

image = tf.clip_by_value(image, 0.0, 1.0)

return image

標(biāo)簽

要想在圖像上加載標(biāo)簽(或其他元數(shù)據(jù)),我們只需在創(chuàng)建初始數(shù)據(jù)集時(shí)就把它們包含在內(nèi):

# files is a python list of image filenames

# labels is a numpy array with label data for each image

dataset = tf.data.Dataset.from_tensor_slices((files, labels))

確保應(yīng)用于數(shù)據(jù)集的所有.map()函數(shù)都允許標(biāo)簽數(shù)據(jù)通過(guò):

def load_image(path, label):

# load image

return image, label

dataset = dataset.map(load_image)

聲明:本文內(nèi)容及配圖由入駐作者撰寫(xiě)或者入駐合作網(wǎng)站授權(quán)轉(zhuǎn)載。文章觀點(diǎn)僅代表作者本人,不代表電子發(fā)燒友網(wǎng)立場(chǎng)。文章及其配圖僅供工程師學(xué)習(xí)之用,如有內(nèi)容侵權(quán)或者其他違規(guī)問(wèn)題,請(qǐng)聯(lián)系本站處理。 舉報(bào)投訴
  • gpu
    gpu
    +關(guān)注

    關(guān)注

    27

    文章

    4590

    瀏覽量

    128139
  • 數(shù)據(jù)集
    +關(guān)注

    關(guān)注

    4

    文章

    1197

    瀏覽量

    24535

原文標(biāo)題:構(gòu)建簡(jiǎn)單數(shù)據(jù)管道,為什么tf.data要比f(wàn)eed_dict更好?

文章出處:【微信號(hào):jqr_AI,微信公眾號(hào):論智】歡迎添加關(guān)注!文章轉(zhuǎn)載請(qǐng)注明出處。

收藏 人收藏

    評(píng)論

    相關(guān)推薦

    帶校時(shí)功能的簡(jiǎn)單數(shù)字鐘

    用555制成振蕩器,74LS90制成分頻器,帶校時(shí)功能的簡(jiǎn)單數(shù)字鐘。
    發(fā)表于 02-01 18:35

    簡(jiǎn)單數(shù)據(jù)采集系統(tǒng)怎樣清除上次采集的數(shù)據(jù)

    各位前輩:我用labview編了一個(gè)簡(jiǎn)單數(shù)據(jù)采集系統(tǒng),現(xiàn)在想在暫停后,再次運(yùn)行時(shí),清除掉上次采集的數(shù)據(jù),需要怎樣做????
    發(fā)表于 03-07 21:29

    Tensorflow快餐教程(1) - 30行代碼搞定手寫(xiě)識(shí)別

    ) == sess.run(predict_op, feed_dict={X: teX})))經(jīng)過(guò)100輪的訓(xùn)練,我們的準(zhǔn)確率是92.36%。無(wú)腦的淺層神經(jīng)網(wǎng)絡(luò)用了最簡(jiǎn)單的線(xiàn)性模型,我們換成經(jīng)典的神經(jīng)網(wǎng)絡(luò)來(lái)實(shí)現(xiàn)這個(gè)功能
    發(fā)表于 04-28 16:08

    TFTF定義兩個(gè)變量相乘之placeholder先hold類(lèi)似變量+feed_dict最后外界傳入值

    TFTF定義兩個(gè)變量相乘之placeholder先hold類(lèi)似變量+feed_dict最后外界傳入值
    發(fā)表于 12-21 10:35

    內(nèi)建屬性__dict__的簡(jiǎn)單概述

    Python中內(nèi)建屬性__dict__
    發(fā)表于 07-24 10:16

    簡(jiǎn)單數(shù)字鐘電路圖

    簡(jiǎn)單數(shù)字鐘電路圖
    發(fā)表于 01-08 11:11 ?179次下載

    簡(jiǎn)單數(shù)字鐘電路圖

    簡(jiǎn)單數(shù)字鐘電路圖
    發(fā)表于 01-08 11:11 ?103次下載

    如何將自定義圖片輸入到TensorFlow的訓(xùn)練模型

    對(duì)于上述代碼中與模型構(gòu)建相關(guān)的代碼,請(qǐng)查閱官方《Deep MNIST for Experts》一節(jié)的內(nèi)容進(jìn)行理解。在本文中,需要重點(diǎn)掌握的是如何將本地圖片源整合成為feed_dict可接受的格式。其中最關(guān)鍵的是這兩行
    的頭像 發(fā)表于 08-17 15:57 ?8853次閱讀

    【連載】深度學(xué)習(xí)筆記13:Tensorflow實(shí)戰(zhàn)之手寫(xiě)mnist手寫(xiě)數(shù)字識(shí)別

    ,1)) accuracy = tf.reduce_mean(tf.cast(correct_prediction, "float")) print(accuracy.eval(feed_dict
    的頭像 發(fā)表于 10-30 18:50 ?7825次閱讀

    tf.data API的功能和最佳實(shí)踐操作

    tf.data API 通過(guò) tf.data.Dataset.prefetch 轉(zhuǎn)換提供了一個(gè)軟件 pipelining 操作機(jī)制,該轉(zhuǎn)換可用于將數(shù)據(jù)生成的時(shí)間與所消耗時(shí)間分離。特別是,轉(zhuǎn)換使用后
    的頭像 發(fā)表于 01-11 13:51 ?1.3w次閱讀

    TensorFlow 2.0將專(zhuān)注于簡(jiǎn)單性和易用性

    使用 tf.data 加載數(shù)據(jù)。使用輸入管道讀取訓(xùn)練數(shù)據(jù),用 tf.data 創(chuàng)建的輸入線(xiàn)程讀取訓(xùn)練數(shù)據(jù)
    的頭像 發(fā)表于 01-18 10:44 ?2525次閱讀
    TensorFlow 2.0將專(zhuān)注于<b class='flag-5'>簡(jiǎn)單</b>性和易用性

    python教程之變量和簡(jiǎn)單數(shù)據(jù)類(lèi)型

    本文檔的主要內(nèi)容詳細(xì)介紹的是python教程之變量和簡(jiǎn)單數(shù)據(jù)類(lèi)型。
    發(fā)表于 04-26 08:00 ?7次下載
    python教程之變量和<b class='flag-5'>簡(jiǎn)單數(shù)據(jù)</b>類(lèi)型

    C語(yǔ)言簡(jiǎn)單數(shù)據(jù)解析

    C語(yǔ)言簡(jiǎn)單數(shù)據(jù)解析? 在嵌入式開(kāi)發(fā)中通過(guò)串口等傳輸數(shù)據(jù)通常使用JSON解析,雖然JSON十分強(qiáng)大,但JSON耗費(fèi)資源太多,數(shù)據(jù)的打包和解析都比較麻煩。有時(shí)我們只是傳輸一些簡(jiǎn)單
    發(fā)表于 01-13 15:17 ?8次下載
    C語(yǔ)言<b class='flag-5'>簡(jiǎn)單數(shù)據(jù)</b>解析

    使用tf.data進(jìn)行數(shù)據(jù)集處理

    在進(jìn)行AI模型訓(xùn)練過(guò)程前,需要對(duì)數(shù)據(jù)集進(jìn)行處理, Tensorflow提供了tf.data數(shù)據(jù)集處理模塊,通過(guò)該接口能夠輕松實(shí)現(xiàn)數(shù)據(jù)集預(yù)處理。tf.
    的頭像 發(fā)表于 11-29 15:34 ?1102次閱讀

    網(wǎng)絡(luò)工程師學(xué)Python之變量和簡(jiǎn)單數(shù)據(jù)類(lèi)型

    Python是一種廣泛應(yīng)用于編程和數(shù)據(jù)科學(xué)的高級(jí)編程語(yǔ)言,它支持許多不同類(lèi)型的變量和簡(jiǎn)單數(shù)據(jù)類(lèi)型。
    的頭像 發(fā)表于 04-15 17:56 ?663次閱讀