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
复制代码