由于自己完全无法适应CSDN的富文本编辑模式ε=ε=ε=┏(゜ロ゜;)┛,实在是用不来,所以“多人种人脸识别“的第二部分转战Markdown编辑器
PyTorch的关键应用
BN层的使用
BN层的优点主要有以下几点:
- 加快训练速度,这样我们就可以使用较大的学习率来训练网络
- 提高网络的泛化能力,这样就可以减少dropout和正则化的使用
- BN层本质上是一个归一化网络层,可以替代局部响应归一化层(LRN层)。
- 可以打乱样本训练顺序(这样就不可能出现同一张照片被多次选择用来训练)论文中提到可以提高1%的精度。
BN层的位置:
BN层一般位于激活层之前(目的是为了让激活层的值更加稳定),在FC层或ConV层之后
BN层的具体实现:
BN层如果放在全连接层后面,则是对全连接层里面每个batch的属性进行计算;如果放在卷积层之后,则一般对channel进行,在tensorflow中可以指定,对哪一维(一般情况不出意外都是axis=channel),而在Pytroch是不用指定可以默认进行的。
PyTorch中的模型加载
如今,迁移学习的思想在各种领域都有很多应用,而在人脸识别领域也不例外,使用迁移学习,这里只说最基本的迁移学习方法,用别人与训练好的best_checkpoint加载进自己的模型,往往可以在短时间内使得自己的模型取得十分好的效果
Torch中加载当前模型的方法
指令 | 解释 |
---|---|
torch.load | 比较通用的一种方法,既可以加载整个模型,也可以只加载参数 |
net.load_state_dict | 只加载参数,他的参数可以为torch.load也可以为model_zoo.load_url |
torchvision.load | 最简单易用的一种模型 |
model_zoo.load_url | 根据model_zoo进行加载 |
另外,pytorch还提供了灵活的预加载方法,可以自己大调或微调模型,原来的预训练模型仍然可以使用。
人脸识别中的两种损失
在本项目中含有两类损失,因为是要衡量两种人脸的相似度,所以有一个用来衡量相似度的损失,这里直接调用的是ArcFaceloss,另一个loss则就是用来进行训练的loss,这里调用的是focalLoss。
如下是未变化前的交叉熵(cross entropy) loss,以二分类为例:
通过实验发现,即使是easy examples(Pt >> 0.5),它的loss也很高,如下图蓝线
- 改进1
因此,对于大量的easy negative examples,这些loss会主导梯度下降的方向,淹没少量的正样本的影响。所以,我们要降低easy example的影响,可以在他的前面加上一项权重,其中权重因子的大小一般为相反类的比重。即负样本不是多吗,它越多,我们给它的权重越小。这样就可以降低负样本的影响。
- 改进2
上面只是解决了正负样本的不平衡,没有解决easy和hard examples之间的不平衡,因此针对easy和hard样本,定义focal loss。这样,当对于简单样本,Pt会比较大,所以权重自然减小了。针对hard example,Pt比较小,则权重比较大,让网络倾向于利用这样的样本来进行参数的更新。
且这个权重是动态变化的,如果复杂的样本逐渐变得好分,则它的影响也会逐渐的下降。
具体代码实现
优化器
这里使用的优化器的特点是,根据训练步数来进行调整学习率,分别在第60000步和100000步来对学习率进行除以10的操作,这样做是为了让其在前期能够快速训练,到后期减慢训练速度。