TensorFlow 運行機制基礎(chǔ)知識

我是一個很懶的人璧疗,我想試試

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

提高自己秧倾,也幫助他人

我的博客:終身學(xué)習(xí)者

TensorFlow Mechanics 101

代碼:tensorflow/examples/tutorials/mnist/

本教程的目標是向大家展示在(經(jīng)典)的 MNIST 數(shù)據(jù)集下如何使用 TensorFlow 訓(xùn)練和評估一個用于識別手寫數(shù)字的簡單的前饋神經(jīng)網(wǎng)絡(luò)(feed-forward neural network)。本教程的目標讀者是有興趣使用 TensorFlow 的有經(jīng)驗的機器學(xué)習(xí)使用者傀缩。

這些教程不適用于機器學(xué)習(xí)初學(xué)者教學(xué)那先。

請確保你已經(jīng)按照說明安裝 TensorFlow

Tutorial Files

本教程引用了以下文件:

文件 目的
mnist.py 構(gòu)建一個全連接 MNIST 模型代碼
fully_connected_feed.py 主要代碼是利用 feed dictionary 對構(gòu)建的 MNIST 模型使用下載數(shù)據(jù)集進行訓(xùn)練

直接運行 fully_connected_feed.py 文件開始訓(xùn)練:

python fully_connected_feed.py

Prepare the Data

在機器學(xué)習(xí)中 MNIST 是一個經(jīng)典問題——通過觀察一個28x28像素的灰度手寫數(shù)字圖像來確定圖上的數(shù)字表示幾赡艰,其中所有的數(shù)字都是從0到9.

MNIST Digits

更多信息售淡,請參考 Yann LeCun's MNIST pageChris Olah's visualizations of MNIST

Download

run_training()方法之前慷垮,input_data.read_data_sets()函數(shù)確保了正確的數(shù)據(jù)集被下載到你的本地的訓(xùn)練目錄揖闸,然后解壓并返回DataSet實例的字典。

data_sets = input_data.read_data_sets(FLAGS.train_dir, FLAGS.fake_data)

注意: fake_data 標志是用于單元測試的料身,讀者可以忽略楔壤。

數(shù)據(jù)集 目的
data_sets.train 55000 個圖像和標志,用于訓(xùn)練
data_sets.validation 5000 個圖像和標志惯驼,迭代驗證訓(xùn)練準確度
data_sets.test 10000 圖像和標志蹲嚣,用于最終測試訓(xùn)練準確度

Inputs and Placeholders

placeholder_inputs() 函數(shù)創(chuàng)建兩個 tf.placeholder 操作,定義了輸入的形狀祟牲,包括 batch_size隙畜,到圖的其余部分,并將實際訓(xùn)練樣本輸入到其中说贝。

images_placeholder = tf.placeholder(tf.float32, shape=(batch_size,
                                                       mnist.IMAGE_PIXELS))
labels_placeholder = tf.placeholder(tf.int32, shape=(batch_size))

再往下议惰,在訓(xùn)練循環(huán)的每一步中,完整的圖像和標簽數(shù)據(jù)集被分割成符合batch_size的大小乡恕,并與占位符操作相匹配言询。然后使用feed_dict參數(shù)將數(shù)據(jù)傳入sess.run()函數(shù)。

Build the Graph

為數(shù)據(jù)創(chuàng)建占位符后傲宜,從mnist.py 文件中根據(jù)三個階段模型:inference()运杭,loss(),和 training()就可以構(gòu)建圖了函卒。

  1. inference() - 根據(jù)需求構(gòu)建圖辆憔,以便向前運行網(wǎng)絡(luò)進行預(yù)測。
  2. loss() - 在 inference 圖中添加產(chǎn)生損失(loss)所需的操作(ops)。
  3. training() - 在 loss 圖中添加計算和應(yīng)用梯度(gradients)的操作虱咧。
img

Inference

根據(jù)需要 inference() 函數(shù)構(gòu)建好圖并返回包含預(yù)測結(jié)果(output predictions)的張量(tensor)熊榛。

它將圖像占位符作為輸入,并在其上構(gòu)建一對全連接層腕巡,其中有一個 ReLU 激活函數(shù)玄坦,其后接著是十個指定輸出logits的線性層節(jié)點。

每一層都在唯一的 tf.name_scope之下創(chuàng)建绘沉,它充當在該范圍內(nèi)創(chuàng)建的項目的前綴营搅。

with tf.name_scope('hidden1'):

在定義的范圍內(nèi)闹究,每個層所使用的權(quán)重和偏置都在 tf.Variable的實例中生成贺待,并具有所需的形狀:

weights = tf.Variable(
    tf.truncated_normal([IMAGE_PIXELS, hidden1_units],
                        stddev=1.0 / math.sqrt(float(IMAGE_PIXELS))),
    name='weights')
biases = tf.Variable(tf.zeros([hidden1_units]),
                     name='biases')

例如,當它們在hidden1范圍內(nèi)創(chuàng)建叼风,賦予權(quán)重變量唯一的名稱就是 "hidden1/weights"帖世。

每個變量作為他們構(gòu)造的一部分都會被賦予初始化操作休蟹。

在這種最常見的情況下,通過tf.truncated_normal 來初始化權(quán)重日矫,并給予他們2維形狀的張量赂弓,其中第一維表示該層中權(quán)重連接的單元數(shù)量,而其中第二維表示該層權(quán)重連接到的單元數(shù)量哪轿。對于名為 hidden1的第一層盈魁,維度為 [IMAGE_PIXELS, hidden1_units],因為權(quán)重連接輸入圖像到 hidden1 層窃诉。根據(jù)給定的均值和標準差 tf.truncated_normal 初始化生成一個隨機分布杨耙。

然后通過 tf.zeros 初始化偏置,以確保他們使用全為零的值開始飘痛,而它們的形狀就是該層連接的所有單元數(shù)量珊膜。

圖的三個主要操作——兩個 tf.nn.relu操作,在隱藏層中包含了 tf.matmul 宣脉。一個 logits 所需的額外的tf.matmul操作车柠。然后依次創(chuàng)建,而每個單獨的 tf.Variable實例連接到每個輸入占位符或前一層的輸出張量塑猖。

hidden1 = tf.nn.relu(tf.matmul(images, weights) + biases)
hidden2 = tf.nn.relu(tf.matmul(hidden1, weights) + biases)
logits = tf.matmul(hidden2, weights) + biases

最后竹祷,返回包含輸出的 logits 張量。

Loss

loss() 函數(shù)通過添加所需的損失操作來進一步構(gòu)建圖羊苟。

首先塑陵,來自labels_placeholder的值被轉(zhuǎn)化為64位整數(shù)。然后增加一個 tf.nn.sparse_softmax_cross_entropy_with_logits 操作到labels_placeholder自動產(chǎn)生的1-hot 標簽践险,并比較從 inference()函數(shù)中的輸出 logits 與這些1-hot 標簽猿妈。

labels = tf.to_int64(labels)
cross_entropy = tf.nn.sparse_softmax_cross_entropy_with_logits(
    labels=labels, logits=logits, name='xentropy')

然后使用tf.reduce_mean計算 batch 維度(第一維)的平均交叉熵的值,并作為總損失巍虫。

loss = tf.reduce_mean(cross_entropy, name='xentropy_mean')

然后返回包含損失值的張量彭则。

注意: 交叉熵是信息論的一個概念,它允許我們基于實際是真的占遥,描述相信神經(jīng)網(wǎng)絡(luò)是有多糟俯抖。欲了解更多信息,請閱讀視覺信息理論博客 (http://colah.github.io/posts/2015-09-Visual-Information/)

Training

training() 函數(shù)添加通過 Gradient Descent 最小化損失的操作瓦胎。

首先芬萍,從loss()函數(shù)中獲取損失張量,并傳遞給 tf.summary.scalar搔啊,然后再使用 tf.summary.FileWriter (見下文)柬祠,向事件文件(events file)生成匯總值(summary values)。在這里负芋,每次寫入?yún)R總值時漫蛔,它都會發(fā)出當前的損失值(snapshot value)。

tf.summary.scalar('loss', loss)

接下來旧蛾,我們實例化一個 tf.train.GradientDescentOptimizer 莽龟,負責(zé)按照我們要求的學(xué)習(xí)率(learning rate),應(yīng)用梯度下降(gradients)锨天。

optimizer = tf.train.GradientDescentOptimizer(learning_rate)

再然后毯盈,我們生成一個變量來保存全局訓(xùn)練步驟的數(shù)值(global training step),并使用tf.train.Optimizer.minimize 操作來更新系統(tǒng)的訓(xùn)練權(quán)重和增加全局訓(xùn)練步驟病袄。按照慣例搂赋,這個操作被稱為 train_op,是 TensorFlow 會話執(zhí)行一整個訓(xùn)練步驟(見下文)必須執(zhí)行的操作益缠。

global_step = tf.Variable(0, name='global_step', trainable=False)
train_op = optimizer.minimize(loss, global_step=global_step)

Train the Model

一旦圖構(gòu)建完成厂镇,就可以通過 fully_connected_feed.py文件中用戶代碼進行循環(huán)迭代訓(xùn)練和評估控制。

The Graph

run_training() 函數(shù)之前是一個 python 的 with 命令左刽,它表明所有的構(gòu)建操作都與默認的全局tf.Graph實例關(guān)聯(lián)起來捺信。

with tf.Graph().as_default():

tf.Graph是一個操作集合,將作為一個組(group)一起被執(zhí)行欠痴。大多數(shù)的 TensorFlow 使用都只需要依賴于一個默認的圖的實例即可迄靠。

使用多個圖實現(xiàn)更復(fù)雜的情況是可能的,但是這超出了本篇教程的范圍喇辽。

The Session

一旦所有的構(gòu)建準備都完成掌挚,并且生成了所有的必須的操作,就可以創(chuàng)建 tf.Session 來執(zhí)行圖菩咨。

sess = tf.Session()

另外吠式,也可以在 with 塊中生成 Session 來限制作用域:

with tf.Session() as sess:

無參 session 函數(shù)表明這段代碼將連接(或者如果沒有創(chuàng)建那就創(chuàng)建)默認的本地 session陡厘。

在創(chuàng)建 session 后立即在它們的初始化操作中調(diào)用tf.Session.run 來初始化所有的tf.Variable 實例。

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

tf.Session.run 方法將運行與作為參數(shù)傳遞的操作(op)對應(yīng)的完整子圖特占。在首次調(diào)用時糙置, init操作是一個只包含變量初始化的tf.group 。圖的其他部分不會在這里執(zhí)行是目,而只會在下面的循環(huán)訓(xùn)練里執(zhí)行谤饭。

Train Loop

在 session 中初始化了所有的變量后,訓(xùn)練就可以開始了懊纳。

訓(xùn)練中的每一步都是由用戶代碼控制著揉抵,而有效訓(xùn)練的最簡單循環(huán)如下:

for step in xrange(FLAGS.max_steps):
    sess.run(train_op)

然而,本教程會稍微復(fù)雜一點點嗤疯,因為它必須在每個循環(huán)中將輸入數(shù)據(jù)切片以匹配先前生成的占位符冤今。

Feed the Graph

對于每一步,代碼將生成一個 反饋字典(feed dictionary)茂缚,其中包含該步驟訓(xùn)練的樣本辟汰,例子的鍵(key)就是它們代表的占位符操作。

fill_feed_dict()函數(shù)中阱佛,查詢給定的DataSet的下一批batch_size的圖像和標簽帖汞,與占位符相匹配的張量包含了下一批的圖像和標簽。

images_feed, labels_feed = data_set.next_batch(FLAGS.batch_size,
                                               FLAGS.fake_data)

生成一個 python 字典對象凑术,其中占位符為 鍵(key)翩蘸,代表的反饋張量(feed tensor)為值(value)。

feed_dict = {
    images_placeholder: images_feed,
    labels_placeholder: labels_feed,
}

這個字典對象將傳遞給 sess.run() 函數(shù)的feed_dict 參數(shù)淮逊,為這一步的訓(xùn)練提供輸入樣本催首。

Check the Status

該代碼指定了兩個要在其運行調(diào)用中獲取的值: [train_op, loss]

for step in xrange(FLAGS.max_steps):
    feed_dict = fill_feed_dict(data_sets.train,
                               images_placeholder,
                               labels_placeholder)
    _, loss_value = sess.run([train_op, loss],
                             feed_dict=feed_dict)

因為需要獲取這兩個值泄鹏,sess.run() 返回一個兩個元素的元組郎任。要獲取的值列表中的每個 Tensor對應(yīng)著返回元組中的一個 numpy 數(shù)組(array),而該數(shù)組包含了這一步訓(xùn)練所需要的張量的值备籽。由于train_op是一個沒有輸出值的 Operation 舶治,返回的元組中對應(yīng)的元素是 None ,因此 train_op 會被丟棄车猬。然后如果在訓(xùn)練期間模型發(fā)散導(dǎo)致loss張量的值可能編程 NaN霉猛,因此我們要獲取這個值并記錄下來。

假設(shè)訓(xùn)練運行的很好珠闰,沒有產(chǎn)生 NaN值惜浅,訓(xùn)練循環(huán)也將每 100 次打印一個簡單的狀態(tài)來讓我們知道訓(xùn)練的狀態(tài)。

if step % 100 == 0:
    print('Step %d: loss = %.2f (%.3f sec)' % (step, loss_value, duration))

Visualize the Status

為了發(fā)布由 [TensorBoard 使用的事件文件伏嗜,在圖的構(gòu)建階段坛悉,所有的總結(jié)信息(summary)(在這里只有一個)被收集進一個張量里伐厌。

summary = tf.summary.merge_all()

在創(chuàng)建好會話(session)之后,實例化一個 tf.summary.FileWriter 來寫事件文件裸影,其中包含了圖本身和總結(jié)信息的值挣轨。

summary_writer = tf.summary.FileWriter(FLAGS.train_dir, sess.graph)

最后,每次summary評估的新的總結(jié)信息值都將更新事件文件空民,并輸出到事件文件讀寫器(writer)的 add_summary() 函數(shù)中刃唐。

summary_str = sess.run(summary, feed_dict=feed_dict)
summary_writer.add_summary(summary_str, step)

當事件文件被寫入時羞迷,在訓(xùn)練文件夾內(nèi) TensorBoard 將會運行來顯示匯總信息的值界轩。

MNIST TensorBoard

注意:欲了解更多如何構(gòu)建和運行 Tensorboard,請參考隨后的 Tensorboard: Visualizing Learning 教程衔瓮。

Save a Checkpoint

為了后續(xù)恢復(fù)模型以便將來能進一步的訓(xùn)練或評估而發(fā)布一個檢查點文件(checkpoint file)浊猾,我們實例化 tf.train.Saver

saver = tf.train.Saver()

在循環(huán)訓(xùn)練中热鞍,周期性的調(diào)用 tf.train.Saver.save 方法寫入檢查點文件到訓(xùn)練目錄下葫慎,其中包含了所有可訓(xùn)練變量的當前值。

saver.save(sess, FLAGS.train_dir, global_step=step)

在未來的某個時候薇宠,可以通過使用 tf.train.Saver.restore 方法來重新載入模型參數(shù)以恢復(fù)訓(xùn)練偷办。

saver.restore(sess, FLAGS.train_dir)

Evaluate the Model

每循環(huán)一千次,代碼將嘗試使用訓(xùn)練數(shù)據(jù)和測試數(shù)據(jù)來評估模型澄港。 do_eval() 方法將被調(diào)用三次椒涯,分別使用訓(xùn)練數(shù)據(jù)集,驗證數(shù)據(jù)集和測試數(shù)據(jù)集回梧。

print('Training Data Eval:')
do_eval(sess,
        eval_correct,
        images_placeholder,
        labels_placeholder,
        data_sets.train)
print('Validation Data Eval:')
do_eval(sess,
        eval_correct,
        images_placeholder,
        labels_placeholder,
        data_sets.validation)
print('Test Data Eval:')
do_eval(sess,
        eval_correct,
        images_placeholder,
        labels_placeholder,
        data_sets.test)

注意更復(fù)雜的用法是隔離 data_sets.test 废岂,直到大量的超參數(shù)(hyperparameter )調(diào)整之后才被檢查。但對于一個簡單的 MNIST 問題狱意,這里我們一次性評估了所有的數(shù)據(jù)湖苞。

Build the Eval Graph

在進入循環(huán)訓(xùn)練之前,通過從mnist.py文件中調(diào)用evaluation()函數(shù)來構(gòu)建評估操作详囤,其中使用了和loss()函數(shù)相同的 logist/labels 參數(shù)财骨。

eval_correct = mnist.evaluation(logits, labels_placeholder)

evaluation() 函數(shù)會簡單的生成一個 tf.nn.in_top_k 操作,如果在 K 個最可能的預(yù)測中發(fā)現(xiàn)了真的標簽藏姐,那么它將自動給每個模型輸出標記為正確蚓再。在這里我們將設(shè)置 K 為1,因為我們只考慮只有在標簽為真的時候的預(yù)測才為正確包各。

eval_correct = tf.nn.in_top_k(logits, labels, 1)

Eval Output

然后我們可以創(chuàng)建一個循環(huán)摘仅,并往里面添加 feed_dict ,并調(diào)用 sess.run() 函數(shù)時傳入 eval_correct 操作以便對給定的數(shù)據(jù)集評估模型性能问畅。

for step in xrange(steps_per_epoch):
    feed_dict = fill_feed_dict(data_set,
                               images_placeholder,
                               labels_placeholder)
    true_count += sess.run(eval_correct, feed_dict=feed_dict)

true_count 變量是 in_top_k 操作中被認為是正確的所有預(yù)測的簡單疊加娃属,這樣六荒,精度的計算可以是簡單地將所有正確的預(yù)測的樣本總數(shù)除以所有的樣本的總數(shù)得到。

precision = true_count / num_examples
print('  Num examples: %d  Num correct: %d  Precision @ 1: %0.04f' %
      (num_examples, true_count, precision))
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末矾端,一起剝皮案震驚了整個濱河市掏击,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌秩铆,老刑警劉巖砚亭,帶你破解...
    沈念sama閱讀 222,681評論 6 517
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異殴玛,居然都是意外死亡捅膘,警方通過查閱死者的電腦和手機,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 95,205評論 3 399
  • 文/潘曉璐 我一進店門滚粟,熙熙樓的掌柜王于貴愁眉苦臉地迎上來寻仗,“玉大人,你說我怎么就攤上這事凡壤∈鹩龋” “怎么了?”我有些...
    開封第一講書人閱讀 169,421評論 0 362
  • 文/不壞的土叔 我叫張陵亚侠,是天一觀的道長曹体。 經(jīng)常有香客問我,道長硝烂,這世上最難降的妖魔是什么箕别? 我笑而不...
    開封第一講書人閱讀 60,114評論 1 300
  • 正文 為了忘掉前任,我火速辦了婚禮钢坦,結(jié)果婚禮上究孕,老公的妹妹穿的比我還像新娘。我一直安慰自己爹凹,他們只是感情好厨诸,可當我...
    茶點故事閱讀 69,116評論 6 398
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著禾酱,像睡著了一般微酬。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上颤陶,一...
    開封第一講書人閱讀 52,713評論 1 312
  • 那天颗管,我揣著相機與錄音,去河邊找鬼滓走。 笑死垦江,一個胖子當著我的面吹牛,可吹牛的內(nèi)容都是我干的搅方。 我是一名探鬼主播比吭,決...
    沈念sama閱讀 41,170評論 3 422
  • 文/蒼蘭香墨 我猛地睜開眼绽族,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了衩藤?” 一聲冷哼從身側(cè)響起吧慢,我...
    開封第一講書人閱讀 40,116評論 0 277
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎赏表,沒想到半個月后检诗,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 46,651評論 1 320
  • 正文 獨居荒郊野嶺守林人離奇死亡瓢剿,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 38,714評論 3 342
  • 正文 我和宋清朗相戀三年逢慌,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片跋选。...
    茶點故事閱讀 40,865評論 1 353
  • 序言:一個原本活蹦亂跳的男人離奇死亡涕癣,死狀恐怖哗蜈,靈堂內(nèi)的尸體忽然破棺而出前标,到底是詐尸還是另有隱情,我是刑警寧澤距潘,帶...
    沈念sama閱讀 36,527評論 5 351
  • 正文 年R本政府宣布炼列,位于F島的核電站,受9級特大地震影響音比,放射性物質(zhì)發(fā)生泄漏俭尖。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點故事閱讀 42,211評論 3 336
  • 文/蒙蒙 一洞翩、第九天 我趴在偏房一處隱蔽的房頂上張望稽犁。 院中可真熱鬧,春花似錦骚亿、人聲如沸已亥。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,699評論 0 25
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽虑椎。三九已至,卻和暖如春俱笛,著一層夾襖步出監(jiān)牢的瞬間捆姜,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 33,814評論 1 274
  • 我被黑心中介騙來泰國打工迎膜, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留泥技,地道東北人。 一個月前我還...
    沈念sama閱讀 49,299評論 3 379
  • 正文 我出身青樓磕仅,卻偏偏與公主長得像珊豹,于是被迫代替她去往敵國和親镊讼。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 45,870評論 2 361

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

  • 簡單線性回歸 import tensorflow as tf import numpy # 創(chuàng)造數(shù)據(jù) x_dat...
    CAICAI0閱讀 3,551評論 0 49
  • 大盤綜述 今日大盤受節(jié)日假期間利好刺激,首個交易日來了個大紅包忽妒,假期前李某在軟文里就有提示道玩裙,布局通信板塊的龍頭股...
    股易有道閱讀 177評論 0 1
  • 1.在健康問題上,你自己比老天爺管用 早上吃好段直,中午吃飽吃溅,晚上吃少。 現(xiàn)在的人相反了鸯檬,早上馬虎决侈,中午對付,晚上大吃...
    萌灬貳閱讀 399評論 0 1
  • 97喧务、洗腳 腳赖歌,每天都是臟的 所以每天要洗 洗或者不洗,它都是臟的 但不洗它會更臟 因此還是要每天都洗 這不僅僅是...
    楊岸達閱讀 114評論 0 0
  • 話說九尾為逐至北邊荒僻之地銀丘那年冬便郁郁而終功茴,僅留其子南狐強撐起剩余軍馬庐冯。自此,南狐忍辱伏于銀丘坎穿,伺機待著飛石城...
    古池笑月閱讀 574評論 0 6