一、整体介绍
神经网络(net)是一个组合模型,它由许多相互连接的层(layers)组合而成,每一层又会涉及到很多参数(定义在caffe.proto文件中)。
Caffe就是组建深度网络的这样一种工具,它按照一定的策略,一层一层的搭建出自己的模型。它将所有的信息数据定义为blobs,从而进行便利的操作和通讯。
1.blob
blob是caffe框架中一种标准的数组,一种统一的内存接口,它详细描述了信息是如何存储的,以及如何在层之间通讯的。
2.layer
layer有多种类型,例如:Data,Python,Convolution,Pooling等,从bottom进行数据的输入,计算后通过top进行输出,layer之间的数据流动是以blobs的方式进行的。
每种layer都定义了三种关键计算:setup,forward,backward
- setup: 层的建立和初始化,以及在整个模型中的连接初始化。
- forward: 从bottom得到输入数据,进行计算,并将计算结果送到top,进行输出。
-
backward: 从层的输出端top得到数据的梯度,计算当前层的梯度,并将计算结果送到bottom,向前传递。
这里以rpn/anchor_target_layer.py的部分代码为例,显而易见包含以上几个部分
class AnchorTargetLayer(caffe.Layer):
"""
Assign anchors to ground-truth targets. Produces anchor classification
labels and bounding-box regression targets.
"""
def setup(self, bottom, top):
layer_params = yaml.load(self.param_str_)
anchor_scales = layer_params.get('scales', (8, 16, 32))
self._anchors = generate_anchors(scales=np.array(anchor_scales))
self._num_anchors = self._anchors.shape[0]
self._feat_stride = layer_params['feat_stride']
# …………………………省略
def forward(self, bottom, top):
# Algorithm:
#
# for each (H, W) location i
# generate 9 anchor boxes centered on cell i
# apply predicted bbox deltas at cell i to each of the 9 anchors
# filter out-of-image anchors
# measure GT overlap
assert bottom[0].data.shape[0] == 1, \
'Only single item batches are supported'
# map of shape (..., H, W)
height, width = bottom[0].data.shape[-2:]
# GT boxes (x1, y1, x2, y2, label)
gt_boxes = bottom[1].data
# im_info
im_info = bottom[2].data[0, :]
# …………………………省略
def backward(self, top, propagate_down, bottom):
"""This layer does not propagate gradients."""
pass
def reshape(self, bottom, top):
"""Reshaping happens during the call to forward."""
pass
#……………………省略
3.net
即由多个layer组合而成,不再赘述
二、自定义Python层
(以下均以models/pascal_voc/VGG16/faster_rcnn_alt_opt/stage1_fast_rcnn_train.pt中的layer为例)
layer {
name: 'data'
type: 'Python'
top: 'data'
top: 'rois'
top: 'labels'
top: 'bbox_targets'
top: 'bbox_inside_weights'
top: 'bbox_outside_weights'
python_param {
module: 'roi_data_layer.layer' # python module名字
layer: 'RoIDataLayer' # 其中定义的类的名字
param_str: "'num_classes': 21"
}
roi_data_layer/layer.py中包含setup,forward,backward,reshape等函数。
三、视觉层及参数
1.Convolution层
layer {
name: "conv4_1"
type: "Convolution"
bottom: "pool3"
top: "conv4_1"
param {
lr_mult: 1
}
param {
lr_mult: 2
}
convolution_param {
num_output: 512
pad: 1
kernel_size: 3
}
- lr_mult:学习率的参数,最终的学习率是lr_mult×base_lr(在solver.prototxt配置文件中)。上方有两个lr_mult,则第一个表示权值的学习率,第二个表示偏置项的学习率,一般偏执项的学习率是权值学习率的两倍。
- num_output(必设):卷积核(filter)的个数
- kernel_size(必设):卷积核的大小
- pad:扩充边缘
- 此外,还有stride、weight_filler、bias_filler、bias_term、group等参数
2.Pooling层
layer {
name: "pool2"
type: "Pooling"
bottom: "conv2_2"
top: "pool2"
pooling_param {
pool: MAX
kernel_size: 2
stride: 2
}
}
- kernel_size(必设):池化核的大小
- pool:池化方法,默认为MAX
- 此外,还有pad,stride等参数
四、激活层及参数
在激活层中,对输入数据进行激活操作(实际上就是一种函数变换),是逐元素进行运算的。从bottom得到一个blob数据输入,运算后,从top输出一个blob数据。在运算过程中,没有改变数据的大小,即输入和输出的数据大小是相等的。
以ReLU为例
layer {
name: "relu6"
type: "ReLU"
bottom: "fc6"
top: "fc6"
}
标准的ReLU函数为max(x,0),当x>0时,输出x;当x<=0时,输出0
- 可选参数:negative_slope:默认为0,当设置了这个值之后,那么输出就不再为0,而是用原始数据×negative_slope
此外还有Sigmoid、TanH等激活层
五、其他常用层及参数
1.softmax-loss
注意softmax-loss层和softmax层计算大致相同,但也有区别,详见Softmax vs. Softmax-Loss
layer {
name: "loss_cls"
type: "SoftmaxWithLoss"
bottom: "cls_score"
bottom: "labels"
top: "loss_cls"
loss_weight: 1
}
2.InnerProduct
全连接层,把输入当作成一个向量,输出也是一个简单向量(把输入数据blobs的width和height全变为1)。
全连接层实际上也是一种卷积层,只是它的卷积核大小和原数据大小一致。因此它的参数基本和卷积层的参数一样。
layer {
name: "fc6"
type: "InnerProduct"
bottom: "pool5"
top: "fc6"
param {
lr_mult: 1
}
param {
lr_mult: 2
}
inner_product_param {
num_output: 4096
}
}
- num_output(必设):filter个数
3.Dropout
Dropout的作用是防止过拟合。可以随机让网络某些隐含层节点的权重不工作。
layer {
name: "drop6"
type: "Dropout"
bottom: "fc6"
top: "fc6"
dropout_param {
dropout_ratio: 0.5
}
}
- 只需设置一个dropout_ratio即可。
六、solver及其设置
在Deep Learning中,往往loss function是非凸的,没有解析解,我们需要通过优化方法来求解。solver的主要作用就是交替调用前向(forward)算法和后向(backward)算法来更新参数,从而最小化loss,实际上就是一种迭代的优化算法。
Solver的流程:
1.设计好需要优化的对象,以及用于学习的训练网络和用于评估的测试网络。
2.通过forward和backward迭代的进行优化来跟新参数。
3.定期的评价测试网络。
4.在优化过程中显示模型和solver的状态
在每一次的迭代过程中,solver所做工作:
1、调用forward算法来计算最终的输出值,以及对应的loss
2、调用backward算法来计算每层的梯度
3、根据选用的slover方法,利用梯度进行参数更新
4、记录并保存每次迭代的学习率、快照,以及对应的状态。
以stage1_fast_rcnn_solver30k40k.pt的内容为例
base_lr: 0.001
lr_policy: "step"
gamma: 0.1
stepsize: 30000
display: 20
average_loss: 100
momentum: 0.9
weight_decay: 0.0005
# We disable standard caffe solver snapshotting and implement our own snapshot function
snapshot: 0
# We still use the snapshot prefix, though
snapshot_prefix: "vgg16_fast_rcnn"
- 其中,前4行是用于学习率的设置。base_lr用于设置基础学习率,在迭代过程中,可以对基础学习率进行调整。调整策略由lr_policy来设置。
- lr_policy的设置以-step为例,如果设置为step,则还需要设置一个stepsize, 返回 base_lr * gamma ^ (floor(iter / stepsize)),其中iter表示当前的迭代次数
- weight_decay:权重衰减项,防止过拟合的一个参数
- snapshot:快照,将训练出来的model和solver状态进行保存。
-
snapshot_prefix:设置保存路径
……
参考:
https://blog.csdn.net/sinat_30071459/article/details/51723483
https://blog.csdn.net/sinat_30071459/article/details/51723544
https://blog.csdn.net/sinat_30071459/article/details/51723600等