TensorFlow的一些基本概念

2021-08-19 15:30:44 字數 4866 閱讀 1306

白天跟著tensorflow的官方文件把最簡單的mnist模型跑通了,基本過程算是大致理清了,但程式看一遍下來,發現tensorflow中很多基本概念還不是很理解,比如tensor這個東西怎麼理解,基於圖又是怎麼回事,於是打道回府從基本概念開始看起。

慶幸的是目前有很多人在學這個,很多學習資料已經歸類整理好了,省去了自己重新找的時間,這裡整理了一下自己查閱的資料,彙總了一篇。

tensorflow是基於計算圖的框架:

tensorflow程式通常可以分為兩個階段: 圖的構建階段和圖的執行階段

現在假如我們要計算下面的表示式,可見,要計算c就需要a和b,計算d需要b,計算e需要c和d,這樣就形成了依賴關係。這種有向無環圖就叫做計算圖

圖中的每個節點就是乙個操作(operation)operation以0個或多個tensor作為輸入,以0個或多個tensor作為輸出。比如圖中節點c=a+b,a和b是作為輸入的兩個tensor,c是作為輸出的tensortensor就在圖中沿著箭頭方向流動,我想這就是為什麼這個框架叫做tensorflow的原因吧。tensor的概念在第二節再細講。

在tensorflow的python庫中已經有乙個預設圖了,使用者可以在圖中新增節點,對於大多數程式,這個預設圖已經夠用了,當然,使用者也可以根據需要管理多張圖。

graph僅僅定義了operationtensor的流向,並不進行任何運算。之後session通過graph的定義預分配資源,計算operation,得出結果。tensor是各個操作之間的輸入或者輸出,除了用variable維護的tensor外所有的tensor在流入下乙個節點後都不再儲存。

在tensorflow中,資料用tensor表示,在計算圖中,所有operation之間傳遞的資料都是tensor。其實乙個tensor可以看成乙個多維陣列,裡面可以存放不同型別的資料。(本來還糾結tensor到底是個什麼東西,和matlab對比後秒懂=.=)。將tensor在控制台輸出,裡面有3個屬性:

>>> 

import tensorflow as tf

>>> a = tf.ones([2, 3])

>>> print(a)

tensor("ones:0", shape=(2, 3), dtype=float32)

>>> b = tf.zeros([2, 3])

>>> print(b)

tensor("zeros:0", shape=(2, 3), dtype=float32)

>>> c = a + b;

>>> print(c)

tensor("add:0", shape=(2, 3), dtype=float32)

括號裡第乙個屬性是操作的型別(後面那個數字好像是裝置號還是什麼,這個問題先放在這,以後遇到再去查),第二個是tensor的維度,第三個是tensor的型別。

和單純的多維陣列不同,tensor中還有有rank這個概念,自己敲了幾行**試了下:

>>> 

import tensorflow as tf

>>> a = tf.ones([4])

>>> b = tf.ones([3, 4])

>>> c = tf.ones([2, 3, 4])

>>> sess = tf.session()

creating tensorflow device (/gpu:0) -> (device: 0, name: geforce gtx 960m, pci bus id: 0000:01:00.0)

>>> print(sess.run(a)) # rank=1,a是乙個向量

[ 1.

1.1.

1.]>>> print(sess.run(b)) # rank=2, b是乙個二維陣列,由3個4維向量組成

[[ 1.

1.1.

1.] [ 1.

1.1.

1.] [ 1.

1.1.

1.]]

>>> print(sess.run(c)) # rank=3, c是乙個三維陣列,由2個3×4的二維陣列組成

[[[ 1.

1.1.

1.] [ 1.

1.1.

1.] [ 1.

1.1.

1.]]

[[ 1.

1.1.

1.] [ 1.

1.1.

1.] [ 1.

1.1.

1.]]]

可以看出,tensorflow中用一對中括號表示乙個行向量,高維陣列就是由若干個行向量組成,中括號可以巢狀使用。所以,乙個tensor前面或者末尾有幾個中括號,其rank值就等於幾。

構造階段完成後,才能啟**。啟**的第一步是建立乙個session物件,如果無任何建立引數,會話構造器將啟動預設圖。

import tensorflow as tf

a = tf.ones([1, 3])

b = tf.ones([1, 3])

myplus = a + b

# 啟動預設圖

sess = tf.session()

# 呼叫session()的run()方法執行操作

# 整個執行過程是自動化的,會話負責傳遞操作所需的所有輸入。操作通常是併發執行的。

# 返回值 'result' 是乙個 numpy `ndarray` 物件.

result = sess.run(myplus)

print(result)

# 關閉會話,釋放資源

sess.close()

在實現上, tensorflow 將圖形定義轉換成分布式執行的操作, 以充分利用可用的計算資源(如 cpu 或 gpu). 一般你不需要顯式指定使用 cpu 還是 gpu, tensorflow 能自動檢測. 如果檢測到 gpu, tensorflow 會盡可能地利用找到的第乙個 gpu 來執行操作.

如果機器上有超過乙個可用的 gpu, 除第乙個外的其它 gpu 預設是不參與計算的. 為了讓 tensorflow 使用這些 gpu, 你必須將 op 明確指派給它們執行.with...device語句用來指派特定的 cpu 或 gpu 執行操作.

with tf.device("/gpu:1"):

matrix1 = tf.constant([[3., 3.]])

matrix2 = tf.constant([[2.],[2.]])

product = tf.matmul(matrix1, matrix2)

...

變數維護圖執行過程中的狀態資訊。tensor一旦擁有variable的指向就不會隨session的多次載入而丟失。在session中variable是單獨儲存的,在使用時必須進行初始化。

init = tf.global_variables_initializer()

sess.run(init)

當我們定義一張graph時,有時候並不知道需要計算的值,比如模型的輸入資料,其只有在訓練與**時才會有值。這時就需要placeholder與feed_dict的幫助。

input1 = tf.placeholder(tf.float32)

input2 = tf.placeholder(tf.float32)

output = tf.mul(input1, input2)

with tf.session() as sess:

print sess.run([output], feed_dict=)

# 輸出:

# [array([ 14.], dtype=float32)]

在上面程式中,input1input2開始的值是未知的,在sess.run()中才傳給它們實際的值,feed_dict=中input1和input2是索引名,預設等於tensor的名字,也可以在定義佔位符時自己定義索引名。

input1 = tf.placeholder(tf.float32, name = 'var1')
注意,在計算圖中,可以用feed_dict來替換任何tensor,並不侷限於佔位符。

tensorflow官方文件 | 基本用法

tensorflow自學之前的bigpicture

tensorflow系列03 | tensorflow基本概念tensor理解

關於tensorflow計算圖與tensor的理解

Tensorflow的一些基本用法

在使用tensorflow中會遇到一些其基本的用法,再次作為記錄備忘 在計算整體的loss是會將不同部分的loss放入乙個集合中,最後計算整體的loss,因此會用到tf.add to collection,具體參考tensorflow中的cifar10的例子,用法如下所示 tf.add to col...

TensorFlow的一些學習筆記

1 靈活性tensorflow不是乙個嚴格的神經網路工具包,只要你可以使用資料流圖來描述你的計算過程,你可以使用tensorflow做任何事情。你還可以方便地根據需要來構建資料流圖,用簡單的python語言來實現高層次的功能。2 可移植性tensorflow可以在任意具備cpu或者gpu的裝置上執行...

tensorflow遇到的一些錯誤

1 tensorflow dtype t.dtype.base dtype attributeerror float object has no attribute dtype 參考 我報錯的行是 disc gradients disc optimizer.compute gradients dis...