• MNIST数据集分类


    import torch
    import torch.nn as nn
    import torch.nn.functional as F
    import torch.optim as optim
    from torchvision import datasets, transforms
    import matplotlib.pyplot as plt
    import numpy
    # 一个函数,用来计算模型中有多少参数
    def get_n_params(model):
        np=0
        for p in list(model.parameters()):
            np += p.nelement()
        return np
    
    # 使用GPU训练,可以在菜单 "代码执行工具" -> "更改运行时类型" 里进行设置
    device = torch.device("cuda:0" if torch.cuda.is_available() else "cpu")
    

    1.加载数据 (MNIST)

    torchvision.datasets.MNIST(root, train=True, transform=None, target_transform=None, download=False)
    input_size  = 28*28   # MNIST上的图像尺寸是 28x28
    output_size = 10      # 类别为 0 到 9 的数字,因此为十类
    
    train_loader = torch.utils.data.DataLoader(
        datasets.MNIST('./data', train=True, download=True,
            transform=transforms.Compose(
                [transforms.ToTensor(),
                 transforms.Normalize((0.1307,), (0.3081,))])),
        batch_size=64, shuffle=True)
    
    test_loader = torch.utils.data.DataLoader(
        datasets.MNIST('./data', train=False, transform=transforms.Compose([
                 transforms.ToTensor(),
                 transforms.Normalize((0.1307,), (0.3081,))])),
        batch_size=1000, shuffle=True)
    
    #显示数据集中的部分图像
    plt.figure(figsize=(8, 5))
    for i in range(20):
        plt.subplot(4, 5, i + 1)
        image, _ = train_loader.dataset.__getitem__(i)
        plt.imshow(image.squeeze().numpy(),'gray')
        plt.axis('off');
    

    2.创建网络

    class FC2Layer(nn.Module):
        def __init__(self, input_size, n_hidden, output_size):
            super(FC2Layer, self).__init__()
            self.input_size = input_size
            # 这里直接用 Sequential 就定义了网络,注意要和下面 CNN 的代码区分开
            self.network = nn.Sequential(
                nn.Linear(input_size, n_hidden), 
                nn.ReLU(), 
                nn.Linear(n_hidden, n_hidden), 
                nn.ReLU(), 
                nn.Linear(n_hidden, output_size), 
                nn.LogSoftmax(dim=1)
            )
        def forward(self, x):
            x = x.view(-1, self.input_size)
            return self.network(x)
    class CNN(nn.Module):
        def __init__(self, input_size, n_feature, output_size):
            super(CNN, self).__init__()
            self.n_feature = n_feature
            self.conv1 = nn.Conv2d(in_channels=1, out_channels=n_feature, kernel_size=5)
            self.conv2 = nn.Conv2d(n_feature, n_feature, kernel_size=5)
            self.fc1 = nn.Linear(n_feature*4*4, 50)
            self.fc2 = nn.Linear(50, 10)    
        # 下面的 forward 函数,定义了网络的结构,按照一定顺序,把上面构建的一些结构组织起来
        # 意思就是,conv1, conv2 等等的,可以多次重用
        def forward(self, x, verbose=False):
            x = self.conv1(x)
            x = F.relu(x)
            x = F.max_pool2d(x, kernel_size=2)
            x = self.conv2(x)
            x = F.relu(x)
            x = F.max_pool2d(x, kernel_size=2)
            x = x.view(-1, self.n_feature*4*4)
            x = self.fc1(x)
            x = F.relu(x)
            x = self.fc2(x)
            x = F.log_softmax(x, dim=1)
            return x
       
    #定义训练和测试函数
    # 训练函数
    def train(model):
        model.train()
        for batch_idx, (data, target) in enumerate(train_loader):
            # 把数据送到GPU中
            data, target = data.to(device), target.to(device)
            optimizer.zero_grad()
            output = model(data)
            loss = F.nll_loss(output, target)
            loss.backward()
            optimizer.step()
            if batch_idx % 100 == 0:
                print('Train: [{}/{} ({:.0f}%)]	Loss: {:.6f}'.format(
                    batch_idx * len(data), len(train_loader.dataset),
                    100. * batch_idx / len(train_loader), loss.item()))
    #测试函数
    def test(model):
        model.eval()
        test_loss = 0
        correct = 0
        for data, target in test_loader:
            # 把数据送到GPU中
            data, target = data.to(device), target.to(device)
            # 把数据送入模型,得到预测结果
            output = model(data)
            # 计算本次batch的损失,并加到 test_loss 中
            test_loss += F.nll_loss(output, target, reduction='sum').item()
            # get the index of the max log-probability,最后一层输出10个数,
            # 值最大的那个即对应着分类结果,然后把分类结果保存在 pred 里
            pred = output.data.max(1, keepdim=True)[1]
            # 将 pred 与 target 相比,得到正确预测结果的数量,并加到 correct 中                       correct += pred.eq(target.data.view_as(pred)).cpu().sum().item()
        test_loss /= len(test_loader.dataset)
        accuracy = 100. * correct / len(test_loader.dataset)
        print('
    Test set: Average loss: {:.4f}, Accuracy: {}/{} ({:.0f}%)
    '.format(
            test_loss, correct, len(test_loader.dataset),
            accuracy))
    
    1. 在小型全连接网络上训练(Fully-connected network)
    n_hidden = 8 # number of hidden units
    
    model_fnn = FC2Layer(input_size, n_hidden, output_size)
    model_fnn.to(device)
    optimizer = optim.SGD(model_fnn.parameters(), lr=0.01, momentum=0.5)
    print('Number of parameters: {}'.format(get_n_params(model_fnn)))
    
    train(model_fnn)
    test(model_fnn)
    

    4.在卷积神经网络上训练

    # Training settings 
    n_features = 6 # number of feature maps
    
    model_cnn = CNN(input_size, n_features, output_size)
    model_cnn.to(device)
    optimizer = optim.SGD(model_cnn.parameters(), lr=0.01, momentum=0.5)
    print('Number of parameters: {}'.format(get_n_params(model_cnn)))
    
    train(model_cnn)
    test(model_cnn)
    

    5.打乱像素顺序再次在两个网络上训练与测试

    perm = torch.randperm(784)
    plt.figure(figsize=(8, 4))
    for i in range(10):
        image, _ = train_loader.dataset.__getitem__(i)
        # permute pixels
        image_perm = image.view(-1, 28*28).clone()
        image_perm = image_perm[:, perm]
        image_perm = image_perm.view(-1, 1, 28, 28)
        plt.subplot(4, 5, i + 1)
        plt.imshow(image.squeeze().numpy(), 'gray')
        plt.axis('off')
        plt.subplot(4, 5, i + 11)
        plt.imshow(image_perm.squeeze().numpy(), 'gray')
        plt.axis('off')
    
    # 对每个 batch 里的数据,打乱像素顺序的函数
    def perm_pixel(data, perm):
        # 转化为二维矩阵
        data_new = data.view(-1, 28*28)
        # 打乱像素顺序
        data_new = data_new[:, perm]
        # 恢复为原来4维的 tensor
        data_new = data_new.view(-1, 1, 28, 28)
        return data_new
    
    # 训练函数
    def train_perm(model, perm):
        model.train()
        for batch_idx, (data, target) in enumerate(train_loader):
            data, target = data.to(device), target.to(device)
            # 像素打乱顺序
            data = perm_pixel(data, perm)
    
            optimizer.zero_grad()
            output = model(data)
            loss = F.nll_loss(output, target)
            loss.backward()
            optimizer.step()
            if batch_idx % 100 == 0:
                print('Train: [{}/{} ({:.0f}%)]	Loss: {:.6f}'.format(
                    batch_idx * len(data), len(train_loader.dataset),
                    100. * batch_idx / len(train_loader), loss.item()))
    
    # 测试函数
    def test_perm(model, perm):
        model.eval()
        test_loss = 0
        correct = 0
        for data, target in test_loader:
            data, target = data.to(device), target.to(device)
    
            # 像素打乱顺序
            data = perm_pixel(data, perm)
    
            output = model(data)
            test_loss += F.nll_loss(output, target, reduction='sum').item()
            pred = output.data.max(1, keepdim=True)[1]                                            
            correct += pred.eq(target.data.view_as(pred)).cpu().sum().item()
    
        test_loss /= len(test_loader.dataset)
        accuracy = 100. * correct / len(test_loader.dataset)
        print('
    Test set: Average loss: {:.4f}, Accuracy: {}/{} ({:.0f}%)
    '.format(
            test_loss, correct, len(test_loader.dataset),
            accuracy))
    
    #在全连接网络上训练与测试:
    perm = torch.randperm(784)
    n_hidden = 8 # number of hidden units
    
    model_fnn = FC2Layer(input_size, n_hidden, output_size)
    model_fnn.to(device)
    optimizer = optim.SGD(model_fnn.parameters(), lr=0.01, momentum=0.5)
    print('Number of parameters: {}'.format(get_n_params(model_fnn)))
    
    train_perm(model_fnn, perm)
    test_perm(model_fnn, perm)
    #在卷积神经网络上训练与测试
    perm = torch.randperm(784)
    n_features = 6 # number of feature maps
    
    model_cnn = CNN(input_size, n_features, output_size)
    model_cnn.to(device)
    optimizer = optim.SGD(model_cnn.parameters(), lr=0.01, momentum=0.5)
    print('Number of parameters: {}'.format(get_n_params(model_cnn)))
    
    train_perm(model_cnn, perm)
    test_perm(model_cnn, perm)
        
    
  • 相关阅读:
    微服务实战(二):使用API Gateway
    微服务实战(一):微服务架构的优势与不足
    在WIN7、WIN10操作系统用WebDAV映射网络驱动器需要的操作
    docker开机启动和docker-compose开机启动执行相应的各个docker容器
    /etc/rc.d/init.d自启动程序说明
    C# 通过反射实现对象映射:将2个属性相近的对象相互转换
    添加windows右键菜单:使用exe应用程序打开文件/文件夹
    .NET5 MVC Program.cs 笔记
    前端 JS 正则表达式积累
    VS Code 快捷键
  • 原文地址:https://www.cnblogs.com/lixinhh/p/13414333.html
Copyright © 2020-2023  润新知