美文网首页
pytorch+cnn实现图像分类器

pytorch+cnn实现图像分类器

作者: __method__ | 来源:发表于2020-07-09 01:01 被阅读0次

    基本数学运算

    import torch
    
    #定义向量
    vector = torch.tensor([1,2,3,4])
    print('Vector:\t\t', vector)
    print('Vector Shape:\t', vector.shape)
    

    Vector: tensor([1, 2, 3, 4])
    Vector Shape: torch.Size([4])

    #定义矩阵
    matrix = torch.tensor([[1,2],[3,4]])
    print('Matrix:\n', matrix)
    print('Matirx Shape:\n', matrix.shape)
    

    Matrix:
    tensor([[1, 2],
    [3, 4]])
    Matirx Shape:
    torch.Size([2, 2])

    #定义张量
    tensor = torch.tensor([[[1,2],[3,4]],[[1,2],[3,4]]])
    print('Tensor:\n', tensor)
    print('Tensor Shape:\n', tensor.shape)
    

    Tensor:
    tensor([[[1, 2],
    [3, 4]],
    [[1, 2],
    [3, 4]]])
    Tensor Shape:
    torch.Size([2, 2, 2])

    
    

    读取ciffar

    import pickle
    
    def unpickle(file):
        import pickle
        with open(file, 'rb') as fo:
            dict = pickle.load(fo, encoding='bytes')
        return dict
    
    label_names = ["airplane","automobile","bird","cat","deer","dog","frog","horse","ship","truck"]
    
    import glob
    
    train_list = glob.glob('./data/cifar-10-batches-py/data_batch_*')
    train_list
    
    ['./data/cifar-10-batches-py\\data_batch_1',
     './data/cifar-10-batches-py\\data_batch_2',
     './data/cifar-10-batches-py\\data_batch_3',
     './data/cifar-10-batches-py\\data_batch_4',
     './data/cifar-10-batches-py\\data_batch_5']
    
    l= [unpickle(l) for l in train_list]
    
    l_dict = l[0]
    l_dict.keys()
    # b'batch_label 第几个文件一共5个, b'labels数据标签, b'data数据b'filenames是数据的列名
    
    dict_keys([b'batch_label', b'labels', b'data', b'filenames'])
    
    l_dict[b'batch_label']
    
    b'training batch 1 of 5'
    
    # l_dict[b'labels']
    l_dict[b'data'].shape # (10000, 3072)
    # l_dict[b'filenames']
    
    (10000, 3072)
    

    显示图像

    import torchvision
    import torchvision.transforms as transforms
    
    transform = transforms.Compose(
        [transforms.ToTensor(),
         transforms.Normalize((0.5, 0.5, 0.5), (0.5, 0.5, 0.5))
        ]
        )
    
    #训练数据集
    trainset = torchvision.datasets.CIFAR10(root='./data', train=True, 
                                           download=True, transform=transform)
    trainloader = torch.utils.data.DataLoader(trainset, batch_size=16,
                                             shuffle=True, num_workers=2)
    
    #测试数据集
    testset = torchvision.datasets.CIFAR10(root='./data', train=False,
                                          download=True, transform=transform)
    testloader = torch.utils.data.DataLoader(testset, batch_size=16,
                                            shuffle=False, num_workers=2)
    
    Files already downloaded and verified
    Files already downloaded and verified
    
    import matplotlib.pyplot as plt
    import numpy as np
    %matplotlib inline
    
    def imshow(img):
        # 输入数据: torch.tensor [c, h, w]
        img = img / 2+0.5
        nping = img.numpy()
        nping = np.transpose(nping, (1,2,0)) # [h,w,c]
        plt.imshow(nping)
        
    dataiter = iter(trainloader) #随机加载一个mini batch
    images, labels = dataiter.next()
    
    imshow(torchvision.utils.make_grid(images))
    

    分步建立神经网络

    import torch
    import torch.nn as nn
    import torch.nn.functional as F
    
    
    class Net(nn.Module):
        def __init__(self): #定义神经网络结构, 输入数据 1x32x32
            super(Net, self).__init__()
            # 第一层(卷积层)
            self.conv1 = nn.Conv2d(1,6,3) #输入频道1, 输出频道6, 卷积3x3
            # 第二层(卷积层)
            self.conv2 = nn.Conv2d(6,16,3) #输入频道6, 输出频道16, 卷积3x3
            # 第三层(全连接层)
            self.fc1 = nn.Linear(16*28*28, 512) #输入维度16x28x28=12544,输出维度 512
            # 第四层(全连接层)
            self.fc2 = nn.Linear(512, 64) #输入维度512, 输出维度64
            # 第五层(全连接层)
            self.fc3 = nn.Linear(64, 2) #输入维度64, 输出维度2
        
        def forward(self, x): #定义数据流向
            x = self.conv1(x)
            x = F.relu(x)
            
            x = self.conv2(x)
            x = F.relu(x)
            
            x = x.view(-1, 16*28*28)
            x = self.fc1(x)
            x = F.relu(x)
            
            x = self.fc2(x)
            x = F.relu(x)
            
            x = self.fc3(x)
            
            return x
            
    
    net = Net()
    print(net)
    
    Net(
      (conv1): Conv2d(1, 6, kernel_size=(3, 3), stride=(1, 1))
      (conv2): Conv2d(6, 16, kernel_size=(3, 3), stride=(1, 1))
      (fc1): Linear(in_features=12544, out_features=512, bias=True)
      (fc2): Linear(in_features=512, out_features=64, bias=True)
      (fc3): Linear(in_features=64, out_features=2, bias=True)
    )
    
    #生成随机输入
    input_data = torch.randn(1,1,32,32) 
    print(input_data)
    print(input_data.size())
    
    tensor([[[[-0.5518,  0.0649,  0.9500,  ...,  0.2207, -1.1846, -0.5081],
              [-0.5137,  0.6061,  0.2845,  ..., -0.6264, -0.8313,  0.4624],
              [ 0.3367, -1.1461,  0.8586,  ..., -1.4342,  0.3141,  1.2599],
              ...,
              [-0.4495,  1.7554, -1.1736,  ..., -1.5489,  1.8449,  1.5590],
              [-0.8913,  0.5652,  1.0342,  ..., -0.4757,  1.1992,  0.8304],
              [ 0.1675, -1.3038,  2.6100,  ..., -1.1493,  0.3754, -0.3571]]]])
    torch.Size([1, 1, 32, 32])
    
    # 运行神经网络
    out = net(input_data)
    print(out)
    print(out.size())
    
    tensor([[-0.0965,  0.0616]], grad_fn=<ThAddmmBackward>)
    torch.Size([1, 2])
    
    # 随机生成真实值
    target = torch.randn(2)
    target = target.view(1,-1)
    print(target)
    
    tensor([[-1.1073,  0.6537]])
    
    criterion = nn.L1Loss() # 定义损失函数
    loss = criterion(out, target) # 计算损失
    print(loss)
    
    tensor(0.8014, grad_fn=<L1LossBackward>)
    
    # 反向传递
    net.zero_grad() #清零梯度
    loss.backward() #自动计算梯度、反向传递
    
    
    import torch.optim as optim
    
    optimizer = optim.SGD(net.parameters(), lr=0.01)
    optimizer.step()
    
    out = net(input_data)
    print(out)
    print(out.size())
    
    tensor([[-0.1450,  0.1121]], grad_fn=<ThAddmmBackward>)
    torch.Size([1, 2])
    
    
    

    CNN分类器

    import torch
    import torchvision
    import torchvision.transforms as transforms
    from tqdm import tqdm
    
    transform = transforms.Compose(
        [transforms.ToTensor(),
         transforms.Normalize((0.5, 0.5, 0.5), (0.5, 0.5, 0.5))
        ]
        )
    
    #训练数据集
    trainset = torchvision.datasets.CIFAR10(root='./data', train=True, 
                                           download=True, transform=transform)
    trainloader = torch.utils.data.DataLoader(trainset, batch_size=16,
                                             shuffle=True, num_workers=2)
    
    #测试数据集
    testset = torchvision.datasets.CIFAR10(root='./data', train=False,
                                          download=True, transform=transform)
    testloader = torch.utils.data.DataLoader(testset, batch_size=16,
                                            shuffle=False, num_workers=2)
    
    
    
    
    Files already downloaded and verified
    Files already downloaded and verified
    
    import matplotlib.pyplot as plt
    import numpy as np
    %matplotlib inline
    
    def imshow(img):
        # 输入数据: torch.tensor [c, h, w]
        img = img / 2+0.5
        nping = img.numpy()
        nping = np.transpose(nping, (1,2,0)) # [h,w,c]
        plt.imshow(nping)
        
    dataiter = iter(trainloader) #随机加载一个mini batch
    images, labels = dataiter.next()
    
    imshow(torchvision.utils.make_grid(images))
    
    import torch.nn as nn
    import torch.nn.functional as F
    
    class Net(nn.Module):
        def __init__(self): #定义神经网络结构, 输入数据 3x32x32
            super(Net, self).__init__()
            # 第一层(卷积层)
            self.conv1 = nn.Conv2d(3,6,3) #输入频道3, 输出频道6, 卷积3x3
            # 第二层(卷积层)
            self.conv2 = nn.Conv2d(6,16,3) #输入频道6, 输出频道16, 卷积3x3
            # 第三层(全连接层)
            self.fc1 = nn.Linear(16*28*28, 512) #输入维度16x28x28=12544,输出维度 512
            # 第四层(全连接层)
            self.fc2 = nn.Linear(512, 64) #输入维度512, 输出维度64
            # 第五层(全连接层)
            self.fc3 = nn.Linear(64, 10) #输入维度64, 输出维度10
        
        def forward(self, x): #定义数据流向
            x = self.conv1(x)
            x = F.relu(x)
            
            x = self.conv2(x)
            x = F.relu(x)
            
            x = x.view(-1, 16*28*28)
            x = self.fc1(x)
            x = F.relu(x)
            
            x = self.fc2(x)
            x = F.relu(x)
            
            x = self.fc3(x)
            
            return x
            
    
    net = Net()
    print(net)
    
    Net(
      (conv1): Conv2d(3, 6, kernel_size=(3, 3), stride=(1, 1))
      (conv2): Conv2d(6, 16, kernel_size=(3, 3), stride=(1, 1))
      (fc1): Linear(in_features=12544, out_features=512, bias=True)
      (fc2): Linear(in_features=512, out_features=64, bias=True)
      (fc3): Linear(in_features=64, out_features=10, bias=True)
    )
    
    import torch.optim as optim
    
    criterion = nn.CrossEntropyLoss()
    optimizer = optim.SGD(net.parameters(), lr=0.0001, momentum=0.9)
    
    
    train_loss_hist = []
    test_loss_hist = []
    
    for epoch in tqdm(range(20)):
        #训练
        net.train()
        running_loss = 0.0
        for i, data in enumerate(trainloader):
            images, labels = data        
            outputs = net(images)
            loss = criterion(outputs, labels) # 计算损失
            
            optimizer.zero_grad()
            loss.backward()
            optimizer.step()
            
            running_loss += loss.item()
            if(i%250 == 0): #每250 mini batch 测试一次
                correct = 0.0
                total = 0.0
    
                net.eval()
                with torch.no_grad():
                    for test_data in testloader:
                        test_images, test_labels = test_data
                        test_outputs = net(test_images)
                        test_loss = criterion(test_outputs, test_labels)
    
                train_loss_hist.append(running_loss/250)
                test_loss_hist.append(test_loss.item())
                running_loss=0.0
    
    
    
    100%|██████████| 20/20 [50:48<00:00, 148.08s/it]
    
    plt.figure()
    plt.plot(temp)
    plt.plot(test_loss_hist)
    plt.legend(('train loss', 'test loss'))
    plt.title('Train/Test Loss')
    plt.xlabel('# mini batch *250')
    plt.ylabel('Loss')
    
    
    
    Text(0,0.5,'Loss')
    
    
    

    相关文章

      网友评论

          本文标题:pytorch+cnn实现图像分类器

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