1.网络结构
1.1论文结构
1.2简化说明
说明:共7层(3Conv+2pool+2FC)
2.作用
2.1各个部分的作用
卷积:特征提取。
(说明:同一卷积层中不同通道学习的是同一尺度下的多种特征,浅层卷积和深层卷积学习到的是多种尺度的特征,且深层次的卷积学习到的特征更抽象。)
激活函数:引入非线性,提高模型的表达能力
池化(降采样):
特征压缩:降低模型复杂度防止过拟合+提取主要特征。
不变性:translation(平移:不同位置),rotation(旋转:不同角度),scale(尺度:放缩)。
全连接:特征整合(减少特征位置对分类带来的影响)。
2.2特点
局部感知(连接):每个输出仅与输入的一块区域连接(理解感受野的概念),这个概念相对于全连接网络。
权值共享:卷积过程中卷积核的权重是不会改变,提取的是不同位置的同样特征。
作用:减少参数数量,加快学习速率,一定程度上减少过拟合。
3.pytorch实现
3.1网络结构:激活函数改用Relu
import torch.nn as nn
import torch
from torchsummary import summary
from torch.utils.data import DataLoader
from torchvision import transforms,datasets
class LenetNet(nn.Module):
def __init__(self, num_classes=10):
super(LenetNet, self).__init__()
self.features = nn.Sequential(
nn.Conv2d(1, 6, 5),
nn.ReLU(inplace=True),
nn.AvgPool2d(kernel_size=2, stride=2),
nn.Conv2d(6, 16, 5),
nn.ReLU(inplace=True),
nn.AvgPool2d(kernel_size=2, stride=2),
nn.Conv2d(16, 120, 5),
nn.ReLU(inplace=True),
)
self.classifier = nn.Sequential(
nn.Linear(120, 84),
nn.ReLU(inplace=True),
nn.Linear(84, num_classes),
)
def forward(self, x):
x = self.features(x)
# print(x.shape)
x = x.view(x.size(0), 120 * 1 * 1)
x = self.classifier(x)
return x
3.2打印网络结构
if __name__ == "__main__":
device = torch.device('cuda' if torch.cuda.is_available() else 'cpu')
model=LenetNet().to(device)
summary(model, (1,32, 32)) #打印网络结构
结果显示
3.3 mnist数据集测试
if __name__ == "__main__":
device = torch.device('cuda' if torch.cuda.is_available() else 'cpu')
learning_rate=0.001
num_epochs = 1 # train the training data n times, to save time, we just train 1 epoch
batch_size = 32
LR = 0.001 # learning rate
DOWNLOAD_MNIST = False
data_tf = transforms.Compose(
[transforms.Resize([32, 32]),
transforms.ToTensor(),
transforms.Normalize([0.5], [0.5])])
train_dataset = datasets.MNIST(
root='mnist', train=True, transform=data_tf)
test_dataset = datasets.MNIST(root='mnist', train=False, transform=data_tf)
train_loader = DataLoader(train_dataset, batch_size=batch_size, shuffle=True)
test_loader = DataLoader(test_dataset, batch_size=batch_size, shuffle=False)
model=LenetNet().to(device)
#summary(model, (1,32, 32)) #打印网络结构
criterion = nn.CrossEntropyLoss()
optimizer = torch.optim.Adam(model.parameters(), lr=learning_rate)
total_step = len(train_loader)
for epoch in range(num_epochs):
for i, (images, labels) in enumerate(train_loader):
images = images.to(device)
labels = labels.to(device)
# Forward pass
outputs = model(images)
loss = criterion(outputs, labels)
# Backward and optimize
optimizer.zero_grad()
loss.backward()
optimizer.step()
if (i + 1) % 100 == 0:
print('Epoch [{}/{}], Step [{}/{}], Loss: {:.4f}'
.format(epoch + 1, num_epochs, i + 1, total_step, loss.item()))
# Test the model
model.eval() #
with torch.no_grad():
correct = 0
total = 0
for images, labels in test_loader:
images = images.to(device)
labels = labels.to(device)
outputs = model(images)
_, predicted = torch.max(outputs.data, 1)
total += labels.size(0)
correct += (predicted == labels).sum().item()
print('Test Accuracy {} %'.format(100 * correct / total))
结果