卷积神经网络学习Fashion_mnist
FashionMNIST 是一个替代 MNIST 手写数字集的图像数据集。 它是由 Zalando(一家德国的时尚科技公司)旗下的研究部门提供。其涵盖了来自 10 种类别的共 7 万个不同商品的正面图片。
FashionMNIST 的大小、格式和训练集/测试集划分与原始的 MNIST 完全一致。60000/10000 的训练测试数据划分,28x28 的灰度图片。你可以直接用它来测试你的机器学习和深度学习算法性能,且不需要改动任何的代码。
引入头文件
import torch
import torch.nn as nn
from torchvision import datasets, transforms
from torch.utils.data import TensorDataset,DataLoader
读取数据集
#help(datasets.MNIST)
mnist_train = datasets.FashionMNIST(root='./', train=True,download=True, transform=transforms.ToTensor())
mnist_test = datasets.FashionMNIST(root='./', train=False, download=True, transform=transforms.ToTensor())
设置训练参数和数据
这里可以直接使用DataLoader来分批读取数据
epoches = 5
lr = 0.01
batch_size = 100
train_data = DataLoader(dataset=mnist_train,batch_size=batch_size,shuffle=True)
valid_data = DataLoader(dataset=mnist_test)
定义卷积网络结构
class CNN_MNIST(nn.Module):
def __init__(self):
super().__init__()
self.layer1 = nn.Sequential(
nn.Conv2d(in_channels=1,#输入通道,灰度图是1
out_channels=24,#输出通道,卷积核的数量,也是特征图的数量
kernel_size=3,#卷积核尺寸
stride=1,#移动步长
padding=2#边缘填充
),
nn.ReLU(),#非线性函数
nn.MaxPool2d(kernel_size=2)#池化层
)
self.layer2 = nn.Sequential(
nn.Conv2d(24,20,4,1,2),
nn.ReLU(),
nn.MaxPool2d(kernel_size=2)
)
self.layer3 = nn.Linear(8*8*20,10)#需要将特征图展开,计算最后有的变量个数
def forward(self, x):
x = self.layer1(x)
x = self.layer2(x)
x = x.view(x.size(0), -1)#展平操作
x = self.layer3(x)
return x
定义网络和优化器
net = CNN_MNIST()
opt = torch.optim.Adam(params=net.parameters(), lr=lr)
定义准确率函数
#此处传入的pred大小为[N,10]
#output = torch.max(input, dim),返回最大值和最大值的索引
#view_as将两个tensor变为形状一样的
def accuracy(pred, target):
_,pred = torch.max(pred.data, 1)
rights = pred.eq(target.data.view_as(pred)).sum()
return rights.item(), len(pred)
定义训练函数
import time
def train(epoches, net, loss_fun, opt, train_data, valid_data):
net.cuda()#将模型放到gpu
loss_fun.cuda()#将损失函数放到gpu
for epoch in range(epoches):
start = time.clock()
net.train()#训练过程
for x, y in train_data:
x = x.cuda()#数据放到gput
y = y.cuda()
opt.zero_grad()#清空梯度
pred = net(x)#前向传播
loss = loss_fun(pred, y)#计算loss
loss.backward()#反向传播
opt.step()#更新参数
rights = 0
nums = 0
loss_val = 0
net.eval()#测试过程
for x, y in valid_data:
x = x.cuda()
y = y.cuda()
pred = net(x)
loss = loss_fun(pred, y)
right, num = accuracy(pred, y)
rights += right
loss_val += loss*num
nums += num
end = time.clock()
print('epoch:' + str(epoch + 1), 'loss:' + str(loss_val.item() / nums), '正确率:' + str(100 * rights / nums) + '%','Running time: %s Seconds' % (end - start))
主函数
经过多次训练准确率在91%
左右
train(5, net, nn.CrossEntropyLoss(), opt, train_data, valid_data)