溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點(diǎn)擊 登錄注冊 即表示同意《億速云用戶服務(wù)條款》

機(jī)器學(xué)習(xí)庫初探之TensorFlow

發(fā)布時間:2020-08-11 21:47:32 來源:網(wǎng)絡(luò) 閱讀:25532 作者:lucianlv 欄目:開發(fā)技術(shù)

機(jī)器學(xué)習(xí)庫初探之TensorFlow

什么是TensorFlow?1

TensorFlow 是一個采用數(shù)據(jù)流圖(data flow graphs),用于數(shù)值計(jì)算的開源軟件庫。節(jié)點(diǎn)(Nodes)在圖中表示數(shù)學(xué)操作,圖中的(edges)則表示在節(jié)點(diǎn)間相互聯(lián)系的多維數(shù)據(jù)數(shù)組,即張量(tensor)。它靈活的架構(gòu)讓你可以在多種平臺上展開計(jì)算,例如臺式計(jì)算機(jī)中的一個或多個CPU(或GPU),服務(wù)器,移動設(shè)備等等。TensorFlow 最初由Google大腦小組(隸屬于Google機(jī)器智能研究機(jī)構(gòu))的研究員和工程師們開發(fā)出來,用于機(jī)器學(xué)習(xí)和深度神經(jīng)網(wǎng)絡(luò)方面的研究,但這個系統(tǒng)的通用性使其也可廣泛用于其他計(jì)算領(lǐng)域。

當(dāng)前TensorFlow最新的開源版本是r0.9。

什么是數(shù)據(jù)流圖?

機(jī)器學(xué)習(xí)庫初探之TensorFlow

數(shù)據(jù)流圖用“結(jié)點(diǎn)”(nodes)和“線”(edges)的有向圖來描述數(shù)學(xué)計(jì)算。“節(jié)點(diǎn)” 一般用來表示施加的數(shù)學(xué)操作,但也可以表示數(shù)據(jù)輸入(feed in)的起點(diǎn)/輸出(push out)的終點(diǎn),或者是讀取/寫入持久變量(persistent variable)的終點(diǎn)?!熬€”表示“節(jié)點(diǎn)”之間的輸入/輸出關(guān)系。這些數(shù)據(jù)“線”可以輸運(yùn)“size可動態(tài)調(diào)整”的多維數(shù)據(jù)數(shù)組,即“張量”(tensor)。張量從圖中流過的直觀圖像是這個工具取名為“Tensorflow”的原因。一旦輸入端的所有張量準(zhǔn)備好,節(jié)點(diǎn)將被分配到各種計(jì)算設(shè)備完成異步并行地執(zhí)行運(yùn)算。

TensorFlow的關(guān)鍵特性2

高度的靈活性

TensorFlow 不是一個嚴(yán)格的“神經(jīng)網(wǎng)絡(luò)”庫。只要可以將計(jì)算表示為一個數(shù)據(jù)流圖,就可以使用Tensorflow來構(gòu)建圖,描寫驅(qū)動計(jì)算的內(nèi)部循環(huán)。Tensorflow提供了有用的工具來幫助你組裝“子圖”(常用于神經(jīng)網(wǎng)絡(luò)),當(dāng)然用戶也可以自己在Tensorflow基礎(chǔ)上寫自己的“上層庫”。定義順手好用的新復(fù)合操作和寫一個python函數(shù)一樣容易,而且也不用擔(dān)心性能損耗。當(dāng)然萬一發(fā)現(xiàn)找不到想要的底層數(shù)據(jù)操作,也可以自己寫一點(diǎn)c++代碼來豐富底層的操作。

真正的可移植性

Tensorflow 可以在CPU和GPU上運(yùn)行,比如說可以運(yùn)行在臺式機(jī)、服務(wù)器、手機(jī)移動設(shè)備等等。想要在沒有特殊硬件的前提下,在你的筆記本上跑一下機(jī)器學(xué)習(xí)的新想法?Tensorflow也可以辦到。準(zhǔn)備將你的訓(xùn)練模型在多個CPU上規(guī)?;\(yùn)算,又不想修改代碼?Tensorflow也可以辦到。想要將你的訓(xùn)練好的模型作為產(chǎn)品的一部分用到手機(jī)app里?Tensorflow可以辦到這點(diǎn)。你改變主意了,想要將你的模型作為云端服務(wù)運(yùn)行在自己的服務(wù)器上,或者運(yùn)行在Docker容器里?Tensorfow也能辦到。

將科研和產(chǎn)品聯(lián)系在一起

過去如果要將科研中的機(jī)器學(xué)習(xí)想法用到產(chǎn)品中,需要大量的代碼重寫工作。那樣的日子一去不復(fù)返了!在Google,科學(xué)家用Tensorflow嘗試新的算法,產(chǎn)品團(tuán)隊(duì)則用Tensorflow來訓(xùn)練和使用計(jì)算模型,并直接提供給在線用戶。使用Tensorflow可以讓應(yīng)用型研究者將想法迅速運(yùn)用到產(chǎn)品中,也可以讓學(xué)術(shù)×××者更直接地彼此分享代碼,從而提高科研產(chǎn)出率。

自動求微分

基于梯度的機(jī)器學(xué)習(xí)算法會受益于Tensorflow自動求微分的能力。作為Tensorflow用戶,你只需要定義預(yù)測模型的結(jié)構(gòu),將這個結(jié)構(gòu)和目標(biāo)函數(shù)(objective function)結(jié)合在一起,并添加數(shù)據(jù),Tensorflow將自動為你計(jì)算相關(guān)的微分導(dǎo)數(shù)。計(jì)算某個變量相對于其他變量的導(dǎo)數(shù)僅僅是通過擴(kuò)展你的圖來完成的,所以你能一直清楚看到究竟在發(fā)生什么。

多語言支持

Tensorflow 有一個合理的c++使用界面,也有一個易用的python使用界面來構(gòu)建和執(zhí)行你的graphs。你可以直接寫python/c++程序,也可以用交互式的ipython界面來用Tensorflow嘗試些想法,它可以幫你將筆記、代碼、可視化等有條理地歸置好。當(dāng)然這僅僅是個起點(diǎn)——Tensorflow鼓勵創(chuàng)造自己最喜歡的語言界面,比如Go,Java,Lua,Javascript,或者是R。

目前開源的版本暫時只看到對于python/C++的支持,并且python的API比C++的還是要更成熟易用。社區(qū)已經(jīng)有針對Java和Ruby的支持。

性能最優(yōu)化

比如說你有一個具有32個CPU內(nèi)核、4個GPU顯卡的工作站,想要將你工作站的計(jì)算潛能全發(fā)揮出來?由于Tensorflow 給予了線程、隊(duì)列、異步操作等以最佳的支持,Tensorflow 讓你可以將你手邊硬件的計(jì)算潛能全部發(fā)揮出來。你可以自由地將Tensorflow圖中的計(jì)算元素分配到不同設(shè)備上,Tensorflow可以幫你管理好這些不同副本。

TensorFlow在Google的應(yīng)用


機(jī)器學(xué)習(xí)庫初探之TensorFlow

  • 超過100項(xiàng)線上產(chǎn)品在使用TensorFlow;

  • Google數(shù)據(jù)科學(xué)家和工程師都在使用TensorFlow;

  • Google用TensorFlow構(gòu)建下一代的智能應(yīng)用;

  • TensorFlow已經(jīng)被Google開源,并部署到Google Cloud上;

社區(qū)活躍度

機(jī)器學(xué)習(xí)庫初探之TensorFlow

TensorFlow的安裝

TensorFlow支持二進(jìn)制包和源碼包等多種安裝方式,支持在Linux、Mac OS X、Ubuntu等多個平臺上進(jìn)行安裝,并且可以運(yùn)行在docker之上,官網(wǎng)上有比較詳細(xì)的安裝文檔。

TensorFlow最簡單的安裝方式是通過pip進(jìn)行安裝,如果條件不允許(例如無外網(wǎng)的條件下),需要通過源碼進(jìn)行安裝,TensorFlow的源碼編譯依賴Python 2.7版本,以及Bazel進(jìn)行編譯。

整體來說TensorFlow的安裝過程還是比較簡單的。

TensorFlow基本術(shù)語

Devices

一塊可以用來運(yùn)算并且擁有自己的地址空間的硬件,比如GPU和CPU。

eval

Tensor 的一個方法,返回 Tensor 的值。觸發(fā)任意一個圖計(jì)算都需要計(jì)算出這個值。只能在一個已經(jīng)啟動的會話的圖中才能調(diào)用該 Tensor 值。

Feed

TensorFlow 的一個概念:把一個 Tensor 直接連接到一個會話圖表中的任意節(jié)點(diǎn)。feed 不是在構(gòu)建圖(graph)的時候創(chuàng)建,而是在觸發(fā)圖的執(zhí)行操作時去申請。一個 feed 臨時替代一個帶有 Tensor 值的節(jié)點(diǎn)。把feed數(shù)據(jù)作為run( )方法和eval( )方法的參數(shù)來初始化運(yùn)算。方法運(yùn)行結(jié)束后,替換的 feed 就會消失,而最初的節(jié)點(diǎn)定義仍然還在??梢酝ㄟ^tf.placeholder( )把特定的節(jié)點(diǎn)指定為 feed 節(jié)點(diǎn)來創(chuàng)建它們。

Fetch

TensorFlow中的一個概念:為了取回運(yùn)算操作的輸出結(jié)果。取回的申請發(fā)生在觸發(fā)執(zhí)行圖操作的時候,而不是發(fā)生在建立圖的時候。如果要取回一個或多個節(jié)點(diǎn)(node)的 Tensor 值,可以通過在 Session 對象上調(diào)用run( )方法并將待取回節(jié)點(diǎn)(node)的列表作為參數(shù)來執(zhí)行圖表(graph)。

Graph

把運(yùn)算任務(wù)描述成一個直接的無環(huán)圖形(DAG),圖表中的節(jié)點(diǎn)(node)代表必須要實(shí)現(xiàn)的一些操作。圖中的邊代表數(shù)據(jù)或者可控的依賴。GratheDef 是系統(tǒng)中描述一個圖表的協(xié)議(api),它由一個 NodeDefs 集合組成。一個GraphDef可以轉(zhuǎn)化成一個更容易操作的圖表對象。

IndexedSlices

在 Python API 中,TensorFlow 僅僅在第一維上對 Tensor 有所體現(xiàn)。如果一個 Tensor 有k維,那么一個 IndexedSlices 實(shí)例在邏輯上代表一個沿著這個 Tensor 第一維的(k-1)維切片的集合。切片的索引被連續(xù)儲存在一個單獨(dú)的一維向量中,而對應(yīng)的切片則被拼接成一個單獨(dú)的k維 Tensor。如果 sparsity 不是受限于第一維空間,請用 SparseTensor。

Node

圖中的一個元素。 把啟動一個特定操作的方式稱為特定運(yùn)算圖表的一個節(jié)點(diǎn),包括任何用來配置這個操作的屬性的值。對于那些多形態(tài)的操作,這些屬性包括能完全決定這個節(jié)點(diǎn)(Node)簽名的充分信息。

operation

在 TensorFlow 的運(yùn)行時中,它是一種類似 add 或 matmul 或 concat的運(yùn)算??梢杂胔ow to add an op中的方法來向運(yùn)行時添加新的操作。

在 Python 的API中,它是圖中的一個節(jié)點(diǎn)。在tf.Operation類中列舉出了這些操作。一個操作(Operation)的 type 屬性決定這個節(jié)點(diǎn)(node)的操作類型,比如add和matmul。

Run

在一個運(yùn)行的圖中執(zhí)行某種操作的行為。要求圖必須運(yùn)行在會話中。

在 Python 的 API 中,它是 Session 類的一個方法tf.Session.run??梢酝ㄟ^ Tensors 來訂閱或獲取run( )操作。

在C++的API中,它是tensorflow::Session類 的一個方法。

Session

啟動圖的第一步是創(chuàng)建一個 Session 對象。Session 提供在圖中執(zhí)行操作的一些方法。

在 Python API中,使用tf.Session。

在 C++ 的API中,tensorflow::Session是用來創(chuàng)建一個圖并運(yùn)行操作的類。

Shape

Tensor 的維度和它們的大小。

在一個已經(jīng)啟動的圖中,它表示流動在節(jié)點(diǎn)(node)之間的 Tensor 的屬性。一些操作對 shape 有比較強(qiáng)的要求,如果沒有 Shape 屬性則會報(bào)告錯誤。

在 Python API中,用創(chuàng)建圖的 API 來說明 Tensor 的 Shape 屬性。Tensor 的Shape 屬性要么只有部分已知,要么全部未知。詳見tf.TensroShape

在C++中,Shape 類用來表示 Tensor 的維度。tensorflow::TensorShape。

SparseTensor

在 Python API 中,它用來表示在 TensorFlow 中稀疏散落在任意地方的 Tensor 。SparseTensor 以字典-值格式來儲存那些沿著索引的非空值。換言之,m個非空值,就包含一個長度為m的值向量和一個由m列索引(indices)組成的矩陣。為了提升效率,SparseTensor 需要將 indice(索引)按維度的增加來按序存儲,比如行主序。如果稀疏值僅沿著第一維度,就用 IndexedSlices。

Tensor

Tensor是一種特定的多維數(shù)組。比如,一個浮點(diǎn)型的四維數(shù)組表示一小批由[batch,height,width,channel]組成的圖片。

在一個運(yùn)行的圖(graph)中,它是一種流動在節(jié)點(diǎn)(node)之間的數(shù)據(jù)。 在 Python 中,Tensor 類表示添加到圖的操作中的輸入和輸出,見tf.Tensor,這樣的類不持有數(shù)據(jù)。

在C++中,Tensor是方法Session::Run( )的返回值,見tensorflow::Tensor,這樣的 Tensor 持有數(shù)據(jù)。

TensorFlow上手層度

TensorFlow 和 Numpy在描述N維數(shù)據(jù)方面是非常相似的,不同的是TensorFlow除了能定義N維數(shù)組,還能創(chuàng)建N維數(shù)組的方程,并能自動計(jì)算求導(dǎo),做更多的事情。

numpy

機(jī)器學(xué)習(xí)庫初探之TensorFlow

tensorflow

機(jī)器學(xué)習(xí)庫初探之TensorFlow

對比兩者之間的區(qū)別: 

機(jī)器學(xué)習(xí)庫初探之TensorFlow

可見在tensorflow中許多基礎(chǔ)的N-array操作都是類似的,這讓很多接觸過numpy進(jìn)行數(shù)據(jù)分析的人員都能很自然的上手tensorflow。

TensorFlow體驗(yàn)

以下借助TensorFlow我實(shí)現(xiàn)了一個簡單的單變量線性回歸程序:

import tensorflow as tf
import numpy as np
import matplotlib.pyplot as plt

# 定義輸入數(shù)據(jù)
X_data = np.linspace(-1, 1, 100)
noise = np.random.normal(0, 0.5, 100)
y_data = 5 * X_data + noise

# Plot 輸入數(shù)據(jù)
fig = plt.figure()
ax = fig.add_subplot(1, 1, 1)
ax.scatter(X_data, y_data)
plt.ion()
plt.show()

# 定義數(shù)據(jù)大小
n_samples = 100

# 轉(zhuǎn)換成向量
X_data = np.reshape(X_data, (n_samples, 1))
y_data = np.reshape(y_data, (n_samples, 1))

# 定義占位符
X = tf.placeholder(tf.float32, shape=(None, 1))
y = tf.placeholder(tf.float32, shape=(None, 1))

# 定義學(xué)習(xí)的變量
W = tf.get_variable("weight", (1, 1),
                    initializer=tf.random_normal_initializer())
b = tf.get_variable("bais", (1,),
                    initializer=tf.constant_initializer(0.0))
y_pred = tf.matmul(X, W) + b
loss = tf.reduce_mean(tf.reduce_sum(tf.square(y - y_pred)))

# 梯度下降
# 定義優(yōu)化函數(shù)
opt = tf.train.GradientDescentOptimizer(0.001)
operation = opt.minimize(loss)

with tf.Session() as sess:
    # 初始化變量
    sess.run(tf.initialize_all_variables())
    
    lines = None
    for i in range(50):  
        _, loss_val = sess.run([operation, loss], 
                               feed_dict={X: X_data, y: y_data})
       
        if i % 5 == 0:
            if lines:
                ax.lines.remove(lines[0])
                
            prediction_value = sess.run(y_pred, feed_dict={X: X_data})
            lines = ax.plot(X_data, prediction_value, 'r-', lw=5)
            plt.pause(0.1)
    
    plt.pause(5)


通過簡單的定義目標(biāo)函數(shù)和選擇優(yōu)化算法,就可以開始訓(xùn)練我的模型了。

機(jī)器學(xué)習(xí)庫初探之TensorFlow

結(jié)果我并沒有親手實(shí)現(xiàn)梯度下降算法,就達(dá)到了訓(xùn)練樣本的目的。開發(fā)人員可以只關(guān)注模型本身,剩下的事情 TensorFlow 幫你搞定的妥妥的!這只是小試牛刀,TensorFlow 可以訓(xùn)練更加復(fù)雜的模型:循環(huán)神經(jīng)網(wǎng)絡(luò),卷積神經(jīng)網(wǎng)絡(luò),遞歸神經(jīng)網(wǎng)絡(luò)等等。

TensorBoard

TensorFlow 提供了一個內(nèi)置的可視化工具叫做 TensorBoard。有了 TensorBoard 可以更方便 TensorFlow 程序的理解、調(diào)試與優(yōu)化。你可以用 TensorBoard 來展現(xiàn)你的 TensorFlow 圖像,繪制圖像生成的定量指標(biāo)圖以及附加數(shù)據(jù)。

通過簡單的改寫,我就可以在上面的例子中使用TensorBoard了:

import tensorflow as tf
import numpy as np

# 定義輸入數(shù)據(jù)
X_data = np.linspace(-1, 1, 100)
noise = np.random.normal(0, 0.5, 100)
y_data = 5 * X_data + noise

# 定義數(shù)據(jù)大小
n_samples = 100

# 轉(zhuǎn)換成向量
X_data = np.reshape(X_data, (n_samples, 1))
y_data = np.reshape(y_data, (n_samples, 1))

with tf.name_scope("input"):
    # 定義占位符
    X = tf.placeholder(tf.float32, shape=(None, 1))
    y = tf.placeholder(tf.float32, shape=(None, 1))

# 定義學(xué)習(xí)的變量
with tf.name_scope("linear-regression"):
    with tf.name_scope("Weight"):
        W = tf.get_variable("weight", (1, 1),
                            initializer=tf.random_normal_initializer())
    with tf.name_scope("bais"):
        b = tf.get_variable("bais", (1,),
                            initializer=tf.constant_initializer(0.0))
    with tf.name_scope("prediction"):
        y_pred = tf.add(tf.matmul(X, W), b)
    with tf.name_scope("loss"):
        loss = tf.reduce_mean(tf.reduce_sum(tf.square(y - y_pred)))
        tf.scalar_summary("loss", loss)

# 梯度下降
# 定義優(yōu)化函數(shù)
with tf.name_scope("train"):
    opt = tf.train.GradientDescentOptimizer(0.001)
    operation = opt.minimize(loss)

with tf.Session() as sess:
    merged = tf.merge_all_summaries()
    writer = tf.train.SummaryWriter("logs/", sess.graph)    
    
    # 初始化變量
    sess.run(tf.initialize_all_variables())
    
    for i in range(50):  
        _, loss_val = sess.run([operation, loss], 
                               feed_dict={X: X_data, y: y_data})
       
        if i % 5 == 0:
            result = sess.run(merged, feed_dict={X: X_data, y: y_data})
            writer.add_summary(result, i)


再次執(zhí)行上面的代碼,會在logs/子目錄下生成一個日志文件。通過在打開 TensorBoard 的時候指定日志目錄加載這個日志文件,我們就可以通過瀏覽器訪問 TensorBoard 了。

tensorboard --logdir=logs

通過 TensorBoard 我們可查看定義的模型:

機(jī)器學(xué)習(xí)庫初探之TensorFlow

同時我們也可以通過 TensorBoard 觀察我們定義的損失量loss有沒有按照預(yù)期的收斂,收斂的過程如何:

機(jī)器學(xué)習(xí)庫初探之TensorFlow

TensorBoard 是一個很好用的工具,官網(wǎng)文檔有關(guān)于 TensorBoard 更為詳盡的描述。

總結(jié)

TensorFlow 作為一款機(jī)器學(xué)習(xí)的庫,提供了類似 Numpy 數(shù)據(jù)結(jié)構(gòu),支持python,C++等多種語言,可以在cpu或者gpu上運(yùn)行,安裝簡單,上手容易,社區(qū)活躍,文檔目前還不夠豐富,好在通俗易懂,但是目前的示例還比較少(特別是python以外的示例)。

更多資源

  1. 神經(jīng)網(wǎng)絡(luò)和深度學(xué)習(xí)入門教程;

  2. Jeff Dean 介紹 TensorFlow(視頻);

  3. TensorFlow WhitePaper(PDF下載);

  4. Google官方Blog宣布TensorFlow開源;

  5. TensorFlow 簡化版接口 Scikit Flow;

  6. TensorFlow 使用樣例;

  7. TensorFlow 與 mxnet, caffe 對比 @chenrudan;

參考文獻(xiàn)


  1. https://www.tensorflow.org/(官方文檔); 

  2. http://www.tensorfly.cn/(中文社區(qū)); 


向AI問一下細(xì)節(jié)

免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點(diǎn)不代表本網(wǎng)站立場,如果涉及侵權(quán)請聯(lián)系站長郵箱:is@yisu.com進(jìn)行舉報(bào),并提供相關(guān)證據(jù),一經(jīng)查實(shí),將立刻刪除涉嫌侵權(quán)內(nèi)容。

AI