該項目的目的是建立一個有關於人臉的二分類器。
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}\n'.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('\nTest 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地址以及數據集,我這篇文章只是做了大概的摘錄。
