民大机器学习Mnist小作业

Mnist作业

1 设计思路

首先,我们要明确我们的任务是什么。任务是对mnist手写数据集进行分类,那么我们用pytorch来做的话,它是内置了Fashion-Mnist和Mnist数据集,我们只要从框架里面下载即可。然后我们创建dataloader,设置batch_size,设置交叉熵损失函数因为这是一个多分类问题。注意一般二分类不用这个损失函数,一般用BCELoss损失函数。然后设置优化器为SGD或者Adam,设置学习率、权重衰减、动量值。设置训练函数,进行训练,将正确率和loss显示在终端上,最后可视化每一个epoch的准确率和损失。

2 实现过程

2.1 导入相关包

import torch

import torch.nn as nn

import torch.nn.functional as F

import torch.optim as optim

import numpy as np

import matplotlib.pyplot as plt

%matplotlib inline

from torch.utils import *

import torchvision

2.2 处理数据集

transfroma = transforms.Compose(

   [

        transforms.ToTensor(),

   ]

)

# 内置mnist

train_ds=torchvision.datasets.MNIST(

    root='MNIST',  # 根路径

    train=True, # 是否为训练集

    transform=transfroma, # 图像预处理 转为tensor  或者裁剪 归一化

    download=True # 是否下载

)

test_ds=torchvision.datasets.MNIST(

    root='MNIST',

    train=False,

    transform=transfroma,

    download=True

)

2.3 创建dataloader

BATCH_SIZE = 64 # 一次送入多少数据

# 创建dataloader

train_dl = data.DataLoader(

    train_ds,

    batch_size = BATCH_SIZE,

    shuffle = True  #乱序

)

test_dl = data.DataLoader(

    test_ds,

    batch_size = 64

)

2.3 画图查看数据集  在pytorch里面图片的表示形式:[batch, channel, hight, width]

plt.figure(figsize=(12,5))

for i,img in enumerate(imgs[:12]):

    plt.subplot(3,4,i+1)

    img = np.array(imgs[i].squeeze())

    plt.title("TrueNumber:{}".format(labels[i]))

    plt.axis('off')  # 去掉坐标轴

    plt.imshow(img)

2.4 创建AlexNet分类模型

class AlexNet(nn.Module):

   def __init__(self):

       super(AlexNet,self).__init__()

       # 28 * 28 * 1 #----> 卷积核 11*11*96 (n-f)/s+1--> 5 * 5 * 96

        self.conv1 = nn.Sequential(  

            nn.Conv2d(in_channels=1,out_channels=96,kernel_size=11,stride=4,padding=0),

            nn.ReLU(),

            nn.MaxPool2d(kernel_size=3,stride=2),

                                   

            nn.Conv2d(in_channels=96,out_channels=256,kernel_size=4,padding=2,stride=1),

            nn.ReLU(),

            nn.MaxPool2d(kernel_size=3,stride=2),

       )

        self.linear = nn.Sequential(

            nn.Linear(256,4096),

            nn.ReLU(),

            nn.Linear(4096,10)

       )

   def forward(self, input):

       input = self.conv1(input)

       #print(input.size())

       input = self.linear(input.view(input.shape[0], -1))

       return input

model = AlexNet()

device = torch.device("cuda:0" if torch.cuda.is_available() else "cpu")

model.to(device) # 把模型放入GPU

2.5 定义训练函数

def fit(epoch, model, trainloader, testloader):

    correct = 0

    total = 0

    running_loss = 0

   for x, y in trainloader:

        x, y = x.to(device), y.to(device)

        y_pred = model(x)

        loss = loss_fn(y_pred, y)

        optim.zero_grad()

        loss.backward()

        optim.step()

       with torch.no_grad():

            y_pred = torch.argmax(y_pred, dim=1)

            correct += (y_pred == y).sum().item()

            total += y.size(0)

            running_loss += loss.item()

       

    epoch_loss = running_loss / len(trainloader.dataset)

    epoch_acc = correct / total

    test_correct = 0

    test_total = 0

    test_running_loss = 0 

   

   with torch.no_grad():

       for x, y in testloader:

            x, y = x.to(device), y.to(device)

            y_pred = model(x)

            loss = loss_fn(y_pred, y)

            y_pred = torch.argmax(y_pred, dim=1)

            test_correct += (y_pred == y).sum().item()

            test_total += y.size(0)

            test_running_loss += loss.item()

   

    epoch_test_loss = test_running_loss / len(testloader.dataset)

    epoch_test_acc = test_correct / test_total

   print('epoch: ', epoch, 

         'loss: ', round(epoch_loss, 3),

         'accuracy:', round(epoch_acc, 3),

         'test_loss: ', round(epoch_test_loss, 3),

         'test_accuracy:', round(epoch_test_acc, 3)

             )

       

   return epoch_loss, epoch_acc, epoch_test_loss, epoch_test_acc

2.6 定义损失函数、优化器

optim = torch.optim.Adam(model.parameters(), lr=0.001)

loss_fn = torch.nn.CrossEntropyLoss()  # 损失函数

2.7 开始训练

epochs = 10

train_loss = []

train_acc = []

test_loss = []

test_acc = []

for epoch in range(epochs):

    epoch_loss, epoch_acc, epoch_test_loss, epoch_test_acc = fit(epoch,

                                                                model,

                                                                train_dl,

                                                                test_dl)

    train_loss.append(epoch_loss)

    train_acc.append(epoch_acc)

    test_loss.append(epoch_test_loss)

    test_acc.append(epoch_test_acc)

2.8 Result

2.9 可视化

plt.plot(range(1, epochs+1), train_loss, label='train_loss')

plt.plot(range(1, epochs+1), test_loss, label='test_loss')

plt.legend()

plt.plot(range(1, epochs+1), train_acc, label='train_acc')

plt.plot(range(1, epochs+1), test_acc, label='test_acc')

plt.legend()

3 调参过程 展现最优结果

由于使用的网络结构比较好,对于这种小的数据集一下就收敛了,所以准确率达到了99%。

lr = 0.001 weight decay=0.0001 momentum = 0.9  opt = SGD、Adam

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值