det_sast_loss.py 5.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121
  1. # copyright (c) 2019 PaddlePaddle Authors. All Rights Reserve.
  2. #
  3. # Licensed under the Apache License, Version 2.0 (the "License");
  4. # you may not use this file except in compliance with the License.
  5. # You may obtain a copy of the License at
  6. #
  7. # http://www.apache.org/licenses/LICENSE-2.0
  8. #
  9. # Unless required by applicable law or agreed to in writing, software
  10. # distributed under the License is distributed on an "AS IS" BASIS,
  11. # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  12. # See the License for the specific language governing permissions and
  13. # limitations under the License.
  14. from __future__ import absolute_import
  15. from __future__ import division
  16. from __future__ import print_function
  17. import paddle
  18. from paddle import nn
  19. from .det_basic_loss import DiceLoss
  20. import numpy as np
  21. class SASTLoss(nn.Layer):
  22. """
  23. """
  24. def __init__(self, eps=1e-6, **kwargs):
  25. super(SASTLoss, self).__init__()
  26. self.dice_loss = DiceLoss(eps=eps)
  27. def forward(self, predicts, labels):
  28. """
  29. tcl_pos: N x 128 x 3
  30. tcl_mask: N x 128 x 1
  31. tcl_label: N x X list or LoDTensor
  32. """
  33. f_score = predicts['f_score']
  34. f_border = predicts['f_border']
  35. f_tvo = predicts['f_tvo']
  36. f_tco = predicts['f_tco']
  37. l_score, l_border, l_mask, l_tvo, l_tco = labels[1:]
  38. #score_loss
  39. intersection = paddle.sum(f_score * l_score * l_mask)
  40. union = paddle.sum(f_score * l_mask) + paddle.sum(l_score * l_mask)
  41. score_loss = 1.0 - 2 * intersection / (union + 1e-5)
  42. #border loss
  43. l_border_split, l_border_norm = paddle.split(
  44. l_border, num_or_sections=[4, 1], axis=1)
  45. f_border_split = f_border
  46. border_ex_shape = l_border_norm.shape * np.array([1, 4, 1, 1])
  47. l_border_norm_split = paddle.expand(
  48. x=l_border_norm, shape=border_ex_shape)
  49. l_border_score = paddle.expand(x=l_score, shape=border_ex_shape)
  50. l_border_mask = paddle.expand(x=l_mask, shape=border_ex_shape)
  51. border_diff = l_border_split - f_border_split
  52. abs_border_diff = paddle.abs(border_diff)
  53. border_sign = abs_border_diff < 1.0
  54. border_sign = paddle.cast(border_sign, dtype='float32')
  55. border_sign.stop_gradient = True
  56. border_in_loss = 0.5 * abs_border_diff * abs_border_diff * border_sign + \
  57. (abs_border_diff - 0.5) * (1.0 - border_sign)
  58. border_out_loss = l_border_norm_split * border_in_loss
  59. border_loss = paddle.sum(border_out_loss * l_border_score * l_border_mask) / \
  60. (paddle.sum(l_border_score * l_border_mask) + 1e-5)
  61. #tvo_loss
  62. l_tvo_split, l_tvo_norm = paddle.split(
  63. l_tvo, num_or_sections=[8, 1], axis=1)
  64. f_tvo_split = f_tvo
  65. tvo_ex_shape = l_tvo_norm.shape * np.array([1, 8, 1, 1])
  66. l_tvo_norm_split = paddle.expand(x=l_tvo_norm, shape=tvo_ex_shape)
  67. l_tvo_score = paddle.expand(x=l_score, shape=tvo_ex_shape)
  68. l_tvo_mask = paddle.expand(x=l_mask, shape=tvo_ex_shape)
  69. #
  70. tvo_geo_diff = l_tvo_split - f_tvo_split
  71. abs_tvo_geo_diff = paddle.abs(tvo_geo_diff)
  72. tvo_sign = abs_tvo_geo_diff < 1.0
  73. tvo_sign = paddle.cast(tvo_sign, dtype='float32')
  74. tvo_sign.stop_gradient = True
  75. tvo_in_loss = 0.5 * abs_tvo_geo_diff * abs_tvo_geo_diff * tvo_sign + \
  76. (abs_tvo_geo_diff - 0.5) * (1.0 - tvo_sign)
  77. tvo_out_loss = l_tvo_norm_split * tvo_in_loss
  78. tvo_loss = paddle.sum(tvo_out_loss * l_tvo_score * l_tvo_mask) / \
  79. (paddle.sum(l_tvo_score * l_tvo_mask) + 1e-5)
  80. #tco_loss
  81. l_tco_split, l_tco_norm = paddle.split(
  82. l_tco, num_or_sections=[2, 1], axis=1)
  83. f_tco_split = f_tco
  84. tco_ex_shape = l_tco_norm.shape * np.array([1, 2, 1, 1])
  85. l_tco_norm_split = paddle.expand(x=l_tco_norm, shape=tco_ex_shape)
  86. l_tco_score = paddle.expand(x=l_score, shape=tco_ex_shape)
  87. l_tco_mask = paddle.expand(x=l_mask, shape=tco_ex_shape)
  88. tco_geo_diff = l_tco_split - f_tco_split
  89. abs_tco_geo_diff = paddle.abs(tco_geo_diff)
  90. tco_sign = abs_tco_geo_diff < 1.0
  91. tco_sign = paddle.cast(tco_sign, dtype='float32')
  92. tco_sign.stop_gradient = True
  93. tco_in_loss = 0.5 * abs_tco_geo_diff * abs_tco_geo_diff * tco_sign + \
  94. (abs_tco_geo_diff - 0.5) * (1.0 - tco_sign)
  95. tco_out_loss = l_tco_norm_split * tco_in_loss
  96. tco_loss = paddle.sum(tco_out_loss * l_tco_score * l_tco_mask) / \
  97. (paddle.sum(l_tco_score * l_tco_mask) + 1e-5)
  98. # total loss
  99. tvo_lw, tco_lw = 1.5, 1.5
  100. score_lw, border_lw = 1.0, 1.0
  101. total_loss = score_loss * score_lw + border_loss * border_lw + \
  102. tvo_loss * tvo_lw + tco_loss * tco_lw
  103. losses = {'loss':total_loss, "score_loss":score_loss,\
  104. "border_loss":border_loss, 'tvo_loss':tvo_loss, 'tco_loss':tco_loss}
  105. return losses