丁香五月天婷婷久久婷婷色综合91|国产传媒自偷自拍|久久影院亚洲精品|国产欧美VA天堂国产美女自慰视屏|免费黄色av网站|婷婷丁香五月激情四射|日韩AV一区二区中文字幕在线观看|亚洲欧美日本性爱|日日噜噜噜夜夜噜噜噜|中文Av日韩一区二区

您正在使用IE低版瀏覽器,為了您的雷峰網(wǎng)賬號(hào)安全和更好的產(chǎn)品體驗(yàn),強(qiáng)烈建議使用更快更安全的瀏覽器
此為臨時(shí)鏈接,僅用于文章預(yù)覽,將在時(shí)失效
人工智能 正文
發(fā)私信給晟煒
發(fā)送

0

機(jī)器學(xué)習(xí)零基礎(chǔ)?手把手教你用TensorFlow搭建圖像識(shí)別系統(tǒng)(二)| 干貨

本文作者: 晟煒 2017-01-16 14:40
導(dǎo)語:這是Wolfgang Beyer一篇博文。詳細(xì)介紹了如何使用TensorFlow搭建一個(gè)簡(jiǎn)單的圖像識(shí)別系統(tǒng)。本篇將手把手地講解搭建圖像識(shí)別系統(tǒng)的全過程。

雷鋒網(wǎng)按:此系列文章主要介紹了不具備機(jī)器學(xué)習(xí)基礎(chǔ)的用戶如何嘗試從零開始在TensorFlow上搭建一個(gè)圖像識(shí)別系統(tǒng)。在文章的第一部分中,作者Woflgang Beyer向讀者們介紹了一些簡(jiǎn)單的概念。本文為系列的第二部分,主要介紹了如何實(shí)現(xiàn)簡(jiǎn)單的圖像識(shí)別功能。雷鋒網(wǎng)編譯,未經(jīng)許可不得轉(zhuǎn)載。 

現(xiàn)在,我們可以開始建立我們的模型啦。實(shí)際上數(shù)值計(jì)算都是由TensorFlow來完成,它使用了一個(gè)快速并高效的C++后臺(tái)程序。TensorFlow希望避免頻繁地在Python和C++之間切換,因?yàn)槟菢訒?huì)降低計(jì)算速度。一般的工作流程是,首先為了定義所有的運(yùn)算,先建立一個(gè)TensorFlow圖表。在這個(gè)過程中沒有計(jì)算,我們只是進(jìn)行設(shè)置操作。之后,我們才針對(duì)輸入數(shù)據(jù)運(yùn)行計(jì)算操作并記錄結(jié)果。

讓我們開始定義我們的圖表。首先通過創(chuàng)建占位符來描述TensorFlow輸入數(shù)據(jù)的形式。占位符不包括任何實(shí)際數(shù)據(jù),它們只是定義了數(shù)據(jù)的類型和形狀。

在我們的模型中,我們首先為圖像數(shù)據(jù)定義了占位符,它們包括浮點(diǎn)數(shù)據(jù)(tf.float32)。shape參數(shù)定義了輸入數(shù)據(jù)的大小。我們將同時(shí)輸入多幅圖像(稍后我們將談到這些處理),但是我們希望可以隨時(shí)改變實(shí)際輸入圖像的個(gè)數(shù)。所以第一項(xiàng)shape參數(shù)為none,這代表大小可以是任何長(zhǎng)度。第二項(xiàng)參數(shù)是3072,這是每幅圖像的浮點(diǎn)值。

分類標(biāo)簽的占位符包括整型數(shù)據(jù)(tf.int64),每幅圖像都有0到9的一個(gè)值。因?yàn)槲覀儧]有指定輸入圖像的個(gè)數(shù),所以shape參數(shù)為[none]。

# Define variables (these are the values we want to optimize)

weights = tf.Variable(tf.zeros([3072, 10]))

biases = tf.Variable(tf.zeros([10]))

weights和biases是我們希望優(yōu)化的變量。但現(xiàn)在還是先談?wù)勎覀兊哪P桶伞?/p>

我們的輸入包括3072個(gè)浮點(diǎn)數(shù)據(jù),而希望實(shí)現(xiàn)的輸出是10個(gè)整型數(shù)據(jù)中的一個(gè)。我們?cè)趺窗?072個(gè)值變成一個(gè)呢?讓我們退后一步,如果不是輸出0到9中的一個(gè)數(shù)字,而是進(jìn)行打分,得到10個(gè)數(shù)字-每個(gè)種類一個(gè)分?jǐn)?shù)-我們挑選出得分最高的一個(gè)種類。所以我們最初的問題就變成了:如何從將3072個(gè)值變成10個(gè)值。

我們所采取的一種簡(jiǎn)單的方法是單獨(dú)查詢每個(gè)像素。對(duì)每一個(gè)像素(或更準(zhǔn)確點(diǎn),每個(gè)像素的顏色通道)和每個(gè)可能的種類,我們問自己是否這個(gè)像素的顏色增加或減少了它屬于某個(gè)種類的可能性。比如說像素顏色是紅色。如果汽車圖片的像素通常是紅色,我們希望增加“汽車”這一種類的得分。我們將像素是紅色通道的值乘以一個(gè)正數(shù)加到“汽車”這一類的的得分里。同樣,如果在位置1的地方,馬的圖像從來不或很少出現(xiàn)紅色像素,我們希望將分類為“馬”的分?jǐn)?shù)維持在低分或再降低一些。也就是說乘以一個(gè)較小的數(shù)或者負(fù)數(shù)后加到分類為“馬”的分?jǐn)?shù)里。對(duì)所有的10個(gè)分類我們都重復(fù)這樣的操作,對(duì)每一個(gè)像素重復(fù)計(jì)算,3072個(gè)值進(jìn)行相加得到一個(gè)總和。3072個(gè)像素的值乘以3072個(gè)加權(quán)參數(shù)值得到這一分類的得分。最后我們得到10個(gè)分類的10個(gè)分?jǐn)?shù)。然后我們挑選出得分最高的,將圖像打上這一類型的標(biāo)簽。


機(jī)器學(xué)習(xí)零基礎(chǔ)?手把手教你用TensorFlow搭建圖像識(shí)別系統(tǒng)(二)| 干貨

一幅圖像通過一個(gè)3072個(gè)值的一維數(shù)組來表示。每個(gè)值乘以一個(gè)加權(quán)參數(shù),將所有值相加得到一個(gè)數(shù)值-特定種類的分值。

我們可以用矩陣的方法,這樣使用像素值乘以加權(quán)值再相加的過程大大簡(jiǎn)化。我們的圖像通過一個(gè)3072維向量表示。如果我們將這個(gè)向量乘以一個(gè)3072x10的加權(quán)矩陣,結(jié)果就是一個(gè)10維向量。它包括了我們需要的加權(quán)和。


機(jī)器學(xué)習(xí)零基礎(chǔ)?手把手教你用TensorFlow搭建圖像識(shí)別系統(tǒng)(二)| 干貨

通過矩陣乘法計(jì)算一個(gè)圖像在所有10個(gè)類別中的分?jǐn)?shù)。

3072x10矩陣中的具體值就是我們模型的參數(shù)。如果它沒有規(guī)律或毫無用處,那我們的輸出也是一樣。這就需要訓(xùn)練數(shù)據(jù)參與工作。通過查詢訓(xùn)練數(shù)據(jù),我們希望模型能自己計(jì)算出最后的參數(shù)。

上面這兩行代碼里,我們告訴TensorFlow,加權(quán)矩陣的大小是3072x10,初始值都被設(shè)置為0。另外,我們定義了第二個(gè)參數(shù),一個(gè)包含偏差值的10維向量。這個(gè)偏差值并不直接作用于圖像數(shù)據(jù),而僅僅是與加權(quán)和相加。這個(gè)偏差值可以被看做是最后得分的一個(gè)起始點(diǎn)。想象一下,一副全黑的圖片,所有像素的只都是0。那么不管加權(quán)矩陣的只是多少,所有分類的得分都是0。通過偏差值,我們則可以保證我們的每一分類的起始值不是0。

# Define the classifier's result

logits = tf.matmul(images_placeholder, weights) + biases

下面就要講到預(yù)測(cè)。通過這一步,我們已經(jīng)確定了多幅圖像向量和矩陣的維度。這個(gè)操作的結(jié)果就是每幅輸入圖像都有一個(gè)10維向量。


機(jī)器學(xué)習(xí)零基礎(chǔ)?手把手教你用TensorFlow搭建圖像識(shí)別系統(tǒng)(二)| 干貨

通過矩陣乘法,計(jì)算多幅圖像的所有10個(gè)分類的分?jǐn)?shù)。

# Define the loss function

loss = tf.reduce_mean(tf.nn.sparse_softmax_cross_entropy_with_logits(logits,labels_placeholder))

weights和bias參數(shù)逐漸優(yōu)化的過程叫做訓(xùn)練,它包括以下步驟:第一,我們輸入訓(xùn)練數(shù)據(jù)讓模型根據(jù)當(dāng)前參數(shù)進(jìn)行預(yù)測(cè)。將預(yù)測(cè)值與正確的分類標(biāo)簽進(jìn)行比較。比較的數(shù)值結(jié)果被叫做損失。越小的損失值表示預(yù)測(cè)值與正確標(biāo)簽越接近,反之亦然。我們希望將模型的損失值降到最小,讓預(yù)測(cè)值與真實(shí)標(biāo)簽更接近。但是在我們將損失最小化之前,先來看看損失是怎么計(jì)算出來的。

前一步計(jì)算出來的分?jǐn)?shù)被存儲(chǔ)在logits變量里,包含任意實(shí)數(shù)。我們可以調(diào)用softmax函數(shù)將這些值轉(zhuǎn)化成概率值(0到1之間的實(shí)數(shù),總和為1),這樣將輸入轉(zhuǎn)變成能表示其特征的輸出。相對(duì)應(yīng)的輸入排列保持不變,原本得分最好的分類擁有最大的概率。softmax函數(shù)輸出的概率分布與真實(shí)的概率分布相比較。在真實(shí)的概率分布中正確的類別概率為1,其他類別的概率為0。我們使用交叉熵來比較兩種概率分布(更多技術(shù)性的解釋可以在這里找到)。交叉熵越小,預(yù)測(cè)值的概率分布與正確值的概率分布的差別就越小。這個(gè)值代表了我們模型的損失。

幸運(yùn)的是TensorFlow提供了一個(gè)函數(shù)幫我們完成了這一系列的操作。我們比較模型預(yù)測(cè)值logits和正確分類值labels_placeholder。sparse_softmax_cross_entropy_with_logits()函數(shù)的輸出就是每幅輸入圖像的損失值。然后我們只需計(jì)算輸入圖像的平均損失值。

# Define the training operation

train_step = tf.train.GradientDescentOptimizer(learning_rate).minimize(loss)

但是我們?nèi)绾握{(diào)整參數(shù)來將損失最小化呢?TensorFlow這時(shí)就大發(fā)神威了。通過被稱作自動(dòng)分化(auto-differentiation)的技術(shù),它可以計(jì)算出相對(duì)于參數(shù)值,損失值的梯度。這就是說它可以知道每個(gè)參數(shù)對(duì)總的損失的影響,小幅度的加或減參數(shù)是否可以降低損失。然后依此調(diào)整所有參數(shù)值,增加模型的準(zhǔn)確性。在完成參數(shù)調(diào)整之后,整個(gè)過程重新開始,新的一組圖片被輸入到模型中。

TensorFlow知道不同的優(yōu)化技術(shù)可以將梯度信息用于更新參數(shù)值。這里我們使用梯度下降算法。在決定參數(shù)是,它只關(guān)心模型當(dāng)前的狀態(tài),而不去考慮以前的參數(shù)值。參數(shù)下降算法只需要一個(gè)單一的參數(shù),學(xué)習(xí)率,它是參數(shù)更新的一個(gè)比例因子。學(xué)習(xí)率越大,表示每一步參數(shù)值的調(diào)整越大。如果學(xué)習(xí)率過大,參數(shù)值可能超過正確值導(dǎo)致模型不能收斂。如果學(xué)習(xí)率過小,模型的學(xué)習(xí)速度會(huì)非常緩慢,需要花很長(zhǎng)時(shí)間才能找到一個(gè)好的參數(shù)值。

輸入圖像分類,比較預(yù)測(cè)結(jié)果和真實(shí)值,計(jì)算損失和調(diào)整參數(shù)的過程需要重復(fù)多次。對(duì)于更大,更復(fù)雜的模型,這個(gè)計(jì)算量將迅速上升。但是對(duì)于我們的簡(jiǎn)單模型,我們既不需要考驗(yàn)?zāi)托囊膊恍枰獙iT的硬件設(shè)備就可以得到結(jié)果。

# Operation comparing prediction with true label

correct_prediction = tf.equal(tf.argmax(logits, 1), labels_placeholder)

 

# Operation calculating the accuracy of our predictions

accuracy = tf.reduce_mean(tf.cast(correct_prediction, tf.float32))

這兩行代碼用于檢驗(yàn)?zāi)P偷木_度。logits的argmax返回分?jǐn)?shù)最高的分類。這就是預(yù)測(cè)的分類標(biāo)簽。tf.equal()將這個(gè)標(biāo)簽與正確的分類標(biāo)簽相比較,然后返回布爾向量。布爾數(shù)轉(zhuǎn)換為浮點(diǎn)數(shù)(每個(gè)值不是0就是1),這些數(shù)求平均得到的分?jǐn)?shù)就是正確預(yù)測(cè)圖像的比例。

# -----------------------------------------------------------------------------

# Run the TensorFlow graph

# -----------------------------------------------------------------------------

 

with tf.Session() as sess:

  # Initialize variables

  sess.run(tf.initialize_all_variables())

 

  # Repeat max_steps times

  for i in range(max_steps):

最后,我們定義了TensorFlow圖表并準(zhǔn)備好運(yùn)行它。在一個(gè)會(huì)話控制中運(yùn)行這個(gè)圖表,可以通過sess變量對(duì)它進(jìn)行訪問。運(yùn)行這個(gè)會(huì)話控制的第一步就是初始化我們?cè)缦葎?chuàng)建的變量。在變量定義中我們指定了初始值,這時(shí)就需要把這些初始值賦給變量。

然后我們開始迭代訓(xùn)練過程。它會(huì)重復(fù)進(jìn)行max_steps次。

# Generate input data batch

indices = np.random.choice(data_sets['images_train'].shape[0], batch_size)

images_batch = data_sets['images_train'][indices]

labels_batch = data_sets['labels_train'][indices]

這幾行代碼隨機(jī)抽取了訓(xùn)練數(shù)據(jù)的幾幅圖像。從訓(xùn)練數(shù)據(jù)中抽取的幾幅圖像和標(biāo)簽被稱作批。批的大小(單個(gè)批中圖像的數(shù)量)告訴我們參數(shù)更新的頻率。我們首先對(duì)批中所有圖像的損失值求平均。然后根據(jù)梯度下降算法更新參數(shù)。

如果我們先就對(duì)訓(xùn)練集中的所有圖像進(jìn)行分類,而不是在批處理完之后這樣做,我們能夠計(jì)算出初始平均損失和初始梯度,用它們來取代批運(yùn)行時(shí)使用的估計(jì)值。但是這樣的話,對(duì)每個(gè)迭代參數(shù)的更新都需要進(jìn)行更多的計(jì)算。在另一種極端情況下,我們可以設(shè)置批的大小為1,然后更新單幅圖像的參數(shù)。這會(huì)造成更高頻率的參數(shù)更新,但是更有可能出現(xiàn)錯(cuò)誤。從而向錯(cuò)誤的方向頻繁修正。

通常在這兩種極端情況的中間位置我們能得到最快的改進(jìn)結(jié)果。對(duì)于更大的模型,對(duì)內(nèi)存的考慮也至關(guān)重要。批的大小最好盡可能大,同時(shí)又能使所有變量和中間結(jié)果能寫入內(nèi)存。

這里第一行代碼batch_size在從0到整個(gè)訓(xùn)練集的大小之間隨機(jī)指定一個(gè)值。然后根據(jù)這個(gè)值,批處理選取相應(yīng)個(gè)數(shù)的圖像和標(biāo)簽。

# Periodically print out the model's current accuracy

if i % 100 == 0:

  train_accuracy = sess.run(accuracy, feed_dict={

    images_placeholder: images_batch, labels_placeholder: labels_batch})

  print('Step {:5d}: training accuracy {:g}'.format(i, train_accuracy))

每100次迭代,我們對(duì)模型訓(xùn)練數(shù)據(jù)批的當(dāng)前精確率進(jìn)行檢查。我們只需要調(diào)用我們之前定義的精確率操作來完成。

# Perform a single training step

sess.run(train_step, feed_dict={images_placeholder: images_batch,labels_placeholder: labels_batch})

這是整個(gè)訓(xùn)練循環(huán)中最重要的一行代碼。我們告訴模型執(zhí)行一個(gè)單獨(dú)的訓(xùn)練步驟。我們沒有必要為了參數(shù)更新再次聲明模型需要做什么。所有的信息都是由TensorFlow圖表中的定義提供的。TensorFlow知道根據(jù)損失使用梯度下降算法更新參數(shù)。而損失依賴logits。Logits又依靠weights,biases和具體的輸入批。

因此我們只需要向模型輸入訓(xùn)練數(shù)據(jù)批。這些通過提供查找表來完成。訓(xùn)練數(shù)據(jù)批已經(jīng)在我們?cè)缦榷x的占位符中完成了賦值。

# After finishing the training, evaluate on the test set

test_accuracy = sess.run(accuracy, feed_dict={

  images_placeholder: data_sets['images_test'],

  labels_placeholder: data_sets['labels_test']})

print('Test accuracy {:g}'.format(test_accuracy))

訓(xùn)練結(jié)束后,我們用測(cè)試集對(duì)模型進(jìn)行評(píng)估。這是模型第一次見到測(cè)試集。所以測(cè)試集中的圖像對(duì)模型來時(shí)是全新的。我們會(huì)評(píng)估訓(xùn)練后的模型在處理從未見過的數(shù)據(jù)時(shí)表現(xiàn)如何。

endTime = time.time()

print('Total time: {:5.2f}s'.format(endTime - beginTime))

最后一行代碼打印出訓(xùn)練和運(yùn)行模型用了多長(zhǎng)時(shí)間。

結(jié)果

讓我們用“python softmax.py”命令運(yùn)行這個(gè)模型。這里是我得到的輸出:

Step     0: training accuracy 0.14

Step   100: training accuracy 0.32

Step   200: training accuracy 0.3

Step   300: training accuracy 0.23

Step   400: training accuracy 0.26

Step   500: training accuracy 0.31

Step   600: training accuracy 0.44

Step   700: training accuracy 0.33

Step   800: training accuracy 0.23

Step   900: training accuracy 0.31

Test accuracy 0.3066

Total time: 12.42s

這意味著什么?在這個(gè)測(cè)試集中訓(xùn)練模型的估計(jì)精度為31%左右。如果你運(yùn)行自己的代碼,你的結(jié)果可能在25-30%。所以我們的模型能夠?qū)奈匆娺^的圖像正確標(biāo)簽的比率為25%-30%。還不算壞!這里有10個(gè)不同的標(biāo)簽,如果隨機(jī)猜測(cè),結(jié)果的準(zhǔn)確率只有10%。我們這個(gè)非常簡(jiǎn)單的方法已經(jīng)優(yōu)于隨機(jī)猜測(cè)。如果你覺得25%仍然有點(diǎn)低,別忘了這個(gè)模型其實(shí)還比較原始。它對(duì)具體圖像的比如線和形狀等特征毫無概念。它只是單獨(dú)檢測(cè)每個(gè)像素的顏色,完全不考慮與其他像素的關(guān)聯(lián)。對(duì)一幅圖像某一個(gè)像素的修改對(duì)模型來說意味著完全不同的輸入??紤]到這些,25%的準(zhǔn)確率看起來也不是那么差勁了。

如果我們多進(jìn)行幾次迭代,結(jié)果又會(huì)如何呢?這可能并不會(huì)改善模型的準(zhǔn)確率。如果看看結(jié)果,你就會(huì)發(fā)現(xiàn),訓(xùn)練的準(zhǔn)確率并不是穩(wěn)定上升的,而是在0.23至0.44之間波動(dòng)。看起來我們已經(jīng)到達(dá)了模型的極限,再進(jìn)行更多的訓(xùn)練于事無補(bǔ)。這個(gè)模型無法再提供更好的結(jié)果。事實(shí)上,比起進(jìn)行1000次迭代的訓(xùn)練,我們進(jìn)行少得多的迭代次數(shù)也能得到相似的準(zhǔn)確率。

你可能注意到的最后一件事就是:測(cè)試的精確度大大低于訓(xùn)練的精確度。如果這個(gè)差距非常巨大,這也意味著過度擬合。模型針對(duì)已經(jīng)見過的訓(xùn)練數(shù)據(jù)進(jìn)行了精細(xì)的調(diào)整,而對(duì)于以前從未見過的數(shù)據(jù)則無法做到這點(diǎn)。

這篇文章已經(jīng)寫了很長(zhǎng)時(shí)間了。很感謝你看完了全文(或直接跳到了文末)!無論是對(duì)機(jī)器學(xué)習(xí)分類器如何工作或是如何使用TensorFlow建立和運(yùn)行簡(jiǎn)單的圖表,我希望你找到了一些你感興趣的東西。當(dāng)然,我還有很多材料希望添加進(jìn)來。目前為止,我們只是用到了softmax分類器,它甚至都沒應(yīng)用任何一種神經(jīng)網(wǎng)絡(luò)。我的下一篇博文進(jìn)行完善:一個(gè)小型神經(jīng)網(wǎng)絡(luò)模型能夠怎樣最大程度地改進(jìn)結(jié)果。雷鋒網(wǎng)將繼續(xù)對(duì)下一篇文章進(jìn)行編譯,敬請(qǐng)期待。

 via wolfib

相關(guān)文章:

機(jī)器學(xué)習(xí)零基礎(chǔ)?手把手教你用TensorFlow搭建圖像識(shí)別系統(tǒng)(一)| 干貨

雷峰網(wǎng)原創(chuàng)文章,未經(jīng)授權(quán)禁止轉(zhuǎn)載。詳情見轉(zhuǎn)載須知

機(jī)器學(xué)習(xí)零基礎(chǔ)?手把手教你用TensorFlow搭建圖像識(shí)別系統(tǒng)(二)| 干貨

分享:
相關(guān)文章

知情人士

當(dāng)月熱門文章
最新文章
請(qǐng)?zhí)顚懮暾?qǐng)人資料
姓名
電話
郵箱
微信號(hào)
作品鏈接
個(gè)人簡(jiǎn)介
為了您的賬戶安全,請(qǐng)驗(yàn)證郵箱
您的郵箱還未驗(yàn)證,完成可獲20積分喲!
請(qǐng)驗(yàn)證您的郵箱
立即驗(yàn)證
完善賬號(hào)信息
您的賬號(hào)已經(jīng)綁定,現(xiàn)在您可以設(shè)置密碼以方便用郵箱登錄
立即設(shè)置 以后再說