構(gòu)建卷積神經(jīng)網(wǎng)絡(luò)
- 卷積網(wǎng)絡(luò)中的輸入和層與傳統(tǒng)神經(jīng)網(wǎng)絡(luò)有些區(qū)別,需重新設(shè)計,訓(xùn)練模塊基本一致
全連接層:batch784,各個像素點之間都是沒有聯(lián)系的。
卷積層:batch12828,各個像素點之間是有聯(lián)系的。
import torch
import torch.nn as nn
import torch.optim as optim
import torch.nn.functional as F
from torchvision import datasets,transforms
import matplotlib.pyplot as plt
import numpy as np
%matplotlib inline
首先讀取數(shù)據(jù)
- 分別構(gòu)建訓(xùn)練集和測試集(驗證集)
- DataLoader來迭代取數(shù)據(jù)
# 定義超參數(shù)
input_size = 28 #圖像的總尺寸28*28
num_classes = 10 #標(biāo)簽的種類數(shù)
num_epochs = 3 #訓(xùn)練的總循環(huán)周期
batch_size = 64 #一個撮(批次)的大小,64張圖片
# 訓(xùn)練集
train_dataset = datasets.MNIST(root='./data',
train=True,
transform=transforms.ToTensor(),
download=True)
# 測試集
test_dataset = datasets.MNIST(root='./data',
train=False,
transform=transforms.ToTensor())
# 構(gòu)建batch數(shù)據(jù)
train_loader = torch.utils.data.DataLoader(dataset=train_dataset,
batch_size=batch_size,
shuffle=True)
test_loader = torch.utils.data.DataLoader(dataset=test_dataset,
batch_size=batch_size,
shuffle=True)
卷積網(wǎng)絡(luò)模塊構(gòu)建
- 一般卷積層,relu層,池化層可以寫成一個套餐
- 注意卷積最后結(jié)果還是一個特征圖,需要把圖轉(zhuǎn)換成向量才能做分類或者回歸任務(wù)
圖像是二維卷積 conv2
視頻是三維卷積 conv3
單向量是一維卷積 conv1
官網(wǎng)有關(guān)conv2d的輸出寬度和長度的計算公式文章來源:http://www.zghlxwxcb.cn/news/detail-635428.html
class CNN(nn.Module):
def __init__(self):
super(CNN, self).__init__()
self.conv1 = nn.Sequential( # 輸入大小 (1, 28, 28)
nn.Conv2d(
in_channels=1, # 1:灰度圖;3:RGB
out_channels=16, # 要得到幾多少個特征圖,即是卷積核的個數(shù)
kernel_size=5, # 卷積核大小
stride=1, # 步長
padding=2, # 如果希望卷積后大小跟原來一樣,需要設(shè)置padding=(kernel_size-1)/2 if stride=1
), # 輸出的特征圖為 (16, 28, 28)
nn.ReLU(), # relu層
nn.MaxPool2d(kernel_size=2), # 進行池化操作(2x2 區(qū)域), 輸出結(jié)果為: (16, 14, 14)
)
self.conv2 = nn.Sequential( # 下一個套餐的輸入 (16, 14, 14)
nn.Conv2d(16, 32, 5, 1, 2), # 輸出 (32, 14, 14)
nn.ReLU(), # relu層
nn.Conv2d(32, 32, 5, 1, 2),
nn.ReLU(),
nn.MaxPool2d(2), # 輸出 (32, 7, 7)
)
self.conv3 = nn.Sequential( # 下一個套餐的輸入 (32, 7, 7)
nn.Conv2d(32, 64, 5, 1, 2), # 輸出 (64, 7, 7)
nn.ReLU(), # 輸出 (64, 7, 7)
)
self.out = nn.Linear(64 * 7 * 7, 10) # 全連接層得到的結(jié)果
def forward(self, x):
x = self.conv1(x)
x = self.conv2(x)
x = self.conv3(x)
x = x.view(x.size(0), -1) # flatten操作,結(jié)果為:(batch_size, 64 * 7 * 7)
output = self.out(x)
return output
準(zhǔn)確率作為評估標(biāo)準(zhǔn)
def accuracy(predictions, labels):
pred = torch.max(predictions.data, 1)[1]
rights = pred.eq(labels.data.view_as(pred)).sum()
return rights, len(labels)
訓(xùn)練網(wǎng)絡(luò)模型
# 實例化
net = CNN()
#損失函數(shù)
criterion = nn.CrossEntropyLoss()
#優(yōu)化器
optimizer = optim.Adam(net.parameters(), lr=0.001) #定義優(yōu)化器,普通的隨機梯度下降算法
#開始訓(xùn)練循環(huán)
for epoch in range(num_epochs):
#當(dāng)前epoch的結(jié)果保存下來
train_rights = []
for batch_idx, (data, target) in enumerate(train_loader): #針對容器中的每一個批進行循環(huán)
net.train()
output = net(data)
loss = criterion(output, target)
optimizer.zero_grad()
loss.backward()
optimizer.step()
right = accuracy(output, target)
train_rights.append(right)
if batch_idx % 100 == 0:
net.eval()
val_rights = []
for (data, target) in test_loader:
output = net(data)
right = accuracy(output, target)
val_rights.append(right)
#準(zhǔn)確率計算
train_r = (sum([tup[0] for tup in train_rights]), sum([tup[1] for tup in train_rights]))
val_r = (sum([tup[0] for tup in val_rights]), sum([tup[1] for tup in val_rights]))
print('當(dāng)前epoch: {} [{}/{} ({:.0f}%)]\t損失: {:.6f}\t訓(xùn)練集準(zhǔn)確率: {:.2f}%\t測試集正確率: {:.2f}%'.format(
epoch, batch_idx * batch_size, len(train_loader.dataset),
100. * batch_idx / len(train_loader),
loss.data,
100. * train_r[0].numpy() / train_r[1],
100. * val_r[0].numpy() / val_r[1]))
文章來源地址http://www.zghlxwxcb.cn/news/detail-635428.html
練習(xí)
- 再加入一層卷積,效果怎么樣?
- 當(dāng)前任務(wù)中為什么全連接層是3277 其中每一個數(shù)字代表什么含義
到了這里,關(guān)于【構(gòu)建卷積神經(jīng)網(wǎng)絡(luò)】的文章就介紹完了。如果您還想了解更多內(nèi)容,請在右上角搜索TOY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!