中文字幕在线观看,亚洲а∨天堂久久精品9966,亚洲成a人片在线观看你懂的,亚洲av成人片无码网站,亚洲国产精品无码久久久五月天

Tensorflow 2.0的這些新設(shè)計,你適應(yīng)好了嗎?

2018-11-30    來源:raincent

容器云強勢上線!快速搭建集群,上萬Linux鏡像隨意使用

 

 

來源:論智,作者:Bot

幾天前,Tensorflow剛度過自己的3歲生日,作為當(dāng)前最受歡迎的機器學(xué)習(xí)框架,Tensorflow在這個寶座上已經(jīng)盤踞了近三年。無論是成熟的Keras,還是風(fēng)頭正盛的pytorch,它的地位似乎總是無法被撼動。而就在即將到來的2019年,Tensorflow 2.0將正式入場,給暗流涌動的框架之爭再燃一把火。

如果說兩代Tensorflow有什么根本不同,那應(yīng)該就是Tensorflow 2.0更注重使用的低門檻,旨在讓每個人都能應(yīng)用機器學(xué)習(xí)技術(shù)。考慮到它可能會成為機器學(xué)習(xí)框架的又一個重要里程碑,本文會介紹1.x和2.x版本之間的所有(已知)差異,重點關(guān)注它們之間的思維模式變化和利弊關(guān)系。

通過閱讀這篇文章,熟悉Tensorflow的老用戶可以盡早轉(zhuǎn)變思維,適應(yīng)新版本的變化。而新手也可以直接以Tensorflow 2.0的方式思考,至少目前沒有必要急著去學(xué)習(xí)別的框架。

Tensorflow 2.0:為什么?何時?

Tensorflow 2.0的開發(fā)初衷是制作一個更簡單易用的Tensorflow。

第一個向公眾透露項目具體開發(fā)內(nèi)容的人是Google Brain的工程師Martin Wicke,我們可以在他的公告郵件列表里找到Tensorflow 2.0的蛛絲馬跡。在這里,我們對它做一些簡單提要:

♦ Tensorflow 2.0的核心功能是動態(tài)圖機制Eager execution。它允許用戶像正常程序一樣去編寫、調(diào)試模型,使TensorFlow更易于學(xué)習(xí)和應(yīng)用。

♦ 支持更多平臺、更多語言,通過標(biāo)準(zhǔn)化API的交換格式和提供準(zhǔn)線改善這些組件之間的兼容性。

♦ 刪除已棄用的API并減少重復(fù)的API數(shù),避免給用戶造成混淆。

♦ 2.0版的設(shè)計對公眾開放:社區(qū)可以和Tensorflow開發(fā)人員一起工作,共同探討新功能。

♦ 兼容性和連續(xù)性:Tensorflow 2.0會提供Tensorflow 1.x的兼容性模塊,也就是它會內(nèi)置所有Tensorflow 1.x API的模塊。

♦ 硬盤兼容性:只需修改一些變量名稱,Tensorflow 1.x中導(dǎo)出的模型(checkpoints和模型freeze)就能和Tensorflow 2.0兼容。

♦ tf.contrib退出歷史舞臺。其中有維護(hù)價值的模塊會被移動到別的地方,剩余的都將被刪除。

換言之,如果你在這之前從沒接觸過Tensorflow,你是幸運的。但是,如果你和我們一樣是從0.x版本用起的,那么你就可能得重寫所有代碼庫——雖然官方說會發(fā)布轉(zhuǎn)換工具方便老用戶,但這種工具肯定有很多bug,需要一定的手動干預(yù)。

而且,你也必須開始轉(zhuǎn)變思維模式。這做起來不容易,但真的猛士不就應(yīng)該喜歡挑戰(zhàn)嗎?

所以為了應(yīng)對挑戰(zhàn),我們先來適應(yīng)第一個巨大差異:移除tf.get_variable,tf.variable_scope,tf.layers,強制轉(zhuǎn)型到基于Keras的方法,也就是用tf.keras。

關(guān)于Tensorflow 2.0的發(fā)布日期,官方并沒有給出明確時間。但根據(jù)開發(fā)小組成員透露的消息,我們可以確定它的預(yù)覽版會在今年年底發(fā)布,官方正式版可能會在2019年春季發(fā)布。

所以留給老用戶的時間已經(jīng)不多了。

Keras(OOP)vs Tensorflow 1.x

在GitHub上,RFC:TensorFlow 2.0中的變量這份意見稿已經(jīng)被官方接受,它可能是對現(xiàn)有代碼庫影響最大的RFC,值得參考。

我們都知道,在Tensorflow里,每個變量在計算圖中都有一個唯一的名稱,我們也已經(jīng)習(xí)慣按照這種模式設(shè)計計算圖:

♦ 哪些操作連接我的變量節(jié)點:把計算圖定義為連接的多個子圖,并用tf.variable_scope在內(nèi)部定義每個子圖,以便定義不同計算圖的變量,并在Tensorboard中獲得清晰的圖形表示。

♦ 需要在執(zhí)行同一步驟時多次使用子圖:一定要用tf.variable_scope里的reuse參數(shù),不然Tensorflow會生成一個前綴為_n的新計算圖。

♦ 定義計算圖:定義參數(shù)初始化節(jié)點(你調(diào)用過幾次tf.global_variables_initializer()?)。

♦ 把計算圖加載到Session,運行。

下面,我們就以在Tensorflow中實現(xiàn)簡單的GAN為例,更生動地展現(xiàn)上述步驟。

Tensorflow 1.x的GAN

要定義GAN的判別器D,我們一定會用到tf.variable_scope里的reuse參數(shù)。因為首先我們會把真實圖像輸入判別器,之后把生成的假樣本再輸進(jìn)去,在且僅在最后計算D的梯度。相反地,生成器G里的參數(shù)不會在一次迭代中被用到兩次,所以沒有擔(dān)心的必要。

 

 

當(dāng)這兩個函數(shù)被調(diào)用時,Tensorflow會默認(rèn)在計算圖內(nèi)部定義兩個不同的子圖,每個子圖都有自己的scope(生成器/判別器)。請注意,這個函數(shù)返回的是定義好的子圖的張量,而不是子圖本身。

為了共享D這個子圖,我們需要定義兩個輸入(真實圖像/生成樣本),并定義訓(xùn)練G和D所需的損失函數(shù)。

 

 

最后要做的是分別定義訓(xùn)練D和G所需的2個損失函數(shù)和2個優(yōu)化器。

 

函數(shù)不難,對抗訓(xùn)練的一個特點是把真實圖像和由G生成的圖像輸入判別器D,由后者輸出評估結(jié)果,并把結(jié)果饋送給生成器G做參考。這意味著對抗訓(xùn)練其實是分兩步走,G和D同在一個計算圖內(nèi),但在訓(xùn)練D時,我們不希望更新G中的參數(shù);同理,訓(xùn)練G時,我們也不希望更新D里的參數(shù)。

 

因此,由于我們在默認(rèn)計算圖中定義了每個變量,而且它們都是全局變量,我們必須在2個不同的列表中收集正確的變量并正確定義優(yōu)化器,從而計算梯度,對正確的子圖進(jìn)行更新。

 

 

到這里,我們已經(jīng)完成了上面提到的“第3步:定義計算圖”,最后是定義參數(shù)初始化節(jié)點:

 

 

優(yōu)/缺點

只要正確定義了計算圖,且在訓(xùn)練循環(huán)內(nèi)和session內(nèi)使用,上述GAN就能正常訓(xùn)練了。但是,從軟件工程角度看,它有一些值得注意的點:

♦ 用tf.variable_scope修改由tf.layers定義的(完整)變量名稱:這其實是對不同scope的變量重新用了一次tf.layers.*,導(dǎo)致的結(jié)果是定義了新scope下的一組新變量。

♦ 布爾標(biāo)志reuse可以完全改變調(diào)用tf.layers.*后的所有行為(定義/reuse)。

♦ 每個變量都是全局變量:tf.layers調(diào)用tf.get_variable(也就是在tf.layers下面調(diào)用)定義的變量可以隨處訪問。

♦ 定義子圖很麻煩:你沒法通過調(diào)用discriminator獲得一個新的、完全獨立的判別器,這有點違背常理。

♦ 子圖定義的輸出值(調(diào)用generator/discriminator)只是它的輸出張量,而不是內(nèi)部所有圖的信息(盡管可以回溯輸出,但這么做很麻煩)。

♦ 定義參數(shù)初始化節(jié)點很麻煩(不過這個可以用tf.train.MonitoredSession和tf.train.MonitoredTrainingSession規(guī)避)。

以上6點都可能是用Tensorflow構(gòu)建GAN的缺點。

Tensorflow 2.x的GAN

前面提到了,Tensorflow 2.x移除了tf.get_variable,tf.variable_scope,tf.layers,強制轉(zhuǎn)型到了基于Keras的方法。明年,如果我們想用它構(gòu)建GAN,我們就必須用tf.keras定義生成器G和判別器的:這其實意味著我們憑空多了一個可以用來定義D的共享變量函數(shù)。

注:明年tf.layers就沒有了,所以你最好從現(xiàn)在就開始適應(yīng)用tf.keras來定義自己的模型,這是過渡到2.x版本的必要準(zhǔn)備。

 

 

看到和Tensorflow的不同了嗎?在這里,generator和discriminator都返回了一個tf.keras.Model,而不僅僅是輸出張量。

在Keras里,變量共享可以通過多次調(diào)用同樣的Keras層或模型來實現(xiàn),而不用像TensorFlow那樣需要考慮變量的scope。所以我們在這里只需定義一個判別器D,然后調(diào)用它兩次。

 

 

再重申一遍,這里我們不需要像原來那樣定義D_fake,在定義計算圖時也不用提前擔(dān)心變量共享。

之后就是定義G和D的損失函數(shù):

 

 

最后,我們要做的是定義分別優(yōu)化D和G的2個優(yōu)化器。由于用的是tf.keras,所以我們不用手動創(chuàng)建要更新的變量列表,tf.keras.Models的對象本身就是我們要的東西。

 

 

截至目前,因為我們用的還是靜態(tài)圖,所以還要定義變量初始化節(jié)點:

 

 

優(yōu)/缺點

♦ 從tf.layers到過渡tf.keras:Keras里有所有tf.layers的對應(yīng)操作。

♦ tf.keras.Model幫我們完全省去了變量共享和計算圖重新定義的煩惱。

♦ tf.keras.Model不是一個張量,而是一個自帶變量的完整模型。

♦ 定義變量初始化節(jié)點還是很麻煩,但之前也提到了,我們可以用tf.train.MonitoredSession規(guī)避。

以上是Tensorflow 1.x和2.x版本的第一個巨大差異,在下文中,我們再來看看第二個差異——Eager模式。

Eager Execution

Eager Execution(動態(tài)圖機制)是TensorFlow的一個命令式編程環(huán)境,它無需構(gòu)建計算圖,可以直接評估你的操作:直接返回具體值,而不是構(gòu)建完計算圖后再返回。它的優(yōu)點主要有以下幾點:

♦ 直觀的界面。更自然地構(gòu)建代碼和使用Python數(shù)據(jù)結(jié)構(gòu),可完成小型模型和小型數(shù)據(jù)集的快速迭代。

♦ 更容易調(diào)試。直接調(diào)用ops來檢查運行模型和測試更改,用標(biāo)準(zhǔn)Python調(diào)試工具獲取即時錯誤報告。

♦ 更自然的流程控制。直接用Python流程控制而不是用計算圖。

簡而言之,有了Eager Execution,我們不再需要事先定義計算圖,然后再在session里評估它。它允許用python語句控制模型的結(jié)構(gòu)。

這里我們舉個典型例子:Eager Execution獨有的tf.GradientTape。在計算圖模式下,如果我們要計算某個函數(shù)的梯度,首先我們得定義一個計算圖,從中知道各個節(jié)點是怎么連接的,然后從輸出回溯到計算圖的輸入,層層計算并得到最終結(jié)果。

但在Eager Execution下,用自動微分計算函數(shù)梯度的唯一方法是構(gòu)建圖。我們得先用tf.GradientTape根據(jù)可觀察元素(如變量)構(gòu)建操作圖,然后再計算梯度。下面是tf.GradientTape文檔中的一個原因和示例:

 

 

此外,用python語句(如if語句和循環(huán)語句)進(jìn)行流程控制區(qū)別于靜態(tài)圖的

 

之前官方發(fā)布了一個名為Autograph的工具,它的作用是把普通Python代碼轉(zhuǎn)換成復(fù)雜的計算圖代碼,也就是允許用戶用Python直接編寫計算圖。但它指的Python事實上并不是真正意義上的Python(比如必須定義一個函數(shù),讓它返回一個具有指定Tensorflow數(shù)據(jù)類型的元素列表),也沒法發(fā)揮編程語言的強大功能。

就個人而言,我不太喜歡Eager Execution,因為我已經(jīng)習(xí)慣靜態(tài)圖了,而這個新改變有點像是對PyTorch的拙劣模仿。至于其他變化,我會在下面以問答方式做簡單介紹。

一問一答

下面是我認(rèn)為從TensorFlow過渡到TensorFlow 2.0會出現(xiàn)的一些常見問題。

問:如果我的項目要用到tf.contrib怎么辦?

你可以用pip安裝一個新的Python包,或者把tf.contrib.something重命名為tf.something。

問:如果在Tensorflow 1.x里能正常工作的東西到2.x沒法運行了怎么辦?

不應(yīng)該存在這種錯誤,建議你仔細(xì)檢查一下代碼轉(zhuǎn)換得對不對,閱讀GitHub上的錯誤報告。

問:我的項目在靜態(tài)圖上好好的,一放到Eager Execution上就不行了怎么辦?

我也遇到了這個問題,而且目前還不知道具體原因。所以建議先不要用Eager Execution。

問:我發(fā)現(xiàn)Tensorflow 2.x里好像沒有某個tf.函數(shù)怎么辦?

這個函數(shù)很有可能只被移到別的地方去了。在Tensorflow 1.x中,很多函數(shù)會有重復(fù)、有別名,Tensorflow 2.x對這些函數(shù)做了統(tǒng)一刪減整理,也移動了部分函數(shù)的位置。你可以在RFC:TensorFlow命名空間里找到將要新增、刪除、移動的所有函數(shù)。官方即將發(fā)布的工具也能幫你適應(yīng)這個更新。

小結(jié)

看了這么多,相信讀者現(xiàn)在已經(jīng)對Tensorflow 2.x有了大致了解,也有了心理準(zhǔn)備?偟膩碚f,正如大部分產(chǎn)品都要經(jīng)歷更新迭代,我認(rèn)為Tensorflow 2.x相比Tensorflow 1.x會是有明顯改進(jìn)的一個版本。最后,我們再來看一下Tensorflow的發(fā)展時間軸,回憶過去三年來它帶給我們的記憶和知識。


標(biāo)簽: Google 代碼 轉(zhuǎn)型

版權(quán)申明:本站文章部分自網(wǎng)絡(luò),如有侵權(quán),請聯(lián)系:west999com@outlook.com
特別注意:本站所有轉(zhuǎn)載文章言論不代表本站觀點!
本站所提供的圖片等素材,版權(quán)歸原作者所有,如需使用,請與原作者聯(lián)系。

上一篇:Python+數(shù)據(jù)分析:數(shù)據(jù)分析北京Python開發(fā)的現(xiàn)狀

下一篇:學(xué)習(xí)機器學(xué)習(xí)需要理解的五個基本概念