最美情侣中文字幕电影,在线麻豆精品传媒,在线网站高清黄,久久黄色视频

歡迎光臨散文網(wǎng) 會員登陸 & 注冊

手把手教你用PyTorch實(shí)現(xiàn)圖像分類器

2019-09-10 19:21 作者:IT教程精選  | 我要投稿

(關(guān)注公眾號AI新視野,發(fā)送‘資料’二字,免費(fèi)獲取50G人工智能視頻教程!)


經(jīng)過幾個(gè)月富有挑戰(zhàn)性但是受益良多的學(xué)習(xí),我最近從Udacity的Python Nanodegree program AI編程專業(yè)畢業(yè)。最后一個(gè)項(xiàng)目是用PyTorch創(chuàng)建一個(gè)102種不同類型的花的圖像分類器。

在做這個(gè)final project的時(shí)候,很多同學(xué)都遇到了類似的問題和挑戰(zhàn)。當(dāng)我接近完成的時(shí)候,我決定與大家分享一些在未來對他人有益的建議和見解。

本文介紹如何實(shí)現(xiàn)圖像分類器的概念基礎(chǔ)------這是一種能夠理解圖像內(nèi)容的算法。

本文的目標(biāo)不是提供手把手的指導(dǎo),而是幫助理解整個(gè)過程。如果你正在考慮學(xué)習(xí)機(jī)器學(xué)習(xí)或人工智能,你將不得不做類似的項(xiàng)目,并理解本系列文章中介紹的概念。

文章主要進(jìn)行概念上的解釋,不需要知道如何編寫代碼。此外,下面所包含的PyTorch細(xì)節(jié)是次要的,主要以PyTorch作為示例。

這個(gè)過程的第一步是加載一個(gè)pre-trained神經(jīng)網(wǎng)絡(luò)。在討論這一步時(shí),我將解釋為什么要"reuse"網(wǎng)絡(luò)(即使用"pre-trained"網(wǎng)絡(luò)),闡明哪些部分可以重用,哪些部分不能重用,并提供如何根據(jù)需要定制pre-trained網(wǎng)絡(luò)的指導(dǎo)。

加載預(yù)訓(xùn)練的網(wǎng)絡(luò)

reuse是一種十分合理的策略,尤其是眾所周知并且得到廣泛認(rèn)可的標(biāo)準(zhǔn)。在示例中,出發(fā)點(diǎn)是torchvision提供的一種模型結(jié)構(gòu)。

本文的目標(biāo)是加載其中的一個(gè)pre-trained網(wǎng)絡(luò),并且將其中的分類器替換為自己的分類器,從而可以訓(xùn)練自己的分類器。

雖然這個(gè)想法是合理的,但我發(fā)現(xiàn)它也會產(chǎn)生一些問題,因?yàn)榧虞d一個(gè)預(yù)先訓(xùn)練的網(wǎng)絡(luò)并不能節(jié)省訓(xùn)練分類器的時(shí)間。

"所以你可能會想,使用預(yù)訓(xùn)練網(wǎng)絡(luò)有什么意義?"

當(dāng)我們?nèi)祟惪吹綀D像時(shí),可以識別線條和形狀。正因?yàn)槿绱?,我們才能將圖像內(nèi)容與之前看到過的內(nèi)容聯(lián)系起來。我們希望我們的分類器能夠做一些類似的事情,但是圖像不是一段微不足道的數(shù)據(jù)。圖像通常由數(shù)千個(gè)獨(dú)立的像素組成,每個(gè)像素都有一種顏色,這種顏色由三個(gè)不同的值組合定義 : Red,Green, Blue。

從左到右:原始,紅色,綠色,藍(lán)色

如果我們希望我們的分類器能夠處理該數(shù)據(jù)量,我們將需要處理每個(gè)圖像中包含的所有信息,并以其可以理解的格式將其提供給分類器。這就是預(yù)訓(xùn)練網(wǎng)絡(luò)發(fā)揮作用的地方。

這些預(yù)先訓(xùn)練的網(wǎng)絡(luò)主要由一組特征檢測器和分類器組成,其中特征檢測器被訓(xùn)練以從每個(gè)圖像中提取信息,并且訓(xùn)練分類器以理解特征層提供的輸入。

我們已經(jīng)在已在ImageNet上培訓(xùn)過功能檢測器,并且證明它可以有很好的表現(xiàn)。因此,我們希望保持原樣。為了防止在我們訓(xùn)練分類器時(shí),要素圖層被修改,我們需要"凍結(jié)"它們。這個(gè)小代碼片段可以幫助解決這個(gè)問題:

for?param?in?model.parameters(): ????param.requires_grad?=?False

如果使用分類器會怎么樣? 為什么我們不能重復(fù)使用它??? 要回答這個(gè)問題,讓我們以架構(gòu)VGG16為例,來看看它的默認(rèn)分類器:

(classifier):?Sequential( ??(0):?Linear(in_features=25088,?out_features=4096,?bias=True) ??(1):?ReLU(inplace) ??(3):?Linear(in_features=4096,?out_features=4096,?bias=True) ??(4):?ReLU(inplace) ??(5):?Dropout(p=0.5) ??(6):?Linear(in_features=4096,?out_features=1000,?bias=True) )

首先,我們無法保證這一定是有效的。并且令人懷疑的是,這些默認(rèn)層和元素,激活函數(shù)和丟失值對于我們的特定情況而言恰好是最佳的。

當(dāng)我們看到它的最后一層有1000個(gè)元素的輸出時(shí),情況就變得很明顯了。在我們的例子中,我們處理102種不同類型的花,因此我們的分類器的輸出必須是102?。

從上面VGG16中的默認(rèn)分類器,我們還可以注意到它的輸入層有25088個(gè)元素,因?yàn)檫@是此特定預(yù)訓(xùn)練模型中特征檢測器的輸出大小。我們的分類器的輸入大小也必須與要素圖層的輸出相匹配。

小結(jié)

由上文我們可以得知,預(yù)先訓(xùn)練好的網(wǎng)絡(luò)非常有益,因?yàn)樗鼈兪刮覀兡軌驅(qū)W⒂谖覀兊挠美?xì)節(jié),同時(shí)重復(fù)使用眾所周知的泛型來進(jìn)行示例中的圖像預(yù)處理。

我們還了解到,分類器輸出的大小必須與我們希望能夠識別的不同類型的數(shù)量相同。

最后,我們已經(jīng)看到要素圖層的輸出和自定義分類器的輸入也必須匹配大小。

訓(xùn)練分類器

首先我們要做的是將訓(xùn)練用的圖片喂給我們的分類器,我們可以使用PyTorch中的ImageFolder接口載入圖片。預(yù)訓(xùn)練網(wǎng)絡(luò)要求我們輸入的都是某種特定格式的圖片,因此,在將圖片喂給神經(jīng)網(wǎng)絡(luò)前,我們需要對圖片進(jìn)行某些變換以達(dá)到對圖片的裁剪和歸一化。

具體來說,我們會將輸入圖片裁剪至224x224尺寸并且使用[0.485, 0.456, 0.406]和[0.229, 0.224, 0.225]兩個(gè)參數(shù)作為均值和標(biāo)準(zhǔn)差進(jìn)行歸一化。歸一化使得圖片顏色通道數(shù)值中心化于0同時(shí)使得標(biāo)準(zhǔn)差為1。

接著我們可以使用PyTorch中的DataLoader接口將所有圖片分成不同的批次。因?yàn)槲覀冃枰N圖片數(shù)據(jù)集------訓(xùn)練集,驗(yàn)證集和測試集,所以我們需要為每個(gè)數(shù)據(jù)集分別創(chuàng)建一個(gè)讀取器。好了,萬事俱備,我們可以開始訓(xùn)練我們的分類器了。

進(jìn)行到此處我們將碰到最重要的挑戰(zhàn):模型準(zhǔn)確度

讓我們的模型去識別一張我們事先已經(jīng)標(biāo)注好類別的圖片并不難,然而我們需要我們的模型擁有泛化能力,即讓模型可以識別我們從未標(biāo)注過的花卉圖片中的花卉種類。我們可以通過防止模型的過擬合達(dá)到模型泛化的目的。過擬合的意思為:我們的模型參數(shù)太過于滿足我們自己的訓(xùn)練圖片的準(zhǔn)確度,從而可能導(dǎo)致無法對除了訓(xùn)練集之外的其他圖片進(jìn)行準(zhǔn)確識別。即模型在訓(xùn)練集上表現(xiàn)優(yōu)越,但是在測試集和驗(yàn)證集上誤差很大。

不同的參數(shù)可以幫助模型達(dá)到最佳擬合

隱藏層

我們總是很容易陷入更多或更大的隱藏層能夠提高分類器準(zhǔn)確性這樣的思維誤區(qū),然而這個(gè)說法不總是對的。

增加隱藏層的數(shù)量和尺寸會使得我們的分類器考慮更多除了那些至關(guān)重要的參數(shù)以外的參數(shù)。例如,將噪音也視為花卉的一部分。這將導(dǎo)致過擬合以及模型準(zhǔn)確度的下降。不僅如此,增加隱藏層的數(shù)量和尺寸也將花費(fèi)我們更多時(shí)間去訓(xùn)練分類器和利用分類器去預(yù)測結(jié)果。

正因如此,我們建議開始訓(xùn)練網(wǎng)絡(luò)時(shí)采用較少數(shù)量和較小尺寸的隱藏層,同時(shí)隱藏層的數(shù)量和尺寸根據(jù)訓(xùn)練進(jìn)展按需增加,而不是一開始便在網(wǎng)絡(luò)中加入大量和大尺寸的隱藏層。

在Udacity的利用python進(jìn)行AI編程納米學(xué)位項(xiàng)目中的花卉分類器項(xiàng)目中(我在本系列文章的第一篇推文中介紹了該項(xiàng)目),利用訓(xùn)練集進(jìn)行第一次全訓(xùn)練輪次時(shí),我僅僅利用包含一層小規(guī)模隱藏層的網(wǎng)絡(luò)便獲得了超過70%的準(zhǔn)確度

數(shù)據(jù)增強(qiáng)

我們有一批圖片用來訓(xùn)練我們的模型,這是極好的事情,但是如果我們有更多的圖片,這將會變得更好。此時(shí)數(shù)據(jù)增強(qiáng)便派上了用場。在訓(xùn)練模型的每一回合中,每張圖片會被喂入網(wǎng)絡(luò)一次。但是在每次喂給網(wǎng)絡(luò)之前,我們可以對圖片進(jìn)行任意的變換,例如旋轉(zhuǎn),平移,縮放。通過這種方式,在不同的訓(xùn)練回合中,同一張圖片將會以不同的形式喂給神經(jīng)網(wǎng)絡(luò)。增加訓(xùn)練數(shù)據(jù)的多樣性可以減少過擬合的出現(xiàn)概率,相應(yīng)地也提高了模型的泛化能力,從而提高了模型總體的準(zhǔn)確性。

打亂數(shù)據(jù)集

當(dāng)訓(xùn)練神經(jīng)網(wǎng)絡(luò)時(shí),為了防止模型出現(xiàn)任何偏向性,我們需要以任意順序?qū)D片喂給神經(jīng)網(wǎng)絡(luò)。

例如,一開始如果我們只將矮牽?;▓D片喂給分類器,那么該分類器的張量很容易傾向于矮牽?;?。事實(shí)上,此時(shí)此刻,我們的分類器將會只知道矮牽?;ㄟ@一種花。即使接下來我們使用其他種類花卉圖片來繼續(xù)訓(xùn)練模型,這種最初的對于某種花卉的傾向性將會隨著時(shí)間繼續(xù)存在。

為了防止這種現(xiàn)象的發(fā)生,我們需要在數(shù)據(jù)載入器中打亂圖片順序,只需要簡單的一步------在創(chuàng)建載入器時(shí)添加shuffle=True語句即可。

trainloader?=?torch.utils.data.DataLoader(train_dataset,?batch_size=batch_size,?shuffle=True)

隨機(jī)失活

有時(shí),分類器內(nèi)的神經(jīng)網(wǎng)絡(luò)節(jié)點(diǎn)會產(chǎn)生過多的影響,從而使得其他節(jié)點(diǎn)不能進(jìn)行正常的訓(xùn)練。同時(shí),節(jié)點(diǎn)之間會產(chǎn)生相互依存關(guān)系從而導(dǎo)致過擬合。

隨機(jī)失活是在每一次訓(xùn)練中通過使一些節(jié)點(diǎn)隨機(jī)失活來防止上述現(xiàn)象發(fā)生的一種訓(xùn)練技巧。因而,每一次訓(xùn)練中分別訓(xùn)練了所有節(jié)點(diǎn)中的不同子集,從而減少了過擬合現(xiàn)象的發(fā)生。

暫且先不談?wù)撨^擬合,我們需要時(shí)刻記住的是學(xué)習(xí)率可能是最重要的超參數(shù)。如果學(xué)習(xí)率太大,我們可能永遠(yuǎn)得不到誤差的最小值,如果學(xué)習(xí)率太小,分類器的訓(xùn)練過程會變得非常漫長。典型的學(xué)習(xí)率數(shù)值分別是:0.01,0.001,0.0001等等。

最后但也仍然非常重要的是,對位于分類器最后一層的激活函數(shù)的正確選擇也會大幅改善模型準(zhǔn)確度。例如,如果在神經(jīng)網(wǎng)絡(luò)中我們使用了負(fù)對數(shù)似然損失函數(shù),按照文檔所述,那么建議在最后一層使用LogSoftmax激活函數(shù)。

小結(jié)

為了訓(xùn)練一個(gè)擁有泛化能力,同時(shí)在預(yù)測新圖片中的花卉種類有著高準(zhǔn)確度的模型,理解模型訓(xùn)練過程是非常有用的。

在文章中我們討論了過擬合是如何影響模型的泛化能力以及如何防止過擬合的發(fā)生。同時(shí)我們也提及了學(xué)習(xí)率的重要性以及常用的學(xué)習(xí)率。最后,我們可以看出在最后一層中選擇正確的激活函數(shù)也是至關(guān)重要的。

既然我們知道了如何訓(xùn)練模型,我們便可以使用模型去識別模型從未見過的圖片中的花卉種類。

預(yù)測花的品種

一旦我們的分類器訓(xùn)練完成,我們希望每次我們需要分析一張圖像時(shí)都不必再次訓(xùn)練它。所以我們想保存分類器,這樣我們就可以在需要的時(shí)候再次加載它。

使用torch.save[1]方法,我們可以輕松地存儲包含我們需要保留的值的字典。類似地,當(dāng)我們需要使用分類器時(shí),我們可以使用torch.load[2]來檢索字典。

專業(yè)提醒:您可以保存結(jié)構(gòu)類型。這將允許您了解應(yīng)加載哪個(gè)初始模型結(jié)構(gòu)。此外,您可以輕松找到分類器的輸入大小,具體取決于所選的初始架構(gòu):

ResNet, Inception: input_size = model.fc.in_features VGG: input_size = model.classifier[0].in_features DenseNet: input_size = model.classifier.in_features SqueezeNet: input_size = model.classifier[1].in_channels AlexNet: alexnet.classifier[1].in_features

水晶球

要預(yù)測花的類型,我們需要先加載圖像。為此,我們可以使用PIL[3]。調(diào)整圖像大小和裁剪以匹配神經(jīng)元網(wǎng)絡(luò)所需的輸入大小 224x224 后,我們需要將其轉(zhuǎn)換為?numpy[4]?數(shù)組。
RGB 顏色通常編碼為整數(shù)從 0 到 255。由于我們的模型需要在 0 和 1 之間的浮點(diǎn)型數(shù)字,我們需要將RGB顏色除以 255。然后,我們再減去平均值,除以標(biāo)準(zhǔn)差來規(guī)范化[5]數(shù)據(jù)。

如上文所示,為了規(guī)范化我們的數(shù)據(jù),我們將使用 [0.485、 0.456、 0.406] 表示平均值,將 [0.229、0.224、0.225]?設(shè)置成標(biāo)準(zhǔn)差。

最后一點(diǎn),我們需要解決 numpy 數(shù)組在其第三個(gè)維度中具有顏色,而 PyTorch?中位于第一個(gè)維度中。為了使數(shù)據(jù)與輸入格式匹配,我們需要使用轉(zhuǎn)置來對其尺寸重新排序。

最后,我們可以使用?tototo.from_numpy[6]為該 numpy 數(shù)組創(chuàng)建張量,并將它們傳遞給模型。傳遞結(jié)果中函數(shù)totorch.topk[7]將給我們提供具有相應(yīng)概率的預(yù)測概率最高的類別。

請注意,使用 Softmax 作為最終激活函數(shù)時(shí),所有類的概率應(yīng)為總和 1。在使用 LogSoftmax 的情況下,我們將獲取概率的對數(shù)。多虧了 matplotlib,我們可以像這樣表示預(yù)測結(jié)果:

? 預(yù)測結(jié)果


小結(jié)

在這最后一篇文章中,我們學(xué)習(xí)了如何保存和加載分類器。我們還討論了如何預(yù)測新圖像中的類型,主要收獲是我們需要預(yù)先處理圖像,以匹配神經(jīng)網(wǎng)絡(luò)期望的格式。

完成后,我們可以創(chuàng)建張量,并使用 topk 方法查找概率最高的類,并繪制結(jié)果以簡化可視化。



手把手教你用PyTorch實(shí)現(xiàn)圖像分類器的評論 (共 條)

分享到微博請遵守國家法律
凌海市| 平凉市| 乌拉特前旗| 万宁市| 花莲市| 左云县| 河间市| 芷江| 剑河县| 汕尾市| 班戈县| 越西县| 合江县| 光山县| 连州市| 志丹县| 松滋市| 罗田县| 涟源市| 平江县| 武隆县| 吉林市| 开阳县| 崇义县| 桓仁| 漳浦县| 镇坪县| 全州县| 平顶山市| 龙南县| 焦作市| 阿拉善右旗| 岚皋县| 延川县| 孝义市| 东兴市| 建德市| 通城县| 潞城市| 南丰县| 始兴县|