1. 程式人生 > >TensorFlow力學101筆記[4]

TensorFlow力學101筆記[4]

col ref 讀取 lag 記錄 獲取 size 展示 寫入文件

TensorFlow力學101筆記[4]

本教程的目的是展示如何使用TensorFlow來訓練和評估使用(經典)MNIST數據集的手寫數字分類的簡單前饋神經網絡。

教程文件

本教程引用以下文件:

文件目的
mnist.py 構建完全連接的MNIST模型的代碼。
fully_connected_feed.py 使用Feed字典對下載的數據集訓練構建的MNIST模型的主要代碼。

fully_connected_feed.py直接運行文件開始培訓:

python fully_connected_feed.py

準備數據

MNIST是機器學習中的一個經典問題。問題是查看手寫數字的灰度28x28像素圖像,並確定圖像表示的數字,從0到9的所有數字。

技術分享

下載

在該run_training()方法的頂部,該input_data.read_data_sets() 函數將確保正確的數據已下載到您的本地培訓文件夾,然後解包該數據以返回DataSet 實例的字典

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

註意:該fake_data標誌用於單元測試,讀取器可能會被忽略。

數據集目的
data_sets.train 55000張圖片和標簽,用於初級培訓。
data_sets.validation 5000張圖像和標簽,用於訓練準確性的叠代驗證。
data_sets.test 10000張圖像和標簽,用於最終測試訓練的精度。

輸入和占位符

placeholder_inputs()函數創建兩個tf.placeholder 操作,定義輸入的形狀,包括batch_size圖形的其余部分,實際訓練示例將被饋送到該操作中

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

進一步下來,在訓練循環中,將完整圖像和標簽數據集切片以適應batch_size每個步驟,與這些占位符操作相匹配,然後sess.run()使用feed_dict 參數傳遞到函數中

構建圖

產生用於數據的占位符後,將圖表從內置 mnist.py文件根據3級圖案:inference()loss(),和training()

  1. inference() - 建立圖表,直到運行網絡前進來進行預測。
  2. loss() - 添加推理圖,生成損失所需的操作。
  3. training() - 將損耗圖表添加到計算和應用漸變所需的操作。

推理

inference()函數根據需要構建圖形,以返回包含輸出預測的張量。

它將圖像占位符作為輸入,並在其頂部構建一對具有ReLU激活的完全連接的層,之後是指定輸出邏輯的十個節點線性層。

每個圖層都創建在唯一的下面tf.name_scope ,作為在該範圍內創建的項目的前綴。

with tf.name_scope(hidden1):

在定義的範圍內,每個這些層要使用的權重和偏差被生成為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)

tf.truncated_normal初始化生成與給定的平均值和標準偏差的隨機分布。

然後,偏置被初始化tf.zeros 以確保它們以所有零值開始,它們的形狀只是它們連接到的層中的單元數量。

然後創建圖形的三個主要操作 - 為隱藏層tf.nn.relu 包裝兩個操作tf.matmul和一個額外tf.matmul的邏輯操作,每個操作依次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()功能通過添加所需的損失操作進一步構建圖。

首先,將值labels_placeholder轉換為64位整數。然後,tf.nn.sparse_softmax_cross_entropy_with_logits添加一個操作以自動生成1個熱標簽

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

然後,它使用tf.reduce_mean 以平均跨批尺寸的交叉熵值(第一尺寸)作為總損耗。

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

並返回張量,然後將包含損耗值。

訓練

training()函數將需要通過盡量減少損失的操作 梯度下降

首先,它需要損失張量從loss()功能和將它交給一個 tf.summary.scalar,用於生成摘要值到事件的運算與使用時的文件 tf.summary.FileWriter(見下文)。在這種情況下,它會在每次總結寫出時間發出損失的快照值。

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

接下來,我們實例化一個tf.train.GradientDescentOptimizer 負責應用與要求的學習率梯度。

optimizer = tf.train.GradientDescentOptimizer(learning_rate)

然後生成一個變量包含全球訓練步驟計數器和tf.train.Optimizer.minimize OP既用於更新系統中的可訓練的權重,並增加全球的一步。這op是,按照慣例,被稱為train_op是什麽必須由TensorFlow會議,以誘導訓練一個完整的步驟(見下文)運行。

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

訓練模型

一旦圖被建成,它可以被叠代訓練和通過在用戶代碼控制的循環進行評價fully_connected_feed.py

該圖

在頂部run_training()的功能是一個Python with的命令,指示所有內置OPS的要與默認的全局相關的tf.Graph 實例。

with tf.Graph().as_default():

tf.Graph是可以一起作為一個組來執行OPS的集合。大多數TensorFlow用途將只需要依靠單一的默認圖形。

有多個圖形更復雜的應用也是可能的,但是超出了簡單的教程的範圍。

會話

一旦所有的構建制備已經完成,所有產生的必要的OPS,一個tf.Session 用於運行圖形創建。

sess = tf.Session()

可替換地,Session可以生成到with用於作用域塊:

with tf.Session() as sess:

空參數會表明這個代碼將附加到(或創建如果尚未創建),默認的本地會話。

創建會話後,立即在所有的tf.Variable 情況下,通過調用初始化tf.Session.run 自己的初始化運算。

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

tf.Session.run 方法將運行對應於作為參數傳遞運算(多個)的曲線圖的完整子集。在這第一個電話時,init OP是tf.group 只包含了變量初始化。圖中的其余部分都沒有在這裏運行; 這種情況發生在下面的訓練循環。

鐵路環線

初始化與會話變量後,訓練就可以開始。

用戶代碼控制每個步驟的培養,並且可以做有用的訓練是最簡單的循環:

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

然而,該教程稍微更復雜的,因為它也必須切片了輸入數據的每個步驟,以匹配先前生成的占位符。

飼料圖表

對於每個步驟,該代碼將生成的進料字典將包含所述一組在其上的步驟,由它們所表示的占位符OPS鍵訓練示例。

fill_feed_dict()功能,給定的DataSet查詢其下一 batch_size組圖像和標簽,和張量相匹配的占位符被填充包含下一圖像和標簽。

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

Python字典對象然後與占位符作為鍵和代表饋送張量作為值生成的。

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

這是傳遞到sess.run()函數的feed_dict參數提供的培訓這一步驟的輸入例子。

檢查狀態

該代碼指定了兩個值,在其運行的調用來獲取:[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在值的列表中獲取對應於所返回的元組numpy的陣列,在這種訓練步驟填充有張量的值。由於train_opOperation沒有輸出值,在返回的元組中的相應元件是None,因此,丟棄。然而,價值loss張量有可能成為NaN的,如果模型訓練過程中發散,所以我們捕獲記錄這個值。

假設訓練運行沒有NaN的罰款,訓練回路還打印一個簡單的狀態文本每100步,讓用戶知道的訓練狀態。

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

可視化狀態

為了發射由所使用的事件文件TensorBoard,所有的摘要(在這種情況下,只有一個)被收集到在圖形建築物相單張量。

summary = tf.summary.merge_all()

然後創建會話後,一個tf.summary.FileWriter 可以被實例事件寫入文件,其中包含兩個圖形本身及摘要的值。

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

最後,事件文件將被新的匯總值在每次更新時間 summary評估,並通過筆者的輸出add_summary() 功能。

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

當事件寫入文件,TensorBoard可以對抗訓練文件夾中運行,從摘要中顯示的值。

技術分享

保存檢查點

為了發射出可用於以後恢復了進一步的培訓或評估模型的檢查點文件,我們實例化一個 tf.train.Saver

saver = tf.train.Saver()

在訓練循環,該tf.train.Saver.save 方法將定期被要求寫檢查點文件到培訓目錄中的所有訓練的變量的當前值。

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

在未來的某個點後,訓練可能會通過使用恢復 tf.train.Saver.restore 方法來重新加載模型參數。

saver.restore(sess, FLAGS.train_dir)

評估模型

每千步,代碼會試圖評估對雙方的訓練和測試數據集模型。do_eval()功能被稱為三次,對於培訓,驗證和測試數據集。

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)

需要註意的是更為復雜的使用通常會封存data_sets.test 只顯著金額超參數整定後進行檢查。對於一個簡單的小問題MNIST的緣故,但是,我們評估對所有的數據。

構建評估和演示圖

在進入訓練循環之前,評估和演示OP應該已經通過調用內置evaluation()的功能mnist.py與同logits /標簽參數的loss()功能。

eval_correct = mnist.evaluation(logits, labels_placeholder)

evaluation()功能簡單地生成一個tf.nn.in_top_k 運算,可以自動得分每個模型輸出正確的,如果真標簽可在K最可能的預測中找到。在這種情況下,我們的K值設置為1只考慮一個預測如果正確的話它是真正的標簽。

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

EVAL輸出

然後可以創建用於填充一個循環feed_dict,並呼籲sess.run()eval_correct運來評估在給定數據集模型。

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_kOP已經確定是正確的。從那裏,精度可以從簡單地通過實施例的總數量除以來計算。

precision = true_count / num_examples
print(‘ Num examples: %d Num correct: %d Precision @ 1: %0.04f‘ %
(num_examples, true_count, precision))

TensorFlow力學101筆記[4]