Tensorflow 入門

我是一個很懶的人八秃,我想試試

希望我能堅持到最后机隙,把tensorflow的官方教程全部翻譯出來

提高自己臼隔,也幫助他人

我的博客:終身學習者

Tensorflow 入門

本篇是Tensorflow編程入門指南寥假。在開始本教程前,請先安裝 TensorFlow疗隶。為了充分利用本指南佑笋,你需要知道以下知識:

  • 如何使用 Python 編程。
  • 至少知道一點 Arrays 知識抽减。
  • 最好能懂一點機器學習的知識允青。但即使你一點機器學習的知識都不懂也沒有關系,這依然可以是你閱讀的第一份教程卵沉。

TensorFlow 提供了多個 APIs。最低級的 API——TensorFlow Core 提供完整的編程控制法牲。我們建議機器學習研究者和其他需要對模型進行精確控制的人員來使用TensorFlow Core史汗。更高級的 APIs 建立在 TensorFlow Core之上。這些更高級的 APIs 相比于 TensorFlow Core 也更加容易學習與使用拒垃。另外停撞,更高級的 API 使得不同用戶之間的重復任務更容易也更一致。像 tf.estimator 這樣的高級 API 可以幫助您管理數(shù)據(jù)集悼瓮,評價戈毒,訓練和推理。
本指南將以 Tensorflow Core 開始横堡。接下來埋市,我們將演示如何在 tf.estimator 中運行相同的模型。理解 Tensorflow Core 原理將在你使用更抽象的高級 API 時能夠更好的理解事情內部的工作原理命贴。

Tensors

Tensorflow 數(shù)據(jù)的核心單位是張量 (tensor)道宅。一個張量是由一組任意維度的原始值組成食听。張量的 (rank) 是它的維數(shù), 下面是一些張量的例子:

3  # a rank 0 tensor; a scalar with shape []  
[1.,  2.,  3.]  # a rank 1 tensor; a vector with shape [3]  
[[1.,  2.,  3.],  [4.,  5.,  6.]]  # a rank 2 tensor; a matrix with shape [2, 3]  
[[[1.,  2.,  3.]],  [[7.,  8.,  9.]]]  # a rank 3 tensor with shape [2, 1, 3]

TensorFlow Core 教程

Importing TensorFlow

TensorFlow 程序規(guī)范導入語句如下:

import tensorflow as tf

這使得 Python 可以訪問所有的 TensorFlow 類(classes), 方法(methods)和符號(symbols)。接下來大多數(shù)的教程都假設你已完成了此項工作污茵。

The Computational Graph

你可能會認為 Tensorflow Core 程序都是包含以下兩個部分:

  1. 構建 computational graph樱报。
  2. 執(zhí)行 computational graph。

計算圖 (computational graph) 是一系列排列成節(jié)點圖的 TensorFlow 操作泞当。讓我們來構建一個簡單的計算圖迹蛤。每個節(jié)點將輸入零個或多個張量并產生一個張量作為輸出。每個類型的節(jié)點都是一個常量襟士。類似于所有的 TensorFlow 常量盗飒,它沒有輸入,而只輸出一個內部存儲值敌蜂。我們可以創(chuàng)建兩個浮點型張量node1node2

node1 = tf.constant(3.0, dtype=tf.float32) 
node2 = tf.constant(4.0)  # also tf.float32 implicitly  
print(node1, node2)

最后打印如下:

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

注意箩兽,打印節(jié)點不會像你預期的那樣輸出 3.04.0 。相反章喉,他們在評估時將會分別輸出 3.0 和 4.0. 為了實際評估節(jié)點汗贫,我們必須在會話 (session) 內運行計算圖。session 封裝了 Tensorflow 運行時的控制和狀態(tài)秸脱。

以下代碼創(chuàng)建了一個 Session 對象并調用了 run 方法運行計算圖來評估node1node2落包。通過在 session 中運行計算圖:

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

我們就可以看到期望的答案 3.0 和 4.0:

[3.0,  4.0]

我們可以通過將張量節(jié)點與操作相結合來構建更復雜的計算(操作也是節(jié)點)。例如摊唇,我們可以增加兩個常量節(jié)點并產生一個新的圖(graph):

from future import print_function
node3 = tf.add(node1, node2)  
print("node3:", node3)  
print("sess.run(node3):", sess.run(node3))

最后兩個打印語句:

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

Tensorflow 提供一個名為TensorBoard的有效的程序咐蝇,它可以將計算圖顯示為圖。以下一個截屏顯示了TensorBoard將圖可視化:

TensorBoard screenshot

就目前來看巷查,這張圖并不特別有趣有序,因為它總是產生一個不變的結果。圖可以被參數(shù)化來接收稱為占位符的外部輸入岛请。占位符是接下來提供值的變量旭寿。

a = tf.placeholder(tf.float32) 
b = tf.placeholder(tf.float32) 
adder_node = a + b  # + provides a shortcut for tf.add(a, b)

這三行有點像一個函數(shù)(function)或者一個lambda,其中我們定義了兩個參數(shù)(a和b)和一個操作崇败。我們可以通過多個輸入來評估這個圖盅称,這些輸入是通過使用 run 方法 的 feed_dict 參數(shù)將具體值 feed 給占位符:

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

輸出結果:

7.5  
[  3. 7.]

在 TensorBoard,這圖看起來是這樣的:

TensorBoard screenshot

我們可以通過添加其他的操作來使得計算圖更加的復雜后室,例如缩膝,

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

輸出結果:

22.5

在TensorBoard中,上面的計算圖如下所示:

TensorBoard screenshot

在機器學習中岸霹,我們通常需要一個可以計算任意輸入的模型疾层,比如上面的模型。為了使得模型可訓練松申,我們需要能夠修改圖使得其具有相同的輸入能得到新的輸出云芦。變量(Variables)允許我們添加可訓練的參數(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

當你調用tf.constant 時,常量就被初始化了舅逸,并且不能被修改桌肴。相比之下,當你調用tf.constant 的時候變量并沒有被初始化琉历。為了初始化TensorFlow里面的變量坠七,你必須顯式的調用下面的操作:

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

實現(xiàn)init 是TensorFlow子圖初始化所有的全局變量的一個很重要的句柄。在我們調用sess.run 之前旗笔,變量是未初始化的彪置。

由于x 是一個占位符,我們可以同時為多個x 評估linear_model :

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

輸出結果:

[  0. 0.30000001 0.60000002 0.90000004]

我們創(chuàng)建了一個模型蝇恶,但是我們不知道這個模型的好壞拳魁。為了評估訓練數(shù)據(jù)的模型,我們需要一個y 占位符來提供期望值撮弧,并且我們需要寫一個代價函數(shù)潘懊。

代價函數(shù)用于衡量當前模型與預期值之間的差距有多遠。我們將使用線性回歸的標準代價模型贿衍,其中代價是當前模型與期望值之間的差距的平方的總和授舟。linear_model - y 創(chuàng)建一個每個元素與其對應實例的誤差的向量。我們調用tf.square 來計算這個誤差的平方贸辈。然后我們統(tǒng)計所有的平方差來創(chuàng)建一個標量释树,通過調用tf.reduce_sum 來抽象所有例子的錯誤:

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

我們可以通過重新將Wb 分別賦值為-1和1來手動改進。一個變量可以通過tf.Variable 來初始化擎淤,也可以使用像tf.assign 的操作來改變奢啥。例如,W=-1b=1 就是我們這個模型的最優(yōu)參數(shù)嘴拢,我們可以對應改變 Wb 的值:

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]}))

結果損失值為零扫尺。

0.0

我們能夠猜測Wb 的最佳值,但是機器學習的重點是自動找到正確的模型參數(shù)炊汤。我們將在下一節(jié)展示如何完成這項工作。

tf.train API

對于機器學習的完整討論已超出了本教程的范圍弊攘。但是Tensorflow提供的優(yōu)化器(optimizers) 可以逐步改變每個變量來逐步使得代價函數(shù)達到最小值抢腐。最簡單的優(yōu)化器是梯度下降(gradient descent) 。它根據(jù)相對于該變量的損失導數(shù)的大小來修改每個變量襟交。一般來說迈倍,手動計算符號導數(shù)是繁瑣而又容易出錯的。所以只要使用tf.gradients 來描述模型 tensorflow 就可以自動計算導數(shù)捣域。簡單來說啼染,優(yōu)化器通常會自動為你做這件事宴合,例如:

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)]

現(xiàn)在我們已經完成了一個實際的機器學習了!雖然這個簡單的線性模型不需要太多的 tensorflow core 代碼迹鹅,但是使用更復雜的模型和方法給我們的模型 feed 數(shù)據(jù)則需要更多的代碼卦洽。因此 tensorflow 為常見的模型,結構和功能提供更高級的抽象斜棚。我們將在下一節(jié)中學習如何使用這些抽象阀蒂。

Complete program

完成可訓練的線性回歸模型如下所示:

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))

運行后結果如下:

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

注意,loss 是一個非常小的數(shù)字(非常接近于零)弟蚀。如果你運行這段代碼蚤霞,你的 loss 可能和上面的 loss 不完全一致,因為模型的初始化是使用偽隨機值的义钉。

在 tensorboard 仍然可以可視化非常復雜的程序昧绣。
TensorBoard final model visualization

tf.estimator

tf.estimator 是一個高級的 TensorFlow 庫,它簡化了機器學習的機制:

  • 運行訓練循環(huán)
  • 運行評估循環(huán)
  • 管理數(shù)據(jù)集

tf.estimator 定義了許多常見的模型捶闸。

Basic usage

注意在 tf.estimator 里夜畴,線性回歸將變得多么的簡單:

# NumPy is often used to load, manipulate and preprocess data.  
import numpy as np 
import tensorflow as tf

# Declare list of features. We only have one numeric feature. There are many  
# other types of columns that are more complicated and useful. 
feature_columns =  [tf.feature_column.numeric_column("x", shape=[1])]  
# An estimator is the front end to invoke training (fitting) and evaluation  
# (inference). There are many predefined types like linear regression,  
# linear classification, and many neural network classifiers and regressors.  
# The following code provides an estimator that does linear regression. 
estimator = tf.estimator.LinearRegressor(feature_columns=feature_columns)  

# TensorFlow provides many helper methods to read and set up data sets.  
# Here we use two data sets: one for training and one for evaluation  
# We have to tell the function how many batches  
# of data (num_epochs) we want and how big each batch should be. 
x_train = np.array([1.,  2.,  3.,  4.]) 
y_train = np.array([0.,  -1.,  -2.,  -3.]) 
x_eval = np.array([2.,  5.,  8.,  1.]) 
y_eval = np.array([-1.01,  -4.1,  -7,  0.]) 
input_fn = tf.estimator.inputs.numpy_input_fn(  
    {"x": x_train}, y_train, batch_size=4, num_epochs=None, shuffle=True) 
train_input_fn = tf.estimator.inputs.numpy_input_fn( 
    {"x": x_train}, y_train, batch_size=4, num_epochs=1000, shuffle=False) 
eval_input_fn = tf.estimator.inputs.numpy_input_fn(  
    {"x": x_eval}, y_eval, batch_size=4, num_epochs=1000, shuffle=False)  
    
# We can invoke 1000 training steps by invoking the  method and passing the  
# training data set. 
estimator.train(input_fn=input_fn, steps=1000)  

# Here we evaluate how well our model did. 
train_metrics = estimator.evaluate(input_fn=train_input_fn) 
eval_metrics = estimator.evaluate(input_fn=eval_input_fn)  
print("train metrics: %r"% train_metrics)  
print("eval metrics: %r"% eval_metrics)

運行后,結果類似如下:

train metrics:  {'average_loss':  1.4833182e-08,  'global_step':  1000,  'loss':  5.9332727e-08}  eval metrics:  {'average_loss':  0.0025353201,  'global_step':  1000,  'loss':  0.01014128}

注意鉴嗤,不論我們評估的loss有多高斩启,但它仍然接近與零。這意味這我們的學習是正確的醉锅。

A custom model

tf.estimator 不會限制你在預定義模型中兔簇。假設我們想要創(chuàng)建一個自定義的 TensorFlow 沒有的模型。我們仍然可以使用 tf.estimator 來使用高度抽象的數(shù)據(jù)集硬耍,處理垄琐,訓練。為了說明经柴,我們將展示如何利用我們的知識使用低級的 TensorFlow API 來實現(xiàn)相同的線性回歸模型狸窘。

為了定義一個使用tf.estimator 的自定義模型,我們需要使用 tf.estimator.Estimator 坯认。實際上 tf.estimator.LinearRegressortf.estimator.Estimator 的一個子類翻擒。為了替代子類Estimator ,我們只需要提供 Estimator 的一個函數(shù) model_fn 來告訴 tf.estimator 如何評估預測牛哺,訓練步驟和損失陋气。代碼如下:

import numpy as np 
import tensorflow as tf 

# Declare list of features, we only have one real-valued feature  
def model_fn(features, labels, mode):  
    # Build a linear model and predict values 
    W = tf.get_variable("W",  [1], dtype=tf.float64) 
    b = tf.get_variable("b",  [1], dtype=tf.float64) 
    y = W*features['x']  + b 
    # Loss sub-graph 
    loss = tf.reduce_sum(tf.square(y - labels))  
    # Training sub-graph 
    global_step = tf.train.get_global_step() 
    optimizer = tf.train.GradientDescentOptimizer(0.01) 
    train = tf.group(optimizer.minimize(loss), 
                    tf.assign_add(global_step,  1))  
    # EstimatorSpec connects subgraphs we built to the  
    # appropriate functionality.  
    return tf.estimator.EstimatorSpec( 
            mode=mode, 
            predictions=y, 
            loss=loss, 
            train_op=train) 
estimator = tf.estimator.Estimator(model_fn=model_fn)  
# define our data sets 
x_train = np.array([1.,  2.,  3.,  4.]) 
y_train = np.array([0.,  -1.,  -2.,  -3.]) 
x_eval = np.array([2.,  5.,  8.,  1.]) 
y_eval = np.array([-1.01,  -4.1,  -7.,  0.]) 
input_fn = tf.estimator.inputs.numpy_input_fn(  
    {"x": x_train}, y_train, batch_size=4, num_epochs=None, shuffle=True) 
train_input_fn = tf.estimator.inputs.numpy_input_fn(  
    {"x": x_train}, y_train, batch_size=4, num_epochs=1000, shuffle=False) 
eval_input_fn = tf.estimator.inputs.numpy_input_fn(  
    {"x": x_eval}, y_eval, batch_size=4, num_epochs=1000, shuffle=False)  
    
# train 
estimator.train(input_fn=input_fn, steps=1000)  
# Here we evaluate how well our model did. 
train_metrics = estimator.evaluate(input_fn=train_input_fn) 
eval_metrics = estimator.evaluate(input_fn=eval_input_fn)  
print("train metrics: %r"% train_metrics)  
print("eval metrics: %r"% eval_metrics)

運行結果如下:

train metrics:  {'loss':  1.227995e-11,  'global_step':  1000}  
eval metrics:  {'loss':  0.01010036,  'global_step':  1000}

注意自定義 model_fn() 函數(shù)的內容與我們從低級 API 得到的手動訓練循環(huán)是非常相似的。

Next steps

現(xiàn)在你已經掌握了 TensorFlow 的基礎知識引润。我們還有更多的教程助你了解學習更多巩趁。如果你是一個機器學習初學者,請查看 MNIST for beginners 淳附,否則請查看 Deep MNIST for experts 议慰。

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯(lián)系作者
  • 序言:七十年代末蠢古,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子别凹,更是在濱河造成了極大的恐慌草讶,老刑警劉巖,帶你破解...
    沈念sama閱讀 216,997評論 6 502
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件番川,死亡現(xiàn)場離奇詭異到涂,居然都是意外死亡,警方通過查閱死者的電腦和手機颁督,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,603評論 3 392
  • 文/潘曉璐 我一進店門践啄,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人沉御,你說我怎么就攤上這事屿讽。” “怎么了吠裆?”我有些...
    開封第一講書人閱讀 163,359評論 0 353
  • 文/不壞的土叔 我叫張陵伐谈,是天一觀的道長。 經常有香客問我试疙,道長诵棵,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 58,309評論 1 292
  • 正文 為了忘掉前任祝旷,我火速辦了婚禮履澳,結果婚禮上,老公的妹妹穿的比我還像新娘怀跛。我一直安慰自己距贷,他們只是感情好,可當我...
    茶點故事閱讀 67,346評論 6 390
  • 文/花漫 我一把揭開白布吻谋。 她就那樣靜靜地躺著忠蝗,像睡著了一般。 火紅的嫁衣襯著肌膚如雪漓拾。 梳的紋絲不亂的頭發(fā)上阁最,一...
    開封第一講書人閱讀 51,258評論 1 300
  • 那天,我揣著相機與錄音骇两,去河邊找鬼闽撤。 笑死,一個胖子當著我的面吹牛脯颜,可吹牛的內容都是我干的。 我是一名探鬼主播贩据,決...
    沈念sama閱讀 40,122評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼栋操,長吁一口氣:“原來是場噩夢啊……” “哼闸餐!你這毒婦竟也來了?” 一聲冷哼從身側響起矾芙,我...
    開封第一講書人閱讀 38,970評論 0 275
  • 序言:老撾萬榮一對情侶失蹤舍沙,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后剔宪,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體拂铡,經...
    沈念sama閱讀 45,403評論 1 313
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內容為張勛視角 年9月15日...
    茶點故事閱讀 37,596評論 3 334
  • 正文 我和宋清朗相戀三年葱绒,在試婚紗的時候發(fā)現(xiàn)自己被綠了感帅。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 39,769評論 1 348
  • 序言:一個原本活蹦亂跳的男人離奇死亡地淀,死狀恐怖失球,靈堂內的尸體忽然破棺而出,到底是詐尸還是另有隱情帮毁,我是刑警寧澤实苞,帶...
    沈念sama閱讀 35,464評論 5 344
  • 正文 年R本政府宣布,位于F島的核電站烈疚,受9級特大地震影響黔牵,放射性物質發(fā)生泄漏。R本人自食惡果不足惜爷肝,卻給世界環(huán)境...
    茶點故事閱讀 41,075評論 3 327
  • 文/蒙蒙 一猾浦、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧阶剑,春花似錦跃巡、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,705評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至猪半,卻和暖如春兔朦,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背磨确。 一陣腳步聲響...
    開封第一講書人閱讀 32,848評論 1 269
  • 我被黑心中介騙來泰國打工沽甥, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人乏奥。 一個月前我還...
    沈念sama閱讀 47,831評論 2 370
  • 正文 我出身青樓摆舟,卻偏偏與公主長得像,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子恨诱,可洞房花燭夜當晚...
    茶點故事閱讀 44,678評論 2 354

推薦閱讀更多精彩內容