分类器训练¶
R-CNN
在完成卷积模型的微调后,额外使用了线性SVM
分类器,采用负样本挖掘方法进行训练,参考Hard Negative Mining
线性SVM¶
参考:
线性SVM
分类器包含了线性回归+折页损失,其中自定义PyTorch
的折页损失实现:
def hinge_loss(outputs, labels):
"""
折页损失计算
:param outputs: 大小为(N, num_classes)
:param labels: 大小为(N)
:return: 损失值
"""
num_labels = len(labels)
corrects = outputs[range(num_labels), labels].unsqueeze(0).T
# 最大间隔
margin = 1.0
margins = outputs - corrects + margin
loss = torch.sum(torch.max(margins, 1)[0]) / len(labels)
# # 正则化强度
# reg = 1e-3
# loss += reg * torch.sum(weight ** 2)
return loss
负样本挖掘¶
实现流程如下:
- 设置初始训练集,正负样本数比值为
1:1
(以正样本数目为基准) - 每轮训练完成后,使用分类器对剩余负样本进行检测,如果检测为正,则加入到训练集中
- 重新训练分类器,重复第二步,直到检测精度开始收敛
训练参数¶
- 学习率:
1e-4
- 动量:
0.9
- 随步长衰减:每隔
4
轮衰减一次,参数因子α=0.1
- 迭代次数:
10
- 批量处理:每次训练
128
个图像,其中32
个正样本,96
个负样本
训练结果¶
$ python linear_svm.py
Epoch 0/9
----------
train - positive_num: 625 - negative_num: 625 - data size: 1152
train Loss: 1.1406 Acc: 0.6424
val - positive_num: 625 - negative_num: 321474 - data size: 322048
val Loss: 1.0560 Acc: 0.8080
remiam negative size: 365403, acc: 0.8821
Epoch 1/9
----------
train - positive_num: 625 - negative_num: 43397 - data size: 43904
train Loss: 1.0180 Acc: 0.9410
val - positive_num: 625 - negative_num: 321474 - data size: 322048
val Loss: 1.0426 Acc: 0.9232
remiam negative size: 365403, acc: 0.9965
Epoch 2/9
----------
train - positive_num: 625 - negative_num: 43606 - data size: 44160
train Loss: 1.0063 Acc: 0.9716
val - positive_num: 625 - negative_num: 321474 - data size: 322048
val Loss: 1.0414 Acc: 0.9241
remiam negative size: 365403, acc: 0.9972
Epoch 3/9
----------
train - positive_num: 625 - negative_num: 43731 - data size: 44288
train Loss: 1.0047 Acc: 0.9767
val - positive_num: 625 - negative_num: 321474 - data size: 322048
val Loss: 1.0429 Acc: 0.9234
remiam negative size: 365403, acc: 0.9980
Epoch 4/9
----------
train - positive_num: 625 - negative_num: 43773 - data size: 44288
train Loss: 1.0039 Acc: 0.9788
val - positive_num: 625 - negative_num: 321474 - data size: 322048
val Loss: 1.0421 Acc: 0.9240
remiam negative size: 365403, acc: 0.9980
Epoch 5/9
----------
train - positive_num: 625 - negative_num: 43795 - data size: 44416
train Loss: 1.0039 Acc: 0.9795
val - positive_num: 625 - negative_num: 321474 - data size: 322048
val Loss: 1.0427 Acc: 0.9234
remiam negative size: 365403, acc: 0.9982
Epoch 6/9
----------
train - positive_num: 625 - negative_num: 43801 - data size: 44416
train Loss: 1.0040 Acc: 0.9786
val - positive_num: 625 - negative_num: 321474 - data size: 322048
val Loss: 1.0428 Acc: 0.9242
remiam negative size: 365403, acc: 0.9981
Epoch 7/9
----------
train - positive_num: 625 - negative_num: 43808 - data size: 44416
train Loss: 1.0036 Acc: 0.9799
val - positive_num: 625 - negative_num: 321474 - data size: 322048
val Loss: 1.0429 Acc: 0.9242
remiam negative size: 365403, acc: 0.9981
Epoch 8/9
----------
train - positive_num: 625 - negative_num: 43814 - data size: 44416
train Loss: 1.0035 Acc: 0.9812
val - positive_num: 625 - negative_num: 321474 - data size: 322048
val Loss: 1.0425 Acc: 0.9242
remiam negative size: 365403, acc: 0.9981
Epoch 9/9
----------
train - positive_num: 625 - negative_num: 43817 - data size: 44416
train Loss: 1.0036 Acc: 0.9802
val - positive_num: 625 - negative_num: 321474 - data size: 322048
val Loss: 1.0424 Acc: 0.9246
remiam negative size: 365403, acc: 0.9981
Training complete in 55m 50s
Best val Acc: 0.924645
经过2
轮训练后,分类器损失就开始收敛