Pytorch学习记录-网络模型保存与加载

作者: 我的昵称违规了 | 来源:发表于2019-04-13 10:53 被阅读5次

    Pytorch学习记录-网络模型保存与加载

    老生常谈的问题,昨天用到了却还是不会。就又看了一下教程。搞定了。
    目前一个问题是我想对训练结果进行可视化,使用pyplot显示,但是在数据降维(比如MNIST数据)和转存到GPU部分没搞定。
    很多网络模型保存和加载的教程都是相互抄,根本没说清代码的整体结构。

    在这里说明一下,模型再次加载的时候,必须再次构建神经网络(你也可以粘过来)。
    分两个文件,我只做了简单的加载,因为目前来看是够用的,后面的参数啊冻结啊什么的暂时不管。
    ckpt格式是保存了模型的graph和各种状态权重,官网上推荐只保存state_dict,保存全部model的话速度会比较慢。

    但是我还是选择保存所有的,毕竟是个小的lstm。

    创建文件1,使用昨天的lstm模型

    import torch
    import torchvision
    import torch.nn as nn
    import torchvision.transforms as transforms
    from torch.autograd import Variable
    
    device = torch.device('cuda' if torch.cuda.is_available() else 'cpu')
    
    sequence_length = 28
    input_size = 28
    hidden_size = 128
    num_layers = 2
    num_classes = 10
    batch_size = 100
    num_epochs = 2
    learning_rate = 0.01
    
    train_dataset = torchvision.datasets.MNIST(root='./data/', train=True, transform=transforms.ToTensor(), download=True)
    test_dataset = torchvision.datasets.MNIST(root='./data/', train=False, transform=transforms.ToTensor())
    train_loader = torch.utils.data.DataLoader(dataset=train_dataset, batch_size=batch_size, shuffle=True)
    test_loader = torch.utils.data.DataLoader(dataset=test_dataset, batch_size=batch_size, shuffle=False)
    
    class RNN(nn.Module):
        def __init__(self, input_size, hidden_size, num_layers, num_classes):
            super(RNN, self).__init__()
            self.hidder_size = hidden_size
            self.num_layers = num_layers
            self.lstm = nn.LSTM(input_size, hidden_size, num_layers, batch_first=True)
            self.fc = nn.Linear(hidden_size, num_classes)
    
        def forward(self, x):
            h0 = torch.zeros(self.num_layers, x.size(0), self.hidder_size).to(device)
            c0 = torch.zeros(self.num_layers, x.size(0), self.hidder_size).to(device)
            out, _ = self.lstm(x, (h0, c0))
            out = self.fc(out[:, -1, :])
            return out
    
    
    model = RNN(input_size, hidden_size, num_layers, num_classes).to(device)
    # 损失和优化函数
    criterion = nn.CrossEntropyLoss()
    optimizer = torch.optim.Adam(model.parameters(), lr=learning_rate)
    
    # 训练模型
    total_step = len(train_loader)
    for epoch in range(num_epochs):
        for i, (images, labels) in enumerate(train_loader):
            images = images.reshape(-1, sequence_length, input_size).to(device)
            labels = labels.to(device)
    
            # Forward pass
            outputs = model(images)
            loss = criterion(outputs, labels)
    
            # Backward and optimize
            optimizer.zero_grad()
            loss.backward()
            optimizer.step()
    
            if (i + 1) % 100 == 0:
                print('Epoch [{}/{}], Step [{}/{}], Loss: {:.4f}'.format(epoch + 1, num_epochs, i + 1, total_step,
                                                                         loss.item()))
    
    # 测试模型
    with torch.no_grad():
        correct = 0
        total = 0
        for images, labels in test_loader:
            images = images.reshape(-1, sequence_length, input_size).to(device)
            labels = labels.to(device)
            outputs = model(images)
            _, predicted = torch.max(outputs.data, 1)
            total += labels.size(0)
            correct += (predicted == labels).sum().item()
    
        print('Test Accuracy of the model on the 10000 test images: {} %'.format(100 * correct / total))
    
    torch.save(model, 'TestSave.ckpt')
    
    #Test Accuracy of the model on the 10000 test images: 97.37 %
    

    这时你在根目录下就可以看到生成的模型了。现在我们加载出来,用同一批数据测试看两边的正确率是否相同。
    创建文件2,加载刚才保存的模型和参数

    
    import torch
    import torch.nn as nn
    import torchvision
    import torchvision.transforms as transforms
    from torch.autograd import Variable
    import matplotlib.pyplot as plt
    
    device = torch.device('cuda' if torch.cuda.is_available() else 'cpu')
    
    sequence_length = 28
    input_size = 28
    hidden_size = 128
    num_layers = 2
    num_classes = 10
    batch_size = 100
    num_epochs = 2
    learning_rate = 0.01
    
    train_dataset = torchvision.datasets.MNIST(root='./data/', train=True, transform=transforms.ToTensor(), download=True)
    test_dataset = torchvision.datasets.MNIST(root='./data/', train=False, transform=transforms.ToTensor())
    train_loader = torch.utils.data.DataLoader(dataset=train_dataset, batch_size=batch_size, shuffle=True)
    test_loader = torch.utils.data.DataLoader(dataset=test_dataset, batch_size=batch_size, shuffle=False)
    # test_x = Variable(torch.unsqueeze(test_dataset.test_data, dim=1), volatile=True).type(torch.FloatTensor) / 255
    # test_y = test_dataset.test_labels
    
    
    class RNN(nn.Module):
        def __init__(self, input_size, hidden_size, num_layers, num_classes):
            super(RNN, self).__init__()
            self.hidder_size = hidden_size
            self.num_layers = num_layers
            self.lstm = nn.LSTM(input_size, hidden_size, num_layers, batch_first=True)
            self.fc = nn.Linear(hidden_size, num_classes)
    
        def forward(self, x):
            h0 = torch.zeros(self.num_layers, x.size(0), self.hidder_size).to(device)
            c0 = torch.zeros(self.num_layers, x.size(0), self.hidder_size).to(device)
            out, _ = self.lstm(x, (h0, c0))
            out = self.fc(out[:, -1, :])
            return out
    
    
    model = RNN(input_size, hidden_size, num_layers, num_classes).to(device)
    # 损失和优化函数
    criterion = nn.CrossEntropyLoss()
    optimizer = torch.optim.Adam(model.parameters(), lr=learning_rate)
    
    model = torch.load('TestSave.ckpt')
    model.eval()
    
    # print(model.state_dict())
    # for k, v in enumerate(model.state_dict()):
    #     print(k, v)
    with torch.no_grad():
        correct = 0
        total = 0
        for images, labels in test_loader:
            images = images.reshape(-1, sequence_length, input_size).to(device)
            labels = labels.to(device)
            outputs = model(images)
            _, predicted = torch.max(outputs.data, 1)
            total += labels.size(0)
            correct += (predicted == labels).sum().item()
    
        print('Test Accuracy of the model on the 10000 test images: {} %'.format(100 * correct / total))
    
    #Test Accuracy of the model on the 10000 test images: 97.31 %
    

    都达到了97.3%。暂时先这样,继续学下面的了。

    相关文章

      网友评论

        本文标题:Pytorch学习记录-网络模型保存与加载

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