Tensorflow从入门到精通之——Tensorflow基本操作
前邊的章節(jié)介紹了什么是Tensorflow,本節(jié)將帶大家真正走進(jìn)Tensorflow的世界,學(xué)習(xí)Tensorflow一些基本的操作及使用方法。同時也歡迎大家關(guān)注我們的網(wǎng)站和系列教程:http://www.tensorflownews.com/,學(xué)習(xí)更多的機器學(xué)習(xí)、深度學(xué)習(xí)的知識!
Tensorflow是一種計算圖模型,即用圖的形式來表示運算過程的一種模型。Tensorflow程序一般分為圖的構(gòu)建和圖的執(zhí)行兩個階段。圖的構(gòu)建階段也稱為圖的定義階段,該過程會在圖模型中定義所需的運算,每次運算的的結(jié)果以及原始的輸入數(shù)據(jù)都可稱為一個節(jié)點(operation ,縮寫為op)。我們通過以下程序來說明圖的構(gòu)建過程:
程序2-1:
程序2-1定義了圖的構(gòu)建過程,“import tensorflow as tf”,是在python中導(dǎo)入tensorflow模塊,并另起名為“tf”;接著定義了兩個常量op,m1和m2,均為1*2的矩陣;最后將m1和m2的值作為輸入創(chuàng)建一個矩陣加法op,并輸出最后的結(jié)果result。
我們分析最終的輸出結(jié)果可知,其并沒有輸出矩陣相加的結(jié)果,而是輸出了一個包含三個屬性的Tensor(Tensor的概念我們會在下一節(jié)中詳細(xì)講解,這里就不再贅述)。
以上過程便是圖模型的構(gòu)建階段:只在圖中定義所需要的運算,而沒有去執(zhí)行運算。我們可以用圖2-1來表示:
圖2-1 圖的構(gòu)建階段
第二個階段為圖的執(zhí)行階段,也就是在會話(session)中執(zhí)行圖模型中定義好的運算。
?
我們通過程序2-2來解釋圖的執(zhí)行階段:
程序2-2:
?
程序2-2描述了圖的執(zhí)行過程,首先通過“tf.session()”啟動默認(rèn)圖模型,再調(diào)用run()方法啟動、運行圖模型,傳入上述參數(shù)result,執(zhí)行矩陣的加法,并打印出相加的結(jié)果,最后在任務(wù)完成時,要記得調(diào)用close()方法,關(guān)閉會話。
除了上述的session寫法外,我們更建議大家,把session寫成如程序2-4所示“with”代碼塊的形式,這樣就無需顯示的調(diào)用close釋放資源,而是自動地關(guān)閉會話。
程序2-3:
此外,我們還可以利用CPU或GPU等計算資源分布式執(zhí)行圖的運算過程。一般我們無需顯示的指定計算資源,Tensorflow可以自動地進(jìn)行識別,如果檢測到我們的GPU環(huán)境,會優(yōu)先的利用GPU環(huán)境執(zhí)行我們的程序。但如果我們的計算機中有多于一個可用的GPU,這就需要我們手動的指派GPU去執(zhí)行特定的op。如下程序2-4所示,Tensorflow中使用with...device語句來指定GPU或CPU資源執(zhí)行操作。
程序2-4:
?
上述程序中的“tf.device(“/gpu:2”)”是指定了第二個GPU資源來運行下面的op。依次類推,我們還可以通過“/gpu:3”、“/gpu:4”、“/gpu:5”...來指定第N個GPU執(zhí)行操作。
關(guān)于GPU的具體使用方法,我們會在下面的章節(jié)結(jié)合案例的形式具體描述。
Tensorflow中還提供了默認(rèn)會話的機制,如程序2-5所示,我們通過調(diào)用函數(shù)as_default()生成默認(rèn)會話。
程序2-5:
我們可以看到程序2-5和程序2-2有相同的輸出結(jié)果。我們在啟動默認(rèn)會話后,可以通過調(diào)用eval()函數(shù),直接輸出變量的內(nèi)容。
有時,我們需要在Jupyter或IPython等python交互式環(huán)境開發(fā)。Tensorflow為了滿足用戶的這一需求,提供了一種專門針對交互式環(huán)境開發(fā)的方法InteractiveSession(),具體用法如程序2-6所示:
程序2-6:
程序2-6就是交互式環(huán)境中經(jīng)常會使用的InteractiveSession()方法,其創(chuàng)建sess對象后,可以直接輸出運算結(jié)果。
綜上所述,我們介紹了Tensorflow的核心概念——計算圖模型,以及定義圖模型和運行圖模型的幾種方式。接下來,我們思考一個問題,為什么Tensorflow要使用圖模型?圖模型有什么優(yōu)勢呢?
首先,圖模型的最大好處是節(jié)約系統(tǒng)開銷,提高資源的利用率,可以更加高效的進(jìn)行運算。因為我們在圖的執(zhí)行階段,只需要運行我們需要的op,這樣就大大的提高了資源的利用率;其次,這種結(jié)構(gòu)有利于我們提取中間某些節(jié)點的結(jié)果,方便以后利用中間的節(jié)點去進(jìn)行其它運算;還有就是這種結(jié)構(gòu)對分布式運算更加友好,運算的過程可以分配給多個CPU或是GPU同時進(jìn)行,提高運算效率;最后,因為圖模型把運算分解成了很多個子環(huán)節(jié),所以這種結(jié)構(gòu)也讓我們的求導(dǎo)變得更加方便。
2.3.2 Tensor介紹
Tensor(張量)是Tensorflow中最重要的數(shù)據(jù)結(jié)構(gòu),用來表示Tensorflow程序中的所有數(shù)據(jù)。Tensor本是廣泛應(yīng)用在物理、數(shù)學(xué)領(lǐng)域中的一個物理量。那么在Tensorflow中該如何理解Tensor的概念呢?
實際上,我們可以把Tensor理解成N維矩陣(N維數(shù)組)。其中零維張量表示的是一個標(biāo)量,也就是一個數(shù);一維張量表示的是一個向量,也可以看作是一個一維數(shù)組;二維張量表示的是一個矩陣;同理,N維張量也就是N維矩陣。
在計算圖模型中,操作間所傳遞的數(shù)據(jù)都可以看做是Tensor。那Tensor的結(jié)構(gòu)到底是怎樣的呢?我們可以通過程序2-7更深入的了解一下Tensor。
程序2-7:
程序2-7的輸出結(jié)果表明:構(gòu)建圖的運算過程輸出的結(jié)果是一個Tensor,且其主要由三個屬性構(gòu)成:Name、Shape和Type。Name代表的是張量的名字,也是張量的唯一標(biāo)識符,我們可以在每個op上添加name屬性來對節(jié)點進(jìn)行命名,Name的值表示的是該張量來自于第幾個輸出結(jié)果(編號從0開始),上例中的“mul_3:0”說明是第一個結(jié)果的輸出。Shape代表的是張量的維度,上例中shape的輸出結(jié)果(1,1)說明該張量result是一個二維數(shù)組,且每個維度數(shù)組的長度是1。最后一個屬性表示的是張量的類型,每個張量都會有唯一的類型,常見的張量類型如圖2-2所示。
圖2-2 常用的張量類型
我們需要注意的是要保證參與運算的張量類型相一致,否則會出現(xiàn)類型不匹配的錯誤。如程序2-8所示,當(dāng)參與運算的張量類型不同時,Tensorflow會報類型不匹配的錯誤:
?
程序2-8:
正如程序的報錯所示:m1是int32的數(shù)據(jù)類型,而m2是float32的數(shù)據(jù)類型,兩者的數(shù)據(jù)類型不匹配,所以發(fā)生了錯誤。所以我們在實際編程時,一定注意參與運算的張量數(shù)據(jù)類型要相同。
2.3.3 常量、變量及占位符
Tensorflow中對常量的初始化,不管是對數(shù)值、向量還是對矩陣的初始化,都是通過調(diào)用constant()函數(shù)實現(xiàn)的。因為constant()函數(shù)在Tensorflow中的使用非常頻繁,經(jīng)常被用于構(gòu)建圖模型中常量的定義,所以接下來,我們通過程序2-9了解一下constant()的相關(guān)屬性:
程序2-9:
如程序2-9所示,函數(shù)constant有五個參數(shù),分別為value,name,dtype,shape和verify_shape。其中value為必選參數(shù),其它均為可選參數(shù)。Value為常量的具體值,可以是一個數(shù)字,一維向量或是多維矩陣。Name是常量的名字,用于區(qū)別其它常量。Dtype是常量的類型,具體類型可參見圖2-2。Shape是指常量的維度,我們可以自行定義常量的維度。
verify_shape是驗證shape是否正確,默認(rèn)值為關(guān)閉狀態(tài)(False)。也就是說當(dāng)該參數(shù)true狀態(tài)時,就會檢測我們所寫的參數(shù)shape是否與value的真實shape一致,若不一致就會報TypeError錯誤。如:上例中的實際shape為(2,0),若我們將參數(shù)中的shape屬性改為(2,1),程序就會報如下錯誤:
TypeError: Expected Tensor's shape: (2, 1), got (2,).
Tensorflow還提供了一些常見常量的初始化,如:tf.zeros、tf.ones、tf.fill、tf.linspace、tf.range等,均可以快速初始化一些常量。例如:我們想要快速初始化N維全0的矩陣,我們可以利用tf.zeros進(jìn)行初始化,如程序2-10所示:
程序2-10:
程序2-10向我們展示了tf.zeros和tf.zeros_like的用法。其它常見常量的具體初始化用法可以參考Tensorflow官方手冊:https://www.tensorflow.org/api_guides/python/constant_op。
此外,Tensorflow還可以生成一些隨機的張量,方便快速初始化一些隨機值。如:tf.random_normal()、tf.truncated_normal()、tf.random_uniform()、tf.random_shuffle()等。如程序2-11所示,我們以tf.random_normal()為例,來看一下隨機張量的具體用法:
程序2-11:
隨機張量random_normal()有shape、mean、stddev、dtype、seed、name六個屬性。 shape是指張量的形狀,如上述程序是生成一個2行3列的tensor;mean是指正態(tài)分布的均值;stddev是指正太分布的標(biāo)準(zhǔn)差;dtype是指生成tensor的數(shù)據(jù)類型;seed是分發(fā)創(chuàng)建的一個隨機種子;而name是給生成的隨機張量命名。
Tensorflow中的其它隨機張量的具體使用方法和屬性介紹,可以參見Tensorflow官方手冊:https://www.tensorflow.org/api_guides/python/constant_op。這里將不在一一贅述。
除了常量constant(),變量variable()也是在Tensorflow中經(jīng)常會被用到的函數(shù)。變量的作用是保存和更新參數(shù)。執(zhí)行圖模型時,一定要對變量進(jìn)行初始化,經(jīng)過初始化后的變量才能拿來使用。變量的使用包括創(chuàng)建、初始化、保存、加載等操作。首先,我們通過程序2-12了解一下變量是如何被創(chuàng)建的:
程序2-12:
程序2-12展示了創(chuàng)建變量的多種方式。我們可以把函數(shù)variable()理解為構(gòu)造函數(shù),構(gòu)造函數(shù)的使用需要初始值,而這個初始值是一個任何形狀、類型的Tensor。也就是說,我們
既可以通過創(chuàng)建數(shù)字變量、一維向量、二維矩陣初始化Tensor,也可以使用常量或是隨機常量初始化Tensor,來完成變量的創(chuàng)建。
當(dāng)我們完成了變量的創(chuàng)建,接下來,我們要對變量進(jìn)行初始化。變量在使用前一定要進(jìn)行初始化,且變量的初始化必須在模型的其它操作運行之前完成。通常,變量的初始化有三種方式,如程序2-13所示:
程序2-13:
程序2-13說明了初始化變量的三種方式:初始化全部變量、初始化變量的子集以及初始化單個變量。首先,global_variables_initializer()方法是不管全局有多少個變量,全部進(jìn)行初始化,是最簡單也是最常用的一種方式;variables_initializer()是初始化變量的子集,相比于全部初始化化的方式更加節(jié)約內(nèi)存;Variable()是初始化單個變量,函數(shù)的參數(shù)便是要初始化的變量內(nèi)容。通過上述的三種方式,我們便可以實現(xiàn)變量的初始化,放心的使用變量了。
我們經(jīng)常在訓(xùn)練模型后,希望保存訓(xùn)練的結(jié)果,以便下次再使用或是方便日后查看,這時就用到了Tensorflow變量的保存。變量的保存是通過tf.train.Saver()方法創(chuàng)建一個Saver管理器,來保存計算圖模型中的所有變量。具體代碼如程序2-14所示:
程序2-14:
我們要注意,我們的存儲文件save.ckpt是一個二進(jìn)制文件,Saver存儲器提供了向該二進(jìn)制文件保存變量和恢復(fù)變量的方法。保存變量的方法就是程序中的save()方法,保存的內(nèi)容是從變量名到tensor值的映射關(guān)系。完成該存儲操作后,會在對應(yīng)目錄下生成如圖2-3所示的文件:
圖2-3 保存變量生成的相應(yīng)文件
Saver提供了一個內(nèi)置的計數(shù)器自動為checkpoint文件編號。這就支持訓(xùn)練模型在任意步驟多次保存。此外,還可以通過global_step參數(shù)自行對保存文件進(jìn)行編號,例如:global_step=2,則保存變量的文件夾為model.ckpt-2。
?
那如何才能恢復(fù)變量呢?首先,我們要知道一定要用和保存變量相同的Saver對象來恢復(fù)變量。其次,不需要事先對變量進(jìn)行初始化。具體代碼如程序2-15所示:
程序2-15:
本程序示例中,我們要注意:變量的獲取是通過restore()方法,該方法有兩個參數(shù),分別是session和獲取變量文件的位置。我們還可以通過latest_checkpoint()方法,獲取到該目錄下最近一次保存的模型。
以上就是對變量創(chuàng)建、初始化、保存、加載等操作的介紹。此外,還有一些與變量相關(guān)的重要函數(shù),如:eval()等。
認(rèn)識了常量和變量,Tensorflow中還有一個非常重要的常用函數(shù)——placeholder。placeholder是一個數(shù)據(jù)初始化的容器,它與變量最大的不同在于placeholder定義的是一個模板,這樣我們就可以session運行階段,利用feed_dict的字典結(jié)構(gòu)給placeholder填充具體的內(nèi)容,而無需每次都提前定義好變量的值,大大提高了代碼的利用率。Placeholder的具體用法如程序2-16所示:
程序序2-16:
?
程序2-16演示了placeholder占位符的使用過程。Placeholder()方法有dtype,shape和name三個參數(shù)構(gòu)成。dtype是必填參數(shù),代表傳入value的數(shù)據(jù)類型;shape是選填參數(shù),代表傳入value的維度;name也是選填參數(shù),代表傳入value的名字。我們可以把這三個參數(shù)看作為形參,在使用時傳入具體的常量值。這也是placeholder不同于常量的地方,它不可以直接拿來使用,而是需要用戶傳遞常數(shù)值。
最后,Tensorflow中還有一個重要的概念——fetch。Fetch的含義是指可以在一個會話中同時運行多個op。這就方便我們在實際的建模過程中,輸出一些中間的op,取回多個tensor。Fetch的具體用法如程序2-17所示:
程序2-17:
程序2-17展示了fetch的用法,即我們利用session的run()方法同時取回多個tensor值,方便我們查看運行過程中每一步op的輸出結(jié)果。
程序2-18:
小結(jié):本節(jié)旨在讓大家學(xué)會Tensorflow的基礎(chǔ)知識,為后邊實戰(zhàn)的章節(jié)打下基礎(chǔ)。主要講了Tensorflow的核心——計算圖模型,如何定義圖模型和計算圖模型;還介紹了Tensor的概念,以及Tensorflow中的常量、變量、占位符、feed等知識點。大家都掌握了嗎?
最后,對深度學(xué)習(xí)感興趣,熱愛Tensorflow的小伙伴,歡迎關(guān)注我們的網(wǎng)站!http://www.tensorflownews.com
《新程序員》:云原生和全面數(shù)字化實踐50位技術(shù)專家共同創(chuàng)作,文字、視頻、音頻交互閱讀總結(jié)
以上是生活随笔為你收集整理的Tensorflow从入门到精通之——Tensorflow基本操作的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 写给初学者的Tensorflow介绍
- 下一篇: 中国高中生近视率高达81%,眼科专家:源