zoukankan      html  css  js  c++  java
  • 使用Pytorch实现简单的人脸二分类器

    该项目的目的是建立一个有关于人脸的二分类器。

    steps :

    1. Load the data
    2. Define a Convolutional Neural Network
    3. Train the Model
    4. Evaluate the Performance of our trained model on a dataset

    加载数据集

    主要内容:加载和预处理。

    预处理:使用pytorch的transform进行转换。预处理后的数据形成实验的数据集。

    1 transform = transforms.Compose([
    2     transforms.RandomHorizontalFlip(),
    3     transforms.RandomRotation(20),
    4     transforms.ToTensor(),
    5     transforms.Normalize((0.5, 0.5, 0.5), (0.5, 0.5, 0.5))
    6 ])

    数据加载:在一般情况下,我们继承 torch.util.data.Dataset 形成数据集,然后使用 torch.util.data.DataLoader 形成完成数据加载。

    在这里,直接使用 torchvision.datasets.ImageFolder实现数据的读取。

    1 train_data = datasets.ImageFolder('face',transform=transform)

    对于项目的数据集常划分为三个部分:训练集,验证集,测试集。  训练集:用于训练模型;验证集:在每一个epoch之后,用于验证模型的性能;测试集用于训练完成后,测试模型的性能。因此,对于train_data需要进行再划分。

     1 # 将数据集进行第一次划分 train / test  获得index list
     2 num_data = len(train_data) 
     3 indices_data = list(range(num_data)) # [0,.....,num_data-1]
     4 np.random.shuffle(indices_data) # 打乱顺序
     5 split_tt = int(np.floor(test_size * num_data))  # np.floor:向下取整 test_size:(0,1) 取部分
     6 train_idx, test_idx = indices_data[split_tt:], indices_data[:split_tt]   # index list
     7 
     8 # 将train数据集划分为 train / validation   获得index list
     9 num_train = len(train_idx)
    10 indices_train = list(range(num_train))
    11 np.random.shuffle(indices_train)
    12 split_tv = int(np.floor(valid_size * num_train))
    13 train_idx, valid_idx = indices_train[split_tv:],indices_train[:split_tv]

    通过Sampler(采样器)和DataLoader实现数据的加载。

    1 # define samplers for obtaining training and validation batches
    2 train_sampler = SubsetRandomSampler(train_idx)
    3 test_sampler = SubsetRandomSampler(test_idx)
    4 valid_sampler = SubsetRandomSampler(valid_idx)
    5 
    6 # Loaders contains the data in tuple format , The train_loader, test_loader and valid_loader will be used to pass the input to the model.
    7 train_loader = torch.utils.data.DataLoader(train_data, batch_size=batch_size, sampler=train_sampler, num_workers=1)
    8 valid_loader = torch.utils.data.DataLoader(train_data, batch_size=batch_size, sampler=valid_sampler, num_workers=1)
    9 test_loader = torch.utils.data.DataLoader(train_data, sampler = test_sampler, batch_size=batch_size,num_workers=1)

    图像的标签:

    1 # variable representing classes of the images , label
    2 classes = [0,1]

    定义一个卷积神经网络

    定义网络的某一个层次:torch.nn.Conv2D(Depth_of_input_image, Depth_of_filter, size_of_filter, padding, strides) 

    Depth of the input image is generally 3 for RGB, and 1 for Grayscale.
    Depth of the filter is specified by the user which generally extracts the low level features。
    the size of the filter is the size of the kernel which is convolved over the whole image.

    定义CNN,并且进行初始化:

    # define
    class Net(nn.Module):
        def __init__(self):
            super(Net, self).__init__()
            # convolutional layer
            self.conv1 = nn.Conv2d(3, 16, 5)
            # max pooling layer
            self.pool = nn.MaxPool2d(2, 2)
            self.conv2 = nn.Conv2d(16, 32, 5)
            self.dropout = nn.Dropout(0.2)
            self.fc1 = nn.Linear(32*53*53, 256)
            self.fc2 = nn.Linear(256, 84) # 线性层: 256长度 -> 84长度
            self.fc3 = nn.Linear(84, 2)   # 线性层:84长度 -> 2长度
            self.softmax = nn.LogSoftmax(dim=1)  # Softmax
            
        def forward(self, x):
            # add sequence of convolutional and max pooling layers
            x = self.pool(F.relu(self.conv1(x)))
            x = self.pool(F.relu(self.conv2(x)))
            x = self.dropout(x)
            x = x.view(-1, 32 * 53 * 53)
            x = F.relu(self.fc1(x))
            x = self.dropout(F.relu(self.fc2(x)))
            x = self.softmax(self.fc3(x))
            return x
    
    # create a complete CNN
    model = Net()

    模型结构:                        

    除了定义模型之外,还需要定义 loss function 和 optimizer 。

    Loss Function will help us in calculating the loss by comparing the prediction and original label.
    The optimizer will minimize the loss by updating the parameters of the model after every epoch.

    1 # Loss function
    2 criterion = torch.nn.CrossEntropyLoss()
    3 # Optimizer  SDG weight = weight - learning_rate*gradient
    4 optimizer = torch.optim.SGD(model.parameters(), lr = 0.003, momentum= 0.9)

    训练模型

    训练模型的过程:

    1) Clear the gradients of all optimized variables : There could be gradients from previous batches, therefore it’s necessary to clear gradient after every epoch
    2) Forward pass: This step computes the predicted outputs by passing inputs to the convolutional neural network model
    3) Calculate the loss: As the model trains, the loss function calculates the loss after every epoch and then it is used by the optimizer.
    4) Backward pass: This step computes the gradient of the loss with respect to model parameters
    5) Optimization: This performs a single optimization step/ parameter update for the model.
    6) Update average training loss

    对模型进行评估

    To evaluate the model, it should be changed from model.train() to model.eval()。

     1 model.eval()
     2 # iterate over test data
     3 len(test_loader)
     4 for data, target in test_loader:
     5     # move tensors to GPU if CUDA is available
     6     if train_on_gpu:
     7         data, target = data.cuda(), target.cuda()
     8     # forward pass
     9     output = model(data)
    10     # calculate the batch loss
    11     loss = criterion(output, target)
    12     # update test loss 
    13     test_loss += loss.item()*data.size(0)
    14     # convert output probabilities to predicted class
    15     _, pred = torch.max(output, 1)    
    16     # compare predictions to true label
    17     correct_tensor = pred.eq(target.data.view_as(pred))
    18     correct = np.squeeze(correct_tensor.numpy()) if not train_on_gpu else np.squeeze(correct_tensor.cpu().numpy())
    19     # calculate test accuracy for each object class
    20     for i in range(batch_size):       
    21         label = target.data[i]
    22         class_correct[label] += correct[i].item()
    23         class_total[label] += 1
     1 # average test loss
     2 test_loss = test_loss/len(test_loader.dataset)
     3 print('Test Loss: {:.6f}
    '.format(test_loss))
     4 
     5 for i in range(2):
     6     if class_total[i] > 0:
     7         print('Test Accuracy of %5s: %2d%% (%2d/%2d)' % (
     8             classes[i], 100 * class_correct[i] / class_total[i],
     9             np.sum(class_correct[i]), np.sum(class_total[i])))
    10     else:
    11         print('Test Accuracy of %5s: N/A (no training examples)' % (classes[i]))
    12 
    13 print('
    Test Accuracy (Overall): %2d%% (%2d/%2d)' % (
    14     100. * np.sum(class_correct) / np.sum(class_total),
    15     np.sum(class_correct), np.sum(class_total)))
    16 
    17 """
    18 Test Loss: 0.006558
    19 Test Accuracy of     0: 99% (805/807) 
    20 Test Accuracy of     1: 98% (910/921)
    21 Test Accuracy (Overall): 99% (1715/1728)
    22 """

    链接

    https://hackernoon.com/binary-face-classifier-using-pytorch-2d835ccb7816

    这个链接有完整的介绍和GitHub地址以及数据集,我这篇文章只是做了大概的摘录。

  • 相关阅读:
    RSA签名算法概述及使用
    PyQt5【入门-窗口】
    CSS的一些文本操作有哪些
    Canvas如何绘制精美的图?
    Python学习路线
    表单都应该提交点什么
    网页的图像、表格以及列表的使用和制作
    网页的头部都装点什么
    HTML5,从零开始
    Redis的安装以及spring整合Redis时出现Could not get a resource from the pool
  • 原文地址:https://www.cnblogs.com/yy-1046741080/p/12720104.html
Copyright © 2011-2022 走看看