TensorFlow入門教程

這篇文章是TensorFlow的入門教程燎悍。在開(kāi)始閱讀本文之前父能,請(qǐng)確保你會(huì)Python宽菜,并且對(duì)矩陣有一定的了解谣膳,除此之外,最好能懂一點(diǎn)機(jī)器學(xué)習(xí)的知識(shí)铅乡,不過(guò)如果你對(duì)機(jī)器學(xué)習(xí)一無(wú)所知也沒(méi)關(guān)系继谚,你可以從閱讀這篇文章開(kāi)始學(xué)起。

TensorFlow提供了豐富的接口供調(diào)用阵幸。TensorFlow的內(nèi)核盡可能開(kāi)放了最完備的接口犬庇,它允許你在此基礎(chǔ)上從最底層開(kāi)始開(kāi)發(fā)。我們建議一般開(kāi)發(fā)者可以不用從這么底層開(kāi)始開(kāi)發(fā)侨嘀,這些底層接口更適合科研人員迁客。TensorFlow的上層接口都是在此基礎(chǔ)上搭建的惭墓。上層接口比底層更容易使用。像tf.contrib.learn這樣的高層接口幫助你去管理數(shù)據(jù)集梨树、估算葬荷、訓(xùn)練和推理涨共。請(qǐng)注意,有一些高層的接口的方法名包含contrib宠漩,這些是正在開(kāi)發(fā)的接口举反,它們?cè)诮酉聛?lái)的版本當(dāng)中,有可能會(huì)被修改甚至刪掉扒吁。

這篇文章會(huì)先講一下TensorFloat的基礎(chǔ)知識(shí)火鼻,然后,我們會(huì)帶著大家一起學(xué)習(xí)一下如何用tf.contrib.learn實(shí)現(xiàn)之前提到的模型雕崩。

Tensors

TensorFlow的核心就是tensor魁索,tensor是由一系列任意維度的矩陣構(gòu)成。

3 # 這是一個(gè)維度為0的tensor盼铁,這是一個(gè)標(biāo)量粗蔚,它的大小是[]。
[1. ,2., 3.] # 這是一個(gè)維度為1的tensor饶火,這是一個(gè)矢量鹏控,它的大小是[3]
[[1., 2., 3.], [4., 5., 6.]] # 這是一個(gè)維度為2的tensor致扯。這是一個(gè)矩陣,它的大小是[2, 3]
[[[1., 2., 3.]], [[7., 8., 9.]]] # 這是一個(gè)維度為3的tensor当辐,它的大小是[2, 1, 3]

TensorFlow的內(nèi)核

導(dǎo)入TensorFlow

TensorFlow的導(dǎo)入方式如下:

import tensorflow as tf

導(dǎo)入了TensorFlow了之后抖僵,就可以通過(guò)Python來(lái)訪問(wèn)TensorFlow的里面的類、方法和符號(hào)瀑构。后續(xù)所有的代碼執(zhí)行前都必須先導(dǎo)入TensorFlow裆针。

算法圖

TensorFlow的內(nèi)核分成兩部分:構(gòu)建算法圖和運(yùn)行算法圖。
算法圖是由一系列算法作為節(jié)點(diǎn)形成的一幅圖寺晌。讓我們一起構(gòu)建一個(gè)簡(jiǎn)單的算法圖世吨。每一個(gè)節(jié)點(diǎn)都有任意數(shù)量的tensor作為輸入,一個(gè)tensor作為輸出呻征。常量是一個(gè)特殊的節(jié)點(diǎn)耘婚。所有的常量都沒(méi)有輸入,它的輸出來(lái)自內(nèi)部存儲(chǔ)的數(shù)據(jù)陆赋。如果想要?jiǎng)?chuàng)建兩個(gè)浮點(diǎn)數(shù)類型的tensor沐祷,比如node1和node2,我們可以這樣寫:

node1 = tf.constant(3.0, dtype=tf.float32)
node2 = tf.constant(4.0) # 隱式指定了tensor內(nèi)部數(shù)據(jù)的類型是tf.float32
print(node1, node2)

最后一行打印出來(lái)的結(jié)果是:

Tensor("Const:0", shape=(), dtype=float32) Tensor("Const_1:0", shape=(), dtype=float32)

請(qǐng)注意攒岛,這里并沒(méi)有像我們期望的那樣打印出3.0和4.0赖临。這是因?yàn)閚ode1和node2是節(jié)點(diǎn),只有運(yùn)算的時(shí)候灾锯,才會(huì)分別生成3.0和4.0兢榨。想要對(duì)這兩個(gè)節(jié)點(diǎn)進(jìn)行運(yùn)算,我們必須啟動(dòng)一個(gè)會(huì)話(Session)顺饮。

下面的代碼創(chuàng)建 了一個(gè)會(huì)話吵聪,并且調(diào)用了它的run方法來(lái)執(zhí)行這個(gè)算法圖。求出了node1和node2的值兼雄。

sess = tf.Session()
print(sess.run([node1, node2]))

這樣我們就可以看到期望的結(jié)果:

[3.0, 4.0]

我們還可以構(gòu)建更加復(fù)雜的圖吟逝。比如,我們可以把剛才的兩個(gè)節(jié)點(diǎn)加起來(lái)生成一個(gè)新的節(jié)點(diǎn):

node3 = tf.add(node1, node2)
print("node3: ", node3)
print("sess.run(node3): ",sess.run(node3))

最后兩行打印的代碼打印出來(lái)的結(jié)果如下:

node3:  Tensor("Add:0", shape=(), dtype=float32)
sess.run(node3):  7.0

TensorFlow提供了一個(gè)工具赦肋,叫TensorBoard块攒,可以用來(lái)查看算法圖的結(jié)構(gòu)。這就是剛才的代碼對(duì)應(yīng)的算法圖佃乘。

這張圖非常簡(jiǎn)單局蚀,因?yàn)槲覀兊乃惴óa(chǎn)生的永遠(yuǎn)是一個(gè)定值。一張圖如果想要有外部輸入恕稠,我們就需要用到占位符(placeholder)琅绅。一個(gè)占位符表示一定會(huì)提供一個(gè)輸入。

a = tf.placeholder(tf.float32)
b = tf.placeholder(tf.float32)
adder_node = a + b  # 這里面的加號(hào)和調(diào)用tf.add(a, b)等效

上面的三行像是一個(gè)函數(shù)鹅巍。定義了兩個(gè)輸入?yún)?shù)a和b千扶。然后把它們加了起來(lái)料祠。我們要執(zhí)行這個(gè)算法圖,就必須要傳參數(shù):

print(sess.run(adder_node, {a: 3, b:4.5}))
print(sess.run(adder_node, {a: [1,3], b: [2, 4]}))

運(yùn)行的結(jié)果是:

7.5
[ 3.  7.]

這張算法圖是這樣的:

我們還可以把圖變得更復(fù)雜澎羞,比如我們可以再添加一個(gè)節(jié)點(diǎn):

add_and_triple = adder_node * 3.
print(sess.run(add_and_triple, {a: 3, b:4.5}))

執(zhí)行的結(jié)果是:

22.5

對(duì)應(yīng)的圖是這樣的:

在機(jī)器學(xué)習(xí)中髓绽,我們希望一個(gè)模型可以接受任何參數(shù)。為了讓模型可以被訓(xùn)練妆绞,我們希望可以通過(guò)修改圖顺呕,使得同樣的輸入會(huì)得到新的輸出。變量(Variables)允許我們把一個(gè)可以訓(xùn)練的參數(shù)加入到圖中括饶。創(chuàng)建變量的時(shí)候株茶,需要指定它們的類型和初始值。

W = tf.Variable([.3], dtype=tf.float32)
b = tf.Variable([-.3], dtype=tf.float32)
x = tf.placeholder(tf.float32)
linear_model = W * x + b

當(dāng)你調(diào)用tf.constant的時(shí)候图焰,常量就被初始化了启盛,它的值永遠(yuǎn)不會(huì)改變。但是當(dāng)你調(diào)用tf.Variable的時(shí)候技羔,變量并沒(méi)有被初始化僵闯,要初始化變量,你必須顯式地執(zhí)行如下操作:

init = tf.global_variables_initializer()
sess.run(init)

有一點(diǎn)很重要藤滥,init是一個(gè)引用鳖粟。它引用的是一個(gè)子圖。這個(gè)子圖初始化了所有全局變量拙绊。一直到執(zhí)行sess.run的時(shí)候向图,這些變量才真正被初始化。

因?yàn)閤是一個(gè)占位符时呀,所以我們可以一次性計(jì)算醋linear_model的四個(gè)值。

print(sess.run(linear_model, {x:[1,2,3,4]}))

運(yùn)行的結(jié)果是:

[ 0.          0.30000001  0.60000002  0.90000004]

我們創(chuàng)建了一個(gè)模型晶默,但是我們不知道這個(gè)模型好不好谨娜。想要對(duì)這個(gè)模型做一個(gè)評(píng)估,我們需要y占位符去提供想要的值磺陡,然后我們需要寫一個(gè)損失函數(shù)(loss function)趴梢。
損失函數(shù)表征了當(dāng)前模型和所提供的數(shù)據(jù)之間的差別。我們將會(huì)用一個(gè)標(biāo)準(zhǔn)的損失函數(shù)來(lái)做線性回歸币他。線性回歸就是把所求的值和所提供數(shù)據(jù)的差的平方加起來(lái)坞靶。linear_model - y是一個(gè)向量,向量的值就是所求的值和提供的數(shù)據(jù)之間的誤差蝴悉。我們調(diào)用tf.square去把這個(gè)值求平方彰阴。然后我們用tf.reduce_sum把所有的值加起來(lái),得到一個(gè)數(shù)字拍冠,通過(guò)這個(gè)方法得到一個(gè)衡量這個(gè)樣本錯(cuò)誤的數(shù)據(jù)尿这。

y = tf.placeholder(tf.float32)
squared_deltas = tf.square(linear_model - y)
loss = tf.reduce_sum(squared_deltas)
print(sess.run(loss, {x:[1,2,3,4], y:[0,-1,-2,-3]}))

求出的損耗是:

23.66

我們可以把W和b設(shè)置為正確答案-1和1簇抵。一個(gè)變量可以用tf.Variable來(lái)初始化,如果要修改它的值射众,也可以用tf.assign碟摆。比如,W = -1 并且 b = 1 就是我們這個(gè)模型最理想的參數(shù):

fixW = tf.assign(W, [-1.])
fixb = tf.assign(b, [1.])
sess.run([fixW, fixb])
print(sess.run(loss, {x:[1,2,3,4], y:[0,-1,-2,-3]}))

當(dāng)我們這么設(shè)置了之后叨橱,我們發(fā)現(xiàn)損耗就變成了:

0.0

我們這里是事先知道W和b的正確值典蜕,而我們現(xiàn)在研究機(jī)器學(xué)習(xí)的目標(biāo)是要機(jī)器自己找到這個(gè)合適的參數(shù)。接下來(lái)罗洗,我們就來(lái)訓(xùn)練我們的機(jī)器找到這個(gè)參數(shù)愉舔。

tf.train

TensorFlow提供了一個(gè)優(yōu)化器,緩慢的改變每個(gè)變量栖博,來(lái)最小化損耗屑宠。最簡(jiǎn)單的優(yōu)化器就是gradient descent。這個(gè)優(yōu)化器調(diào)整參數(shù)的方式是根據(jù)變量和損耗之間的導(dǎo)數(shù)的大小仇让。簡(jiǎn)單起見(jiàn)典奉,一般都幫你代勞。

optimizer = tf.train.GradientDescentOptimizer(0.01)
train = optimizer.minimize(loss)

sess.run(init) # reset values to incorrect defaults.
for i in range(1000):
  sess.run(train, {x:[1,2,3,4], y:[0,-1,-2,-3]})

print(sess.run([W, b]))

最終求得模型的參數(shù)是:

[array([-0.9999969], dtype=float32), array([ 0.99999082],
 dtype=float32)]

到此為止丧叽,我們讓機(jī)器完成了一次學(xué)習(xí)的過(guò)程卫玖。盡管這僅僅是一個(gè)簡(jiǎn)單的線性回歸的問(wèn)題,根本不需要用TensorFlow大費(fèi)周章的來(lái)實(shí)現(xiàn)踊淳。TensorFlow為常見(jiàn)的設(shè)計(jì)模式假瞬,數(shù)據(jù)結(jié)構(gòu)和功能提供了很好的抽象。我們將在下節(jié)開(kāi)始學(xué)習(xí)怎么使用TensorFlow的這些特性迂尝。

完整的代碼

一個(gè)完整的訓(xùn)練線性回歸模型的代碼如下:

import numpy as np
import tensorflow as tf

# Model parameters
W = tf.Variable([.3], dtype=tf.float32)
b = tf.Variable([-.3], dtype=tf.float32)
# Model input and output
x = tf.placeholder(tf.float32)
linear_model = W * x + b
y = tf.placeholder(tf.float32)
# loss
loss = tf.reduce_sum(tf.square(linear_model - y)) # sum of the squares
# optimizer
optimizer = tf.train.GradientDescentOptimizer(0.01)
train = optimizer.minimize(loss)
# training data
x_train = [1,2,3,4]
y_train = [0,-1,-2,-3]
# training loop
init = tf.global_variables_initializer()
sess = tf.Session()
sess.run(init) # reset values to wrong
for i in range(1000):
  sess.run(train, {x:x_train, y:y_train})

# evaluate training accuracy
curr_W, curr_b, curr_loss = sess.run([W, b, loss], {x:x_train, y:y_train})
print("W: %s b: %s loss: %s"%(curr_W, curr_b, curr_loss))

運(yùn)行的結(jié)果是:

W: [-0.9999969] b: [ 0.99999082] loss: 5.69997e-11

注意這里的損耗是一個(gè)非常接近于0的數(shù)字脱茉,如果你運(yùn)行同樣的代碼,得到的結(jié)果不一定和這個(gè)一模一樣垄开,因?yàn)槲覀兪怯秒S機(jī)值來(lái)訓(xùn)練這個(gè)模型的琴许。
最后給出這個(gè)算法圖的圖形:

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市溉躲,隨后出現(xiàn)的幾起案子榜田,更是在濱河造成了極大的恐慌,老刑警劉巖锻梳,帶你破解...
    沈念sama閱讀 221,888評(píng)論 6 515
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件箭券,死亡現(xiàn)場(chǎng)離奇詭異,居然都是意外死亡疑枯,警方通過(guò)查閱死者的電腦和手機(jī)辩块,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 94,677評(píng)論 3 399
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái),“玉大人庆捺,你說(shuō)我怎么就攤上這事古今。” “怎么了滔以?”我有些...
    開(kāi)封第一講書(shū)人閱讀 168,386評(píng)論 0 360
  • 文/不壞的土叔 我叫張陵捉腥,是天一觀的道長(zhǎng)。 經(jīng)常有香客問(wèn)我你画,道長(zhǎng)抵碟,這世上最難降的妖魔是什么? 我笑而不...
    開(kāi)封第一講書(shū)人閱讀 59,726評(píng)論 1 297
  • 正文 為了忘掉前任坏匪,我火速辦了婚禮拟逮,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘适滓。我一直安慰自己敦迄,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 68,729評(píng)論 6 397
  • 文/花漫 我一把揭開(kāi)白布凭迹。 她就那樣靜靜地躺著罚屋,像睡著了一般。 火紅的嫁衣襯著肌膚如雪嗅绸。 梳的紋絲不亂的頭發(fā)上脾猛,一...
    開(kāi)封第一講書(shū)人閱讀 52,337評(píng)論 1 310
  • 那天,我揣著相機(jī)與錄音鱼鸠,去河邊找鬼猛拴。 笑死,一個(gè)胖子當(dāng)著我的面吹牛蚀狰,可吹牛的內(nèi)容都是我干的愉昆。 我是一名探鬼主播,決...
    沈念sama閱讀 40,902評(píng)論 3 421
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼麻蹋,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼跛溉!你這毒婦竟也來(lái)了?” 一聲冷哼從身側(cè)響起哥蔚,我...
    開(kāi)封第一講書(shū)人閱讀 39,807評(píng)論 0 276
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤倒谷,失蹤者是張志新(化名)和其女友劉穎蛛蒙,沒(méi)想到半個(gè)月后糙箍,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 46,349評(píng)論 1 318
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡牵祟,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 38,439評(píng)論 3 340
  • 正文 我和宋清朗相戀三年深夯,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 40,567評(píng)論 1 352
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡咕晋,死狀恐怖雹拄,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情掌呜,我是刑警寧澤滓玖,帶...
    沈念sama閱讀 36,242評(píng)論 5 350
  • 正文 年R本政府宣布,位于F島的核電站质蕉,受9級(jí)特大地震影響势篡,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜模暗,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,933評(píng)論 3 334
  • 文/蒙蒙 一禁悠、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧兑宇,春花似錦碍侦、人聲如沸。這莊子的主人今日做“春日...
    開(kāi)封第一講書(shū)人閱讀 32,420評(píng)論 0 24
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)。三九已至若厚,卻和暖如春拦英,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背测秸。 一陣腳步聲響...
    開(kāi)封第一講書(shū)人閱讀 33,531評(píng)論 1 272
  • 我被黑心中介騙來(lái)泰國(guó)打工疤估, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人霎冯。 一個(gè)月前我還...
    沈念sama閱讀 48,995評(píng)論 3 377
  • 正文 我出身青樓铃拇,卻偏偏與公主長(zhǎng)得像,于是被迫代替她去往敵國(guó)和親沈撞。 傳聞我的和親對(duì)象是個(gè)殘疾皇子慷荔,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 45,585評(píng)論 2 359

推薦閱讀更多精彩內(nèi)容