国产片侵犯亲女视频播放_亚洲精品二区_在线免费国产视频_欧美精品一区二区三区在线_少妇久久久_在线观看av不卡

腳本之家,腳本語(yǔ)言編程技術(shù)及教程分享平臺(tái)!
分類導(dǎo)航

Python|VBS|Ruby|Lua|perl|VBA|Golang|PowerShell|Erlang|autoit|Dos|bat|

服務(wù)器之家 - 腳本之家 - Python - 使用pytorch完成kaggle貓狗圖像識(shí)別方式

使用pytorch完成kaggle貓狗圖像識(shí)別方式

2020-04-28 09:38charsenhz Python

今天小編就為大家分享一篇使用pytorch完成kaggle貓狗圖像識(shí)別方式,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過(guò)來(lái)看看吧

kaggle是一個(gè)為開(kāi)發(fā)商和數(shù)據(jù)科學(xué)家提供舉辦機(jī)器學(xué)習(xí)競(jìng)賽、托管數(shù)據(jù)庫(kù)、編寫(xiě)和分享代碼的平臺(tái),在這上面有非常多的好項(xiàng)目、好資源可供機(jī)器學(xué)習(xí)、深度學(xué)習(xí)愛(ài)好者學(xué)習(xí)之用。

碰巧最近入門(mén)了一門(mén)非常的深度學(xué)習(xí)框架:pytorch,所以今天我和大家一起用pytorch實(shí)現(xiàn)一個(gè)圖像識(shí)別領(lǐng)域的入門(mén)項(xiàng)目:貓狗圖像識(shí)別。

深度學(xué)習(xí)的基礎(chǔ)就是數(shù)據(jù),咱們先從數(shù)據(jù)談起。此次使用的貓狗分類圖像一共25000張,貓狗分別有12500張,我們先來(lái)簡(jiǎn)單的瞅瞅都是一些什么圖片。

我們從下載文件里可以看到有兩個(gè)文件夾:train和test,分別用于訓(xùn)練和測(cè)試。以train為例,打開(kāi)文件夾可以看到非常多的小貓圖片,圖片名字從0.jpg一直編碼到9999.jpg,一共有10000張圖片用于訓(xùn)練。

而test中的小貓只有2500張。仔細(xì)看小貓,可以發(fā)現(xiàn)它們姿態(tài)不一,有的站著,有的瞇著眼睛,有的甚至和其他可識(shí)別物體比如桶、人混在一起。

同時(shí),小貓們的圖片尺寸也不一致,有的是豎放的長(zhǎng)方形,有的是橫放的長(zhǎng)方形,但我們最終需要是合理尺寸的正方形。小狗的圖片也類似,在這里就不重復(fù)了。

緊接著我們了解一下特別適用于圖像識(shí)別領(lǐng)域的神經(jīng)網(wǎng)絡(luò):卷積神經(jīng)網(wǎng)絡(luò)。學(xué)習(xí)過(guò)神經(jīng)網(wǎng)絡(luò)的同學(xué)可能或多或少地聽(tīng)說(shuō)過(guò)卷積神經(jīng)網(wǎng)絡(luò)。這是一種典型的多層神經(jīng)網(wǎng)絡(luò),擅長(zhǎng)處理圖像特別是大圖像的相關(guān)機(jī)器學(xué)習(xí)問(wèn)題。

卷積神經(jīng)網(wǎng)絡(luò)通過(guò)一系列的方法,成功地將大數(shù)據(jù)量的圖像識(shí)別問(wèn)題不斷降維,最終使其能夠被訓(xùn)練。CNN最早由Yann LeCun提出并應(yīng)用在手寫(xiě)體識(shí)別上。

一個(gè)典型的CNN網(wǎng)絡(luò)架構(gòu)如下:

使用pytorch完成kaggle貓狗圖像識(shí)別方式

這是一個(gè)典型的CNN架構(gòu),由卷基層、池化層、全連接層組合而成。其中卷基層與池化層配合,組成多個(gè)卷積組,逐層提取特征,最終完成分類。

聽(tīng)到上述一連串的術(shù)語(yǔ)如果你有點(diǎn)蒙了,也別怕,因?yàn)檫@些復(fù)雜、抽象的技術(shù)都已經(jīng)在pytorch中一一實(shí)現(xiàn),我們要做的不過(guò)是正確的調(diào)用相關(guān)函數(shù),

我在粘貼代碼后都會(huì)做更詳細(xì)、易懂的解釋。

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
import os
import shutil
import torch
import collections
from torchvision import transforms,datasets
from __future__ import print_function, division
import os
import torch
import pylab
import pandas as pd
import torch.nn as nn
import torch.nn.functional as F
from torch.autograd import Variable
from skimage import io, transform
import numpy as np
import matplotlib.pyplot as plt
from torch.utils.data import Dataset, DataLoader
from torchvision import transforms, utils
 
# Ignore warnings
import warnings
warnings.filterwarnings("ignore")
 
plt.ion() # interactive mode

一個(gè)正常的CNN項(xiàng)目所需要的庫(kù)還是蠻多的。

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
import math
from PIL import Image
 
class Resize(object):
 """Resize the input PIL Image to the given size.
 Args:
 size (sequence or int): Desired output size. If size is a sequence like
  (h, w), output size will be matched to this. If size is an int,
  smaller edge of the image will be matched to this number.
  i.e, if height > width, then image will be rescaled to
  (size * height / width, size)
 interpolation (int, optional): Desired interpolation. Default is
  ``PIL.Image.BILINEAR``
 """
 
 def __init__(self, size, interpolation=Image.BILINEAR):
 # assert isinstance(size, int) or (isinstance(size, collections.Iterable) and len(size) == 2)
 self.size = size
 self.interpolation = interpolation
 
 def __call__(self, img):
 w,h = img.size
 
 min_edge = min(img.size)
 rate = min_edge / self.size
 
 new_w = math.ceil(w / rate)
 new_h = math.ceil(h / rate)
 
 return img.resize((new_w,new_h))

這個(gè)稱為Resize的庫(kù)用于給圖像進(jìn)行縮放操作,本來(lái)是不需要親自定義的,因?yàn)閠ransforms.Resize已經(jīng)實(shí)現(xiàn)這個(gè)功能了,但是由于目前還未知的原因,我的庫(kù)里沒(méi)有提供這個(gè)函數(shù),所以我需要親自實(shí)現(xiàn)用來(lái)代替transforms.Resize。

如果你的torch里面已經(jīng)有了這個(gè)Resize函數(shù)就不用像我這樣了。

?
1
2
3
4
5
6
7
8
9
10
11
12
data_transform = transforms.Compose([
 Resize(84),
 transforms.CenterCrop(84),
 transforms.ToTensor(),
 transforms.Normalize(mean = [0.5,0.5,0.5],std = [0.5,0.5,0.5])
])
 
train_dataset = datasets.ImageFolder(root = 'train/',transform = data_transform)
train_loader = torch.utils.data.DataLoader(train_dataset,batch_size = 4,shuffle = True,num_workers = 4)
 
test_dataset = datasets.ImageFolder(root = 'test/',transform = data_transform)
test_loader = torch.utils.data.DataLoader(test_dataset,batch_size = 4,shuffle = True,num_workers = 4)

transforms是一個(gè)提供針對(duì)數(shù)據(jù)(這里指的是圖像)進(jìn)行轉(zhuǎn)化的操作庫(kù),Resize就是上上段代碼提供的那個(gè)類,主要用于把一張圖片縮放到某個(gè)尺寸,在這里我們把需求暫定為要把圖像縮放到84 x 84這個(gè)級(jí)別,這個(gè)就是可供調(diào)整的參數(shù),大家為部署好項(xiàng)目以后可以試著修改這個(gè)參數(shù),比如改成200 x 200,你就發(fā)現(xiàn)你可以去玩一盤(pán)游戲了~_~。

CenterCrop用于從中心裁剪圖片,目標(biāo)是一個(gè)長(zhǎng)寬都為84的正方形,方便后續(xù)的計(jì)算。

ToTenser()就比較重要了,這個(gè)函數(shù)的目的就是讀取圖片像素并且轉(zhuǎn)化為0-1的數(shù)字。

Normalize作為墊底的一步也很關(guān)鍵,主要用于把圖片數(shù)據(jù)集的數(shù)值轉(zhuǎn)化為標(biāo)準(zhǔn)差和均值都為0.5的數(shù)據(jù)集,這樣數(shù)據(jù)值就從原來(lái)的0到1轉(zhuǎn)變?yōu)?1到1。

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
class Net(nn.Module):
 def __init__(self):
 super(Net,self).__init__()
 
 self.conv1 = nn.Conv2d(3,6,5)
 self.pool = nn.MaxPool2d(2,2)
 self.conv2 = nn.Conv2d(6,16,5)
 self.fc1 = nn.Linear(16 * 18 * 18,800)
 self.fc2 = nn.Linear(800,120)
 self.fc3 = nn.Linear(120,2)
 
 def forward(self,x):
 x = self.pool(F.relu(self.conv1(x)))
 x = self.pool(F.relu(self.conv2(x)))
 x = x.view(-1,16 * 18 * 18)
 x = F.relu(self.fc1(x))
 x = F.relu(self.fc2(x))
 x = self.fc3(x)
 
 return x
 
net = Net()

好了,最復(fù)雜的一步就是這里了。在這里,我們首先定義了一個(gè)Net類,它封裝了所以訓(xùn)練的步驟,包括卷積、池化、激活以及全連接操作。

__init__函數(shù)首先定義了所需要的所有函數(shù),這些函數(shù)都會(huì)在forward中調(diào)用。我們從conv1說(shuō)起。conv1實(shí)際上就是定義一個(gè)卷積層,3,6,5分別是什么意思?

3代表的是輸入圖像的像素?cái)?shù)組的層數(shù),一般來(lái)說(shuō)就是你輸入的圖像的通道數(shù),比如這里使用的小貓圖像都是彩色圖像,由R、G、B三個(gè)通道組成,所以數(shù)值為3;6代表的是我們希望進(jìn)行6次卷積,每一次卷積都能生成不同的特征映射數(shù)組,用于提取小貓和小狗的6種特征。

每一個(gè)特征映射結(jié)果最終都會(huì)被堆疊在一起形成一個(gè)圖像輸出,再作為下一步的輸入;5就是過(guò)濾框架的尺寸,表示我們希望用一個(gè)5 * 5的矩陣去和圖像中相同尺寸的矩陣進(jìn)行點(diǎn)乘再相加,形成一個(gè)值。

定義好了卷基層,我們接著定義池化層。池化層所做的事說(shuō)來(lái)簡(jiǎn)單,其實(shí)就是因?yàn)榇髨D片生成的像素矩陣實(shí)在太大了,我們需要用一個(gè)合理的方法在降維的同時(shí)又不失去物體特征,所以深度學(xué)習(xí)學(xué)者們想出了一個(gè)稱為池化的技術(shù),說(shuō)白了就是從左上角開(kāi)始,每四個(gè)元素(2 * 2)合并成一個(gè)元素,用這一個(gè)元素去代表四個(gè)元素的值,所以圖像體積一下子降為原來(lái)的四分之一。

再往下一行,我們又一次碰見(jiàn)了一個(gè)卷基層:conv2,和conv1一樣,它的輸入也是一個(gè)多層像素?cái)?shù)組,輸出也是一個(gè)多層像素?cái)?shù)組,不同的是這一次完成的計(jì)算量更大了,我們看這里面的參數(shù)分別是6,16,5。

之所以為6是因?yàn)閏onv1的輸出層數(shù)為6,所以這里輸入的層數(shù)就是6;16代表conv2的輸出層數(shù),和conv1一樣,16代表著這一次卷積操作將會(huì)學(xué)習(xí)小貓小狗的16種映射特征,特征越多理論上能學(xué)習(xí)的效果就越好,大家可以嘗試一下別的值,看看效果是否真的編變好。

conv2使用的過(guò)濾框尺寸和conv1一樣,所以不再重復(fù)。最后三行代碼都是用于定義全連接網(wǎng)絡(luò)的,接觸過(guò)神經(jīng)網(wǎng)絡(luò)的應(yīng)該就不再陌生了,主要是需要解釋一下fc1。

之前在學(xué)習(xí)的時(shí)候比較不理解的也是這一行,為什么是16 * 18 * 18呢?16很好理解,因?yàn)樽詈笠淮尉矸e生成的圖像矩陣的高度就是16層,那18 * 18是怎么來(lái)的呢?我們回過(guò)頭去看一行代碼

?
1
transforms.CenterCrop(84)

在這行代碼里我們把訓(xùn)練圖像裁剪成一個(gè)84 * 84的正方形尺寸,所以圖像最早輸入就是一個(gè)3 * 84 * 84的數(shù)組。經(jīng)過(guò)第一次5 * 5的卷積之后,我們可以得出卷積的結(jié)果是一個(gè)6 * 80 * 80的矩陣,這里的80就是因?yàn)槲覀兪褂昧艘粋€(gè)5 * 5的過(guò)濾框,當(dāng)它從左上角第一個(gè)元素開(kāi)始卷積后,過(guò)濾框的中心是從2到78,并不是從0到79,所以結(jié)果就是一個(gè)80 * 80的圖像了。

經(jīng)過(guò)一個(gè)池化層之后,圖像尺寸的寬和高都分別縮小到原來(lái)的1/2,所以變成40 * 40。

緊接著又進(jìn)行了一次卷積,和上一次一樣,長(zhǎng)寬都減掉4,變成36 * 36,然后應(yīng)用了最后一層的池化,最終尺寸就是18 * 18。

所以第一層全連接層的輸入數(shù)據(jù)的尺寸是16 * 18 * 18。三個(gè)全連接層所做的事很類似,就是不斷訓(xùn)練,最后輸出一個(gè)二分類數(shù)值。

net類的forward函數(shù)表示前向計(jì)算的整個(gè)過(guò)程。forward接受一個(gè)input,返回一個(gè)網(wǎng)絡(luò)輸出值,中間的過(guò)程就是一個(gè)調(diào)用init函數(shù)中定義的層的過(guò)程。

F.relu是一個(gè)激活函數(shù),把所有的非零值轉(zhuǎn)化成零值。此次圖像識(shí)別的最后關(guān)鍵一步就是真正的循環(huán)訓(xùn)練操作。

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
import torch.optim as optim
 
cirterion = nn.CrossEntropyLoss()
optimizer = optim.SGD(net.parameters(),lr = 0.0001,momentum = 0.9)
 
for epoch in range(3):
 running_loss = 0.0
 
 for i,data in enumerate(train_loader,0):
 inputs,labels = data
 inputs,labels = Variable(inputs),Variable(labels)
 optimizer.zero_grad()
 outputs = net(inputs)
 loss = cirterion(outputs,labels)
 loss.backward()
 optimizer.step()
 
 running_loss += loss.data[0]
 
 if i % 2000 == 1999:
  print('[%d %5d] loss: %.3f' % (epoch + 1,i + 1,running_loss / 2000))
  running_loss = 0.0
 
print('finished training!')
?
1
2
3
4
5
6
7
[1 2000] loss: 0.691
[1 4000] loss: 0.687
[2 2000] loss: 0.671
[2 4000] loss: 0.657
[3 2000] loss: 0.628
[3 4000] loss: 0.626
finished training!

在這里我們進(jìn)行了三次訓(xùn)練,每次訓(xùn)練都是批量獲取train_loader中的訓(xùn)練數(shù)據(jù)、梯度清零、計(jì)算輸出值、計(jì)算誤差、反向傳播并修正模型。我們以每2000次計(jì)算的平均誤差作為觀察值。可以看到每次訓(xùn)練,誤差值都在不斷變小,逐漸學(xué)習(xí)如何分類圖像。代碼相對(duì)性易懂,這里就不再贅述了。

?
1
2
3
4
5
6
7
8
9
10
11
correct = 0
total = 0
 
for data in test_loader:
 images,labels = data
 outputs = net(Variable(images))
 _,predicted = torch.max(outputs.data,1)
 total += labels.size(0)
 correct += (predicted == labels).sum()
 
print('Accuracy of the network on the 5000 test images: %d %%' % (100 * correct / total))

終于來(lái)到模型準(zhǔn)確度驗(yàn)證了,這也是開(kāi)篇提到的test文件夾的用途之所在。程序到這一步時(shí),net是一個(gè)已經(jīng)訓(xùn)練好的神經(jīng)網(wǎng)絡(luò)了。傳入一個(gè)images矩陣,它會(huì)輸出相應(yīng)的分類值,我們拿到這個(gè)分類值與真實(shí)值做一個(gè)比較計(jì)算,就可以獲得準(zhǔn)確率。在我的計(jì)算機(jī)上當(dāng)前準(zhǔn)確率是66%,在你的機(jī)器上可能值有所不同但不會(huì)相差太大。

最后我們做一個(gè)小總結(jié)。在pytorch中實(shí)現(xiàn)CNN其實(shí)并不復(fù)雜,理論性的底層都已經(jīng)完成封裝,我們只需要調(diào)用正確的函數(shù)即可。當(dāng)前模型中的各個(gè)參數(shù)都沒(méi)有達(dá)到相對(duì)完美的狀態(tài),有興趣的小伙伴可以多調(diào)整參數(shù)跑幾次,訓(xùn)練結(jié)果不出意外會(huì)越來(lái)越好。

另外,由于在一篇文章中既要闡述CNN,又要貼項(xiàng)目代碼會(huì)顯得沒(méi)有重點(diǎn),我就沒(méi)有兩件事同時(shí)做,因?yàn)榫W(wǎng)上已經(jīng)有很多很好的解釋CNN的文章了,如果看了代碼依然是滿頭霧水的小伙伴可以先去搜關(guān)于CNN的文章,再回過(guò)頭來(lái)看項(xiàng)目代碼應(yīng)該會(huì)更加清晰。

第一次寫(xiě)關(guān)于自己的神經(jīng)網(wǎng)絡(luò)方面的文章,如有寫(xiě)得不好的地方請(qǐng)大家多多見(jiàn)諒。

以上這篇使用pytorch完成kaggle貓狗圖像識(shí)別方式就是小編分享給大家的全部?jī)?nèi)容了,希望能給大家一個(gè)參考,也希望大家多多支持服務(wù)器之家。

原文鏈接:https://blog.csdn.net/xcszjjh1991/article/details/79256576

延伸 · 閱讀

精彩推薦
主站蜘蛛池模板: 精品国产子伦久久久久久小说 | 97在线观看视频 | 懂色av一区二区三区免费观看 | 真实国产露脸乱 | 韩国成人精品a∨在线观看 欧美精品综合 | 亚洲狼人 | hh99me在线观看 | 日韩精品专区 | 中文字幕在线视频一区 | 久久久久久99 | 中文字幕一区二区三区精彩视频 | 久久九九这里只有精品 | 国产精品中文字幕在线观看 | 精品一区二区三区在线观看 | 久久久麻豆 | 欧洲精品视频在线观看 | 欧美成人专区 | 国内美女人妻一级毛片免费看 | 久久国产精品视频 | 亚洲欧美日韩成人 | 国产一区二区精品在线观看 | 日日干夜夜骑 | 黄色在线免费看 | 精品一区二区在线观看 | 亚洲精品系列 | 欧美精品在线视频 | 国产精品中文字幕在线观看 | 国产白浆在线观看 | 黄色tv在线观看 | 99精品99 | 日韩一区二区影视 | 日韩三级高清 | 久久五月视频 | 国产一级一级特黄女人精品毛片 | 精品亚洲国产成av人片传媒 | 亚洲综合二区 | 久久精品免费观看 | 亚洲日本va中文字幕 | 99精品国产一区二区青青牛奶 | 亚洲毛片在线观看 | 中文字幕在线第一页 |