本文通过总结网上课程的构建深度学习(卷积)神经网络的主要架构,为大家写CNN提供参考,并在一些代码中间加注了一些解释方法(供大家参考学习)
希望能帮到你 ~
导入数据包
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
Using matplotlib backend: TkAgg
# 定义超参数
input_size = 28 # 图像尺寸是 28 * 28
num_classes = 10 # 标签的种类数
num_epochs = 3 # 图像训练的总时长
batch_size = 64 # 一个批次送进出图像数量的大小,这里一次性送进去64张图片
# 训练集
train_dataset = datasets.MNIST(root = './data',
train = True,
transform = transforms.ToTensor(),
download = True)
# 测试集
test_dataset = datasets.MNIST(root = './data',
train = False,
transform = transforms.ToTensor())
# 构建batch数据
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)
在构件完成batch之后,我们只需要在batch中一个一个去取数据就行了
DataLoader:
dataset(Dataset): 传入的数据集
batch_size(int, optional): 每个batch有多少个样本
shuffle(bool, optional): 在每个epoch开始的时候,对数据进行重新排序
注意def forward 要与init的缩进对齐!
class CNN(nn.Module):
def __init__(self):
super(CNN, self).__init__() # 子类调用父类的方法使用父类进行初始化
# 第一个卷积单元
self.conv1 = nn.Sequential( # 输入大小(1, 28, 28) 第一个卷积模块
nn.Conv2d(
in_channels = 1, # 灰度图
out_channels = 16, # 得到特征图的个数
kernel_size = 5, # 卷积核的大小
stride = 1, # 步长
padding = 2, # 输出的特征图为 (28, 28, 16)
), # 输出结构为
nn.ReLU(),
nn.MaxPool2d(kernel_size = 2), # 2 * 2 大小的矩阵做maxpool
# 输出(14, 14, 16)
)
# 第二个卷积单元
# 上一个模块的channel out 为下一个模块的channel in
self.conv2 = nn.Sequential( # 输入(16, 14, 14)
nn.Conv2d(16, 32, 5, 1, 2), # 对应的参数上面的一个已经写了
# 输出大小 (32,14,14)
nn.ReLU(),
nn.MaxPool2d(2), # 输出大小 (32,7,7)
)
# 将输出的向量拉直
# 输入神经元个数, 输出神经元个数,是否包含偏置值
self.out = nn.Linear(32 * 7 * 7, 10)
# 定义一个前推 规则方法
def forward(self, x):
x = self.conv1(x)
x = self.conv2(x)
# 将所有的结果转为向量的形式
x = x.view(x.size(0), -1) # flatten 操作,结果为: (batch_size, 32 * 7 * 7)
output = self.out(x)
return output
self:通过这个类实例化后的对象本身,你对这个对象有什么要求
奋斗の博客_解惑(一) ----- super(XXX, self).init()到底是代表什么含义
这篇文章真的写的很好,大家可以去看一下~
pytorch系列7 -----nn.Sequential讲解_墨氲一个有序的容器,神经网络模块将按照在传入构造器的顺序依次被添加到计算图中执行
注解:
该函数对输出的结果进行分类
output = torch.max(input, dim)
https://www.jianshu.com/p/3ed11362b54f
def accuracy(predictions, labels):
# prediction的形状(batch_size * 10)
# 按照行优先,每10个10个地取出来该行内的最大值(下标)
# 下标对应的恰好就是0-9这10个数值
pred = torch.max(predictions.data, 1)[1]
# 与原来的结果进行比较
# 对了的就是1,不对就是0,然后求和
rights = pred.eq(labels.data.view_as(pred)).sum()
return rights, len(labels)
DataLoader使用enumerate来遍历,逐个取batch
# 实例化
net = CNN()
# 损失函数
criterion = nn.CrossEntropyLoss()
# 优化器
optimizer = optim.Adam(net.parameters(), lr = 0.001) # 定义优化器
# 开始训练循环
for epoch in range(num_epochs):
# 当前的epoch的结果保存下来
# 每一轮循环开始前先清零
train_rights = []
for batch_idx, (data, target) in enumerate(train_loader):
# 针对容器中的每一个batch进行循环
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)
# 计算准确率
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('当前epoch: {} [{}/{} ({:.0f}%)]\t损失: {:.6f}\t训练集准确率: {:.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]))
当前epoch: 0 [0/60000 (0%)] 损失: 2.295074 训练集准确率: 15.62% 测试集正确率: 12.67%
当前epoch: 0 [6400/60000 (11%)] 损失: 0.286456 训练集准确率: 77.10% 测试集正确率: 92.20%
当前epoch: 0 [12800/60000 (21%)] 损失: 0.252975 训练集准确率: 85.43% 测试集正确率: 94.98%
当前epoch: 0 [19200/60000 (32%)] 损失: 0.117255 训练集准确率: 88.77% 测试集正确率: 96.69%
当前epoch: 0 [25600/60000 (43%)] 损失: 0.093021 训练集准确率: 90.83% 测试集正确率: 97.19%
当前epoch: 0 [32000/60000 (53%)] 损失: 0.171856 训练集准确率: 92.10% 测试集正确率: 96.74%
当前epoch: 0 [38400/60000 (64%)] 损失: 0.024938 训练集准确率: 92.94% 测试集正确率: 97.28%
当前epoch: 0 [44800/60000 (75%)] 损失: 0.045772 训练集准确率: 93.60% 测试集正确率: 98.13%
当前epoch: 0 [51200/60000 (85%)] 损失: 0.036130 训练集准确率: 94.11% 测试集正确率: 98.08%
当前epoch: 0 [57600/60000 (96%)] 损失: 0.019689 训练集准确率: 94.52% 测试集正确率: 98.32%
当前epoch: 1 [0/60000 (0%)] 损失: 0.014988 训练集准确率: 100.00% 测试集正确率: 98.50%
当前epoch: 1 [6400/60000 (11%)] 损失: 0.039536 训练集准确率: 97.94% 测试集正确率: 98.42%
当前epoch: 1 [12800/60000 (21%)] 损失: 0.053510 训练集准确率: 97.99% 测试集正确率: 98.42%
当前epoch: 1 [19200/60000 (32%)] 损失: 0.168834 训练集准确率: 98.18% 测试集正确率: 98.56%
当前epoch: 1 [25600/60000 (43%)] 损失: 0.084785 训练集准确率: 98.16% 测试集正确率: 98.46%
当前epoch: 1 [32000/60000 (53%)] 损失: 0.036668 训练集准确率: 98.21% 测试集正确率: 98.43%
当前epoch: 1 [38400/60000 (64%)] 损失: 0.019413 训练集准确率: 98.23% 测试集正确率: 98.57%
当前epoch: 1 [44800/60000 (75%)] 损失: 0.063640 训练集准确率: 98.25% 测试集正确率: 98.57%
当前epoch: 1 [51200/60000 (85%)] 损失: 0.022920 训练集准确率: 98.28% 测试集正确率: 98.48%
当前epoch: 1 [57600/60000 (96%)] 损失: 0.019340 训练集准确率: 98.31% 测试集正确率: 98.80%
当前epoch: 2 [0/60000 (0%)] 损失: 0.050389 训练集准确率: 98.44% 测试集正确率: 98.67%
当前epoch: 2 [6400/60000 (11%)] 损失: 0.007058 训练集准确率: 98.90% 测试集正确率: 98.73%
当前epoch: 2 [12800/60000 (21%)] 损失: 0.054998 训练集准确率: 98.76% 测试集正确率: 98.74%
当前epoch: 2 [19200/60000 (32%)] 损失: 0.050147 训练集准确率: 98.79% 测试集正确率: 98.70%
当前epoch: 2 [25600/60000 (43%)] 损失: 0.012523 训练集准确率: 98.77% 测试集正确率: 98.83%
当前epoch: 2 [32000/60000 (53%)] 损失: 0.046355 训练集准确率: 98.76% 测试集正确率: 98.71%
当前epoch: 2 [38400/60000 (64%)] 损失: 0.061045 训练集准确率: 98.78% 测试集正确率: 98.78%
当前epoch: 2 [44800/60000 (75%)] 损失: 0.060261 训练集准确率: 98.79% 测试集正确率: 98.71%
当前epoch: 2 [51200/60000 (85%)] 损失: 0.036363 训练集准确率: 98.83% 测试集正确率: 98.66%
当前epoch: 2 [57600/60000 (96%)] 损失: 0.041269 训练集准确率: 98.81% 测试集正确率: 98.66%
共训练了2个epoch,达到了99.66%的准确率,说明在图像分类的任务里面,小卷积核的CNN有不错的表现效果~
各位看官,都看到这里了,麻烦动动手指头给博主来个点赞8,您的支持作者最大的创作动力哟!
本文代码参考课程:五大深度神经网络基础 Lesson14
才疏学浅,若有纰漏,恳请斧正
本文章仅用于各位作为学习交流之用,不作任何商业用途,若涉及版权问题请速与作者联系,望悉知