1. 程式人生 > >Google TensorFlow 機器學習框架介紹和使用

Google TensorFlow 機器學習框架介紹和使用

TensorFlow是什麼?

TensorFlow是Google開源的第二代用於數字計算(numerical computation)的軟體庫。它是基於資料流圖的處理框架,圖中的節點表示數學運算(mathematical operations),邊表示運算節點之間的資料互動。TensorFlow從字面意義上來講有兩層含義,一個是Tensor,它代表的是節點之間傳遞的資料,通常這個資料是一個多維度矩陣(multidimensional data arrays)或者一維向量;第二層意思Flow,指的是資料流,形象理解就是資料按照流的形式進入資料運算圖的各個節點。

TensorFlow是一個非常靈活的框架,它能夠執行在個人電腦或者伺服器的單個或多個CPU和GPU上,甚至是移動裝置上。TensorFlow最早是Google大腦團隊為了研究機器學習和深度神經網路而開發的,但後來發現這個系統足夠通用,能夠支援更加廣泛的應用。至於為什麼谷歌要開源這個框架,它是這樣迴應的:

IfTensorFlow is so great, why open source it rather than keep it proprietary? Theanswer is simpler than you might think: We believe that machine learning is akey ingredient to the innovative products and technologies of the future.Research in this area is global and growing fast, but lacks standard tools. Bysharing what we believe to be one of the best machine learning toolboxes in theworld, we hope to create an open standard for exchanging research ideas andputting machine learning in products. Google engineers really do use TensorFlowin user-facing products and services, and our research group intends to shareTensorFlow implementations along side many of our research publications.

TensorFlow特點

1.    靈活(Deep Flexibility)

它不僅是可以用來做神經網路演算法研究,也可以用來做普通的機器學習演算法,甚至是隻要你能夠把計算表示成資料流圖,都可以用TensorFlow。

2.    便攜(True Portability)

這個工具可以部署在個人PC上,單CPU,多CPU,單GPU,多GPU,單機多GPU,多機多CPU,多機多GPU,Android手機上等,幾乎涵蓋各種場景的計算裝置。

3.    研究和產品的橋樑(Connect Research andProduction)

在谷歌,研究科學家可以用TensorFlow研究新的演算法,產品團隊可以用它來訓練實際的產品模型,更重要的是這樣就更容易將研究成果轉化到實際的產品。另外Google在白皮書上說道,幾乎所有的產品都用到了TensorFlow,比如搜尋排序,語音識別,谷歌相簿,自然語言處理等。

4.    自動做微分運算(Auto-Differentiation)

機器學習中的很多演算法都用到了梯度,使用TensorFlow,它將自動幫你求出梯度,只要你定義好目標函式,增加資料就好了。聽上去很誘人,暫時不知道具體咋實現的。

5.    語言靈活(Language Options)

TensorFlow使用C++實現的,然後用Python封裝,暫時只支援這兩種語言,谷歌號召社群通過SWIG開發更多的語言介面來支援TensorFlow。

6.    最大化效能(Maximize Performance)

通過對執行緒,佇列和非同步計算的支援(first-class support),TensorFlow可以執行在各種硬體上,同時根據計算的需要,合理將運算分配到相應的裝置,比如卷積就分配到GPU上。

TensorFlow安裝

具體安裝可以參看這個連結:

https://www.tensorflow.org/versions/master/get_started/os_setup.html

原始碼可以從這個連結下載:

安裝很簡單,沒有嘗試GPU:

# Ubuntu/Linux 64-bit
$ sudo apt-get install python-pip python-dev
# Mac OS X
$ sudo easy_install pip

Install TensorFlow:

# Ubuntu/Linux 64-bit, CPU only:
$ sudo pip install --upgrade https://storage.googleapis.com/tensorflow/linux/cpu/tensorflow-0.6.0-cp27-none-linux_x86_64.whl
# Ubuntu/Linux 64-bit, GPU enabled:
$ sudo pip install --upgrade https://storage.googleapis.com/tensorflow/linux/gpu/tensorflow-0.6.0-cp27-none-linux_x86_64.whl
# Mac OS X, CPU only:
$ sudo easy_install --upgrade six
$ sudo pip install --upgrade https://storage.googleapis.com/tensorflow/mac/tensorflow-0.6.0-py2-none-any.whl

安裝完成後,輸入如下命令,檢測是否安裝成功。

$ python
...
>>> import tensorflow as tf
>>> hello = tf.constant('Hello, TensorFlow!')
>>> sess = tf.Session()
>>> print(sess.run(hello))
Hello, TensorFlow!
>>> a = tf.constant(10)
>>> b = tf.constant(32)
>>> print(sess.run(a + b))
42
>>> 
如果報無法獲取CPU資訊錯誤,可以在上述程式碼中,修改新增如下幾行:
NUM_CORES = 4 # Choose how many cores to use.
sess = tf.Session(
   config=tf.ConfigProto(inter_op_parallelism_threads=NUM_CORES,
                  intra_op_parallelism_threads=NUM_CORES))

基礎使用

在使用TensorFlow之前,有必要了解如下幾個概念:

1. 計算是用圖的形式表示的。

2. Sessions是執行的入口,類似於SparkContext。

3. 資料是用tensor表示的。

4. Variables用來表示可變狀態,比如模型引數。

5. 使用feeds和fetches從運算節點輸入和輸出資料。

TensorFlow計算框架要求所有的計算都表示成圖,節點在圖中被稱為運算op(operation簡稱)。一個運算可以獲得零個或者多個Tensors,經過計算,可以產生零個或者多個Tensors。一個Tensor是一個多維陣列,舉個例子,可以把一批影象資料表示成一個4維浮點陣列[batch, height, width, channels]

計算圖是通過Session提交,一個Session決定圖中的運算該到那個裝置上去計算,比如是選CPU還是CPU。運算op產生的結果在python中是一個numpy.ndarray陣列物件,在C和C++中是tensorflow::Tensor例項。

構建一個計算圖

構建圖首先有構建運算op,op不一定要有輸入,可以用Constant商量來構建一個運算節點,然後把它的結果輸出到另外的運算中。如下是利用Constant生成一個簡單的運算,並且以此構建了一個計算圖。

import tensorflow as tf

# 建立一個1X2的矩陣matrix1

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

# 建立一個2X1的矩陣matrix2

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

# 建立matrix1和matrix2的乘積運算,返回矩陣product

product = tf.matmul(matrix1, matrix2)

上面這個圖中包含三個運算,兩個constant()運算,一個矩陣乘法運算matmul()。要獲得最終矩陣乘積的結果,需要用session提交這個圖。

Session提交計算圖

# 建立session物件

sess = tf.Session()

# 通過Session中run()方法提交計算圖

result = sess.run(product)

print(result)

# ==> [[ 12.]]

# 執行完關閉這個Session

sess.close()

當Session執行完成後,需要手動關閉,當然你也可以利用“with”關鍵字,執行完自動關閉。

with tf.Session() as sess:

  result= sess.run([product])

 print(result)

在分散式執行環境下,一般不需要手動指出哪些運算該放到哪些機器上,比如CPU,GPU,但是框架提供了手動設定的功能。

with tf.Session() as sess:

  withtf.device("/gpu:1"):

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

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

   product = tf.matmul(matrix1, matrix2)

    ...

目前支援這幾種裝置:

·       "/cpu:0": The CPU of your machine.

·       "/gpu:0": The GPU of your machine, if you have one.

·       "/gpu:1": The second GPU of your machine, etc.

互動式使用

TensorFlow提供了一個類似iPython的機制,通過建立InteractiveSeesion物件來實現。

# Enter an interactive TensorFlow Session.

import tensorflow as tf

sess = tf.InteractiveSession()

x = tf.Variable([1.0, 2.0])

a = tf.constant([3.0, 3.0])

# Initialize 'x' using the run() method of itsinitializer op.

x.initializer.run()

# Add an op to subtract 'a' from 'x'.  Run it and print the result

sub = tf.sub(x, a)

print(sub.eval())

# ==> [-2. -1.]

# Close the Session when we're done.

sess.close()

變數(Variables)

變數維護整個執行圖過程中間的狀態,比如Hadoop中的計數器就是一個變數。具體在機器學習任務中,當我們訓練一個深度神經網路的時候,每一層的節點權重就是用Variable來表示的,在訓練過程中,權重會不斷地更新。看如下示例:

# Create a Variable, that will be initializedto the scalar value 0.

state = tf.Variable(0,name="counter")

# Create an Op to add one to `state`.

one = tf.constant(1)

new_value = tf.add(state, one)

update = tf.assign(state, new_value)

# Variables must be initialized by running an`init` Op after having

# launched the graph.  We first have to add the `init` Op to thegraph.

init_op = tf.initialize_all_variables()

# Launch the graph and run the ops.

with tf.Session() as sess:

  # Runthe 'init' op

 sess.run(init_op)

  # Printthe initial value of 'state'

 print(sess.run(state))

  # Runthe op that updates 'state' and print 'state'.

  for _in range(3):

   sess.run(update)

   print(sess.run(state))

# output:

# 0

# 1

# 2

# 3

assign()是賦值運算,實際的執行是在 run() 被執行的時候開始。

資料獲取(Fetches)

獲取一個op的運算結果,可以通過呼叫Session中的run()方法,同時可以獲得多個結果,所有結果獲取只需要執行一次run請求。

input1 = tf.constant(3.0)

input2 = tf.constant(2.0)

input3 = tf.constant(5.0)

intermed = tf.add(input2, input3)

mul = tf.mul(input1, intermed)

with tf.Session() as sess:

  result= sess.run([mul, intermed])

 print(result)

# output:

# [array([ 21.], dtype=float32), array([ 7.],dtype=float32)]

資料輸入(Feeds)

之前介紹的資料輸入使用Constant,直接輸入一個明確的常量資料,TensorFlow同時提供了一種“佔位符(placeholder)”方式,用來表示一個數據,然後在呼叫run,通過引數傳入批量輸入資料進去後,具體獲取資料,具體可以如下示例:

# 建立兩個輸入input1和input2,這時這兩個資料裡面什麼都沒有

# 可以理解為申明瞭兩個輸入變數。

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={input1:[7.], input2:[2.]}))

# output:

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

具體輸入是feed_dict。

參考文獻

廖博森 @DataSpark