1、【網絡結構分析】bash
手寫數字識別數據集,數據集訓練樣本是60000張28 * 28的灰度圖,測試集是10000張28 * 28的灰度圖,作10分類,即0-9。 主要目的是練習使用CNN搭建網絡框架,採用4個卷積層,1個池化層和一個全鏈接層的方式。因爲訓練集的batch——size是128,因此每一step訓練樣本是128個,本例中每步訓練過程當中數據變化過程以下: 網絡
2、【知識點整理】app
1.每一個卷積層中是包含激活函數的:框架
每一個conv表明一個卷積層,卷積層內不止是進行了nn.Conv2d二維卷積操做,還有激活函數,不要忘記了。ide
2.torch.nn.BatchNorm2d():函數
在每一個卷積層中,nn.Conv2d以後,先進行nn.BatchNorm2d作數據的歸一化處理,再加入激活函數,做用是使得數據在進行Relu以前不會由於數據過大而致使網絡性能的不穩定。公式以下:性能
3.在與全鏈接層銜接時,對數據作維度拉伸處理:測試
將最後一次卷積的輸出拉伸爲一行,每個輸入都拉成一個維度以知足全鏈接層的輸入要求,即將128 * 1 * 1 * 64的矩陣x變爲128 * 64:優化
x=x.view(x.size(0),-1)ui
3、【源代碼】
# 定義網絡結構
import torch
import numpy as np
from torch.utils import data # 獲取迭代數據
from torch.autograd import Variable # 獲取變量
import torchvision
from torchvision.datasets import mnist # 獲取數據集
import matplotlib.pyplot as plt
class CNNnet(torch.nn.Module):
def __init__(self):
super(CNNnet,self).__init__()
self.los=torch.nn.CrossEntropyLoss()
self.conv1 = torch.nn.Sequential(
torch.nn.Conv2d(in_channels=1,
out_channels=16,
kernel_size=3,
stride=2,
padding=1),
torch.nn.BatchNorm2d(16),
torch.nn.ReLU()
)
self.conv2 = torch.nn.Sequential(
torch.nn.Conv2d(16,32,3,2,1),
torch.nn.BatchNorm2d(32),
torch.nn.ReLU()
)
self.conv3 = torch.nn.Sequential(
torch.nn.Conv2d(32,64,3,2,1),
torch.nn.BatchNorm2d(64),
torch.nn.ReLU()
)
self.conv4 = torch.nn.Sequential(
torch.nn.Conv2d(64,64,2,2,0),
torch.nn.BatchNorm2d(64),
torch.nn.ReLU()
)
self.maxpool=torch.nn.AdaptiveMaxPool2d((1,1))
self.mlp1 = torch.nn.Linear(1*1*64,10)
#self.mlp2 = torch.nn.Linear(100,10)
self.opt=torch.optim.Adam(params=self.parameters(),lr=0.1)
def forward(self, x):
x = self.conv1(x)
x = self.conv2(x)
x = self.conv3(x)
x = self.conv4(x)
x=self.maxpool(x)
x = self.mlp1(x.view(x.size(0),-1))
#x = self.mlp2(x)
return x
def train(self,x,label):
out=self.forward(x)# 獲取最後輸出
loss=self.los(out,label) # 獲取損失
#利用優化器優化損失
self.opt.zero_grad() # 清空上一步殘餘更新參數值
loss.backward() # 偏差反向傳播,計算參數更新值
self.opt.step() # 將參數更新值施加到net的parmeters上
return loss
def getdata():
data_tf = torchvision.transforms.Compose(
[
torchvision.transforms.ToTensor(),
torchvision.transforms.Normalize([0.5],[0.5])
]
)
train_data = mnist.MNIST('./dataset/mnist/train',train=True,transform=data_tf,download=True)#60000張圖片,每張28*28
test_data = mnist.MNIST('./dataset/mnist/test',train=False,transform=data_tf,download=True)#10000張圖片
return train_data,test_data
if __name__=='__main__':
train_data,test_data=getdata()
train_loader=data.DataLoader(train_data,batch_size=128,shuffle=True)
test_loader=data.DataLoader(test_data,batch_size=1000,shuffle=True)
model = CNNnet()
loss_count = []
acc=[]
for epoch in range(2):
for i,(x,y) in enumerate(train_loader):
loss=model.train(x,y)
if i%20 == 0:
loss_count.append(loss)
if i % 100 == 0:
for a,b in test_loader:
test_x = Variable(a)
test_y = Variable(b)
out = model.forward(test_x)
pred_y=torch.max(out, 1)[1]
accuracy =(pred_y.data.numpy() == test_y.data.numpy()).astype(int).sum()/float(test_y.numpy().size)
acc.append(accuracy)
break
#每20*128個數據量,即每20step計算一次損失值
plt.figure('PyTorch_CNN_Loss')
plt.plot(loss_count,label='Loss')
plt.legend()
plt.show()
#訓練集每100step,對1000個訓練數據作預測,計算準確率
plt.figure('accuracy')
plt.plot(acc,label='accuracy')
plt.legend()
plt.show
複製代碼