真实的国产乱ⅩXXX66竹夫人,五月香六月婷婷激情综合,亚洲日本VA一区二区三区,亚洲精品一区二区三区麻豆

成都創(chuàng)新互聯(lián)網(wǎng)站制作重慶分公司

如何使用pytorch完成kaggle貓狗圖像識別方式-創(chuàng)新互聯(lián)

這篇文章將為大家詳細講解有關(guān)如何使用pytorch完成kaggle貓狗圖像識別方式,小編覺得挺實用的,因此分享給大家做個參考,希望大家閱讀完這篇文章后可以有所收獲。

創(chuàng)新互聯(lián)專業(yè)為企業(yè)提供城關(guān)網(wǎng)站建設(shè)、城關(guān)做網(wǎng)站、城關(guān)網(wǎng)站設(shè)計、城關(guān)網(wǎng)站制作等企業(yè)網(wǎng)站建設(shè)、網(wǎng)頁設(shè)計與制作、城關(guān)企業(yè)網(wǎng)站模板建站服務(wù),10年城關(guān)做網(wǎng)站經(jīng)驗,不只是建網(wǎng)站,更提供有價值的思路和整體網(wǎng)絡(luò)服務(wù)。

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

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

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

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

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

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

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

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

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

如何使用pytorch完成kaggle貓狗圖像識別方式

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

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

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

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

一個正常的CNN項目所需要的庫還是蠻多的。

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))

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

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

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

CenterCrop用于從中心裁剪圖片,目標是一個長寬都為84的正方形,方便后續(xù)的計算。

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

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

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ù)雜的一步就是這里了。在這里,我們首先定義了一個Net類,它封裝了所以訓練的步驟,包括卷積、池化、激活以及全連接操作。

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

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

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

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

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

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

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

之前在學習的時候比較不理解的也是這一行,為什么是16 * 18 * 18呢?16很好理解,因為最后一次卷積生成的圖像矩陣的高度就是16層,那18 * 18是怎么來的呢?我們回過頭去看一行代碼

transforms.CenterCrop(84)

在這行代碼里我們把訓練圖像裁剪成一個84 * 84的正方形尺寸,所以圖像最早輸入就是一個3 * 84 * 84的數(shù)組。經(jīng)過第一次5 * 5的卷積之后,我們可以得出卷積的結(jié)果是一個6 * 80 * 80的矩陣,這里的80就是因為我們使用了一個5 * 5的過濾框,當它從左上角第一個元素開始卷積后,過濾框的中心是從2到78,并不是從0到79,所以結(jié)果就是一個80 * 80的圖像了。

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

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

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

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

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

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 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!

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

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))

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

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

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

關(guān)于“如何使用pytorch完成kaggle貓狗圖像識別方式”這篇文章就分享到這里了,希望以上內(nèi)容可以對大家有一定的幫助,使各位可以學到更多知識,如果覺得文章不錯,請把它分享出去讓更多的人看到。

另外有需要云服務(wù)器可以了解下創(chuàng)新互聯(lián)scvps.cn,海內(nèi)外云服務(wù)器15元起步,三天無理由+7*72小時售后在線,公司持有idc許可證,提供“云服務(wù)器、裸金屬服務(wù)器、高防服務(wù)器、香港服務(wù)器、美國服務(wù)器、虛擬主機、免備案服務(wù)器”等云主機租用服務(wù)以及企業(yè)上云的綜合解決方案,具有“安全穩(wěn)定、簡單易用、服務(wù)可用性高、性價比高”等特點與優(yōu)勢,專為企業(yè)上云打造定制,能夠滿足用戶豐富、多元化的應(yīng)用場景需求。


本文題目:如何使用pytorch完成kaggle貓狗圖像識別方式-創(chuàng)新互聯(lián)
本文地址:http://weahome.cn/article/dshoed.html

其他資訊

在線咨詢

微信咨詢

電話咨詢

028-86922220(工作日)

18980820575(7×24)

提交需求

返回頂部