深度學習Pytorch(四)——影像分類器
文章目錄
- 深度學習Pytorch(四)——影像分類器
- 一、簡介
- 二、資料集
- 三、訓練一個影像分類器
- 1、匯入package吧
- 2、歸一化處理+貼標簽吧
- 3、先來康康訓練集中的照片吧
- 4、定義一個神經網路吧
- 5、定義一個損失函式和優化器吧
- 6、訓練網路吧
- 7、在測驗集上測驗一下網路吧
- 8、分別查看一下訓練效果吧
一、簡介
通常,當處理影像、文本、語音或視頻資料時,可以使用標準Python將資料加載到numpy陣列格式,然后將這個陣列轉換成torch.*Tensor
- 對于影像,可以用Pillow,OpenCV
- 對于語音,可以用scipy,librosa
- 對于文本,可以直接用Python或Cython基礎資料加載模塊,或者用NLTK和SpaCy
特別是對于視覺,Pytorch已經創建了一個叫torchvision的package,該報包含了支持加載類似Imagenet,CIFAR10,MNIST等公共資料集的資料加載模快torchvision.datasets和支持加載影像資料資料轉換模塊torch.utils.data.DataLoader,這提供了極大地便利,并避免了撰寫“樣板代碼”
二、資料集
對于本小節,使用CIFAR10資料集,它包含了是個類別:airplane,automobile,bird,cat,deer,dog,frog,horse,ship,truck,CIFAR10中的影像尺寸是33232,也就是RGB的3層顏色通道,每層通道內的尺寸為32*32
三、訓練一個影像分類器
訓練影像分類器的步驟:
- 使用torchvision加載并且歸一化CIFAR10的訓練和測驗資料集
- 定義一個卷積神經網路
- 定義一個損失函式
- 在訓練樣本資料上訓練網路
- 在測驗樣本資料上測驗網路
1、匯入package吧
# 使用torchvision,加載并歸一化CIFAR10
import torch
import torchvision
import torchvision.transforms as transforms
2、歸一化處理+貼標簽吧
# torchvision資料集的輸出是范圍在[0,1]之間的PILImage,將他們轉換成歸一化范圍為[-1,1]之間的張量Tensor
transform=transforms.Compose(
[transforms.ToTensor(),
transforms.Normalize((0.5,0.5,0.5),(0.5,0.5,0.5))]
)
# 訓練集
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)
# 測驗集
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、先來康康訓練集中的照片吧
# 展示其中的訓練照片
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()
# 得到隨機訓練影像
dataiter=iter(trainloader)
images,labels=dataiter.next()
# 展示圖片
imshow(torchvision.utils.make_grid(images))
#列印標簽labels
print(' '.join("%5s"%classes[labels[j]] for j in range(4)))
運行結果


注:初學的猿仔們如果Spyder不顯示圖片,自己設定一下就OK,在Tools——>Preferences中設定如下:

4、定義一個神經網路吧
此處,復制前一節的神經網路(在這里),并修改為3通道的圖片(之前定義的是1通道)
#%%
# 定義卷積神經網路
import torch.nn as nn
import torch.nn.functional as F
class Net(nn.Module):
def __init__(self):
super(Net,self).__init__()
# 1個輸入,6個輸出,5*5的卷積
# 內核
self.conv1=nn.Conv2d(3,6,5)#定義三個通道
self.pool=nn.MaxPool2d(2,2)
self.conv2=nn.Conv2d(6,16,5)
# 映射函式:線性——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塊,之后對每個cell進行運行,快捷鍵(Ctrl+Enter)——>我太愛用快捷鍵了,無論是什么能用鍵盤堅決不用滑鼠(是真的懶吧!!!)
5、定義一個損失函式和優化器吧
使用分類交叉熵Cross-Entropy做損失函式,動量SGD做優化器
#%%
# 定義一個損失函式和優化器
import torch.optim as optim
criterion=nn.CrossEntropyLoss()
optimizer=optim.SGD(net.parameters(), lr=0.001,momentum=0.9)
6、訓練網路吧
此處只需要在資料迭代器上回圈輸入網路和優化器
#%%訓練網路
for epoch in range(2):
running_loss=0.0
for i,data in enumerate(trainloader,0):
#得到輸入
inputs,labels=data
# 將引數的梯度值置零
optimizer.zero_grad()
#反向傳播+優化
outputs=net(inputs)
loss=criterion(outputs,labels)
loss.backward()
optimizer.step()
#列印資料
running_loss+=loss.item()
if i% 2000==1999:
print('[%d,%5d] loss: %.3f'%(epoch+1,i+1,running_loss/2000))#每2000個輸出一次
print('Finished Training')
運行結果

7、在測驗集上測驗一下網路吧
已經通過訓練資料集對網路進行了兩次訓練,但是我們需要檢查是否已經學到了東西,將使用神經網路的輸出作為預測的類標來檢查網路的預測性能,用樣本的真實類標校對,如過預測正確,將樣本添加到正確預測的串列中
#%%
#在測驗集上顯示
outputs=net(images)
# 輸出是預測與十個類的相似程度,與某一個類的近似程度越高,網路就越認為影像是屬于這一類別
# 列印其中最相似類別類標
_, predictd=torch.max(outputs,1)
print('Predicted:',' '.join('%5s'% classes[predictd[j]]
for j in range(4)))
運行結果

把網路放在整個資料集上看看具體表現
#%% 結果看起來還好55%,看看網路在整個資料集的表現
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))
運行結果

8、分別查看一下訓練效果吧
#%%分類查看
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]))
運行結果

今日告一段落,明天見!(等,明天早上有課,不知道有沒有空,盡量見!嘻嘻嘻)
轉載請註明出處,本文鏈接:https://www.uj5u.com/qita/337600.html
標籤:AI
下一篇:新手必須要注意的編程范式
