<kbd id="5sdj3"></kbd>
<th id="5sdj3"></th>

  • <dd id="5sdj3"><form id="5sdj3"></form></dd>
    <td id="5sdj3"><form id="5sdj3"><big id="5sdj3"></big></form></td><del id="5sdj3"></del>

  • <dd id="5sdj3"></dd>
    <dfn id="5sdj3"></dfn>
  • <th id="5sdj3"></th>
    <tfoot id="5sdj3"><menuitem id="5sdj3"></menuitem></tfoot>

  • <td id="5sdj3"><form id="5sdj3"><menu id="5sdj3"></menu></form></td>
  • <kbd id="5sdj3"><form id="5sdj3"></form></kbd>

    正確debug的TensorFlow的姿勢(shì)

    共 4922字,需瀏覽 10分鐘

     ·

    2022-03-23 10:42

    點(diǎn)擊上方小白學(xué)視覺”,選擇加"星標(biāo)"或“置頂

    重磅干貨,第一時(shí)間送達(dá)

    導(dǎo)讀

    TensorFlow代碼很難調(diào)試,這個(gè)大家已達(dá)成共識(shí),不過,就算是難,也還是需要調(diào)試的,畢竟誰也沒有把握不出bug,看看這篇文章能不能讓你減輕一點(diǎn)調(diào)試時(shí)的痛苦。

    當(dāng)討論在tensorflow上編寫代碼時(shí),總是將其與PyTorch進(jìn)行比較,討論框架有多復(fù)雜,以及為什么要使用tf.contrib的某些部分,做得太爛了。此外,我認(rèn)識(shí)很多數(shù)據(jù)科學(xué)家,他們只用Github上已有的repo來用tensorflow。對(duì)這個(gè)框架持這種態(tài)度的原因是非常不同的,但是今天讓我們關(guān)注更實(shí)際的問題:調(diào)試用tensorflow編寫的代碼并理解它的主要特性。

    ?

    核心抽象


    • 計(jì)算圖。第一個(gè)抽象是計(jì)算圖tf.Graph,它使框架能夠處理惰性評(píng)估模式(不是立即執(zhí)行,這是“傳統(tǒng)”命令式Python編程實(shí)現(xiàn)的)?;旧?,這種方法允許程序員創(chuàng)建tf.Tensor(邊)和tf.Operation (節(jié)點(diǎn)),它不是立即計(jì)算的,而是在執(zhí)行圖形時(shí)才計(jì)算的。這種構(gòu)造機(jī)器學(xué)習(xí)模型的方法在許多框架中都很常見(例如,在Apache Spark中使用了類似的思想),并且具有不同的優(yōu)缺點(diǎn),這在編寫和運(yùn)行代碼時(shí)表現(xiàn)得非常明顯。最主要和最重要的優(yōu)點(diǎn)是,數(shù)據(jù)流圖可以很容易地實(shí)現(xiàn)并行性和分布式執(zhí)行,而無需顯式地使用multiprocessing 模塊。在實(shí)踐中,編寫良好的tensorflow模型在啟動(dòng)時(shí)立即使用所有核心的資源,而不需要任何額外的配置。

      然而,這個(gè)工作流的一個(gè)非常明顯的缺點(diǎn)是,一旦你構(gòu)建圖的時(shí)候,沒有用提供的輸入來運(yùn)行,你就不能確保它不會(huì)崩潰。它肯定會(huì)崩潰。此外,除非你已經(jīng)執(zhí)行了圖形,否則你無法估計(jì)它的運(yùn)行時(shí)間。

      計(jì)算圖的主要組成部分是圖集合和圖結(jié)構(gòu)。嚴(yán)格地說,圖的結(jié)構(gòu)是前面討論的特定的節(jié)點(diǎn)集和邊集,而圖集合是可以邏輯地分組的變量集。例如,檢索圖形的可訓(xùn)練變量的常用方法是'tf.get_collection(tf.GraphKeys.TRAINABLE_VARIABLES)。

    • 會(huì)話 。第二個(gè)抽象與第一個(gè)抽象高度相關(guān),并且有更復(fù)雜的解釋:tensorflow會(huì)話的tf.Session用于客戶端程序和c++運(yùn)行時(shí)之間的連接(如你所知,tensorflow是用c++編寫的)。為什么是c++ ?答案是,通過這種語言實(shí)現(xiàn)的數(shù)學(xué)運(yùn)算可以得到很好的優(yōu)化,因此,計(jì)算圖運(yùn)算可以得到很好的處理。

      如果你正在使用低級(jí)的tensorflow API(大多數(shù)Python開發(fā)人員都在使用),則tensorflow session將作為上下文管理器調(diào)用:with tf.Session() as sess:。沒有參數(shù)傳遞給構(gòu)造函數(shù)(如前一個(gè)示例)的會(huì)話僅使用本地機(jī)器的資源和默認(rèn)的tensorflow圖,但它也可以通過分布式tensorflow運(yùn)行時(shí)訪問遠(yuǎn)程設(shè)備。在實(shí)踐中,如果沒有會(huì)話,計(jì)算圖就不能存在(沒有會(huì)話,它就不能執(zhí)行),而會(huì)話總是有一個(gè)指向全局圖的指針。

      深入研究運(yùn)行會(huì)話的細(xì)節(jié),值得注意的主要一點(diǎn)是它的語法:tf.Session.run()。它可以作為張量、操作或類張量對(duì)象的參數(shù)獲取(或獲取列表)。另外,可以傳遞feed_dict(這個(gè)可選參數(shù)是tf.placeholder的對(duì)象及其值)以及一組選項(xiàng)。

    ?

    實(shí)驗(yàn)中一些可能的問題以及可能的解決方案


    1. 會(huì)話加載并通過預(yù)先訓(xùn)練的模型進(jìn)行預(yù)測(cè)。這就是瓶頸,我花了幾周的時(shí)間來理解、調(diào)試和修復(fù)它。我想高度關(guān)注這個(gè)問題,并描述兩種重新加載預(yù)訓(xùn)練模型(圖和會(huì)話)并使用它的可能技術(shù)。

      首先,當(dāng)我們談?wù)摷虞d模型時(shí),我們真正的意思是什么?當(dāng)然,為了做到這一點(diǎn),我們需要事先訓(xùn)練并保存它。后者通常是通過tf.train.Saver.save完成的。因此,我們有3個(gè)二進(jìn)制文件.index、.meta.data-00000-of-00001,其中包含恢復(fù)會(huì)話和圖所需的所有數(shù)據(jù)。

      要加載以這種方式保存的模型,需要通過tf.train.import_meta_graph() (參數(shù)是.meta的文件)來恢復(fù)。按照前一段描述的步驟之后,所有變量(包括所謂的“隱藏”變量,稍后將討論)都將被移植到當(dāng)前圖中。檢索某個(gè)有自己名字的張量(記住,它可能不同于你初始化它時(shí)使用的張量,這取決于創(chuàng)建張量的范圍和操作的結(jié)果)應(yīng)該執(zhí)行graph.get_tensor_by_name()。這是第一種方法。

      第二種方法更顯式,也更難實(shí)現(xiàn)(對(duì)于我一直在使用的模型的架構(gòu),我還沒有成功用起來),它的主要思想是將圖的邊(張量)顯式地保存到.npy.npz文件中,然后將它們加載回圖中(并根據(jù)創(chuàng)建它們的范圍分配適當(dāng)?shù)拿Q)。這種方法的問題在于它有兩個(gè)巨大的缺點(diǎn):首先,當(dāng)模型架構(gòu)變得非常復(fù)雜時(shí),它也變得很難控制和保存所有的權(quán)重矩陣。其次,有一種“隱藏的”張量,它是在沒有顯式初始化的情況下創(chuàng)建的。例如,當(dāng)你創(chuàng)建 tf.nn.rnn_cell.BasicLSTMCell時(shí)。它創(chuàng)建了所有需要的權(quán)值和偏差來實(shí)現(xiàn)LSTM cell。變量名也是自動(dòng)分配的。

      這種行為看起來還可以,但實(shí)際上,在很多情況下,并不是很好用。這種方法的主要問題是,當(dāng)你查看圖的集合時(shí),看到一堆變量,你不知道它們的來源,你實(shí)際上不知道應(yīng)該保存什么以及在哪里加載它們。坦率地說,很難將隱藏變量放到圖中正確的位置并適當(dāng)?shù)夭僮魉鼈儭?/span>

    2. 在沒有任何警告的情況下兩次創(chuàng)建同名張量(通過自動(dòng)添加_index結(jié)尾)。我認(rèn)為這個(gè)問題不像前一個(gè)問題那么重要,但是這個(gè)問題確實(shí)困擾著我,因?yàn)樗鼤?huì)導(dǎo)致很多圖執(zhí)行錯(cuò)誤。為了更好地解釋這個(gè)問題,我們來看一下這個(gè)例子。

      例如,你用tf.get_variable(name=’char_embeddings’, dtype=…)來創(chuàng)建張量。然后保存它并在新會(huì)話中加載。你已經(jīng)忘記了這個(gè)變量是可訓(xùn)練的,并通過tf.get_variable()以相同的方式再次創(chuàng)建了它。在圖執(zhí)行過程中,會(huì)發(fā)生的這樣的錯(cuò)誤:FailedPreconditionError (see above for traceback): Attempting to use uninitialized value char_embeddings_2。原因是,你已經(jīng)創(chuàng)建了一個(gè)空變量,但是并沒有將它放到模型的適當(dāng)?shù)奈恢?,而?shí)際上只要它已經(jīng)包含在計(jì)算圖中,就可以放到模型的某個(gè)地方。

      正如你所看到的,由于開發(fā)人員創(chuàng)建了同名張量兩次(甚至Windows也會(huì)這樣做),所以沒有出現(xiàn)錯(cuò)誤或警告。也許這一點(diǎn)只對(duì)我很重要,但這是tensorflow的特性,我并不喜歡它的這個(gè)行為。

    3. 在編寫單元測(cè)試和其他問題時(shí)手動(dòng)重置圖。由于許多原因,測(cè)試用tensorflow編寫的代碼總是很困難。第一個(gè)— 也是最明顯的一個(gè),已經(jīng)在這一段的開頭提到過了,可能聽起來很傻,但對(duì)我來說,讓人很惱火。由于在運(yùn)行期間訪問的所有模塊的所有張量只有一個(gè)默認(rèn)的tensorflow圖,因此不可能在不重置這個(gè)圖的情況下,使用不同的參數(shù)(例如)測(cè)試相同的功能。它只是一行代碼tf.reset_default_graph(),但是知道它應(yīng)該寫在大多數(shù)方法的頂部,這個(gè)解決方案就變成了某種惡作劇,當(dāng)然,一個(gè)明顯的代碼復(fù)制示例。我還沒有發(fā)現(xiàn)任何可能的方法處理這個(gè)問題(除了使用reuse參數(shù),我們將在后面討論),只要所有的張量與默認(rèn)圖并沒有辦法隔離(當(dāng)然,可以有一個(gè)單獨(dú)的tensorflow圖方法,但在我看來這不是最佳實(shí)踐)。

      為tensorflow寫單元測(cè)試的代碼也困擾我很多的事情,在這種情況下,計(jì)算圖的一部分是不應(yīng)該被執(zhí)行的(里面有張量未初始化,因?yàn)槟P蜎]有訓(xùn)練)。但是,計(jì)算圖本身并不知道我們應(yīng)該測(cè)試什么。我的意思是 self.assertEqual()的參數(shù)不清楚(我們應(yīng)該測(cè)試輸出張量的名稱或它們的形狀嗎?如果形狀為None呢?如果張量的名字或形狀不足以得出這個(gè)結(jié)論,那該怎么辦?)。在我的例子中,我只是簡單地?cái)嘌詮埩康拿Q、形狀和維數(shù),但是我確信,在不執(zhí)行圖的情況下,只檢查這部分功能是不合理的。

    4. 混淆張量的名字。很多人會(huì)說這個(gè)關(guān)于tensorflow的評(píng)論是一種另外的抱怨方式,但是我們并不能說出來在做了某種運(yùn)算之后得到的張量的名字是什么。我的意思是,名稱bidirectional_rnn/bw/bw/while/Exit_4:0清楚嗎?對(duì)我來說,絕對(duì)不清楚。我得到這個(gè)張量是對(duì)動(dòng)態(tài)雙向RNN的后向單元進(jìn)行某種操作的結(jié)果,但是如果沒有顯式地調(diào)試代碼,就無法知道執(zhí)行了哪些操作以及操作的順序。另外,索引的結(jié)尾也不太好理解,只要你想知道數(shù)字4是從哪里來的,就需要閱讀tensorflow文檔并深入研究計(jì)算圖。

      前面討論的“隱藏”變量的情況也是一樣的:為什么這里有biaskernel名稱?也許這是我的水平不夠,但是這樣的調(diào)試案例對(duì)我來說很不自然。

    5. tf.AUTO_REUSE,可訓(xùn)練的變量,重新編譯的庫和其他的東西。這個(gè)列表的最后,我們看一些小的細(xì)節(jié),這些細(xì)節(jié)只有在錯(cuò)誤中才能學(xué)習(xí)到。第一件事是reuse=tf.AUTO_REUSE參數(shù)的作用域,它允許自動(dòng)處理已經(jīng)創(chuàng)建的變量,如果它們已經(jīng)存在,就不會(huì)創(chuàng)建兩次。事實(shí)上,在許多情況下,它可以解決本段第二點(diǎn)所述的問題。但是,在實(shí)踐中,這個(gè)參數(shù)應(yīng)該謹(jǐn)慎使用,并且只有在開發(fā)人員知道代碼的某些部分需要運(yùn)行兩次或多次時(shí)才使用。

      第二點(diǎn)是可訓(xùn)練變量,這里最重要的一點(diǎn)是:所有的張量在默認(rèn)情況下都是可訓(xùn)練的。有時(shí)這可能是一個(gè)頭痛的行為,因?yàn)橛袝r(shí)候我們并不想要所有的張量都可訓(xùn)練,但是又很容易忘記,他們是都可以訓(xùn)練的。

      第三件事只是一個(gè)優(yōu)化技巧,我建議每個(gè)人都這么做:幾乎在所有情況下,當(dāng)你使用通過pip安裝的包時(shí),你都會(huì)收到這樣的警告:Your CPU supports instructions that this TensorFlow binary was not compiled to use: AVX AVX2。如果你看到這類消息,最好卸載tensorflow,然后使用你喜歡的選項(xiàng)通過bazel重新編譯它。這樣做的主要好處是計(jì)算速度的提高和更好的總體性能。

    ?

    總結(jié)


    我希望這篇文章能夠?qū)δ切┱陂_發(fā)他們的第一個(gè)tensorflow模型的數(shù)據(jù)科學(xué)家有所幫助,他們正在努力解決框架中某些部分的不明顯的行為,這些行為很難理解,而且調(diào)試起來相當(dāng)復(fù)雜。要點(diǎn)我想說的是,使用這個(gè)庫工作的時(shí)候,犯一些錯(cuò)誤也不是壞事(對(duì)于其他的事情也是一樣的),這可以讓我們多問些問題,深入查看文檔和調(diào)試每一行代碼,這樣也是很好的。

    就像跳舞或游泳一樣,任何事情都需要練習(xí),我希望我能讓這種練習(xí)變得更愉快和有趣。

    下載1:OpenCV-Contrib擴(kuò)展模塊中文版教程
    在「小白學(xué)視覺」公眾號(hào)后臺(tái)回復(fù):擴(kuò)展模塊中文教程即可下載全網(wǎng)第一份OpenCV擴(kuò)展模塊教程中文版,涵蓋擴(kuò)展模塊安裝、SFM算法、立體視覺、目標(biāo)跟蹤、生物視覺、超分辨率處理等二十多章內(nèi)容。

    下載2:Python視覺實(shí)戰(zhàn)項(xiàng)目52講
    小白學(xué)視覺公眾號(hào)后臺(tái)回復(fù):Python視覺實(shí)戰(zhàn)項(xiàng)目,即可下載包括圖像分割、口罩檢測(cè)、車道線檢測(cè)、車輛計(jì)數(shù)、添加眼線、車牌識(shí)別、字符識(shí)別、情緒檢測(cè)、文本內(nèi)容提取、面部識(shí)別等31個(gè)視覺實(shí)戰(zhàn)項(xiàng)目,助力快速學(xué)校計(jì)算機(jī)視覺。

    下載3:OpenCV實(shí)戰(zhàn)項(xiàng)目20講
    小白學(xué)視覺公眾號(hào)后臺(tái)回復(fù):OpenCV實(shí)戰(zhàn)項(xiàng)目20講,即可下載含有20個(gè)基于OpenCV實(shí)現(xiàn)20個(gè)實(shí)戰(zhàn)項(xiàng)目,實(shí)現(xiàn)OpenCV學(xué)習(xí)進(jìn)階。

    交流群


    歡迎加入公眾號(hào)讀者群一起和同行交流,目前有SLAM、三維視覺、傳感器自動(dòng)駕駛、計(jì)算攝影、檢測(cè)、分割、識(shí)別、醫(yī)學(xué)影像、GAN、算法競賽等微信群(以后會(huì)逐漸細(xì)分),請(qǐng)掃描下面微信號(hào)加群,備注:”昵稱+學(xué)校/公司+研究方向“,例如:”張三?+?上海交大?+?視覺SLAM“。請(qǐng)按照格式備注,否則不予通過。添加成功后會(huì)根據(jù)研究方向邀請(qǐng)進(jìn)入相關(guān)微信群。請(qǐng)勿在群內(nèi)發(fā)送廣告,否則會(huì)請(qǐng)出群,謝謝理解~


    瀏覽 47
    點(diǎn)贊
    評(píng)論
    收藏
    分享

    手機(jī)掃一掃分享

    分享
    舉報(bào)
    評(píng)論
    圖片
    表情
    推薦
    點(diǎn)贊
    評(píng)論
    收藏
    分享

    手機(jī)掃一掃分享

    分享
    舉報(bào)

    <kbd id="5sdj3"></kbd>
    <th id="5sdj3"></th>

  • <dd id="5sdj3"><form id="5sdj3"></form></dd>
    <td id="5sdj3"><form id="5sdj3"><big id="5sdj3"></big></form></td><del id="5sdj3"></del>

  • <dd id="5sdj3"></dd>
    <dfn id="5sdj3"></dfn>
  • <th id="5sdj3"></th>
    <tfoot id="5sdj3"><menuitem id="5sdj3"></menuitem></tfoot>

  • <td id="5sdj3"><form id="5sdj3"><menu id="5sdj3"></menu></form></td>
  • <kbd id="5sdj3"><form id="5sdj3"></form></kbd>
    天天干天天操天天透 | 日韩91在线 | www.婷婷 | 亚洲福利久久 | 黄色视频链接在线观看 |