pytorch卷積神經網路訓練
關于卷積神經網路(CNN)的基礎知識此處就不再多說,詳細的資料參考我在CSDN的說明
CNN卷積神經網路原理流程整理
以下是一個可視化展示卷積程序的網站
https://www.cs.ryerson.ca/~aharley/vis/conv/
一、使用pytorch訓練MINST手寫數字資料集
1. 匯入相關庫
import torch
import numpy as np
from torch.autograd import Variable
from torchvision import datasets,transforms
from torch.utils.data import DataLoader
from torch import nn
from torch import optim
2. 載入和下載資料集
train_dataset = datasets.MNIST(root='./data/06_MNIST/',
train=True,
transform=transforms.ToTensor(),
download=True)
test_dataset = datasets.MNIST(root='./data/06_MNIST/',
train=False, # 載入測驗集
transform=transforms.ToTensor(),
download=True)
batch_size = 64
train_loader = DataLoader(dataset = train_dataset,
batch_size=batch_size,
shuffle=True)
test_loader = DataLoader(dataset=test_dataset,
batch_size=batch_size,
shuffle=True)
3. 定義網路結構
# 定義網路結構
class CNN(nn.Module):
def __init__(self):
'''
Conv2d的引數:
nn.Conv2d(
in_channels, # 輸入圖片的通道(黑白的圖片就是一個通道)
out_channels, # 輸出資料通道:卷積層輸出的通道數
kernel_size, # 卷積核的大小
stride=1, # 步長
padding=0, # 填充0值的圈數(3*3視窗1圈,5*5兩圈得到的結果與原圖相同)
dilation=1,
groups=1,
bias=True,
padding_mode='zeros',)
'''
super(CNN,self).__init__()
# 卷積+激活+池化
self.conv1 = nn.Sequential(nn.Conv2d(1,32,5,1,2),nn.ReLU(),nn.MaxPool2d(2,2)) # 1張輸入得到32張14*14的特征圖
self.conv2 = nn.Sequential(nn.Conv2d(32,64,5,1,2),nn.ReLU(),nn.MaxPool2d(2,2))# 得到64張7*7的特征圖
self.fc1 = nn.Sequential(nn.Linear(64*7*7,1000),nn.Dropout(p=0.5),nn.ReLU()) # 輸入64*7*7的資料,輸出一個大小1000的陣列
self.fc2 = nn.Sequential(nn.Linear(1000,10),nn.Softmax(dim=1))
def forward(self,x):
# [64,1,28,28] 傳入資料的格式
x = self.conv1(x)
x = self.conv2(x)
# [64,64,7,7]
x = x.view(x.size()[0],-1)
x = self.fc1(x)
x = self.fc2(x)
return x
4.定義模型
# 定義模型
LR = 0.001
model = CNN()
crossEntropyloss = nn.CrossEntropyLoss()
optimizer = optim.Adam(model.parameters(),LR)
5. 訓練模型
def train():
# 訓練狀態
model.train()
for i,data in enumerate(train_loader):
inputs,labels = data
out = model(inputs)
loss = crossEntropyloss(out,labels)
optimizer.zero_grad()
loss.backward()
optimizer.step()
correct = 0
for i,data in enumerate(train_loader):
inputs,labels = data
out = model(inputs)
_,predictions = torch.max(out,1)
correct +=(predictions == labels).sum()
print("Train acc:{0}".format(correct.item()/len(train_dataset)))
def test():
model.eval()
correct = 0
for i,data in enumerate(test_loader):
inputs,labels = data
out = model(inputs)
_,predictions = torch.max(out,1)
correct +=(predictions == labels).sum()
print("Test acc:{0}".format(correct.item()/len(test_dataset)))
6. 運行模型
if __name__=='__main__':
for epoch in range(10):
print('epoch:',epoch)
train()
test()
7. 結果:

二、pytorch訓練CIFAR-10彩色圖片資料集
主要的步驟與上述方法相同
1. 加載與查看資料
# 匯入資料
CIFAR_train_dataset = datasets.CIFAR10(root='./data/',
train=True,
download=True,
transform = transforms.ToTensor()
)
CIFAR_test_dataset = datasets.CIFAR10(root='./data/',
train=False,
download=True,
transform = transforms.ToTensor()
)
# 查看資料
imgdata,label = CIFAR_train_dataset[90]
print('label:',label)
print('imgdata型別:',type(imgdata))
print('測驗集',CIFAR_train_dataset.data.shape)
print('訓練集',CIFAR_test_dataset.data.shape)
# 資料裝載
batch_size = 64
CIFAR_train_loader = DataLoader(dataset=CIFAR_train_dataset,
batch_size=batch_size,
shuffle=True)
CIFAR_test_loader = DataLoader(dataset=CIFAR_test_dataset,
batch_size=batch_size,
shuffle=True)
2.繪圖查看圖片集
fig, ax = plt.subplots(
nrows=3,
ncols=4,
sharex=True,
sharey=True) # sharex和sharey表示子圖是不是有相同的坐標
ax = ax.flatten()
for i in range(12):
# 只查看了前面12張圖片
img = CIFAR_train_dataset.data[i]
ax[i].imshow(img, cmap='Greys', interpolation='nearest')
ax[i].set_title("".join([k for k,v in CIFAR_train_dataset.class_to_idx.items() if v==CIFAR_train_dataset.targets[i]]))
ax[0].set_xticks([])
ax[0].set_yticks([])
plt.tight_layout()
plt.show()

3.定義網路結構
說明:CNN網路卷積層數量、卷積層引數、卷積層之后的激活函式、池化層的引數都需要自己再調整,我所填寫的引數得到的結果并不是很好,
# 定義網路結構
class CNN2(nn.Module):
def __init__(self):
'''
Conv2d的引數:
nn.Conv2d(
in_channels, # 輸入圖片的通道(黑白的圖片就是一個通道)
out_channels, # 輸出資料通道:卷積層輸出的通道數
kernel_size, # 卷積核的大小
stride=1, # 步長
padding=0, # 填充0值的圈數(3*3視窗1圈,5*5兩圈得到的結果與原圖相同)
dilation=1,
groups=1,
bias=True,
padding_mode='zeros',)
'''
super(CNN2,self).__init__()
# 卷積+激活+池化
self.conv1 = nn.Sequential(nn.Conv2d(3,32,5,1,2),nn.ReLU(),nn.MaxPool2d(2,2)) # 1張輸入得到32張16*16的特征圖
self.conv2 = nn.Sequential(nn.Conv2d(32,64,5,1,2),nn.ReLU(),nn.MaxPool2d(2,2))# 得到64張8*8的特征圖
self.fc1 = nn.Sequential(nn.Linear(64*8*8,1000),nn.Dropout(p=0.5),nn.ReLU()) # 輸入64*8*8的資料,輸出一個大小1000的陣列
self.fc2 = nn.Sequential(nn.Linear(1000,10),nn.Softmax(dim=1))
def forward(self,x):
# [64,3,32,32] 傳入資料的格式
x = self.conv1(x)
x = self.conv2(x)
# [64,64,8,8]
x = x.view(x.size()[0],-1)
x = self.fc1(x)
x = self.fc2(x)
return x
4.定義模型與訓練模型
# 定義模型
LR = 0.001
model = CNN2()
crossEntropyloss = nn.CrossEntropyLoss()
optimizer = optim.Adam(model.parameters(),LR)
def train(epoch):
# 訓練狀態
model.train()
running_loss = 0.0
for i,data in enumerate(CIFAR_train_loader):
inputs,labels = data
out = model(inputs)
loss = crossEntropyloss(out,labels)
optimizer.zero_grad()
loss.backward()
optimizer.step()
_,predictions = torch.max(out,1)
running_loss +=(predictions == labels).sum()
if i % 10 == 0: # 每10批次列印一次(1批次64張圖)
print('[%d, %5d] loss: %.3f' %
(epoch+1, i + 1, running_loss.item()/640))
running_loss = 0.0
correct = 0
for i,data in enumerate(CIFAR_train_loader):
inputs,labels = data
out = model(inputs)
_,predictions = torch.max(out,1)
correct +=(predictions == labels).sum()
print("Train acc:{0}".format(correct.item()/len(CIFAR_train_dataset)))
def test():
model.eval()
correct = 0
for i,data in enumerate(CIFAR_test_loader):
inputs,labels = data
out = model(inputs)
_,predictions = torch.max(out,1)
correct +=(predictions == labels).sum()
print("Test acc:{0}".format(correct.item()/len(CIFAR_test_dataset)))
if __name__=='__main__':
for epoch in range(10):
print('epoch:',epoch)
train(epoch)
test()
最后結果就不展示了,要得到好的訓練結果就需要調整引數和神經網路的結構,
轉載請註明出處,本文鏈接:https://www.uj5u.com/qita/225573.html
標籤:其他
