Caffe代码夜话1
点击上方“深度学习大讲堂”可订阅哦!
深度学习大讲堂是高质量原创内容的平台,邀请学术界、工业界一线专家撰稿,致力于推送人工智能与深度学习最新技术、产品和活动信息!
1. 从零开始的Label
在使用SoftmaxLoss层作为损失函数层的单标签分类问题中,label要求从零开始,例如1000类的ImageNet分类任务,label的范围是0~999。这个限制来自于Caffe的一个实现机制,label会直接作为数组的下标使用,具体代码SoftmaxLoss.cpp中133行和139行的实现代码。
图1. SoftmaxLoss.cpp部分实现代码
132行第一层for循环中的outer_num等于batch size,对于人脸识别和图像分类等单标签分类任务而言,inner_num等于1。如果label从1开始,会导致bottom_diff数组访问越界。
留两个思考题:
思考题1:为什么Caffe中引入了这个inner_num,inner_num等于什么,提示一下从FCN全卷积网络的方向去思考。
思考题2:在标签正确的前提下,如果倒数第一个全连接层num_output > 实际的类别数,Caffe的训练是否会报错?
2. BN中的use_global_status
图2. ResNet部署阶模型Proto文件片段
但是如果直接拿这个Proto用于训练(基于随机初始化),则会导致模型不收敛,原因在于在Caffe的batch_norm_layer.cpp实现中,use_global_stats==true时会强制使用模型中存储的BatchNorm层均值与方差参数,而非基于当前batch内计算均值和方差。
首先看use_global_stats变量是如何计算的:
图3. use_global_stats计算
再看这个变量的作用:
图4. use_global_stats为true时的行为
以下代码在use_global_stats为false的时候通过moving average策略计算模型中最终存储的均值和方差:
图5. BatchNorm层均值和方差的moving average
因此,对于随机初始化训练BatchNorm层,只需要在Proto文件中移除use_global_stats参数即可,Caffe会根据当前的Phase(TRAIN或者TEST)自动去设置use_global_stats的值。
再留一个思考题。
思考题3:BatchNorm层是否支持in place运算,为什么?
本期Caffe夜话就到这里。在后续几期的代码夜话中,我们将陆续介绍网络参数的初始化、Fine-tune的参数拷贝、Net类的组装、Solver类的参数更新机制、添加新的Caffe Layer等内容,敬请期待。
该文章属于“深度学习大讲堂”原创,如需要转载,请联系loveholicguoguo。
作者简介:
深度学习大讲堂内容组。一个神秘的组织,还没有介绍。
欢迎大家在留言区回答思考题,第一个答对任意一个思考题的同学,有神秘礼物。
往期精彩回顾
【Technical Review】ECCV16 Grid Loss及其在人脸检测中的应用
【ECCV2016论文速读】回归框架下的人脸对齐和三维重建
IJCAI16论文速读:Deep Learning论文选读(下)
[冠军之道]ECCV16视频性格分析竞赛冠军团队分享
IJCAI16论文速读:人脸自动美妆与深度哈希
欢迎关注我们!
深度学习大讲堂是高质量原创内容的平台,邀请学术界、工业界一线专家撰稿,致力于推送人工智能与深度学习最新技术、产品和活动信息!
深度学习大讲堂