LeNet-5(fashion-mnist)

前言

LeNet是最早发布的卷积神经网络之一。该模型被提出用于识别图像中的手写数字。

LeNet

LeNet-5由以下两个部分组成

  • 卷积编码器(2)
  • 全连接层(3)
    卷积块由一个卷积层、一个sigmoid激活函数和一个平均汇聚层组成。
    第一个卷积层有6个输出通道,第二个卷积层有16个输出通道。采用2×2的汇聚操作,且步幅为2.
    3个全连接层分别有120,84,10个输出。
    此处对原始模型做出部分修改,去除最后一层的高斯激活。
net=nn.Sequential(nn.Conv2d(1,6,kernel_size=5,padding=2),nn.Sigmoid(),
                  nn.AvgPool2d(kernel_size=2,stride=2),
                  nn.Conv2d(6,16,kernel_size=5),nn.Sigmoid(),
                  nn.AvgPool2d(kernel_size=2,stride=2),
                  nn.Flatten(),
                  nn.Linear(16*5*5,120),nn.Sigmoid(),
                  nn.Linear(120,84),nn.Sigmoid(),
                  nn.Linear(84,10))

模型训练

为了加快训练,使用GPU计算测试集上的精度以及训练过程中的计算。
此处采用xavier初始化模型参数以及交叉熵损失函数和小批量梯度下降。

batch_size=256
train_iter,test_iter=data_iter.load_data_fashion_mnist(batch_size)

将数据送入GPU进行计算测试集准确率

def evaluate_accuracy_gpu(net,data_iter,device=None):
    """使用GPU计算模型在数据集上的精度"""
    if isinstance(net,torch.nn.Module):
        net.eval()
        if not device:
            device=next(iter(net.parameters())).device
    # 正确预测的数量,预测的总数
    eva = 0.0
    y_num = 0.0
    with torch.no_grad():
        for X,y in data_iter:
            if isinstance(X,list):
                X=[x.to(device) for x in X]
            else:
                X=X.to(device)
            y=y.to(device)
            eva += accuracy(net(X), y)
            y_num += y.numel()
    return eva/y_num

训练过程同样将数据送入GPU计算

def train_epoch_gpu(net, train_iter, loss, updater,device):

    # 训练损失之和,训练准确数之和,样本数
    train_loss_sum = 0.0
    train_acc_sum = 0.0
    num_samples = 0.0
    # timer = d2l.torch.Timer()
    for i, (X, y) in enumerate(train_iter):
        # timer.start()
        updater.zero_grad()
        X, y = X.to(device), y.to(device)
        y_hat = net(X)
        l = loss(y_hat, y)
        l.backward()
        updater.step()
        with torch.no_grad():
            train_loss_sum += l * X.shape[0]
            train_acc_sum += evaluation.accuracy(y_hat, y)
            num_samples += X.shape[0]
        # timer.stop()
    return train_loss_sum/num_samples,train_acc_sum/num_samples


def train_gpu(net,train_iter,test_iter,num_epochs,lr,device):
    def init_weights(m):
        if type(m)==torch.nn.Linear or type(m)==torch.nn.Conv2d:
            torch.nn.init.xavier_uniform_(m.weight)

    net.apply(init_weights)
    net.to(device)
    print('training on',device)
    optimizer=torch.optim.SGD(net.parameters(),lr=lr)
    loss=torch.nn.CrossEntropyLoss()
    # num_batches=len(train_iter)
    tr_l=[]
    tr_a=[]
    te_a=[]
    for epoch in range(num_epochs):
        net.train()
        train_metric=train_epoch_gpu(net,train_iter,loss,optimizer,device)
        test_accuracy = evaluation.evaluate_accuracy_gpu(net, test_iter)
        train_loss, train_acc = train_metric
        train_loss = train_loss.cpu().detach().numpy()
        tr_l.append(train_loss)
        tr_a.append(train_acc)
        te_a.append(test_accuracy)
        print(f'epoch: {epoch + 1}, train_loss: {train_loss}, train_acc: {train_acc}, test_acc:{test_accuracy}')
    x = torch.arange(num_epochs)
    plt.plot((x + 1), tr_l, '-', label='train_loss')
    plt.plot(x + 1, tr_a, '--', label='train_acc')
    plt.plot(x + 1, te_a, '-.', label='test_acc')
    plt.legend()
    plt.show()
    print(f'on {str(device)}')
lr,num_epochs=0.9,10
Train.train_gpu(net,train_iter,test_iter,num_epochs,lr,device='cuda')

在这里插入图片描述
在这里插入图片描述

  • 9
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
利用tensorflow实现的卷积神经网络来进行MNIST手写数字图像的分类。 #导入numpy模块 import numpy as np #导入tensorflow模块,程序使用tensorflow来实现卷积神经网络 import tensorflow as tf #下载mnist数据集,并从mnist_data目录中读取数据 from tensorflow.examples.tutorials.mnist import input_data mnist = input_data.read_data_sets('mnist_data',one_hot=True) #(1)这里的“mnist_data” 是和当前文件相同目录下的一个文件夹。自己先手工建立这个文件夹,然后从https://yann.lecun.com/exdb/mnist/ 下载所需的4个文件(即该网址中第三段“Four files are available on this site:”后面的四个文件),并放到目录MNIST_data下即可。 #(2)MNIST数据集是手写数字字符的数据集。每个样本都是一张28*28像素的灰度手写数字图片。 #(3)one_hot表示独热编码,其值被设为true。在分类问题的数据集标注时,如何不采用独热编码的方式, 类别通常就是一个符号而已,比如说是9。但如果采用独热编码的方式,则每个类表示为一个列表list,共计有10个数值,但只有一个为1,其余均为0。例如,“9”的独热编码可以为[00000 00001]. #定义输入数据x和输出y的形状。函数tf.placeholder的目的是定义输入,可以理解为采用占位符进行占位。 #None这个位置的参数在这里被用于表示样本的个数,而由于样本个数此时具体是多少还无法确定,所以这设为None。而每个输入样本的特征数目是确定的,即为28*28。 input_x = tf.placeholder(tf.float32,[None,28*28])/255 #因为每个像素的取值范围是 0~255 output_y = tf.placeholder(tf.int32,[None,10]) #10表示10个类别 #输入层的输入数据input_x被reshape成四维数据,其中第一维的数据代表了图片数量 input_x_images = tf.reshape(input_x,[-1,28,28,1]) test_x = mnist.test.images[:3000] #读取测试集图片的特征,读取3000个图片 test_y = mnist.test.labels[:3000] #读取测试集图片的标签。就是这3000个图片所对应的标签
好的,我可以为您提供一份基于PyTorch实现LeNet-5模型的代码,并使用FashionMNIST数据集进行训练。 首先,您需要安装PyTorch和torchvision库,以便使用LeNet-5模型和FashionMNIST数据集。您可以使用以下命令在终端中安装它们: ``` pip install torch pip install torchvision ``` 然后,您可以使用以下代码来定义LeNet-5模型: ```python import torch.nn as nn import torch.nn.functional as F class LeNet5(nn.Module): def __init__(self): super(LeNet5, self).__init__() self.conv1 = nn.Conv2d(1, 6, kernel_size=5, stride=1) self.pool1 = nn.MaxPool2d(kernel_size=2, stride=2) self.conv2 = nn.Conv2d(6, 16, kernel_size=5, stride=1) self.pool2 = nn.MaxPool2d(kernel_size=2, stride=2) self.fc1 = nn.Linear(16 * 4 * 4, 120) self.fc2 = nn.Linear(120, 84) self.fc3 = nn.Linear(84, 10) def forward(self, x): x = self.pool1(F.relu(self.conv1(x))) x = self.pool2(F.relu(self.conv2(x))) x = x.view(-1, 16 * 4 * 4) x = F.relu(self.fc1(x)) x = F.relu(self.fc2(x)) x = self.fc3(x) return x ``` 这个LeNet-5模型定义了两个卷积层和三个全连接层。在forward()函数中,我们使用ReLU激活函数和max pooling操作来提取特征,并将特征传递到全连接层中进行分类。 接下来,您可以使用以下代码来加载FashionMNIST数据集并进行训练: ```python import torch import torch.nn as nn import torch.optim as optim import torchvision.transforms as transforms import torchvision.datasets as datasets # 定义一些超参数 batch_size = 64 learning_rate = 0.01 num_epochs = 10 # 加载FashionMNIST数据集 transform = transforms.Compose([ transforms.ToTensor(), transforms.Normalize((0.1307,), (0.3081,)) ]) train_dataset = datasets.FashionMNIST(root='./data', train=True, transform=transform, download=True) train_loader = torch.utils.data.DataLoader(train_dataset, batch_size=batch_size, shuffle=True) # 实例化LeNet-5模型和损失函数 model = LeNet5() criterion = nn.CrossEntropyLoss() optimizer = optim.SGD(model.parameters(), lr=learning_rate) # 训练模型 for epoch in range(num_epochs): for i, (images, labels) in enumerate(train_loader): # 前向传播和反向传播 outputs = model(images) loss = criterion(outputs, labels) optimizer.zero_grad() loss.backward() optimizer.step() # 每100步打印一次日志 if (i + 1) % 100 == 0: print('Epoch [{}/{}], Step [{}/{}], Loss: {:.4f}'.format(epoch + 1, num_epochs, i + 1, len(train_loader), loss.item())) ``` 在这个训练循环中,我们首先使用SGD优化器和交叉熵损失函数实例化了LeNet-5模型。然后,我们将FashionMNIST数据集加载到train_loader中,并使用train_loader在每个epoch中进行训练。对于每个batch,我们首先执行前向传播,计算输出和损失,然后执行反向传播并更新模型参数。最后,我们在每个epoch的日志中记录损失值。 希望这个代码对您有所帮助!

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值