日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 > 人文社科 > 生活经验 >内容正文

生活经验

FastAI 课程学习笔记 lesson 1:宠物图片分类

發(fā)布時間:2023/11/28 生活经验 28 豆豆
生活随笔 收集整理的這篇文章主要介紹了 FastAI 课程学习笔记 lesson 1:宠物图片分类 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.

文章目錄

  • 代碼解析
    • 神奇的"%"
    • 導(dǎo)入fastAI 庫
    • 下載解壓數(shù)據(jù)集 untar_data
    • 獲取幫助文檔
      • help()
      • ?
      • ??
      • doc
    • 設(shè)置路徑
    • get_image_files
    • ImageDataBunch
      • from_name_re
        • grep命令檢驗正則表達(dá)式
        • python re檢驗正則表達(dá)式
      • from_name_re使用方法
      • data.normalize()來進(jìn)行數(shù)據(jù)歸一化
      • data.show_batch()顯示圖像
      • 查看標(biāo)簽
  • 訓(xùn)練
    • 利用resnet框架訓(xùn)練模型
    • 應(yīng)用one-cycle-policy
    • 保存模型權(quán)重
    • 分析結(jié)果
    • 繪制出loss最大的案例
    • 混淆矩陣
    • 通過微調(diào)讓模型更加好
      • Unfreezing
      • fine-tuning
      • learning rates
  • 參考

代碼解析

神奇的"%"

%reload_ext autoreload
%autoreload 2
%matplotlib inline

這些東西開始%是對jupyter notebook本身的特殊指令,它們不是Python代碼。它們被稱為“魔法”。
表示

  • 如果有人在我運行這個程序時更改了底層庫代碼,請自動重新加載它
  • 如果有人想畫點什么,請在這個jupyter notebook上畫出來

導(dǎo)入fastAI 庫

from fastai import *
from fastai.vision import *

fastai的官方文檔見這里:http://docs.fast.ai/
在大多數(shù)庫的標(biāo)準(zhǔn)生產(chǎn)代碼中,有很好的理由不使用import *
jupyter notebook中,你希望能夠快速交互地嘗試一些東西,而不是不斷地回到頂部,導(dǎo)入更多的東西。您希望能夠使用大量完整的選項卡,并且非常具有實驗性,因此import *非常棒。
當(dāng)您在生產(chǎn)中構(gòu)建東西時,您可以進(jìn)行正常的PEP8風(fēng)格的適當(dāng)軟件工程實踐。這是一種不同的編碼風(fēng)格。并不是說在數(shù)據(jù)科學(xué)編程中沒有規(guī)則,規(guī)則是不同的。
當(dāng)你在訓(xùn)練模型時,最重要的是能夠快速地進(jìn)行交互實驗。所以你會看到我們使用了很多不同的過程,風(fēng)格,和你習(xí)慣的東西。但它們的存在是有原因的,隨著時間的推移,你會了解它們。
另一件需要提到的事情是,fastai庫是以一種非常有趣的模塊化方式設(shè)計的,而且當(dāng)您使用import *時,事情比您預(yù)期的要少得多。所有這些都是顯式設(shè)計的,目的是讓您能夠快速地導(dǎo)入并使用它們,而不會出現(xiàn)任何問題。

下載解壓數(shù)據(jù)集 untar_data

數(shù)據(jù)集在深度學(xué)習(xí)中發(fā)揮著重要的作用,在fastai中,通過untar_data函數(shù)來下載和解壓我們所需要的數(shù)據(jù)集。比如我們需要下載fastai指定的寵物數(shù)據(jù)集,我們可以采用如下的代碼來完成工作:

path = untar_data(URLs.PETS); path

獲取幫助文檔

在有的時候我們可能會因為某些fastai的某些函數(shù)或者其他用法困擾,我們可以通過下面幾種方法來獲取幫助文檔

help()

通過使用下面的代碼可以獲取untar_data的使用說明

help(untar_data)

獲取結(jié)果如下:

Help on function untar_data in module fastai.datasets:untar_data(url:str, fname:Union[pathlib.Path, str]=None, dest:Union[pathlib.Path, str]=None)Download `url` if doesn't exist to `fname` and un-tgz to folder `dest`

?

也可以使用如下?來獲取該函數(shù)的定義和參數(shù)。這種方法可用于任何python庫,使用方法如下代碼所示:

?untar_data

獲取結(jié)果如下:

Signature: untar_data(url:str, fname:Union[pathlib.Path, str]=None, dest:Union[pathlib.Path, str]=None, data=True, force_download=False) -> pathlib.Path
Docstring: Download `url` to `fname` if it doesn't exist, and un-tgz to folder `dest`.
File:      /usr/local/lib/python3.6/dist-packages/fastai/datasets.py
Type:      function

??

通過??可以獲取相關(guān)函數(shù)的源程序,這種方法可用于任何python庫,使用方法如下代碼所示:

??untar_data

獲取結(jié)果如下:


Signature: untar_data(url:str, fname:Union[pathlib.Path, str]=None, dest:Union[pathlib.Path, str]=None, data=True, force_download=False) -> pathlib.Path
Source:   
def untar_data(url:str, fname:PathOrStr=None, dest:PathOrStr=None, data=True, force_download=False) -> Path:"Download `url` to `fname` if it doesn't exist, and un-tgz to folder `dest`."dest = url2path(url, data) if dest is None else Path(dest)/url2name(url)fname = Path(ifnone(fname, _url2tgz(url, data)))if force_download or (fname.exists() and url in _checks and _check_file(fname) != _checks[url]):print(f"A new version of the {'dataset' if data else 'model'} is available.")if fname.exists(): os.remove(fname)if dest.exists(): shutil.rmtree(dest)if not dest.exists():fname = download_data(url, fname=fname, data=data)if url in _checks:assert _check_file(fname) == _checks[url], f"Downloaded file {fname} does not match checksum expected! Remove that file from {Config().data_archive_path()} and try your code again."tarfile.open(fname, 'r:gz').extractall(dest.parent)return dest
File:      /usr/local/lib/python3.6/dist-packages/fastai/datasets.py
Type:      function

doc

通過使用doc,這種方法只適用于fastai,顯示函數(shù)的定義、docstring和指向文檔的鏈接(僅適用于導(dǎo)入fastai庫),使用方法如下:

doc(untar_data)

但是需要注意的是,在使用doc()可能會遇到一些問題,會報如下的錯誤:

markdown2html() missing 1 required positional argument: 'source'

這個bug,fastai官方已經(jīng)修復(fù)了,詳細(xì)可參考這里

設(shè)置路徑

在我們通過如下代碼下載解壓數(shù)據(jù)集之后,我們可以得到數(shù)據(jù)集所在的路徑path

path = untar_data(URLs.PETS)

我們可以使用path.ls()來查看數(shù)據(jù)集的根目錄都有哪些目錄。
當(dāng)我們查看到根目錄的結(jié)果如下:

['annotations', 'images']

我們可以為這些目錄設(shè)置路徑的變量,如下代碼所示:

path_anno = path/'annotations'
path_img = path/'images'

這種路徑拼接方式是源于fastai集成了python中的pathlib的相關(guān)功能,關(guān)于pathlib更多內(nèi)容可以查看這里

get_image_files

在fastai中,通過get_image_files能將圖像文件的路徑存儲到列表之中

fnames = get_image_files(path_img)
fnames[:5]

結(jié)果如下:

[PosixPath('/data1/jhoward/git/course-v3/nbs/dl1/data/oxford-iiit-pet/images/american_bulldog_146.jpg'),PosixPath('/data1/jhoward/git/course-v3/nbs/dl1/data/oxford-iiit-pet/images/german_shorthaired_137.jpg'),PosixPath('/data1/jhoward/git/course-v3/nbs/dl1/data/oxford-iiit-pet/images/japanese_chin_139.jpg'),PosixPath('/data1/jhoward/git/course-v3/nbs/dl1/data/oxford-iiit-pet/images/great_pyrenees_121.jpg'),PosixPath('/data1/jhoward/git/course-v3/nbs/dl1/data/oxford-iiit-pet/images/Bombay_151.jpg')]

這是計算機(jī)視覺數(shù)據(jù)集傳遞的一種非常常見的方式——只有一個文件夾,里面有一大堆文件。有趣的是我們?nèi)绾蔚玫綐?biāo)簽。在機(jī)器學(xué)習(xí)中,標(biāo)簽指的是我們試圖預(yù)測的東西。如果我們仔細(xì)觀察一下,我們可以馬上看到標(biāo)簽實際上是文件名的一部分。我們需要以某種方式獲得每個文件名的標(biāo)簽位列表,這將給我們標(biāo)簽。進(jìn)行深度學(xué)習(xí)主要依賴于兩個部分:

  • 數(shù)據(jù)
  • 標(biāo)簽

ImageDataBunch

在fastai中通過ImageDataBunch對象可以輕松實現(xiàn)圖像數(shù)據(jù)訓(xùn)練的問題。ImageDataBunch表示構(gòu)建模型所需的所有數(shù)據(jù),還有一些工廠方法可以很容易地創(chuàng)建這些數(shù)據(jù)——訓(xùn)練集、帶有圖像和標(biāo)簽的驗證集。

from_name_re

在這一節(jié)中,通過使用ImageDataBunchfrom_name_re函數(shù)通過正則表達(dá)式的方式來從圖像名稱中提取標(biāo)簽——label。
通過下面的正則表達(dá)式來對圖像名稱進(jìn)行字符串匹配:

pat = r'/([^/]+)_\d+.jpg$'

我們來對這個正則表達(dá)式進(jìn)行解析下:

正則表達(dá)式解釋
$匹配字符串結(jié)尾
.jpg表示字符串最后的的字符,這里表示文件的格式
\d匹配數(shù)字,+表示匹配前一個字符1次或者無限次
_應(yīng)該數(shù)字開始前的下劃線
()表示一組字符
[]表示字符集
^/^在中括號中表示取反,^/表示除了/的所有字符
( [ ^/ ] + )表示除了/的任意字符串
/表示最開始的/
r表明字符串為原始字符串,否則\d就需要寫成\\d,否則python無法解析

加入現(xiàn)在我們的圖像所在路徑如下所示:

/data/oxford-iiit-pet/images/german_shorthaired_105.jpg
/data/oxford-iiit-pet/images/Siamese_86.jpg
/data/oxford-iiit-pet/images/British_Shorthair_56.jpg
.....

通過正則表達(dá)式‘/([^/]+)_\d+.jpg$來過濾上述的這些路徑,我們最終會得到如下結(jié)果:

/german_shorthaired_105.jpg
/Siamese_86.jpg
/British_Shorthair_56.jpg
.....

grep命令檢驗正則表達(dá)式

我們可以通過linux的grep命令來檢驗這個正則表達(dá)式是否正確,假設(shè)當(dāng)前我們處于/data/oxford-iiit-pet/路徑下,我們可以如下命令來檢驗

ls | xargs readlink -f | grep -P "/([^/]+)_\d+.jpg$"
或者
ls | xargs readlink -f | grep -E "/([^/]+)_[0-9]+.jpg$"

其中ls | xargs readlink -f是為了獲取圖像文件的絕對路徑。
關(guān)于grep -Egrep -P的使用區(qū)別主要在于:

  • grep -E 使用的是擴(kuò)展的正則表達(dá)式,不支持\d
  • grep -P 使用的是Perl 的正則表達(dá)式,支持\d

關(guān)于它們的更多區(qū)別可以查看這里

python re檢驗正則表達(dá)式

可以通過如下的程序來檢驗正則表達(dá)式的作用

import re
temp_name = "/data/oxford-iiit-pet/images/german_shorthaired_105.jpg"
pat = r'/([^/]+)_\d+.jpg$'
pat = re.compile(pat)
print(pat.search(temp_name).group())
print(pat.search(temp_name).group(1))

得到的結(jié)果如下:

/german_shorthaired_105.jpg
german_shorthaired

其中,通過pat.search(temp_name).group(1)獲取到圖像的標(biāo)簽,這個通過正則表達(dá)式中的()定義分組實現(xiàn)。關(guān)于正則表達(dá)式的更多知識和正則表達(dá)式在python中的使用,可以參考這里。

from_name_re使用方法

from_name_re使用方法如下:

 data = ImageDataBunch.from_name_re(path_img, fnames, pat, ds_tfms=get_transforms(), size=224)

其中的參數(shù)解釋如下:

參數(shù)解釋
path_img含有圖圖像的文件夾路徑
fnames具體圖像文件的路徑
pat用來提取標(biāo)簽的正則表達(dá)式
ds_tfm將變換應(yīng)用到圖像上
size統(tǒng)一設(shè)置訓(xùn)練的圖像的大小

其中利用size統(tǒng)一設(shè)置訓(xùn)練的圖像的大小的原因是因為這是當(dāng)前深度學(xué)習(xí)技術(shù)的一個缺點,即GPU必須將完全相同的指令同時應(yīng)用到一大堆東西上,以達(dá)到更快的速度。如果圖像的形狀和大小不同,就不能這樣做,所以必須讓所有的圖像都具有相同的形狀和大小。當(dāng)前使用的形狀以方形為主,當(dāng)然還有一些矩形的情況。
之所以將size設(shè)置成224,一個重要的原因是因為很多經(jīng)典的模型都使用size=224,通常使用這個尺寸可以解決大部分的問題。

其中get_transforms()將所有圖像的size調(diào)整成224,當(dāng)然get_transforms()函數(shù)可以快速的得到圖像的多種變換結(jié)果,因此get_transforms()函數(shù)也經(jīng)常被用在數(shù)據(jù)增強(qiáng)上。

什么是數(shù)據(jù)增強(qiáng)?
數(shù)據(jù)增強(qiáng)也許是在訓(xùn)練模型計算機(jī)視覺最重要的正則化技術(shù),在訓(xùn)練模型時候不是每次都使用相同的圖片,而是做一些小隨機(jī)變換(旋轉(zhuǎn),縮放、翻譯等…),不改變里面有什么圖像(肉眼),但改變其像素值。經(jīng)過數(shù)據(jù)增強(qiáng)訓(xùn)練的模型將更好地泛化。

關(guān)于在fastai中如何實現(xiàn)數(shù)據(jù)增強(qiáng)和圖像變換的知識可以查看這里

ImageDataBunch.from_name_re將返回DataBunch對象。在fastai中,所有的模型對象都是DataBunch對象DataBunch對象包含2或3個數(shù)據(jù)集——它包含您的訓(xùn)練數(shù)據(jù)集、驗證數(shù)據(jù)集和可選的測試數(shù)集。對于每一個數(shù)據(jù)集,它包含你的圖像和標(biāo)簽,你的文本和標(biāo)簽,或者你的表格數(shù)據(jù)和標(biāo)簽,等等。

data.normalize()來進(jìn)行數(shù)據(jù)歸一化

通過使用如下代碼來進(jìn)行,其中參數(shù)imagenet_stats是fastai通過使用在ImageNet上得到的預(yù)訓(xùn)練模型,然后將預(yù)訓(xùn)練模型的標(biāo)準(zhǔn)化必須應(yīng)用于新數(shù)據(jù)(pets)。

data.normalize(imagenet_stats)

如果在訓(xùn)練模型時遇到問題,需要驗證的一件事是是否正確地數(shù)據(jù)歸一化。

對數(shù)據(jù)歸一化的意義何在?
圖像的像素值范圍從0到255像素值,通常包含3個顏色通道(紅、綠、藍(lán))。并且含有有些通道可能非常亮,有些可能一點也不亮,有些可能變化很大,有些可能一點也不亮。如果這些紅綠藍(lán)通道的均值都是0,標(biāo)準(zhǔn)差都是1,這將有助于訓(xùn)練一個深度學(xué)習(xí)模型。如果您的數(shù)據(jù)沒有規(guī)范化,那么您的模型將很難很好地訓(xùn)練。所以,如果你在訓(xùn)練一個模型時遇到問題,那首先需要驗證就是是否對數(shù)據(jù)進(jìn)行了歸一化。

data.show_batch()顯示圖像

查看數(shù)據(jù)并檢查是否一切正常是非常重要的。
有時圖像上可能有文本,或者它們可能被其他對象遮擋,或者它們中的一些可能以奇怪的方式旋轉(zhuǎn)。
通過如下代碼來查看圖像數(shù)據(jù):

data.show_batch(rows=3, figsize=(7,6))

顯示情況如下:

這些圖像均以一種相當(dāng)好的方式展示出來,它們大小顯示一致,并且是默認(rèn)情況下的中心裁剪也就是說它會對齊中間的位置并調(diào)整大小。

查看標(biāo)簽

我們要做的另一件事是看標(biāo)簽。所有可能的標(biāo)簽名都稱為classes,可以通過data.classes來進(jìn)行輸出:

print(data.classes)
len(data.classes),data.c

得到這樣的結(jié)果:

['american_bulldog', 'german_shorthaired', 'japanese_chin', 'great_pyrenees', 'Bombay', 'Bengal', 'keeshond', 'shiba_inu', 'Sphynx', 'boxer', 'english_cocker_spaniel', 'american_pit_bull_terrier', 'Birman', 'basset_hound', 'British_Shorthair', 'leonberger', 'Abyssinian', 'wheaten_terrier', 'scottish_terrier', 'Maine_Coon', 'saint_bernard', 'newfoundland', 'yorkshire_terrier', 'Persian', 'havanese', 'pug', 'miniature_pinscher', 'Russian_Blue', 'staffordshire_bull_terrier', 'beagle', 'Siamese', 'samoyed', 'chihuahua', 'Egyptian_Mau', 'Ragdoll', 'pomeranian', 'english_setter'](37, 37)

這就是我們從文件名中使用正則表達(dá)式提取到的所有可能的標(biāo)簽。我們之前在之前學(xué)習(xí)過,有37種可能的類別,所以僅檢查len(data.classes),它確實是37。DataBunch總是有一個名為c的屬性。我們將在稍后討論技術(shù)細(xì)節(jié),但現(xiàn)在可以把它看作類的數(shù)量。對于像回歸問題和多標(biāo)簽分類這樣的問題,這并不完全準(zhǔn)確,但現(xiàn)在就可以了。重要的是要知道data.c是一個非常重要的信息片段。

訓(xùn)練

利用resnet框架訓(xùn)練模型

現(xiàn)在我們已經(jīng)可以開始訓(xùn)練一個模型了,在fastai中我們可以通過一個稱為learner的東西來進(jìn)行訓(xùn)練模型。

  • DataBunch:是數(shù)據(jù)在fastai中的一般概念,從這里開始,有一些它的子類用于特定的應(yīng)用程序,比如ImageDataBunch
  • Learner: 一個通過學(xué)習(xí)相關(guān)內(nèi)容來訓(xùn)練模型的一般概念。在此基礎(chǔ)上,有各種子類來簡化操作,特別是有一個convnet learner(它可以為您創(chuàng)建卷積神經(jīng)網(wǎng)絡(luò))。
learn = create_cnn(data, models.resnet34, metrics=error_rate)

create_cnn方法存在于fastai.vision.learner類中。
在fastai中,模型是由學(xué)習(xí)者訓(xùn)練的,create_cnn只接受很少的參數(shù),首先是DataBunch數(shù)據(jù)對象,然后是模型resnet34,最后傳遞的是指標(biāo)列表。
當(dāng)首次調(diào)用時候會下載resnet34的預(yù)訓(xùn)練模型,預(yù)訓(xùn)練是指這個特定的模型已經(jīng)為特定的任務(wù)進(jìn)行了訓(xùn)練,當(dāng)前這個預(yù)訓(xùn)練模型是使用Imagenet圖像數(shù)據(jù)集進(jìn)行訓(xùn)練得到的。所以我們不一定要從一個對圖像一無所知的模型開始,而是從1000個類別的圖像開始。

應(yīng)用one-cycle-policy

簡單來說,one-cycle-policy, 使用的是一種周期性學(xué)習(xí)率,從較小的學(xué)習(xí)率開始學(xué)習(xí),緩慢提高至較高的學(xué)習(xí)率,然后再慢慢下降,周而復(fù)始,每個周期的長度略微縮短,在訓(xùn)練的最后部分,學(xué)習(xí)率比之前的最小值降得更低。這不僅可以加速訓(xùn)練,還有助于防止模型落入損失平面的陡峭區(qū)域,使模型更傾向于尋找更平坦部分的極小值,從而緩解過擬合現(xiàn)象。

One-Cycle-Policy 大概有三個步驟:

  1. 我們逐漸將學(xué)習(xí)率從 lr_max / div_factor 提高到 lr_max,同時我們逐漸減少從 mom_max 到 mom_min 的動量 (momentum)。

  2. 反向再做一次:我們逐漸將學(xué)習(xí)率從 lr_max 降低到 lr_max / div_factor,同時我們逐漸增加從 mom_min 到 mom_max 的動量。

  3. 我們進(jìn)一步將學(xué)習(xí)率從 lr_max / div_factor 降低到 lr_max /(div_factor x 100),我們保持動力穩(wěn)定在 mom_max。

關(guān)于one-cycle-policy的知識可以參考這里(中文,英文)

在fastai中通過如下代碼實現(xiàn):

learn.fit_one_cycle(4)

原型是這樣的:

fit_one_cycle(learn:Learner, cyc_len:int, max_lr:Union[float, Collection[float], slice]=slice(None, 0.003, None), moms:Point=(0.95, 0.85), div_factor:float=25.0, pct_start:float=0.3, final_div:float=None, wd:float=None, callbacks:Optional[Collection[Callback]]=None, tot_epochs:int=None, start_epoch:int=None)

它接受一個整數(shù)cycle_len,該整數(shù)描述你希望希望通過完整數(shù)據(jù)集的次數(shù),每次模型看到圖片,它就會變得越來越好,這要花很多時間。但是如果你把圖像顯示太多次,這個模型只會單獨識別某些圖像。在機(jī)器學(xué)習(xí)中,這被稱為過度擬合。
max_lr是最大學(xué)習(xí)速率,mom是動量,wd是重量衰減我們將在以后的課程中學(xué)習(xí)所有這些參數(shù)。

保存模型權(quán)重

這一步非常重要,因為你需要在下次運行代碼時重新加載權(quán)重

learn.save('stage-1')

分析結(jié)果

觀察模型的運行結(jié)果十分重要,我們已經(jīng)觀察了如何訓(xùn)練模型,現(xiàn)在我們觀察我們的模型預(yù)測出了什么?

interp = ClassificationInterpretation.from_learner(learn)

ClassificationInterpretationl類擁有用于創(chuàng)建混淆矩陣以及繪制分類錯誤的圖像的方法。

切記傳遞學(xué)習(xí)對象,學(xué)習(xí)對象知道兩件事,數(shù)據(jù)和模型
這里的模型不僅是體系結(jié)構(gòu),而且是經(jīng)過訓(xùn)練的帶有權(quán)重的模型。
我們需要解釋那個模型,我們傳入ClassificationInterpretation對象的學(xué)習(xí)者

繪制出loss最大的案例

通過如下代碼繪制

interp.plot_top_losses(9, figsize=(15,11))

后面將學(xué)習(xí)損失函數(shù),但是損失函數(shù)告訴你,你的預(yù)測和實際情況相比有多好。具體來說,如果你非常有信心的預(yù)測了一類狗,你說它是哈士奇,但是實際上它是中華田園犬,你對錯誤的答案非常有信心,所以損失會很大,因此通過繪制最大損失,我們將繪制出對預(yù)測最自信但錯誤的圖像。


所有的圖片的題目包含4個信息,分別是:預(yù)測類型,真實類型,loss(損失),真實類型概率

混淆矩陣

interp.plot_confusion_matrix(figsize=(12, 12), dpi=60)


它顯示了每一個實際類型的狗或貓,有多少時間模型預(yù)測的狗或貓。因為這一次非常準(zhǔn)確,它顯示了較暗的對角線,對于其他一些錯誤的組合使用了較亮的數(shù)字。如果你有很多類,不要使用混淆矩陣。相反,使用fastai的命名函數(shù)most_confused()。

interp.most_confused(min_val=2)

得到:

[('american_pit_bull_terrier', 'staffordshire_bull_terrier', 6),('Egyptian_Mau', 'Bengal', 5),('Bengal', 'Egyptian_Mau', 4),('Birman', 'Ragdoll', 3),('Ragdoll', 'Birman', 3),('Russian_Blue', 'British_Shorthair', 3),('Siamese', 'Birman', 3),('keeshond', 'leonberger', 3),('miniature_pinscher', 'chihuahua', 3),('staffordshire_bull_terrier', 'american_pit_bull_terrier', 3),('Abyssinian', 'Russian_Blue', 2),('Bengal', 'Abyssinian', 2),('British_Shorthair', 'Bombay', 2),('British_Shorthair', 'Russian_Blue', 2),('Maine_Coon', 'Ragdoll', 2),('Sphynx', 'chihuahua', 2),('american_bulldog', 'american_pit_bull_terrier', 2),('beagle', 'basset_hound', 2),('boxer', 'american_bulldog', 2),('english_cocker_spaniel', 'english_setter', 2),('yorkshire_terrier', 'havanese', 2),('yorkshire_terrier', 'scottish_terrier', 2)]

通過微調(diào)讓模型更加好

Unfreezing

到目前為止,我們已經(jīng)擬合了4個epoch,而且運行得相當(dāng)快。為什么會這樣?因為我們用了一個小技巧——遷移學(xué)習(xí)

我們在架構(gòu)的最后增加了少量額外的層,并且我們只訓(xùn)練那些層,我們保留了大部分早期的圖層,這稱為凍結(jié)層(freezing layers)

如果我們想構(gòu)建一個模型,這和原始的再訓(xùn)練模型非常相似,在本例中與imageNet數(shù)據(jù)集非常相似

我們應(yīng)該如何做?
返回并且重新訓(xùn)練模型,所以這就是為什么我們總是采用兩級訓(xùn)練過程:

  1. 當(dāng)我們在create_cnn函數(shù)中調(diào)用fit或者fit_one_cycle,它會很好地調(diào)整這些額外的層在最后,并運行得非常快。
  2. 它基本上不會過擬合,但是為了得到更好的模型,我們還是調(diào)用為好
learn.unfreeze()
learn.fit_one_cycle(1)

unfreeze()表明解放所有的參數(shù),重新訓(xùn)練整個模型,然后我們再一次調(diào)用fit_one_cycle(),但是我們得到的錯誤率非常糟糕,為什么會這樣?
為了弄清楚這個問題需要理解卷積神經(jīng)網(wǎng)絡(luò)背后發(fā)生了什么。
圖像有Red、Green、Blue三種顏色,數(shù)字范圍從0到255。這些值在第一層進(jìn)入簡單的計算,然后它的輸出進(jìn)入第二層的計算,其結(jié)果進(jìn)入第三層,以此類推。這些層可以達(dá)到神經(jīng)網(wǎng)絡(luò)的1000層。

  1. 第1層
    我們可以把這些具體的系數(shù)/參數(shù)畫成圖來形象化。
    可能會有幾十個這樣的過濾器,但是我們會看看隨機(jī)的9個過濾器。
    下面是9個實際系數(shù)或參數(shù)的例子

    它們對相鄰的一組像素進(jìn)行操作。
    第一行的第一列和第二列找出在任何方向上是否有一條對角線。
    第三列顯示它找到了從黃色到藍(lán)色的梯度反之亦然,在這些方向上也有從粉色到綠色的梯度等等。
    這是一個非常簡單的卷積它可以找到一些小的直線。
    這是Imagenet預(yù)訓(xùn)練卷積神經(jīng)網(wǎng)絡(luò)的第一層。

  2. 第2層
    獲取這些過濾器的結(jié)果并執(zhí)行第2層計算

    如果你看左下角最右邊的圖像,如果你看窗口的角,或者在第三列第二行圖像中它發(fā)現(xiàn)了右邊的曲線或者第二列第二行它學(xué)會了尋找小圓圈。
    如果在圖層1中我們可以找到一條直線,通過圖層2我們可以找到形狀。

    如果你在實際的照片中看到這9張圖片,它激活了這些過濾器。
    這個過濾器/數(shù)學(xué)函數(shù)很擅長找到窗口角之類的。

  3. 第3層
    可以找到線和形狀的組合。
    我們可以找到重復(fù)的二維物體或連接在一起的線的模式

    它在右下角找到了毛茸茸的東西的邊緣。
    還有左上角的幾何圖案。
    此外,我們還可以看到下面重復(fù)粘貼的文本有時窗口也激活了這些過濾器。

  4. 第4層
    從第三層中取出所有的東西,把它們組合在一起,發(fā)現(xiàn)了狗的臉或鳥的腿。

  5. 第5層
    它可以發(fā)現(xiàn)鳥類/蜥蜴的眼球,或者特定品種的狗的臉。

到34層的時候,它就會學(xué)會準(zhǔn)確地想象出一種帶有細(xì)節(jié)的貓或狗。
這就是它的工作原理。

現(xiàn)在我們在微調(diào)(fine-tuning)我們說讓我們改變所有這些。我們會讓他們留在原地,但讓我們看看是否能讓他們變得更好。

所以,如果我們能把第1層的功能做得更好,這是非常不可能的。相對于最初訓(xùn)練的Imagenet數(shù)據(jù),對于狗或貓的品種或任何類型的圖像,對角線的定義不太可能發(fā)生變化。

但最后一層是第5層。我們想要在我們的數(shù)據(jù)集中改變狗的臉。

因此,直觀地,你可以理解卷積神經(jīng)網(wǎng)絡(luò)的不同層代表不同層次的語義復(fù)雜性。

這就是為什么我們對這個網(wǎng)絡(luò)進(jìn)行微調(diào)的嘗試沒有像我們預(yù)期的那樣奏效。
默認(rèn)情況下,它以相同的速度訓(xùn)練所有層。所以它更新那些看起來像對角線或圓圈的東西就像它更新那些有特定的狗或貓品種的特定細(xì)節(jié)的東西一樣。所以我們必須改變這一點。

要改變這一點,我們需要回到以前的狀態(tài)。我們剛剛打破了這個模型。

fine-tuning

learning rates

參考

總結(jié)

以上是生活随笔為你收集整理的FastAI 课程学习笔记 lesson 1:宠物图片分类的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯,歡迎將生活随笔推薦給好友。