TensorFlow 是一個(gè)采用數(shù)據(jù)流圖(data flow graphs),用于數(shù)值計(jì)算的開源軟件庫(kù)。節(jié)點(diǎn)(Nodes)在圖中表示數(shù)學(xué)操作,圖中的線(edges)則表示在節(jié)點(diǎn)間相互聯(lián)系的多維數(shù)據(jù)數(shù)組,即張量(tensor)。它靈活的架構(gòu)讓你可以在多種平臺(tái)上展開計(jì)算,例如臺(tái)式計(jì)算機(jī)中的一個(gè)或多個(gè)CPU(或GPU),服務(wù)器,移動(dòng)設(shè)備等等。TensorFlow 最初由Google大腦小組(隸屬于Google機(jī)器智能研究機(jī)構(gòu))的研究員和工程師們開發(fā)出來,用于機(jī)器學(xué)習(xí)和深度神經(jīng)網(wǎng)絡(luò)方面的研究,但這個(gè)系統(tǒng)的通用性使其也可廣泛用于其他計(jì)算領(lǐng)域。
當(dāng)前TensorFlow最新的開源版本是r0.9。
數(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可動(dòng)態(tài)調(diào)整”的多維數(shù)據(jù)數(shù)組,即“張量”(tensor)。張量從圖中流過的直觀圖像是這個(gè)工具取名為“Tensorflow”的原因。一旦輸入端的所有張量準(zhǔn)備好,節(jié)點(diǎn)將被分配到各種計(jì)算設(shè)備完成異步并行地執(zhí)行運(yùn)算。
TensorFlow 不是一個(gè)嚴(yán)格的“神經(jīng)網(wǎng)絡(luò)”庫(kù)。只要可以將計(jì)算表示為一個(gè)數(shù)據(jù)流圖,就可以使用Tensorflow來構(gòu)建圖,描寫驅(qū)動(dòng)計(jì)算的內(nèi)部循環(huán)。Tensorflow提供了有用的工具來幫助你組裝“子圖”(常用于神經(jīng)網(wǎng)絡(luò)),當(dāng)然用戶也可以自己在Tensorflow基礎(chǔ)上寫自己的“上層庫(kù)”。定義順手好用的新復(fù)合操作和寫一個(gè)python函數(shù)一樣容易,而且也不用擔(dān)心性能損耗。當(dāng)然萬一發(fā)現(xiàn)找不到想要的底層數(shù)據(jù)操作,也可以自己寫一點(diǎn)c++代碼來豐富底層的操作。
Tensorflow 可以在CPU和GPU上運(yùn)行,比如說可以運(yùn)行在臺(tái)式機(jī)、服務(wù)器、手機(jī)移動(dòng)設(shè)備等等。想要在沒有特殊硬件的前提下,在你的筆記本上跑一下機(jī)器學(xué)習(xí)的新想法?Tensorflow也可以辦到。準(zhǔn)備將你的訓(xùn)練模型在多個(gè)CPU上規(guī)?;\(yùn)算,又不想修改代碼?Tensorflow也可以辦到。想要將你的訓(xùn)練好的模型作為產(chǎn)品的一部分用到手機(jī)app里?Tensorflow可以辦到這點(diǎn)。你改變主意了,想要將你的模型作為云端服務(wù)運(yùn)行在自己的服務(wù)器上,或者運(yùn)行在Docker容器里?Tensorfow也能辦到。
過去如果要將科研中的機(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í)算法會(huì)受益于Tensorflow自動(dòng)求微分的能力。作為Tensorflow用戶,你只需要定義預(yù)測(cè)模型的結(jié)構(gòu),將這個(gè)結(jié)構(gòu)和目標(biāo)函數(shù)(objective function)結(jié)合在一起,并添加數(shù)據(jù),Tensorflow將自動(dòng)為你計(jì)算相關(guān)的微分導(dǎo)數(shù)。計(jì)算某個(gè)變量相對(duì)于其他變量的導(dǎo)數(shù)僅僅是通過擴(kuò)展你的圖來完成的,所以你能一直清楚看到究竟在發(fā)生什么。
Tensorflow 有一個(gè)合理的c++使用界面,也有一個(gè)易用的python使用界面來構(gòu)建和執(zhí)行你的graphs。你可以直接寫python/c++程序,也可以用交互式的ipython界面來用Tensorflow嘗試些想法,它可以幫你將筆記、代碼、可視化等有條理地歸置好。當(dāng)然這僅僅是個(gè)起點(diǎn)——Tensorflow鼓勵(lì)創(chuàng)造自己最喜歡的語(yǔ)言界面,比如Go,Java,Lua,Javascript,或者是R。
目前開源的版本暫時(shí)只看到對(duì)于python/C++的支持,并且python的API比C++的還是要更成熟易用。社區(qū)已經(jīng)有針對(duì)Java和Ruby的支持。
比如說你有一個(gè)具有32個(gè)CPU內(nèi)核、4個(gè)GPU顯卡的工作站,想要將你工作站的計(jì)算潛能全發(fā)揮出來?由于Tensorflow 給予了線程、隊(duì)列、異步操作等以最佳的支持,Tensorflow 讓你可以將你手邊硬件的計(jì)算潛能全部發(fā)揮出來。你可以自由地將Tensorflow圖中的計(jì)算元素分配到不同設(shè)備上,Tensorflow可以幫你管理好這些不同副本。
超過100項(xiàng)線上產(chǎn)品在使用TensorFlow;
Google數(shù)據(jù)科學(xué)家和工程師都在使用TensorFlow;
Google用TensorFlow構(gòu)建下一代的智能應(yīng)用;
TensorFlow已經(jīng)被Google開源,并部署到Google Cloud上;
TensorFlow支持二進(jìn)制包和源碼包等多種安裝方式,支持在Linux、Mac OS X、Ubuntu等多個(gè)平臺(tái)上進(jìn)行安裝,并且可以運(yùn)行在docker之上,官網(wǎng)上有比較詳細(xì)的安裝文檔。
TensorFlow最簡(jiǎn)單的安裝方式是通過pip進(jìn)行安裝,如果條件不允許(例如無外網(wǎng)的條件下),需要通過源碼進(jìn)行安裝,TensorFlow的源碼編譯依賴Python 2.7版本,以及Bazel進(jìn)行編譯。
整體來說TensorFlow的安裝過程還是比較簡(jiǎn)單的。
一塊可以用來運(yùn)算并且擁有自己的地址空間的硬件,比如GPU和CPU。
Tensor 的一個(gè)方法,返回 Tensor 的值。觸發(fā)任意一個(gè)圖計(jì)算都需要計(jì)算出這個(gè)值。只能在一個(gè)已經(jīng)啟動(dòng)的會(huì)話的圖中才能調(diào)用該 Tensor 值。
TensorFlow 的一個(gè)概念:把一個(gè) Tensor 直接連接到一個(gè)會(huì)話圖表中的任意節(jié)點(diǎn)。feed 不是在構(gòu)建圖(graph)的時(shí)候創(chuàng)建,而是在觸發(fā)圖的執(zhí)行操作時(shí)去申請(qǐng)。一個(gè) feed 臨時(shí)替代一個(gè)帶有 Tensor 值的節(jié)點(diǎn)。把feed數(shù)據(jù)作為run( )方法和eval( )方法的參數(shù)來初始化運(yùn)算。方法運(yùn)行結(jié)束后,替換的 feed 就會(huì)消失,而最初的節(jié)點(diǎn)定義仍然還在??梢酝ㄟ^tf.placeholder( )把特定的節(jié)點(diǎn)指定為 feed 節(jié)點(diǎn)來創(chuàng)建它們。
TensorFlow中的一個(gè)概念:為了取回運(yùn)算操作的輸出結(jié)果。取回的申請(qǐng)發(fā)生在觸發(fā)執(zhí)行圖操作的時(shí)候,而不是發(fā)生在建立圖的時(shí)候。如果要取回一個(gè)或多個(gè)節(jié)點(diǎn)(node)的 Tensor 值,可以通過在 Session 對(duì)象上調(diào)用run( )方法并將待取回節(jié)點(diǎn)(node)的列表作為參數(shù)來執(zhí)行圖表(graph)。
把運(yùn)算任務(wù)描述成一個(gè)直接的無環(huán)圖形(DAG),圖表中的節(jié)點(diǎn)(node)代表必須要實(shí)現(xiàn)的一些操作。圖中的邊代表數(shù)據(jù)或者可控的依賴。GratheDef 是系統(tǒng)中描述一個(gè)圖表的協(xié)議(api),它由一個(gè) NodeDefs 集合組成。一個(gè)GraphDef可以轉(zhuǎn)化成一個(gè)更容易操作的圖表對(duì)象。
在 Python API 中,TensorFlow 僅僅在第一維上對(duì) Tensor 有所體現(xiàn)。如果一個(gè) Tensor 有k維,那么一個(gè) IndexedSlices 實(shí)例在邏輯上代表一個(gè)沿著這個(gè) Tensor 第一維的(k-1)維切片的集合。切片的索引被連續(xù)儲(chǔ)存在一個(gè)單獨(dú)的一維向量中,而對(duì)應(yīng)的切片則被拼接成一個(gè)單獨(dú)的k維 Tensor。如果 sparsity 不是受限于第一維空間,請(qǐng)用 SparseTensor。
圖中的一個(gè)元素。 把啟動(dòng)一個(gè)特定操作的方式稱為特定運(yùn)算圖表的一個(gè)節(jié)點(diǎn),包括任何用來配置這個(gè)操作的屬性的值。對(duì)于那些多形態(tài)的操作,這些屬性包括能完全決定這個(gè)節(jié)點(diǎn)(Node)簽名的充分信息。
在 TensorFlow 的運(yùn)行時(shí)中,它是一種類似 add 或 matmul 或 concat的運(yùn)算??梢杂胔ow to add an op中的方法來向運(yùn)行時(shí)添加新的操作。
在 Python 的API中,它是圖中的一個(gè)節(jié)點(diǎn)。在tf.Operation類中列舉出了這些操作。一個(gè)操作(Operation)的 type 屬性決定這個(gè)節(jié)點(diǎn)(node)的操作類型,比如add和matmul。
在一個(gè)運(yùn)行的圖中執(zhí)行某種操作的行為。要求圖必須運(yùn)行在會(huì)話中。
在 Python 的 API 中,它是 Session 類的一個(gè)方法tf.Session.run??梢酝ㄟ^ Tensors 來訂閱或獲取run( )操作。
在C++的API中,它是tensorflow::Session類 的一個(gè)方法。
啟動(dòng)圖的第一步是創(chuàng)建一個(gè) Session 對(duì)象。Session 提供在圖中執(zhí)行操作的一些方法。
在 Python API中,使用tf.Session。
在 C++ 的API中,tensorflow::Session是用來創(chuàng)建一個(gè)圖并運(yùn)行操作的類。
Tensor 的維度和它們的大小。
在一個(gè)已經(jīng)啟動(dòng)的圖中,它表示流動(dòng)在節(jié)點(diǎn)(node)之間的 Tensor 的屬性。一些操作對(duì) shape 有比較強(qiáng)的要求,如果沒有 Shape 屬性則會(huì)報(bào)告錯(cuò)誤。
在 Python API中,用創(chuàng)建圖的 API 來說明 Tensor 的 Shape 屬性。Tensor 的Shape 屬性要么只有部分已知,要么全部未知。詳見tf.TensroShape
在C++中,Shape 類用來表示 Tensor 的維度。tensorflow::TensorShape。
在 Python API 中,它用來表示在 TensorFlow 中稀疏散落在任意地方的 Tensor 。SparseTensor 以字典-值格式來儲(chǔ)存那些沿著索引的非空值。換言之,m個(gè)非空值,就包含一個(gè)長(zhǎng)度為m的值向量和一個(gè)由m列索引(indices)組成的矩陣。為了提升效率,SparseTensor 需要將 indice(索引)按維度的增加來按序存儲(chǔ),比如行主序。如果稀疏值僅沿著第一維度,就用 IndexedSlices。
Tensor是一種特定的多維數(shù)組。比如,一個(gè)浮點(diǎn)型的四維數(shù)組表示一小批由[batch,height,width,channel]組成的圖片。
在一個(gè)運(yùn)行的圖(graph)中,它是一種流動(dòng)在節(jié)點(diǎn)(node)之間的數(shù)據(jù)。 在 Python 中,Tensor 類表示添加到圖的操作中的輸入和輸出,見tf.Tensor,這樣的類不持有數(shù)據(jù)。
在C++中,Tensor是方法Session::Run( )的返回值,見tensorflow::Tensor,這樣的 Tensor 持有數(shù)據(jù)。
TensorFlow 和 Numpy在描述N維數(shù)據(jù)方面是非常相似的,不同的是TensorFlow除了能定義N維數(shù)組,還能創(chuàng)建N維數(shù)組的方程,并能自動(dòng)計(jì)算求導(dǎo),做更多的事情。
對(duì)比兩者之間的區(qū)別:
可見在tensorflow中許多基礎(chǔ)的N-array操作都是類似的,這讓很多接觸過numpy進(jìn)行數(shù)據(jù)分析的人員都能很自然的上手tensorflow。
以下借助TensorFlow我實(shí)現(xiàn)了一個(gè)簡(jiǎ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)
通過簡(jiǎn)單的定義目標(biāo)函數(shù)和選擇優(yōu)化算法,就可以開始訓(xùn)練我的模型了。
結(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ò)等等。
TensorFlow 提供了一個(gè)內(nèi)置的可視化工具叫做 TensorBoard。有了 TensorBoard 可以更方便 TensorFlow 程序的理解、調(diào)試與優(yōu)化。你可以用 TensorBoard 來展現(xiàn)你的 TensorFlow 圖像,繪制圖像生成的定量指標(biāo)圖以及附加數(shù)據(jù)。
通過簡(jiǎn)單的改寫,我就可以在上面的例子中使用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í)行上面的代碼,會(huì)在logs/
子目錄下生成一個(gè)日志文件。通過在打開 TensorBoard 的時(shí)候指定日志目錄加載這個(gè)日志文件,我們就可以通過瀏覽器訪問 TensorBoard 了。
tensorboard --logdir=logs
通過 TensorBoard 我們可查看定義的模型:
同時(shí)我們也可以通過 TensorBoard 觀察我們定義的損失量loss
有沒有按照預(yù)期的收斂,收斂的過程如何:
TensorBoard 是一個(gè)很好用的工具,官網(wǎng)文檔有關(guān)于 TensorBoard 更為詳盡的描述。
TensorFlow 作為一款機(jī)器學(xué)習(xí)的庫(kù),提供了類似 Numpy 數(shù)據(jù)結(jié)構(gòu),支持python
,C++
等多種語(yǔ)言,可以在cpu或者gpu上運(yùn)行,安裝簡(jiǎn)單,上手容易,社區(qū)活躍,文檔目前還不夠豐富,好在通俗易懂,但是目前的示例還比較少(特別是python
以外的示例)。
神經(jīng)網(wǎng)絡(luò)和深度學(xué)習(xí)入門教程;
Jeff Dean 介紹 TensorFlow(視頻);
TensorFlow WhitePaper(PDF下載);
Google官方Blog宣布TensorFlow開源;
TensorFlow 簡(jiǎn)化版接口 Scikit Flow;
TensorFlow 使用樣例;
TensorFlow 與 mxnet, caffe 對(duì)比 @chenrudan;
https://www.tensorflow.org/(官方文檔);
http://www.tensorfly.cn/(中文社區(qū));
另外有需要云服務(wù)器可以了解下創(chuàng)新互聯(lián)scvps.cn,海內(nèi)外云服務(wù)器15元起步,三天無理由+7*72小時(shí)售后在線,公司持有idc許可證,提供“云服務(wù)器、裸金屬服務(wù)器、高防服務(wù)器、香港服務(wù)器、美國(guó)服務(wù)器、虛擬主機(jī)、免備案服務(wù)器”等云主機(jī)租用服務(wù)以及企業(yè)上云的綜合解決方案,具有“安全穩(wěn)定、簡(jiǎn)單易用、服務(wù)可用性高、性價(jià)比高”等特點(diǎn)與優(yōu)勢(shì),專為企業(yè)上云打造定制,能夠滿足用戶豐富、多元化的應(yīng)用場(chǎng)景需求。