轉(zhuǎn)載自 Hujun/Sanglei
【導(dǎo)讀】主題鏈路知識(shí)是我們專知的核心功能之一吱肌,為用戶提供AI領(lǐng)域系統(tǒng)性的知識(shí)學(xué)習(xí)服務(wù)溃卡,一站式學(xué)習(xí)人工智能的知識(shí)悠鞍,包含人工智能( 機(jī)器學(xué)習(xí)吨岭、自然語(yǔ)言處理、計(jì)算機(jī)視覺(jué)等)车荔、大數(shù)據(jù)渡冻、編程語(yǔ)言、系統(tǒng)架構(gòu)忧便。使用請(qǐng)?jiān)L問(wèn)專知 進(jìn)行主題搜索查看 - 桌面電腦訪問(wèn)http://www.zhuanzhi.ai, 手機(jī)端訪問(wèn)http://www.zhuanzhi.ai 或關(guān)注微信公眾號(hào)后臺(tái)回復(fù)" 專知"進(jìn)入專知族吻,搜索主題查看。隨著TensorFlow 1.4 Eager Execution的出現(xiàn)珠增,TensorFlow的使用出現(xiàn)了革命性的變化超歌。專知為大家推出TensorFlow 1.4系列教程:
- 01:動(dòng)態(tài)圖機(jī)制Eager Execution
- 02:利用Eager Execution自定義操作和梯度(可在GPU上運(yùn)行)
- 03 : 利用Eager Execution構(gòu)建和訓(xùn)練卷積神經(jīng)網(wǎng)絡(luò)(CNN)
簡(jiǎn)介
近期PyTorch比較火,并不是因?yàn)镻yTorch輪子多或者生態(tài)圈龐大蒂教,而是因?yàn)镻yTorch可以構(gòu)建動(dòng)態(tài)圖巍举,即可以像正常程序一樣去編寫或者調(diào)試深度學(xué)習(xí)模型。1.4版本之前的Tensorflow一直被人詬病的一個(gè)問(wèn)題就是它不具備構(gòu)建動(dòng)態(tài)圖的能力凝垛。Tensorflow 1.4的Eager Execution在兼容老版本的基礎(chǔ)上懊悯,提供了動(dòng)態(tài)圖以及其它的一些新特性蜓谋,通俗地來(lái)說(shuō)有下面幾個(gè)特點(diǎn):
無(wú)需Placeholder和Feed,可以直接使用numpy作為輸入
可以立即執(zhí)行Operation炭分,例如輸入圖像數(shù)據(jù)(numpy)桃焕,立即輸出卷積結(jié)果,并將結(jié)果轉(zhuǎn)換為numpy欠窒。即可以將老版本中定義靜態(tài)圖的Operation直接當(dāng)做函數(shù)來(lái)立即執(zhí)行一個(gè)Operation覆旭。(老版本需要先利用Operation定義靜態(tài)圖,然后到Session中執(zhí)行不可變的靜態(tài)圖岖妄,并且獲取Operation的結(jié)果需要通過(guò)sess.run()和feed型将,非常麻煩)。
動(dòng)態(tài)圖特性使得Tensorflow可以使用python的if語(yǔ)句和循環(huán)語(yǔ)句來(lái)控制模型的結(jié)構(gòu)荐虐,而不用通過(guò)
tf.cond
這種難用的函數(shù)來(lái)控制模型的解構(gòu)七兜。動(dòng)態(tài)圖特性使得模型更便于調(diào)試,模型的運(yùn)行過(guò)程與代碼的運(yùn)行過(guò)程一致福扬。而在老版本的靜態(tài)圖中腕铸,網(wǎng)絡(luò)的forward與backward都是黑箱操作,想加個(gè)print來(lái)輸出過(guò)程中的變量都很難铛碑。
梯度的計(jì)算和更新也變成函數(shù)的調(diào)用狠裹,可由開(kāi)發(fā)者自己調(diào)用。
-
上述的Eager Execution特性的實(shí)現(xiàn)汽烦,只需在代碼頂部加上下面兩行代碼即可涛菠,其他的操作均兼容老版本的API:
import tensorflow.contrib.eager as tfe tfe.enable_eager_execution()
安裝
想體驗(yàn)1.4版Tensorflow的,可以用pip下載nightly build版本的Tensorflow:
- CPU:
pip install tf-nightly
- GPU:
pip install tf-nightly-gpu
注意撇吞,使用GPU版需要安裝cuDNN 6以上的版本俗冻。在Windows上推薦使用conda(python3.5)+pip進(jìn)行安裝。
示例
下面用一些示例來(lái)展示Eager Execution為我們帶來(lái)的禮物牍颈。
下面所有的示例都依賴下面的import:
import tensorflow as tf
import tensorflow.contrib.eager as tfe
import numpy as np
tfe.enable_eager_execution()
示例1迄薄,直接使用Operation進(jìn)行卷積操作
# 隨機(jī)生成2個(gè)圖像(batch_size=2),每個(gè)圖像的大小為 28 * 28 * 3
images = np.random.randn(2, 28, 28, 3).astype(np.float32)
# 卷積核參數(shù)
filter = tf.get_variable("conv_w0", shape = [5,5,3,20], initializer = tf.truncated_normal_initializer)
# 對(duì)生成的batch_size=2的數(shù)據(jù)進(jìn)行卷積操作煮岁,立即獲得結(jié)果
conv = tf.nn.conv2d(input = images, filter = filter, strides = [1,2,2,1], padding = 'VALID')
# 用結(jié)果的numpy()方法可獲得結(jié)果的numpy表示讥蔽,顯示其shape
print(conv.numpy().shape)
運(yùn)行結(jié)果如下,成功獲得卷積后結(jié)果的大小画机。
(2, 12, 12, 20)
示例2冶伞,自動(dòng)計(jì)算梯度
為x*x + 40
自動(dòng)求導(dǎo):
grad = tfe.gradients_function(lambda x: x * x + 4.0)
print(grad(10))
print(grad(5))
計(jì)算結(jié)果:
[<tf.Tensor: id=11, shape=(), dtype=int32, numpy=20>]
[<tf.Tensor: id=22, shape=(), dtype=int32, numpy=10>]
可以看到,輸入為10和5時(shí)的導(dǎo)數(shù)為20和10色罚。
示例3,使用Python的程序流程控制模型的流程
自己動(dòng)手實(shí)現(xiàn)leaky relu激活函數(shù):
def leaky_relu(x):
if x < 0:
return x * 0.1
else:
return x
grad = tfe.gradients_function(leaky_relu)
print(grad(4.0))
print(grad(-3.0))
代碼運(yùn)行記結(jié)果如下:
[<tf.Tensor: id=9, shape=(), dtype=float32, numpy=1.0>]
[<tf.Tensor: id=21, shape=(), dtype=float32, numpy=0.1>]
結(jié)果中的1.0和0.1分別是leaky relu對(duì)于輸入4和-3的梯度账劲〈粱ぃ可以看出金抡,leakly relu需要條件語(yǔ)句來(lái)控制流程,上面代碼在老版本TensorFlow里是不可行的腌且,因?yàn)闂l件語(yǔ)句的判斷會(huì)發(fā)生在定義靜態(tài)圖的階段梗肝,而定義靜態(tài)圖的階段連輸入數(shù)據(jù)是啥都不知道。
示例4铺董,自動(dòng)優(yōu)化
w = tf.get_variable("w", initializer = 3.0)
def loss(x):
return x * w
optimizer = tf.train.GradientDescentOptimizer(learning_rate=0.1)
for i in range(5):
optimizer.minimize(lambda: loss(5))
print(w.numpy())
運(yùn)行結(jié)果如下巫击,可以看出變量w的值在不斷被更新,以減小loss的值
2.5
2.0
1.5
1.0
0.5
分布式和多GPU
TensorFlow的Github上對(duì)于Eager Execution的描述如下:
This feature is in early stages and work remains to be done in terms of smooth support for distributed and multi-GPU training and CPU performance.
意思是說(shuō)精续,Eager Execution仍然是一個(gè)新特性坝锰,對(duì)于分布式訓(xùn)練、多GPU訓(xùn)練和CPU的性能重付,仍有很多的工作可做顷级。對(duì)于想使用分布式訓(xùn)練的朋友來(lái)說(shuō),還是老老實(shí)實(shí)先用TensorFlow的靜態(tài)圖吧确垫。下面這段引用描述了TensorFlow的分布式運(yùn)行方法:
TensorFlow是Google開(kāi)源的基于神經(jīng)網(wǎng)絡(luò)的深度學(xué)習(xí)引擎弓颈,可以支持分布式運(yùn)行。通常構(gòu)建單一的包含了一系列參數(shù)的圖, 并且創(chuàng)建多個(gè)模型的副本來(lái)映射到不同tasks删掀。每個(gè)model的副本有一個(gè)不同的train_op翔冀,并且對(duì)于每個(gè)Worker service而言一個(gè)或者多個(gè)的客戶端線程可以調(diào)用sess.run(train_ops[i])。這種方法只使用了單一的tf.Session披泪,它的工作目標(biāo)是集群中的某個(gè)workers纤子。而另一種分布式訓(xùn)練器的方法使用多張圖,一張圖對(duì)應(yīng)一個(gè)worker付呕,并且每張圖都包含了一系列的參數(shù)的集合和一份模型的賦值计福。而容器的機(jī)制就是在不同的圖之間共享變量:一旦某個(gè)變量構(gòu)造完成,可選的container參數(shù)會(huì)由圖中每份復(fù)制的相同值來(lái)決定徽职。對(duì)于較大的模型而言象颖,這種方法會(huì)更加有效,畢竟整個(gè)圖更小了一點(diǎn)姆钉。這種方法就需要使用多個(gè)tf.Session對(duì)象:每個(gè)worker過(guò)程都會(huì)包含一個(gè)说订,不過(guò)不同的Session會(huì)指向不同的目標(biāo)worker。這個(gè)tf.Session對(duì)象即可以在單一的Python客戶端中創(chuàng)建潮瓶,也可以在多個(gè)客戶端中創(chuàng)建陶冷。
性能
國(guó)外一些人在博客里公布了一些Eager Execution和PyTorch的對(duì)比,總的來(lái)說(shuō)毯辅,就是目前TensorFlow的Eager Execution特性并不是特別理想埂伦,但正如上面所說(shuō),Eager正處于非常初級(jí)的階段思恐,相信Google可以很快地將Eager特性完善沾谜。