在分享了yolo3的庖丁解牛版后,陆续有一些小伙伴发来信息说,损失函数讲的太简单了 - -,各位大哥,我错了,现在把yolo3的损失函数重新一点一点刨开,同时预先对接下来要分享的faster rcnn中的损失函数部分一起,提前跟大家一点一点解释清楚,以提早发现问题,方便我在重组代码时能把注释写得明明白白的。
先上frcnn吧。。。代码参考:https://github.com/ldhsight/keras_frcnn同事有人问我,没人star,你还去学- -
相比大众版的frcnn或者yolo3等代码,他们确实很完善,然而不便于新手上路。正是因为他们的完善和代码的优化,很多地方会导致你看不懂,比如yolo3对nms的写法,掺杂了非常不常用的tensorflow函数,数据处理大篇幅用numpy大法,空间想象力不足的话会抓狂。同时那些代码是面向工程的,很多附加内容与标准写法让你望而却步。因此,这也是为什么先把frcnn代码先进行分享,因为这篇代码,是我选了又选挑出来最平易近人的(虽然他是有问题的)
OK,开始吧
1、Faster Rcnn
要想知道损失函数的意义,必定需要详细地了解三个内容:真实数据,神经网络输出,优化目标
(1)第一阶段:
真实数据为:
1)y_rpn_cls 和 y_rpn_regr
其中y_rpn_cls.shape=(1, row, col, 18),这里以tf版为标准。18代表着:前9个值为anchor是否可用于当前区域,后9个值为该区域是前景还是背景
y_rpn_regr.shape=(1, row, col, 72),72表示:前36个值为是前景背景的X4版本,其实就用4个1表示前景,4个0表示背景,就是y_rpn_cls后9个值扩大四个长度
网络输出为:
1)x_class
x_class.shape=(n, row, col, 9)
x_regr.shape=(n, row, col, 36)
损失函数为:
def rpn_loss_cls(num_anchors):
def rpn_loss_cls_fixed_num(y_true, y_pred):
if K.image_dim_ordering() == 'tf':
# 炒鸡神奇炒鸡巧妙的损失函数
return lambda_rpn_class * K.sum(y_true[:, :, :, :num_anchors] * K.binary_crossentropy(y_pred[:, :, :, :], y_true[:, :, :, num_anchors:])) / K.sum(epsilon + y_true[:, :, :, :num_anchors])
else:
return lambda_rpn_class * K.sum(y_true[:, :num_anchors, :, :] * K.binary_crossentropy(y_pred[:, :, :, :], y_true[:, num_anchors:, :, :])) / K.sum(epsilon + y_true[:, :num_anchors, :, :])
return rpn_loss_cls_fixed_num
def rpn_loss_regr(num_anchors):
def rpn_loss_regr_fixed_num(y_true, y_pred):
if K.image_dim_ordering() == 'th':
x = y_true[:, 4 * num_anchors:, :, :] - y_pred
x_abs = K.abs(x)
x_bool = K.less_equal(x_abs, 1.0)