Python Pytorch深度學(xué)習(xí)之圖像分類器
一、簡(jiǎn)介
通常,當(dāng)處理圖像、文本、語(yǔ)音或視頻數(shù)據(jù)時(shí),可以使用標(biāo)準(zhǔn)Python將數(shù)據(jù)加載到numpy數(shù)組格式,然后將這個(gè)數(shù)組轉(zhuǎn)換成torch.*Tensor
- 對(duì)于圖像,可以用Pillow,OpenCV
- 對(duì)于語(yǔ)音,可以用scipy,librosa
- 對(duì)于文本,可以直接用Python或Cython基礎(chǔ)數(shù)據(jù)加載模塊,或者用NLTK和SpaCy
特別是對(duì)于視覺(jué),Pytorch已經(jīng)創(chuàng)建了一個(gè)叫torchvision的package,該報(bào)包含了支持加載類似Imagenet,CIFAR10,MNIST等公共數(shù)據(jù)集的數(shù)據(jù)加載??靦orchvision.datasets和支持加載圖像數(shù)據(jù)數(shù)據(jù)轉(zhuǎn)換模塊torch.utils.data.DataLoader。這提供了極大地便利,并避免了編寫(xiě)“樣板代碼”
二、數(shù)據(jù)集
對(duì)于本小節(jié),使用CIFAR10數(shù)據(jù)集,它包含了是個(gè)類別:airplane,automobile,bird,cat,deer,dog,frog,horse,ship,truck。CIFAR10中的圖像尺寸是33232,也就是RGB的3層顏色通道,每層通道內(nèi)的尺寸為32*32
三、訓(xùn)練一個(gè)圖像分類器
訓(xùn)練圖像分類器的步驟:
- 使用torchvision加載并且歸一化CIFAR10的訓(xùn)練和測(cè)試數(shù)據(jù)集
- 定義一個(gè)卷積神經(jīng)網(wǎng)絡(luò)
- 定義一個(gè)損失函數(shù)
- 在訓(xùn)練樣本數(shù)據(jù)上訓(xùn)練網(wǎng)絡(luò)
- 在測(cè)試樣本數(shù)據(jù)上測(cè)試網(wǎng)絡(luò)
1、導(dǎo)入package吧
# 使用torchvision,加載并歸一化CIFAR10 import torch import torchvision import torchvision.transforms as transforms
2、歸一化處理+貼標(biāo)簽吧
# torchvision數(shù)據(jù)集的輸出是范圍在[0,1]之間的PILImage,將他們轉(zhuǎn)換成歸一化范圍為[-1,1]之間的張量Tensor transform=transforms.Compose( [transforms.ToTensor(), transforms.Normalize((0.5,0.5,0.5),(0.5,0.5,0.5))] ) # 訓(xùn)練集 trainset=torchvision.datasets.CIFAR10(root='./data',train=True,download=False,transform=transform) trainloader=torch.utils.data.DataLoader(trainset,batch_size=4,shuffle=True,num_workers=2) # 測(cè)試集 testset=torchvision.datasets.CIFAR10(root='./data',train=False,download=False,transform=transform) testloader=torch.utils.data.DataLoader(testset,batch_size=4,shuffle=False,num_workers=2) classes=("plane","car","bird","cat","deer","dog","frog","horse","ship","truck")
3、先來(lái)康康訓(xùn)練集中的照片吧
# 展示其中的訓(xùn)練照片 import matplotlib.pyplot as plt import numpy as np # 定義圖片顯示的function def imshow(img): img=img/2+0.5 npimg=img.numpy() plt.imshow(np.transpose(npimg,(1,2,0))) plt.show() # 得到隨機(jī)訓(xùn)練圖像 dataiter=iter(trainloader) images,labels=dataiter.next() # 展示圖片 imshow(torchvision.utils.make_grid(images)) #打印標(biāo)簽labels print(' '.join("%5s"%classes[labels[j]] for j in range(4)))
運(yùn)行結(jié)果
注:初學(xué)的猿仔們?nèi)绻鸖pyder不顯示圖片,自己設(shè)置一下就OK,在Tools——>Preferences中設(shè)置如下:
4、定義一個(gè)神經(jīng)網(wǎng)絡(luò)吧
此處,復(fù)制前一節(jié)的神經(jīng)網(wǎng)絡(luò)(在這里),并修改為3通道的圖片(之前定義的是1通道)
#%% # 定義卷積神經(jīng)網(wǎng)絡(luò) import torch.nn as nn import torch.nn.functional as F class Net(nn.Module): def __init__(self): super(Net,self).__init__() # 1個(gè)輸入,6個(gè)輸出,5*5的卷積 # 內(nèi)核 self.conv1=nn.Conv2d(3,6,5)#定義三個(gè)通道 self.pool=nn.MaxPool2d(2,2) self.conv2=nn.Conv2d(6,16,5) # 映射函數(shù):線性——y=Wx+b self.fc1=nn.Linear(16*5*5,120)#輸入特征值:16*5*5,輸出特征值:120 self.fc2=nn.Linear(120,84) self.fc3=nn.Linear(84,10) 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*5*5) x=F.relu(self.fc1(x)) x=F.relu(self.fc2(x)) x=self.fc3(x) return x net=Net()
Tips:在Spyder中可用使用“#%%”得到cell塊,之后對(duì)每個(gè)cell進(jìn)行運(yùn)行,快捷鍵(Ctrl+Enter)——>我太愛(ài)用快捷鍵了,無(wú)論是什么能用鍵盤(pán)堅(jiān)決不用鼠標(biāo)(是真的懶吧?。。。?/p>
5、定義一個(gè)損失函數(shù)和優(yōu)化器吧
使用分類交叉熵Cross-Entropy做損失函數(shù),動(dòng)量SGD做優(yōu)化器
#%% # 定義一個(gè)損失函數(shù)和優(yōu)化器 import torch.optim as optim criterion=nn.CrossEntropyLoss() optimizer=optim.SGD(net.parameters(), lr=0.001,momentum=0.9)
6、訓(xùn)練網(wǎng)絡(luò)吧
此處只需要在數(shù)據(jù)迭代器上循環(huán)輸入網(wǎng)絡(luò)和優(yōu)化器
#%%訓(xùn)練網(wǎng)絡(luò) for epoch in range(2): running_loss=0.0 for i,data in enumerate(trainloader,0): #得到輸入 inputs,labels=data # 將參數(shù)的梯度值置零 optimizer.zero_grad() #反向傳播+優(yōu)化 outputs=net(inputs) loss=criterion(outputs,labels) loss.backward() optimizer.step() #打印數(shù)據(jù) running_loss+=loss.item() if i% 2000==1999: print('[%d,%5d] loss: %.3f'%(epoch+1,i+1,running_loss/2000))#每2000個(gè)輸出一次 print('Finished Training')
運(yùn)行結(jié)果
7、在測(cè)試集上測(cè)試一下網(wǎng)絡(luò)吧
已經(jīng)通過(guò)訓(xùn)練數(shù)據(jù)集對(duì)網(wǎng)絡(luò)進(jìn)行了兩次訓(xùn)練,但是我們需要檢查是否已經(jīng)學(xué)到了東西。將使用神經(jīng)網(wǎng)絡(luò)的輸出作為預(yù)測(cè)的類標(biāo)來(lái)檢查網(wǎng)絡(luò)的預(yù)測(cè)性能,用樣本的真實(shí)類標(biāo)校對(duì),如過(guò)預(yù)測(cè)正確,將樣本添加到正確預(yù)測(cè)的列表中
#%% #在測(cè)試集上顯示 outputs=net(images) # 輸出是預(yù)測(cè)與十個(gè)類的相似程度,與某一個(gè)類的近似程度越高,網(wǎng)絡(luò)就越認(rèn)為圖像是屬于這一類別 # 打印其中最相似類別類標(biāo) _, predictd=torch.max(outputs,1) print('Predicted:',' '.join('%5s'% classes[predictd[j]] for j in range(4)))
運(yùn)行結(jié)果
把網(wǎng)絡(luò)放在整個(gè)數(shù)據(jù)集上看看具體表現(xiàn)
#%% 結(jié)果看起來(lái)還好55%,看看網(wǎng)絡(luò)在整個(gè)數(shù)據(jù)集的表現(xiàn) correct=0 total=0 with torch.no_grad(): for data in testloader: images,labels=data outputs=net(images) _, predicted = torch.max(outputs.data, 1) total += labels.size(0) correct += (predicted==labels).sum().item() print('Accuracy of the network on the 10000 test images:%d %%' % ( 100*correct/total))
運(yùn)行結(jié)果
8、分別查看一下訓(xùn)練效果吧
#%%分類查看 class_correct=list(0. for i in range(10)) class_total=list(0. for i in range(10)) with torch.no_grad(): for data in testloader: images,labels=data outputs=net(images) _, predictd=torch.max(outputs,1) c=(predictd==labels).squeeze() for i in range(4): label=labels[i] class_correct[label]+=c[i].item() class_total[label]+=1 for i in range(10): print('Accuracy of %5s:%2d %%'% (classes[i],100*class_correct[i]/class_total[i]))
運(yùn)行結(jié)果
總結(jié)
本篇文章就到這里了,希望能夠給你帶來(lái)幫助,也希望您能夠多多關(guān)注本站的更多內(nèi)容!
版權(quán)聲明:本站文章來(lái)源標(biāo)注為YINGSOO的內(nèi)容版權(quán)均為本站所有,歡迎引用、轉(zhuǎn)載,請(qǐng)保持原文完整并注明來(lái)源及原文鏈接。禁止復(fù)制或仿造本網(wǎng)站,禁止在非www.sddonglingsh.com所屬的服務(wù)器上建立鏡像,否則將依法追究法律責(zé)任。本站部分內(nèi)容來(lái)源于網(wǎng)友推薦、互聯(lián)網(wǎng)收集整理而來(lái),僅供學(xué)習(xí)參考,不代表本站立場(chǎng),如有內(nèi)容涉嫌侵權(quán),請(qǐng)聯(lián)系alex-e#qq.com處理。