只有光頭才能變強。
文本已收錄至我的GitHub倉庫,歡迎Star:https://github.com/ZhongFuCheng3y/3y
TensorFlow是什麼意思?Tensor?Flow?這篇文章介紹TensorFlow一些最基礎的知識。
一、Tensor介紹在介紹之前,首先要記住一個結論:TensorFlow使用Tensor來表示數據
接著我們來看看什麼是Tensor,在官網的文檔中,Tensor被翻譯成」張量「。其中也給出了一個定義:
張量是對矢量和矩陣向潛在的更高維度的泛化,TensorFlow 在內部將張量表示為基本數據類型的n維數組。
不知道你們看完這句話有啥感受,反正我當時就看不懂,啥是」張量「?。於是,我就跑去知乎裡邊用關鍵字搜了一下:」張量是什麼「。果真給我搜到了相關的問題:《怎麼通俗地理解張量?》
我本以為通過知乎,就可以通俗易懂地理解什麼是張量,能給我一個清晰的認識。殊不知,大多數答主都在回答在物理和數學中張量的定義,隨後貼出了一堆我看不懂的公式。其中,也看到了一種相對通俗易懂的定義:
一個量, 在不同的參考系下按照某種特定的法則進行變換, 就是張量.
把所有答主的回答都閱讀了一遍,看完就更加抽象了。再回到官方文檔中,看看官方介紹張量的例子,貌似有點懂了。
目前為止我們有兩個結論:
我再翻譯一下上面的兩句話:在TensorFlow所有的數據都是一個n維的數組,只是我們給它起了個名字叫做張量(Tensor)
中間折騰了一大堆,實際上還是將最開頭的結論和官方的定義再翻譯成自己覺得好理解的話…但很多時候,學習就這麼一個過程。
1.1Tensor的基礎從上面我們已經得知,Tensor(張量)實際上就是一個n維的數組。這就延伸了幾個的術語:
1.1.1階(秩)其實上,階就是平時我們所說的維數。
比如我們有一個二維的數組,那麼這個階就是2
比如我們有一個三維的數組,那麼這個階就是3
以前在寫Java的時候,可能一般接觸到的都是二維的,但在機器學習上就很可能有很高的維度,那維數我們怎麼數?很簡單,我們數括號就行了。舉個例子,我們可能會看到有下面的一個數組輸出形式:
[[[9 6]
[6 9]
[8 8]
[7 9]]
[[6 1]
[3 5]
[1 7]
[9 4]]]
我們直接看第一個括號到第一個數字,有多少個括號就知道了。[[[9可以發現有3個括號,那這個就是一個三維的數組,它的階(秩)就是3
1.1.2形狀張量的形狀可以讓我們看到每個維度中元素的數量。
比如我們在Java中創建出一個二維的數組:int [][] array = new int[3][4],我們就可以知道這個數組有三行有四列。但如果我們創建出一個多維的數組,單單只用行和列就描述不清了。所以,在TensorFlow一般我們會這樣描述:
如果我們要列印上面數組的形狀時,我們可以得到這樣的結果:shape = (3,4)。我們再看看第一篇寫」機器學習HelloWorld「的時候,再來看看當時列印的結果:shape = (60000, 28, 28)。通過shape我們就可以得到一些信息:
當前數組是三維的
在第一維中有60000個元素
在第二維中有28個元素
在第三維中有28個元素
那我們如果拿到一個數組,怎麼通過肉眼看他的shape呢?
比如說:m = [[1, 2, 3], [4, 5, 6], [7, 8, 9]],這個很簡單,一眼就可以看出這個是一個二維數組(矩陣),有三行三列。所以shape的結果應該是(3,3)
再來看一個:t = [[[2], [4], [6]], [[8], [10], [12]], [[14], [16], [18]]],從多個括號上我們可以看出,這是三維的。我們先把最外層括號去掉得到的結果是[[2], [4], [6]], [[8], [10], [12]], [[14], [16], [18]]
Ok,到這一步,我們可以理解成有三個子數組,於是我們的shape可以先寫成shape(3,?,?)
隨後,我們繼續把外層的括號去除,得到這樣的結果:[2], [4], [6],也是有三個元素,於是我們的shape就可以填成shape(3,3,?)
最後,再把括號去掉,我們可以發現只有一個元素,於是最後的結果就是shape(3,3,1)
我們可以看下圖來鞏固一下上面所說的概念:
例子1.1.3 Tensor數據類型TensorFlow 在內部將張量表示為基本數據類型的 n維數組,沒錯的。在一個數組裡邊,我們總得知道我們的存進去的數據究竟是什麼類型。
Tensor的數據類型如下所示:
Tenor的數據類型二、特殊的張量特殊的張量由一下幾種:
tf.Variable— 變量
tf.constant— 常量
tf.placeholder—佔位符
tf.SparseTensor—稀疏張量
這次,我們先來講講前三種(比較好理解),分別是變量、常量和佔位符。
2.1 常量常量就是常量的意思,一經創建就不會被改變。(相信大家還是能夠理解的)
在TensorFlow中,創建常量的方式十分簡單:
a = tf.constant(2)
b = tf.constant(3)
變量也挺好理解的(就將程式語言的概念跟這裡類比就好了)。一般來說,我們在訓練過程中的參數一般用變量進行存儲起來,因為我們的參數會不停的變化。
在TensorFlow創建變量有兩種方式:
W = tf.Variable(initial_value=tf.random_normal(shape=(1, 4), mean=100, stddev=0.35), name="W")
b = tf.Variable(tf.zeros([4]), name="b")
my_int_variable = tf.get_variable("my_int_variable", [1, 2, 3], dtype=tf.int32,
initializer=tf.zeros_initializer)
值得注意的是:當我們創建完變量以後,我們每次使用之前,都需要為其進行初始化!
tf.global_variables_initializer()
我最早接觸佔位符這個概念的時候是在JDBC的時候。因為SQL需要傳入的參數才能確定下來,所以我們可能會寫出這樣的SQL語句:select * from user where id =?
同樣地,在TensorFlow佔位符也是這麼一個概念,可能需要等到運行的時候才把某些變量確定下來,於是我們就有了佔位符。
在TensorFlow使用佔位符也很簡單:
train_filenames = tf.placeholder(tf.string, shape=[None])
feed_dict={train_filenames: training_filenames}
上面的東西說白了在程式語言中都是有的,只是語法變了而已。
三、Flow?介紹圖和節點我們將Flow翻譯成中文:流,所以現在是Tensor流?
其實,在TensorFlow中,使用圖 (graph) 來表示計算任務。其實TensorFlow默認會給我們一張空白的圖,一般我們會叫這個為」數據流圖「。數據流圖由有向邊和節點組成,在使用TensorFlow的時候我們會在圖中創建各種的節點,而Tensor會在這些節點中流通。所以,就叫做TensorFlow
那有人就會好奇,我們執行什麼操作會創建節點呢?在TensorFlow中,節點的類型可以分為三種:
看到這裡的同學,可能就反應過來了:原來在上面創建的變量、常量和佔位符在TensorFlow中都會生成一個節點!對於這類的操作Operation(行為)一般大家會簡說成op
所以,op就是在TensorFlow中所執行的一個操作統稱而已(有可能是創建變量的操作、也有可能是計算的操作)。在TensorFlow的常見的op有以下:
Tensorflow常見的op其實說白了就是TensorFlow會給我們一張空白的數據流圖,我們往這張數據流圖填充(創建節點),從而實現想要效果。
開局一張圖,內容全靠編!
數據流圖的組成
我們來看看官方的給出數據流圖的gif,加深下印象。
數據流圖四、啥是session?TensorFlow程序通常被組織成一個構建階段和執行階段. 在構建階段, op的執行步驟被描述成一個圖. 在執行階段, 使用會話執行執行圖中的op。
說白了,就是當我們在編寫代碼的時候,實際上就是在將TensorFlow給我們的空白圖描述成一張我們想要的圖。但我們想要運行出圖的結果,那就必須通過session來執行。
舉個小例子:
import tensorflow as tf
x = tf.placeholder(tf.float32)
W = tf.Variable(1.0)
b = tf.Variable(1.0)
y = W * x + b
with tf.Session() as sess:
tf.global_variables_initializer().run()
fetch = y.eval(feed_dict={x: 3.0})
print(fetch)
Fetch就時候可以在session.run的時候傳入多個op(tensor),然後返回多個tensor(如果只傳入一個tensor的話,那就是返回一個tensor)
4.2tensor.eval()和Operation.run()有的同學在查閱資料的時候,發現可能調用的不是session.run,而是tensor.eval()和Operation.run()。其實,他們最後的調用的還是session.run。不同的是session.run可以一次返回多個tensor(通過Fetch)。
最後實際還是掉session.run最後曾經看到一段話總結得不錯:
使用 tensor 表示數據.
使用圖 (graph) 來表示計算任務.
在會話(session)中運行圖
通過 變量 (Variable) 維護狀態.
TensorFlow 是一個編程系統, 使用圖來表示計算任務. 圖中的節點被稱之為 op (operation 的縮寫). 一個 op 獲得 0 個或多個 Tensor, 執行計算, 產生 0 個或多個 Tensor. 每個 Tensor 是一個類型化的多維數組.
這篇文章簡單講了TensorFlow是啥意思以及一些基礎的概念。但我也只是簡單以我的理解方式來說了一些常見概念。裡頭的知識點還是比較多的(比如創建變量的時候一般我們會指定哪些參數….),這些就交由大家去官網、博客、書籍去學習了。
我相信,只要了解了這些概念,那學習一定可以事半功倍!
下一篇TensorFlow文章敬請期待~
參考資料:
樂於輸出乾貨的Java技術公眾號:Java3y。公眾號內有200多篇原創技術文章、海量視頻資源、精美腦圖,不妨來關注一下!
帥的人都關注了有幫助?好看!轉發!