DL之RetinaNet:基于RetinaNet算法(keras框架)利用resnet50_coco数据集(.h5文件)实现目标检测

简介: DL之RetinaNet:基于RetinaNet算法(keras框架)利用resnet50_coco数据集(.h5文件)实现目标检测

输出结果

image.png


image.png

image.png

设计思路

更新中


核心代码

def __create_pyramid_features(C3, C4, C5, feature_size=256):

   """ Creates the FPN layers on top of the backbone features.

      在ResNet基础上创建FPN金字塔特征:参照博客的框架图,输入[C3,C4,C5],返回5个特征级别[P3, P4, P5, P6, P7]

      参考博客:https://yunyaniu.blog.csdn.net/article/details/100010853

   Args

       C3           : Feature stage C3 from the backbone.

       C4           : Feature stage C4 from the backbone.

       C5           : Feature stage C5 from the backbone.

       feature_size : The feature size to use for the resulting feature levels.

   Returns

       A list of feature levels [P3, P4, P5, P6, P7].

   """

   # upsample C5 to get P5 from the FPN paper

   P5           = keras.layers.Conv2D(feature_size, kernel_size=1, strides=1, padding='same', name='C5_reduced')(C5)

   P5_upsampled = layers.UpsampleLike(name='P5_upsampled')([P5, C4])

   P5           = keras.layers.Conv2D(feature_size, kernel_size=3, strides=1, padding='same', name='P5')(P5)

   # add P5 elementwise to C4

   P4           = keras.layers.Conv2D(feature_size, kernel_size=1, strides=1, padding='same', name='C4_reduced')(C4)

   P4           = keras.layers.Add(name='P4_merged')([P5_upsampled, P4])

   P4_upsampled = layers.UpsampleLike(name='P4_upsampled')([P4, C3])

   P4           = keras.layers.Conv2D(feature_size, kernel_size=3, strides=1, padding='same', name='P4')(P4)

   # add P4 elementwise to C3

   P3 = keras.layers.Conv2D(feature_size, kernel_size=1, strides=1, padding='same', name='C3_reduced')(C3)

   P3 = keras.layers.Add(name='P3_merged')([P4_upsampled, P3])

   P3 = keras.layers.Conv2D(feature_size, kernel_size=3, strides=1, padding='same', name='P3')(P3)

   # "P6 is obtained via a 3x3 stride-2 conv on C5"

   P6 = keras.layers.Conv2D(feature_size, kernel_size=3, strides=2, padding='same', name='P6')(C5)

   # "P7 is computed by applying ReLU followed by a 3x3 stride-2 conv on P6"

   P7 = keras.layers.Activation('relu', name='C6_relu')(P6)

   P7 = keras.layers.Conv2D(feature_size, kernel_size=3, strides=2, padding='same', name='P7')(P7)

   return [P3, P4, P5, P6, P7]

def default_submodels(num_classes, num_anchors):

   """ Create a list of default submodels used for object detection.

            两个子模型:目标分类子模型default_classification_model、框回归子模型default_regression_model

   The default submodels contains a regression submodel and a classification submodel.

   Args

       num_classes : Number of classes to use.

       num_anchors : Number of base anchors.

   Returns

       A list of tuple, where the first element is the name of the submodel and the second element is the submodel itself.

   """

   return [

       ('regression', default_regression_model(4, num_anchors)),

       ('classification', default_classification_model(num_classes, num_anchors))

   ]

def __build_model_pyramid(name, model, features):

   """ Applies a single submodel to each FPN level.

       真正的构造金字塔模型

   Args

       name     : Name of the submodel.

       model    : The submodel to evaluate.

       features : The FPN features.

   Returns

       A tensor containing the response from the submodel on the FPN features.

   """

   return keras.layers.Concatenate(axis=1, name=name)([model(f) for f in features])

"""

The default anchor parameters. 默认的anchors参数,组合以后有9个anchors

"""

AnchorParameters.default = AnchorParameters(

   sizes   = [32, 64, 128, 256, 512],

   strides = [8, 16, 32, 64, 128],

   ratios  = np.array([0.5, 1, 2], keras.backend.floatx()),

   scales  = np.array([2 ** 0, 2 ** (1.0 / 3.0), 2 ** (2.0 / 3.0)], keras.backend.floatx()),

)

def anchor_targets_bbox(

   anchors,

   image_group,

   annotations_group,

   num_classes,

   #negative_overlap和positive_overlap,根据IOU区分

   negative_overlap=0.4,  

   positive_overlap=0.5

):

def focal(alpha=0.25, gamma=2.0):

   """ Create a functor for computing the focal loss.

   Args

       alpha: Scale the focal weight with alpha.

       gamma: Take the power of the focal weight with gamma.

   Returns

       A functor that computes the focal loss using the alpha and gamma.

   """

   def _focal(y_true, y_pred):

       """ Compute the focal loss given the target tensor and the predicted tensor.

       As defined in https://arxiv.org/abs/1708.02002

       Args

           y_true: Tensor of target data from the generator with shape (B, N, num_classes).

           y_pred: Tensor of predicted data from the network with shape (B, N, num_classes).

       Returns

           The focal loss of y_pred w.r.t. y_true.

       """

       labels         = y_true[:, :, :-1]

       anchor_state   = y_true[:, :, -1]  # -1 for ignore, 0 for background, 1 for object

       classification = y_pred

       # filter out "ignore" anchors

       indices        = backend.where(keras.backend.not_equal(anchor_state, -1))

       labels         = backend.gather_nd(labels, indices)

       classification = backend.gather_nd(classification, indices)

       # compute the focal loss

       alpha_factor = keras.backend.ones_like(labels) * alpha

       alpha_factor = backend.where(keras.backend.equal(labels, 1), alpha_factor, 1 - alpha_factor)

       focal_weight = backend.where(keras.backend.equal(labels, 1), 1 - classification, classification)

       focal_weight = alpha_factor * focal_weight ** gamma

     

       #定义分类损失: 权重*原来的交叉熵损失

       cls_loss = focal_weight * keras.backend.binary_crossentropy(labels, classification)

       # compute the normalizer: the number of positive anchors

       normalizer = backend.where(keras.backend.equal(anchor_state, 1))

       normalizer = keras.backend.cast(keras.backend.shape(normalizer)[0], keras.backend.floatx())

       normalizer = keras.backend.maximum(keras.backend.cast_to_floatx(1.0), normalizer)

       return keras.backend.sum(cls_loss) / normalizer

   return _focal

def smooth_l1(sigma=3.0):  #框回归损失采用smooth_l1函数

   """ Create a smooth L1 loss functor.

   Args

       sigma: This argument defines the point where the loss changes from L2 to L1.

   Returns

       A functor for computing the smooth L1 loss given target data and predicted data.

   """

   sigma_squared = sigma ** 2

   def _smooth_l1(y_true, y_pred):

       """ Compute the smooth L1 loss of y_pred w.r.t. y_true.

       Args

           y_true: Tensor from the generator of shape (B, N, 5). The last value for each box is the state of the anchor (ignore, negative, positive).

           y_pred: Tensor from the network of shape (B, N, 4).

       Returns

           The smooth L1 loss of y_pred w.r.t. y_true.

       """

       # separate target and state

       regression        = y_pred

       regression_target = y_true[:, :, :-1]

       anchor_state      = y_true[:, :, -1]

       # filter out "ignore" anchors

       indices           = backend.where(keras.backend.equal(anchor_state, 1))

       regression        = backend.gather_nd(regression, indices)

       regression_target = backend.gather_nd(regression_target, indices)

       # compute smooth L1 loss

       # f(x) = 0.5 * (sigma * x)^2          if |x| < 1 / sigma / sigma

       #        |x| - 0.5 / sigma / sigma    otherwise

       regression_diff = regression - regression_target

       regression_diff = keras.backend.abs(regression_diff)

       regression_loss = backend.where(

           keras.backend.less(regression_diff, 1.0 / sigma_squared),

           0.5 * sigma_squared * keras.backend.pow(regression_diff, 2),

           regression_diff - 0.5 / sigma_squared

       )

       # compute the normalizer: the number of positive anchors

       normalizer = keras.backend.maximum(1, keras.backend.shape(indices)[0])

       normalizer = keras.backend.cast(normalizer, dtype=keras.backend.floatx())

       return keras.backend.sum(regression_loss) / normalizer

   return _smooth_l1


相关文章
|
2月前
|
机器学习/深度学习 算法 测试技术
低照度增强算法(图像增强+目标检测+代码)
低照度增强算法(图像增强+目标检测+代码)
170 1
|
2月前
|
机器学习/深度学习 监控 算法
yolov8+多算法多目标追踪+实例分割+目标检测+姿态估计(代码+教程)
yolov8+多算法多目标追踪+实例分割+目标检测+姿态估计(代码+教程)
233 1
|
9月前
|
机器学习/深度学习 监控 算法
YoloV(You Only Look Once)是一种基于深度学习的目标检测算法
YoloV(You Only Look Once)是一种基于深度学习的目标检测算法
|
2月前
|
监控 算法 自动驾驶
主流的目标检测算法是那种?
主流的目标检测算法是那种?
|
2月前
|
机器学习/深度学习 算法 计算机视觉
[YOLOv8/YOLOv7/YOLOv5系列算法改进NO.5]改进特征融合网络PANET为BIFPN(更新添加小目标检测层yaml)
本文介绍了改进YOLOv5以解决处理复杂背景时可能出现的错漏检问题。
162 5
|
9天前
|
机器学习/深度学习 人工智能 算法
【昆虫识别系统】图像识别Python+卷积神经网络算法+人工智能+深度学习+机器学习+TensorFlow+ResNet50
昆虫识别系统,使用Python作为主要开发语言。通过TensorFlow搭建ResNet50卷积神经网络算法(CNN)模型。通过对10种常见的昆虫图片数据集('蜜蜂', '甲虫', '蝴蝶', '蝉', '蜻蜓', '蚱蜢', '蛾', '蝎子', '蜗牛', '蜘蛛')进行训练,得到一个识别精度较高的H5格式模型文件,然后使用Django搭建Web网页端可视化操作界面,实现用户上传一张昆虫图片识别其名称。
140 7
【昆虫识别系统】图像识别Python+卷积神经网络算法+人工智能+深度学习+机器学习+TensorFlow+ResNet50
|
2月前
|
缓存 算法 安全
Java集合框架:深入探究数据结构与算法的精华
Java集合框架:深入探究数据结构与算法的精华
|
2月前
|
机器学习/深度学习 算法 固态存储
深度学习算法工程师面试问题总结| 深度学习目标检测岗位面试总结
本文给大家带来的百面算法工程师是深度学习目标检测岗位面试总结,文章内总结了常见的提问问题,旨在为广大学子模拟出更贴合实际的面试问答场景。在这篇文章中,我们还将介绍一些常见的深度学习目标检测面试问题,并提供参考的回答及其理论基础,以帮助求职者更好地准备面试。通过对这些问题的理解和回答,求职者可以展现出自己的深度学习目标检测领域的专业知识、解决问题的能力以及对实际应用场景的理解。同时,这也是为了帮助求职者更好地应对深度学习目标检测岗位的面试挑战,提升面试的成功率和竞争力。
|
2月前
|
设计模式 算法 Java
[设计模式Java实现附plantuml源码~行为型]定义算法的框架——模板方法模式
[设计模式Java实现附plantuml源码~行为型]定义算法的框架——模板方法模式
|
9月前
|
机器学习/深度学习 监控 算法
目标检测算法的优缺点及适用场景
目标检测算法的优缺点及适用场景
304 0