感知器的c++实现_使用FastAI和PyTorch的多层感知器
我將向您展示如何使用FastAIv1和Pytorch構(gòu)建神經(jīng)網(wǎng)絡(luò)(多層感知器)并成功訓(xùn)練它以識別圖像中的數(shù)字。Pytorch是一個(gè)非常流行的深度學(xué)習(xí)框架,FastAI v1是一個(gè)使用現(xiàn)代最佳實(shí)踐簡化訓(xùn)練快速準(zhǔn)確的神經(jīng)網(wǎng)絡(luò)的庫。它基于對fast.ai進(jìn)行快速學(xué)習(xí)最佳實(shí)踐的研究,包括對視覺,文本,表格和協(xié)作(協(xié)作過濾)模型的支持。我會(huì)在本文最后貼出源代碼地址。
BoilerPlate命令
使用以下三行代碼可以確保對您所創(chuàng)建的庫的任何編輯都自動(dòng)重新加載,并且顯示的任何圖表或圖像都會(huì)顯示在此內(nèi)容中。
%reload_ext autoreload%autoreload 2%matplotlib inline導(dǎo)入Fast AI庫
讓我們導(dǎo)入fastai庫并將我們的batch_size參數(shù)定義為128。圖像數(shù)據(jù)庫是巨大的,所以我們需要使用批處理將這些圖像輸入GPU,批處理大小為128意味著我們將一次輸入128幅圖像來更新我們的深度學(xué)習(xí)模型的參數(shù)。如果由于GPU RAM較小而導(dǎo)致內(nèi)存不足,則可以將批處理大小減小到64或32。
from fastai.vision import *bs=128使用數(shù)據(jù)集
我們將從MNIST手寫數(shù)據(jù)集開始。MNIST是小型(28x28)手寫灰度數(shù)字的標(biāo)準(zhǔn)數(shù)據(jù)集,于20世紀(jì)90年代開發(fā),用于測試當(dāng)今最復(fù)雜的模型; 現(xiàn)在,經(jīng)常被用作介紹深度學(xué)習(xí)的基本“hello world”。此fast.ai數(shù)據(jù)集版本使用標(biāo)準(zhǔn)PNG格式而不是原始的特殊二進(jìn)制格式,以便您可以在大多數(shù)庫中使用常規(guī)數(shù)據(jù)路徑; 如果您只想使用與原始輸入通道相同的單個(gè)輸入通道,只需從通道軸中選取一部分即可。
path = untar_data(URLs.MNIST);path通過運(yùn)行上述命令,數(shù)據(jù)被下載并存儲(chǔ)在上面顯示的路徑中。讓我們看看如何設(shè)置數(shù)據(jù)目錄,因?yàn)槲覀儽仨殢倪@些目錄導(dǎo)入數(shù)據(jù)。讓我們從查看路徑目錄開始,我們可以看到下面的數(shù)據(jù)已經(jīng)有了訓(xùn)練和測試文件夾。
path.ls()讓我們看一下訓(xùn)練文件夾。數(shù)據(jù)在不同的文件夾中按數(shù)字1到9分離出來。
(path/'training').ls()在每個(gè)數(shù)字文件夾中,我們還有圖像。
(path/'training/0').ls()[1:5]導(dǎo)入數(shù)據(jù)
現(xiàn)在我們了解了如何設(shè)置數(shù)據(jù)目錄; 我們將使用FastAI 的data block API導(dǎo)入數(shù)據(jù)和FastAI image transform函數(shù)來進(jìn)行數(shù)據(jù)擴(kuò)充。
ds_tfms = get_transforms(do_flip=False, flip_vert=False, max_rotate= 15,max_zoom=1.1, max_lighting=0.2, max_warp=0.2)在get_transforms函數(shù)中,我們可以定義我們想要做的所有轉(zhuǎn)換。FastAI使得數(shù)據(jù)增強(qiáng)非常容易,因?yàn)樗修D(zhuǎn)換都可以在一個(gè)函數(shù)中傳遞并使用非常快速的實(shí)現(xiàn)。函數(shù)中給出的每個(gè)參數(shù):
- do_flip = False,flip_vert = False:不允許在垂直和水平方向上翻轉(zhuǎn)數(shù)字。
- max_rotate = 15:設(shè)置在順時(shí)針和逆時(shí)針方向上導(dǎo)入圖像時(shí)最多隨機(jī)旋轉(zhuǎn)15度。
- max_zoom = 1.1:設(shè)置放大/縮小原始圖像的尺寸不超過10%
- max_lighting = 0.2:設(shè)置將應(yīng)用由max_lighting控制的隨機(jī)閃光和對比度變化
- max_warp = 0.2:在-max_warp和+ max_warp之間的隨機(jī)對稱扭曲應(yīng)用概率p_affine,在這種情況下默認(rèn)為0.75。
現(xiàn)在我們已經(jīng)定義了我們想要對輸入圖像做什么轉(zhuǎn)換,讓我們從定義數(shù)據(jù)批處理或databunch (FastAI將其稱為databunch)開始。因?yàn)閳D像數(shù)據(jù)集的數(shù)據(jù)量很大,所以盡量不在內(nèi)存中導(dǎo)入整個(gè)數(shù)據(jù)集,而是我們一個(gè)databunch,它允許我們加載批量數(shù)據(jù)并動(dòng)態(tài)執(zhí)行所需的轉(zhuǎn)換。
data = (ImageItemList.from_folder(path, convert_mode='L') .split_by_folder(train='training', valid='testing') .label_from_folder() .transform(tfms=ds_tfms, size=28) .databunch(bs=bs))Jeremy Howard將上述步驟稱為標(biāo)簽工程,因?yàn)榇蟛糠謺r(shí)間和精力花在正確導(dǎo)入數(shù)據(jù)上。FastAI的data block API使我們可以非常容易地定義我們想要如何使用R ggplots (如API)來導(dǎo)入我們的數(shù)據(jù),可以一直鏈接不同的函數(shù),直到數(shù)據(jù)集準(zhǔn)備好為止。讓我們理解上面的代碼在做什么 -
- ImageItemList.from_folder(path,convert_mode ='L') - 在帶有文件名后綴擴(kuò)展名的文件夾中創(chuàng)建ItemList。Convert_mode ='L'幫助我們定義我們導(dǎo)入的圖像是灰度/單通道圖像默認(rèn)為'RGB',這意味著一個(gè)3通道圖像。FastAI使用PIL庫,所以convert實(shí)際上是PIL函數(shù)
- split_by_folder(train ='training',valid ='testing'):這個(gè)函數(shù)告訴數(shù)據(jù)庫我們在Path目錄的'training'和'testing'子文件夾中有訓(xùn)練和測試數(shù)據(jù)
- label_from_folder() - 此函數(shù)通知databunch從其文件夾名稱中獲取數(shù)字標(biāo)簽
- transform(tfms = ds_tfms,size = 28) - 此函數(shù)通知databunch將ds_tfms變量中定義的轉(zhuǎn)換應(yīng)用于每個(gè)圖像
- databunch(bs = bs) - 此函數(shù)將此數(shù)據(jù)庫轉(zhuǎn)換為FastAI的ImageDataBunch類,批量大小在bs變量中定義,本例中為128。
現(xiàn)在我們已經(jīng)定義了我們的databunch,現(xiàn)在可以看看我們的數(shù)據(jù)。如下所示,您可以看到數(shù)字是使用show_batch函數(shù)導(dǎo)入和可視化,這些圖像已應(yīng)用了我們定義的轉(zhuǎn)換。
print(data.classes) ## Prints class labelsprint(data.c) ## Prints number of classesdata.show_batch(rows=3, figsize=(10,6), hide_axis=False) ## Show sample data使用Pytorch定義多層感知器
現(xiàn)在我們已經(jīng)定義了我們的databunch。讓我們使用Pytorch定義我們的Multilayer感知器模型。對于完全連接的層,我們使用nn.Linear函數(shù),我們使用ReLU轉(zhuǎn)換應(yīng)用于非線性。在Pytorch中,我們只需要定義前向函數(shù),并使用autograd自動(dòng)定義后向函數(shù)。
class Mnist_NN(nn.Module): def __init__(self): super().__init__() self.lin1 = nn.Linear(784, 512, bias=True) self.lin2 = nn.Linear(512, 256, bias=True) self.lin3 = nn.Linear(256, 10, bias=True) def forward(self, xb): x = xb.view(-1,784) x = F.relu(self.lin1(x)) x = F.relu(self.lin2(x)) return self.lin3(x)訓(xùn)練模型
現(xiàn)在我們已經(jīng)定義了我們的模型,我們需要訓(xùn)練它。我們可以使用FastAI的Learner函數(shù),它可以更輕松地利用現(xiàn)代增強(qiáng)優(yōu)化方法和許多其他巧妙的技巧,如1-Cycle樣式的訓(xùn)練。
現(xiàn)在定義Learner類
## Defining the learnermlp_learner = Learner(data=data, model=Mnist_NN(), loss_func=nn.CrossEntropyLoss(),metrics=accuracy)解釋一下我們做了什么:
- data = data - 傳遞Databunch函數(shù)
- model = Mnist_NN() - 傳遞我們定義的MLP模型Mnist_NN
- loss_func = nn.CrossEntropyLoss() - 定義優(yōu)化損失函數(shù),在本例中我們使用交叉熵?fù)p失函數(shù)。
- metrics =準(zhǔn)確度 - 這只是為了在訓(xùn)練時(shí)進(jìn)行輸出。
我們可以試著在訓(xùn)練深度學(xué)習(xí)模型時(shí)找到理想的學(xué)習(xí)速率。
## Finidng Ideal learning latemlp_learner.lr_find()mlp_learner.recorder.plot()理想情況下,我們要找到斜率最大的點(diǎn)。在這種情況下,該點(diǎn)是1e-2。因此,我們將開始從1e-2作為我們的學(xué)習(xí)率,并使用fit_one_cycle函數(shù)開始五個(gè)訓(xùn)練周期,該函數(shù)使用1-Cycle樣式訓(xùn)練方法。此外,FastAI 在訓(xùn)練時(shí)顯示tqdm樣式進(jìn)度條,在訓(xùn)練結(jié)束時(shí),它開始顯示我們在驗(yàn)證數(shù)據(jù)上定義的損失函數(shù)和指標(biāo)的進(jìn)度。
mlp_learner.fit_one_cycle(5,1e-2)通過降低學(xué)習(xí)速率來對模型進(jìn)行更多的訓(xùn)練。
mlp_learner.fit_one_cycle(5,1e-3)mlp_learner.recorder.plot_losses()我們可以看到,通過使用簡單的多層感知器,我們的準(zhǔn)確率達(dá)到了98.6%。
結(jié)論
Fast.ai是Jeremy Howard和他的團(tuán)隊(duì)的一項(xiàng)出色的倡議,我相信fastai庫可以通過使構(gòu)建深度學(xué)習(xí)模型變得非常簡單,真正實(shí)現(xiàn)將深度學(xué)習(xí)大眾化,讓每個(gè)人都可以建造自己的深度學(xué)習(xí)模型。
總結(jié)
以上是生活随笔為你收集整理的感知器的c++实现_使用FastAI和PyTorch的多层感知器的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: zabbix监控mysql的哪些参数_C
- 下一篇: mysql 按月统计 包括空月_mysq