将Mnist数据集减少类别并用lenet训练

Mnist数据集:包含60,000个用于训练的示例和10,000个用于测试的示例。这些数字已经过尺寸标准化并位于图像中心,图像是固定大小(28x28像素)。类别为数字0~9,共10类。

我们将Mnist数据集减少至只剩0、1的两类。

并使用lenet进行训练。

首先需要处理数据集:

需要自己新建文件夹,文件夹内包括图片(两个类别分成两个文件夹,如下)和图片对应的标签(下图中的txt,需要自己生成)

 标签中包含:图片路径+类别(如下)

 然后数据集部分就准备好了

代码修改:

 原代码参考:https://www.bilibili.com/video/BV1vU4y1A7QJ/?spm_id_from=333.337.search-card.all.click

首先在代码根目录中新建.py文件,用于读取图片路径,代码如下:

from PIL import Image
from torch.utils.data import Dataset
import os
import time

import torch
from torch import nn
from torch.optim import lr_scheduler
from torchvision import datasets, transforms
import os
# from net import MyLeNet5

class MyDataset(Dataset):
    def __init__(self, txt_path, transform = None, target_transform = None):
        fh = open(txt_path, 'r')
        imgs = []
        for line in fh:
            line = line.rstrip()
            words = line.split()
            imgs.append((words[0], words[1]))
            self.imgs = imgs
            self.transform = transform
            self.target_transform = target_transform
    def __getitem__(self, index):
        fn, label = self.imgs[index]
        #img = Image.open(fn).convert('RGB')
        img = Image.open(fn)
        if self.transform is not None:
            img = self.transform(img)
        return img, label
    def __len__(self):
        return len(self.imgs)
pipline_train = transforms.Compose([
    #随机旋转图片
    transforms.RandomHorizontalFlip(),
    #将图片尺寸resize到32x32
    transforms.Resize((32,32)),
    #将图片转化为Tensor格式
    transforms.ToTensor(),
    #正则化(当模型出现过拟合的情况时,用来降低模型的复杂度)
    transforms.Normalize((0.1307,),(0.3081,))
])
pipline_test = transforms.Compose([
    #将图片尺寸resize到32x32
    transforms.Resize((32,32)),
    transforms.ToTensor(),
    transforms.Normalize((0.1307,),(0.3081,))
])

train.py中引用,xjj就是我在根目录中新建py,xjj.py

 

train.py中将读取数据集部分改为:

train_data = MyDataset('./data/LEDNUM/train.txt', transform=data_transform)
test_data = MyDataset('./data/LEDNUM/test.txt', transform=data_transform)

#train_data 和test_data包含多有的训练与测试数据,调用DataLoader批量加载
trainloader = torch.utils.data.DataLoader(dataset=train_data, batch_size=8, shuffle=True)
testloader = torch.utils.data.DataLoader(dataset=test_data, batch_size=4, shuffle=False)

train.py中修改定义训练函数:

def train(dataloader, model, loss_fn, optimizer):
    loss, current, n = 0.0, 0.0, 0
    #numerate()会返回两个值, 一个是索引, 一个是数据,numerate()需要两个参数: 第一个参数是可迭代的对象,第二个参数是起始位置, 数据类型为int
    for batch, (X,y) in enumerate(dataloader):#enumerate() 函数用于将一个可遍历的数据对象(如列表、元组或字符串)组合为一个索引序列,同时列出数据和数据下标,一般用在 for 循环当中。
        #前向转播
        # X, y = X.to(device), y.to(device)
        X, y = X, y
        output = model(X)

        ##########
        y_ = y
        label_y = []
        for _ in y_:
            item = int(_)
            label_y.append(item)

        # y = list(y)
        y = torch.tensor(label_y)
        #print(type(y))
        ###############

        cur_loss = loss_fn(output, y)
        _, pred = torch.max(output, axis=1)#通过torch.max输出每一行的最大概率
        cur_acc = torch.sum(y == pred)/output.shape[0]#16个批次即16张照片,通过y与预测值pred相比较,判断预测是否准确,如果准确返回1,不准确返回0,最后所有的加起来判断一批次的精确度,最后通过for判断一轮的精确度,得动精确度权重
       #反向传播
        optimizer.zero_grad()#优化器梯度清理
        cur_loss.backward()
        optimizer.step()#梯度更新

        loss += cur_loss.item()#把这一批次的损失值累加的一起
        current += cur_acc.item()#把所有的精度累加的一起
        n = n+1
    print("train_loss" + str(loss/n))#每一轮平均损失
    print("train_acc" + str(current/n))#每一轮平均精确度

 这步增加了更改数据集格式,将图片矩阵改为张量

train.py中修改定义验证函数:

def val(dataloader, model, loss_fn):
    #model.eval()是保证BN(Batch Normalization分批归一化)用全部数据的均值和方差;
    model.eval()#改为验证模式,eval() 函数用来执行一个字符串表达式,并返回表达式的值。model.eval() 作用等同于 self.train(False)简而言之,就是评估模式
    loss, current, n = 0.0, 0.0, 0
    with torch.no_grad():#在模型不参与更新的情况下进行验证
        for batch, (X, y) in enumerate(dataloader):

            ##########
            y_ = y
            label_y = []
            for _ in y_:
                item = int(_)
                label_y.append(item)

            # y = list(y)
            y = torch.tensor(label_y)
            # print(type(y))
            ###############

            # 前向转播
            # X, y = X.to(device), y.to(device)
            output = model(X)
            cur_loss = loss_fn(output, y)
            _, pred = torch.max(output, axis=1)
            cur_acc = torch.sum(y == pred) / output.shape[0]
            loss += cur_loss.item()
            current += cur_acc.item()
            n = n + 1
        print("val_loss" + str(loss / n))
        print("val_acc" + str(current / n))

        return current/n#返回精确度,精确度越高模型越好

 net.py中修改类别和类别数

然后就可以训练了,结果如下:

 

  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值