落水人员检测
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

wj_loss.py 7.3KB

8 kuukautta sitten
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187
  1. import numpy as np
  2. import matplotlib.pyplot as plt
  3. from torch.nn import Module
  4. import torch
  5. import torch.nn as nn
  6. class wj_bce_Loss(Module):
  7. def __init__(self, kernel_size=11, sigma=2,weights=[0.2,1.0,1.0], weight_fuse='add',classweight=None,as_loss=True):
  8. super().__init__()
  9. self.kernel_size = kernel_size
  10. self.sigma = sigma
  11. self.weights = torch.tensor(weights)
  12. self.as_loss = as_loss
  13. self.gaussian_kernel = self._create_gaussian_kernel(self.kernel_size, self.sigma)
  14. self.sobel_kernel = torch.tensor([[[[-1, -1, -1], [-1, 8, -1], [-1, -1, -1]]]])
  15. self.pad = int((self.kernel_size - 1)/2)
  16. self.tmax = torch.tensor(1.0)
  17. self.weight_fuse = weight_fuse
  18. if classweight:
  19. self.criterion = nn.CrossEntropyLoss( weight=torch.tensor(classweight),reduction = 'none')
  20. else:
  21. self.criterion = nn.CrossEntropyLoss( reduction = 'none')
  22. def forward(self, x, y):
  23. if not self.gaussian_kernel.is_cuda:
  24. self.gaussian_kernel = self.gaussian_kernel.to(x.device)
  25. if not self.sobel_kernel.is_cuda:
  26. self.sobel_kernel = self.sobel_kernel.to(x.device)
  27. if not self.tmax.is_cuda:
  28. self.tmax = self.tmax.to(x.device)
  29. if not self.weights.is_cuda:
  30. self.weights = self.weights.to(x.device)
  31. mix_weights = self._get_mix_weight(x, y)
  32. loss = self.criterion(x,y.long())
  33. return torch.mean(loss*mix_weights)
  34. def _get_weight(self,mask):
  35. ##preds 变成0,1图,(bs,h,w)
  36. mask_map = (mask <= self.tmax).float() * mask + (mask > self.tmax).float() * self.tmax
  37. mask_map = mask_map.unsqueeze(1)
  38. padLayer = nn.ReflectionPad2d(1)
  39. mask_pad = padLayer(mask_map)
  40. # 定义sobel算子参数
  41. mask_edge = torch.conv2d(mask_pad.float(), self.sobel_kernel.float(), padding=0)
  42. mask_edge = torch.absolute(mask_edge)
  43. ##低通滤波膨胀边界
  44. smooth_edge = torch.conv2d(mask_edge.float(), self.gaussian_kernel.float(), padding=self.pad)
  45. return smooth_edge
  46. def _get_mix_weight(self, x, y):
  47. #get pred weight
  48. preds_x = torch.argmax(x,axis=1)
  49. preds_weights = self._get_weight(preds_x).squeeze(1)
  50. #get label weight
  51. labels_weights = self._get_weight(y).squeeze(1)
  52. #normal weight
  53. normal_weights = torch.ones(y.shape)
  54. if not normal_weights.is_cuda:
  55. normal_weights = normal_weights.to(x.device)
  56. #print(self.weights)
  57. if self.weight_fuse=='multify':
  58. mix_weights = self.weights[0] * preds_weights * labels_weights + self.weights[2] *normal_weights
  59. else:
  60. mix_weights = self.weights[0] * preds_weights + self.weights[1] * labels_weights + self.weights[2] *normal_weights
  61. return mix_weights
  62. def _create_gaussian_kernel(self, kernel_size, sigma):
  63. start = (1 - kernel_size) / 2
  64. end = (1 + kernel_size) / 2
  65. kernel_1d = torch.arange(start, end, step=1, dtype=torch.float)
  66. kernel_1d = torch.exp(-torch.pow(kernel_1d / sigma, 2) / 2)
  67. kernel_1d = (kernel_1d / kernel_1d.sum()).unsqueeze(dim=0)
  68. kernel_2d = torch.matmul(kernel_1d.t(), kernel_1d)
  69. kernel_2d = kernel_2d.expand(1, 1, kernel_size, kernel_size).contiguous()
  70. return kernel_2d
  71. class thFloater(Module):
  72. def __init__(self, weights=[0.5,0.5]):
  73. super().__init__()
  74. self.weights = torch.tensor(weights)
  75. self.baseCriterion = nn.CrossEntropyLoss( reduction = 'none')
  76. def forward(self, x, y):
  77. if not self.weights.is_cuda:
  78. self.weights = self.weights.to(x[0].device)
  79. assert len(x) == 2
  80. loss_river = self.baseCriterion(x[0],y[0].long())
  81. #loss_floater = self.baseCriterion(x[1],y[1].long()) * y[0]
  82. loss_floater = self.baseCriterion(x[1],y[1].long())
  83. return torch.mean(loss_river * self.weights[0] + loss_floater * self.weights[1] )
  84. def GaussLowPassFiltering(ksize,sigma):
  85. kernel = np.zeros((ksize,ksize),dtype=np.float32)
  86. cons = 1.0/(2.0*np.pi*sigma*sigma)
  87. for i in range(ksize):
  88. for j in range(ksize):
  89. x = i - (ksize-1)/2
  90. y = j - (ksize-1)/2
  91. kernel[j,i] = cons * np.exp((-1.0)*(x**2+y**2)/2.0/(sigma**2) )
  92. return kernel.reshape(1,1,ksize,ksize)
  93. def create_gaussian_kernel( kernel_size, sigma):
  94. start = (1 - kernel_size) / 2
  95. end = (1 + kernel_size) / 2
  96. kernel_1d = torch.arange(start, end, step=1, dtype=torch.float)
  97. kernel_1d = torch.exp(-torch.pow(kernel_1d / sigma, 2) / 2)
  98. kernel_1d = (kernel_1d / kernel_1d.sum()).unsqueeze(dim=0)
  99. kernel_2d = torch.matmul(kernel_1d.t(), kernel_1d)
  100. kernel_2d = kernel_2d.expand(3, 1, kernel_size, kernel_size).contiguous()
  101. return kernel_2d
  102. def main():
  103. import matplotlib.pyplot as plt
  104. import numpy as np
  105. import torch
  106. import torch.nn as nn
  107. #preds=torch.rand(8,5,10,10)
  108. #preds=torch.argmax(preds,axis=1)
  109. preds=torch.zeros(8,100,100)
  110. preds[:,:,50:]=3.0
  111. t_max = torch.tensor(1.0)
  112. ##preds 变成0,1图,(bs,h,w)
  113. preds_map = (preds <= t_max).float() * preds + (preds > t_max).float() * t_max
  114. preds_map = preds_map.unsqueeze(1)
  115. padLayer = nn.ReflectionPad2d(1)
  116. preds_pad = padLayer(preds_map)
  117. # 定义sobel算子参数
  118. sobel_kernel =torch.tensor([[[[-1, -1, -1], [-1, 8, -1], [-1, -1, -1]]]])
  119. preds_edge_dilate = torch.conv2d(preds_pad.float(), sobel_kernel.float(), padding=0)
  120. preds_edge_dilate = torch.absolute(preds_edge_dilate)
  121. ##低通滤波,平滑边界
  122. f_shift ,pad, sigma= 11, 5 , 2
  123. kernel = torch.from_numpy(GaussLowPassFiltering(f_shift,sigma))
  124. smooth_edge = torch.conv2d(preds_edge_dilate.float(), kernel.float(), padding=pad)
  125. print('####line134')
  126. cv2.imwrite('')
  127. show_result0 = preds_map.numpy()
  128. show_result2 = smooth_edge.numpy()
  129. show_result3=preds.numpy()
  130. #print(show_result2[0,0,:,5])
  131. #print(show_result2[0,0,5,:])
  132. #plt.figure(0);plt.imshow(show_result0[0,0]);plt.figure(1);
  133. plt.imshow(show_result2[0,0]);plt.show();
  134. #plt.figure(3);plt.imshow(show_result3[0]);plt.show();
  135. print()
  136. def test_loss_moule():
  137. preds=torch.rand(8,5,100,100)
  138. #preds=torch.argmax(preds,axis=1)
  139. targets =torch.zeros(8,100,100)
  140. targets[:,:,50:]=3.0
  141. for weights in [[1.0,1.0,1.0],[ 0.0,0.0,1.0],[ 1.0,0.0,0.0],[ 0.0,1.0,0.0],[ 1.0,1.0,0.0] ]:
  142. loss_layer = wj_bce_Loss(kernel_size=11, sigma=2,weights=weights, as_loss=True)
  143. loss = loss_layer(preds,targets)
  144. print(weights,' loss: ',loss)
  145. def test_multify_output():
  146. pred1=torch.rand(8,2,100,100)
  147. pred2=torch.rand(8,5,100,100)
  148. target1 =torch.randint(0,2,(8,100,100))
  149. target2 =torch.randint(0,5,(8,100,100))
  150. loss_layer = thFloater(weights=[0.5,0.5])
  151. loss = loss_layer([pred1,pred2],[target1,target2])
  152. print(loss)
  153. if __name__=='__main__':
  154. #main()
  155. #kk = create_gaussian_kernel( kernel_size=11, sigma=2)
  156. #print(kk.numpy().shape)
  157. #plt.figure(0);plt.imshow(kk[0,0]);plt.show()
  158. #test_loss_moule()
  159. test_multify_output()