美文网首页
Pytorch学习之LSTM识别MNIST数据集

Pytorch学习之LSTM识别MNIST数据集

作者: 骆旺达 | 来源:发表于2019-01-09 21:13 被阅读0次

    实验RNN循环神经网络识别MNIST手写数字集

    本文主要是讲述pytorch实现的RNN神经网络去识别MNIST手写数据集,但RNN网络是一个序列化网络,倘若对于大图片来说,效率会很低。倘若对图片进行识别,尽量选择CNN卷积神经网络网络。
    本文实现的算法分类准确度在90%左右

    引入库函数

    引入pytorch库,主要是nn,optim,Variable。

    import torch
    from torch import nn,optim
    from torch.autograd import Variable
    from torch.utils.data import DataLoader
    from torchvision import datasets,transforms
    

    设置超参数

    设置超参数,其为神经网络的基础配置。

    # 超参数
    batch_size = 100    # 批大小
    learning_rate = 0.01 # 学习率
    num_epoches = 20  # 训练次数
    

    数据集预处理

    将图片转换成tensor类型,并把图片中心化,缩放到[-1,1]上。

    data_tf = transforms.Compose([transforms.ToTensor(),transforms.Normalize([0.5],[0.5])])
    

    获得数据

    下载MINIST集数据,并获取训练和测试集数据。

    train_dataset = datasets.MNIST(root='./data',train=True,transform=data_tf,download=True)
    test_dataset = datasets.MNIST(root='./data',train=False,transform=data_tf)
    train_loader = DataLoader(train_dataset,batch_size=batch_size,shuffle=True)
    test_loader = DataLoader(test_dataset,batch_size=batch_size,shuffle=False)
    

    建立RNN模型

    建立RNN神经网络,该神经网络为两层,第一层为LSTM神经网络,用于进行序列分析,第二层为全连接层,用作分类。

    class Rnn(nn.Module):
        def __init__(self,in_dim,hidden_dim,n_layer,n_class):
            super(Rnn,self).__init__()
            self.n_layer = n_layer
            self.hidden_dim = hidden_dim
            self.lstm = nn.LSTM(in_dim,hidden_dim,n_layer,batch_first=True)
            self.classifier = nn.Linear(hidden_dim,n_class)
        
        def forward(self,x):
            out,_ = self.lstm(x)
            out = out[:,-1,:]
            out = self.classifier(out)
            return out
        
        
    model = Rnn(28,128,2,10)  # 图片大小是28x28
    use_gpu = torch.cuda.is_available()  # 判断是否有GPU加速
    if use_gpu:
        model = model.cuda()
    

    定义损失函数和优化器

    损失函数为交叉熵顺势函数,优化器的自适应随机梯度下降算法

    # 定义loss和optimizer
    criterion = nn.CrossEntropyLoss()
    optimizer = optim.Adam(model.parameters(), lr=learning_rate)
    

    训练数据和评估

    训练num_epoches次,每次记录损失值及进行模型测试

    # 开始训练
    for epoch in range(num_epoches):
        running_loss = 0.0
        running_acc = 0.0
        for i, data in enumerate(train_loader, 1):
            img, label = data
            img = img.squeeze(1)
            if torch.cuda.is_available():
                img = img.cuda()
                label = label.cuda()
            else:
                img = Variable(img)
                label = Variable(label)
    
                # 向前传播
                out = model(img)
                loss = criterion(out, label)
                running_loss += loss.data[0] * label.size(0)
                _, pred = torch.max(out, 1)
                num_correct = (pred == label).sum()
                running_acc += num_correct.data[0]
                
                # 向后传播
                optimizer.zero_grad()
                loss.backward()
                optimizer.step()
                if i % 300 == 0:
                    print('[{}/{}] Loss: {:.6f}, Acc: {:.6f}'.format(
                        epoch + 1, num_epoches, running_loss.item() / (batch_size * i),
                        running_acc.item() / (batch_size * i)))
            print('Finish {} epoch, Loss: {:.6f}, Acc: {:.6f}'.format(
                epoch + 1, running_loss.item() / (len(train_dataset)), running_acc.item() / (len(
                    train_dataset))))
                    
        model.eval()
        eval_loss = 0.
        eval_acc = 0.
        for data in test_loader:
            img, label = data
            b, c, h, w = img.size()
            assert c == 1, 'channel must be 1'
            img = img.squeeze(1)
            # img = img.view(b*h, w)
            # img = torch.transpose(img, 1, 0)
            # img = img.contiguous().view(w, b, h)
            if use_gpu:
                img = Variable(img, volatile=True).cuda()
                label = Variable(label, volatile=True).cuda()
            else:
                img = Variable(img, volatile=True)
                label = Variable(label, volatile=True)
            out = model(img)
            loss = criterion(out, label)
            eval_loss += loss.data[0] * label.size(0)
            _, pred = torch.max(out, 1)
            num_correct = (pred == label).sum()
            eval_acc += num_correct.data[0]
        print('Test Loss: {:.6f}, Acc: {:.6f}'.format(eval_loss.item() / (len(
            test_dataset)), eval_acc.item() / (len(test_dataset))))
    

    模型结果

    [1/20] Loss: 0.276766, Acc: 0.917283  
    Test Loss: 0.227039, Acc: 0.931700
    [2/20] Loss: 0.368415, Acc: 0.889717
    Finish 2 epoch, Loss: 0.368415, Acc: 0.889717
    Test Loss: 0.401789, Acc: 0.882400
    [3/20] Loss: 0.308447, Acc: 0.907267
    Finish 3 epoch, Loss: 0.308447, Acc: 0.907267
    Test Loss: 0.254289, Acc: 0.923200
    [4/20] Loss: 0.310579, Acc: 0.905850
    Finish 4 epoch, Loss: 0.310579, Acc: 0.905850
    Test Loss: 0.308438, Acc: 0.904400
    [5/20] Loss: 0.400899, Acc: 0.878133
    Finish 5 epoch, Loss: 0.400899, Acc: 0.878133
    Test Loss: 0.391112, Acc: 0.883500
    
    ...
    
    [11/20] Loss: 0.232482, Acc: 0.928167
    Finish 11 epoch, Loss: 0.232482, Acc: 0.928167
    Test Loss: 0.179359, Acc: 0.944000
    
    ...
    
    [13/20] Loss: 0.209641, Acc: 0.934883
    Finish 13 epoch, Loss: 0.209641, Acc: 0.934883
    Test Loss: 0.187486, Acc: 0.943700
    
    ...
    
    [19/20] Loss: 0.304291, Acc: 0.906167
    Finish 19 epoch, Loss: 0.304291, Acc: 0.906167
    Test Loss: 0.303386, Acc: 0.910300
    [20/20] Loss: 0.312536, Acc: 0.903133
    Finish 20 epoch, Loss: 0.312536, Acc: 0.903133
    Test Loss: 0.349427, Acc: 0.885400
    

    相关文章

      网友评论

          本文标题:Pytorch学习之LSTM识别MNIST数据集

          本文链接:https://www.haomeiwen.com/subject/fblnrqtx.html