这个版本再看有些不懂的问题:
优点:除了训练速度快,GPU并行等优点
1. 可以使用GN 而不是BN
2.
不懂的地方:
1. rpn网络使用resnet c2345去建立,最后一个p6为何:pool_size=1, strides=2, 匪夷所思(此处结构和原版相同)
if use_gn:
p2345 = [GroupNorm('gn_p{}'.format(i + 2), c) for i, c in enumerate(p2345)]
p6 = MaxPooling('maxpool_p6', p2345[-1], pool_size=1, strides=2, data_format='channels_first', padding='VALID')
2. rpn里类别预测稍有不同
keras版本 用的二分类,后面softmax后计算交叉式损失
loss = K.sparse_categorical_crossentropy(target=anchor_class,
output=rpn_class_logits,
from_logits=True)
这个版本最后是sigmoid函数 最后用的也是交叉熵损失
label_loss = tf.nn.sigmoid_cross_entropy_with_logits(
labels=tf.cast(valid_anchor_labels, tf.float32), logits=valid_label_logits)
解释参考知乎:https://www.zhihu.com/question/36307214
但是不知道除了设计成二分类后更加优雅之外,不知道对性能有如何的影响, 目前我似乎觉得影响甚微.
3. 在rpn bbox的回归上也有不同
keras 版本:
def smooth_l1_loss(y_true, y_pred):
"""Implements Smooth-L1 loss.
y_true and y_pred are typically: [N, 4], but could be any shape.
"""
diff = K.abs(y_true - y_pred)
less_than_one = K.cast(K.less(diff, 1.0), "float32")
loss = (less_than_one * 0.5 * diff**2) + (1 - less_than_one) * (diff - 0.5)
return loss
tensorpack版本:
delta = 1.0 / 9
box_loss = tf.losses.huber_loss(
pos_anchor_boxes, pos_box_logits, delta=delta,
reduction=tf.losses.Reduction.SUM) / delta
这里的delta是0.0999 同样huber_loss和smooth_l1类似,就是分段函数边界可以设置,这里是0.0999那么这个地方差别较大:
根据huber_loss损失函数定义:
def huber_loss(labels, predictions, weights=1.0, delta=1.0, scope=None,
loss_collection=ops.GraphKeys.LOSSES,
reduction=Reduction.SUM_BY_NONZERO_WEIGHTS):
"""Adds a Huber Loss term to the training procedure.
For each value x in `error=labels-predictions`, the following is calculated:
```
0.5 * x^2 if |x| <= d
0.5 * d^2 + d * (|x| - d) if |x| > d
```
where d is `delta`.
那么当delta=0.09999时候和smooth对比
如上图所示,这里使用的delta使得bbox loss远远比之前缓和很多,以我之前训练keras版本的经验,因为rpn bbox回归的损失数量级远远大于前后背景预测的损失,我会把class的损失调大很多,使得更加均衡.
其他部分,有时间继续查看改进.
转载请注明出处: