1. 程式人生 > >斯坦福CS20 TensorFlow學習筆記(1):Overview of Tensorflow

斯坦福CS20 TensorFlow學習筆記(1):Overview of Tensorflow

     斯坦福CS20 TensorFlow學習筆記(1):Overview of Tensorflow

1- TensorFlow是什麼?

Google官方的介紹是:

TensorFlow™ is an open source software library for high performance numerical computation.

TensorFlow最早起源於Google內部的機器學習工具,而TensorFlow則是該工具於2015年11月的開源實現(剝離了Google內部程式碼的依賴)。

2- 為什麼選TensorFlow

除TensorFlow之外,還有許多比較流行的機器學習框架,比如:

  • Torch (facebook)
  • Theano
  • Caffe (Microsoft)
  • CNTK

我們選擇TensorFlow的原因是:

  • 靈活性(Flexiblity)和可伸縮性(Scalablity)

  • 流行度(Popularity)
    特別是流行度,目前TensorFlow的流行度遠超其他幾個框架。下圖展示了GitHub上TensorFlow的start數和倉庫數遠大於其他框架

    Xnip2018-08-13_21-14-34

另外,TensorFlow還具有如下幾個特性:

  • Portability
  • visualization:TensorBoard
  • autodiff
  • checkpoints

3- 課程輔助資料

TensorFlow的變化非常大,因此最好的參考資料還是官網,但CS20也推薦的一些參考資料:

  • TensorFlow’s official sample models
  • StackOverflow should be your first port of call in case of bug
    Books
  • Aurélien Géron’s Hands-On Machine Learning with Scikit-Learn and TensorFlow (O’Reilly, March 2017)
  • François Chollet’s Deep Learning with Python (Manning Publications, November 2017)
  • Nishant Shukla’s Machine Learning with TensorFlow (Manning Publications, January 2018)
  • Lieder et al.’s Learning TensorFlow A Guide to Building Deep Learning Systems (O’Reilly, August 2017)

4- Graph和Session

4.1- 計算定義與執行分離

TensorFlow的重要思想是:將計算的定義和其執行相分離,這樣思想也是依賴於graph和session的,即:

  • 第一步:組裝一個graph,即定義計算
  • 第二部:使用session執行graph上的操作(operation),即執行計算。

下面是graph的一個圖示:

Xnip2018-08-13_21-23-29

建議通過官方文件進一步深入瞭解TensorFlow的核心概念,我們補充了下面幾個參考:

4.2- 什麼是tensor?

個人認為,在談tensor的時候,我們最好區別一下廣義的tensor和狹義的tensor,分別理解。廣義的tensor是一個數學概念,狹義的tensor是指TensorFlow框架中的tf.Tensor

廣義的tensor,一種理解是指對向量和矩陣的推廣,可以理解為n維陣列(An n-dimensional array),所以有:

  • 0-d tensor: scalar (number)
  • 1-d tensor: vector
  • 2-d tensor: matrix
  • and so on

在機器學習裡,是借用了tensor這種數學概念,表示常常出現的多維陣列。

tf.Tensor是一種Python型別,它並沒有實際儲存資料,技術上來說,我們直接列印一個Tensor,並不能得到tf.Tensor對應的值(或稱之為tensor value,具體來說就是numpy中的ndarray,對應理解為即廣義上的tensor)。而要得到tensor value,則需要通過session執行得到,接下來會介紹。

4.3- Data Flow Graphs

TensorFlow的計算過程會被表示為graph,比如:

import tensorflow as tf
a = tf.add(3, 5)

對應的graph是:

Xnip2018-08-15_20-39-01

特別需要注意的是:常規的圖,我們一般習慣用node表示資料,edge表示功能。在TensorFlow裡恰好相反,需要適應:

  • node表示的是:operators, variables, and constants(相當於flow)
  • edge表示的是:tensors

若tensor理解為data,則:TensorFlow = tensor + flow = data + flow。即tensor(廣義的含義)在graph中流動(flow)。

4.4- sessioin

4.4.1- How to get the value of a tensor?

tf.Tensor並不直接儲存對應的tensor value。比如我們直接對一個tensor應用print,得到的是結果類似如下:

<tf.Tensor 'Add:0' shape=() dtype=int32>

因為,我們只是用tf.Tensor定義計算過程,但得到計算值,要使用session來evaluate,具體來說就是:

  • 建立一個session
  • 在session內,使用run方法evaluate一個graph

比如:

import tensorflow as tf
a = tf.add(3, 5)
sess = tf.Session()
print(sess.run(a))
sess.close()

session會檢視graph,然後思考:嗯,我怎麼得到a的值呢?為此它會計算所有通向a的node。(這裡有個隱含的意思,session只計算通向a需要的部分,對於跟本次計算無關的部分不計算,下面會有例子看到。)

總結一下,一個session物件封裝了一個環境,在這個環境內operation物件被執行,Tensor物件被evaluate。(A Session object encapsulates the environment in which Operation objects are executed, and Tensor objects are evaluated.

另外,session也會為儲存當前Variable的值分配記憶體。

4.4.2- subgraphs

之前,我們提到session指計算圖中通向目標node的node們,下面加以說明。假如我們有以下程式碼:

x = 2
y = 3
add_op = tf.add(x, y)
mul_op = tf.multiply(x, y)
useless = tf.multiply(x, add_op)
pow_op = tf.pow(add_op, mul_op)
with tf.Session() as sess:
	z = sess.run(pow_op)

計算圖如下:

Xnip2018-08-15_21-43-09

我們看到useless這個節點,對最後計算pow_op沒有作用,因此實際上useless節點並沒有被計算。

如果我們將pow_opuse_less都放在session.run裡面,就可以一起計算了:

x = 2
y = 3
add_op = tf.add(x, y)
mul_op = tf.multiply(x, y)
useless = tf.multiply(x, add_op)
pow_op = tf.pow(add_op, mul_op)
with tf.Session() as sess:
	z, not_useless = sess.run([pow_op, useless])

這裡,傳入run的引數是一個list。tf.Session.run的方法簽名如下,其中第一個引數fetches可以是一個list:

tf.Session.run(fetches,
   	 feed_dict=None,
 options=None,
 run_metadata=None)

subgraph的作用之一是做分散式計算,即將一個graph拆分為多個部分,並行的在多個GPU、CPU、TPU或其他裝置上執行。比如AlexNet的第一個卷積層,就是將96個filter放在兩個GPU上運算的。下圖是將graph分佈到兩個GPU上計算的示意圖:

Xnip2018-08-15_21-51-33

下面是TensorFlow中用tf.device指定graph部分節點在不同裝置上計算的程式碼:

# Creates a graph.
with tf.device('/gpu:2'):
  a = tf.constant([1.0, 2.0, 3.0, 4.0, 5.0, 6.0], name='a')
  b = tf.constant([1.0, 2.0, 3.0, 4.0, 5.0, 6.0], name='b')
  c = tf.multiply(a, b)

# Creates a session with log_device_placement set to True.
sess = tf.Session(config=tf.ConfigProto(log_device_placement=True))

# Runs the op.
print(sess.run(c))

4.5- multi graph

上面介紹的程式碼中,並沒有顯式的出現graph物件。事實上session會我們建立一個預設的graph,通常這已經足夠了。但TensorFlow裡是可以建立多個graph的,不過使用多個graph,下面幾點是必須瞭解的:

  • Multiple graphs require multiple sessions, each will try to use all available resources by default
  • Can't pass data between them without passing them through python/numpy, which doesn't work in distributed
  • It’s better to have disconnected subgraphs within one graph

下面總結了graph的一些API:

建立graph的方法是:

tf.graph()

建立graph後,可以在graph上增加操作,前提是將其設定為預設graph:

g = tf.Graph()
with g.as_default():
	x = tf.add(3, 5)
sess = tf.Session(graph=g)
with tf.Session() as sess:
	sess.run(x)

獲取當前預設的graph:

g = tf.get_default_graph()

不要將預設graph和使用者定義graph混淆,比如下面分別在兩個graph上定義了操作,如果不注意可能混淆:

g = tf.Graph()
# add ops to the default graph
a = tf.constant(3)
# add ops to the user created graph
with g.as_default():
	b = tf.constant(5)

下面的寫法會更清晰些:

g1 = tf.get_default_graph()
g2 = tf.Graph()
# add ops to the default graph
with g1.as_default():
	a = tf.Constant(3)
# add ops to the user created graph
with g2.as_default():
	b = tf.Constant(5)

最後說明一下,即便如此,還是不推薦使用多個graph

4.6- Why graphs

TensorFlow為什麼要使用graph呢?主要有如下幾點:

  1. Save computation. Only run subgraphs that lead to the values you want to fetch.
  2. Break computation into small, differential pieces to facilitate auto-differentiation
  3. Facilitate distributed computation, spread the work across multiple CPUs, GPUs, TPUs, or other devices
  4. Many common machine learning models are taught and visualized as directed graphs

我個人理解,第2點的自動求導是最重要的。只有得到了計算圖,才有可能實現自動求導,進而自動做反向傳播,這也是機器學習框架的重要功能。

【轉載】:http://imshuai.com/cs20-tensorflow-notes-1/