落水人员检测
Вы не можете выбрать более 25 тем Темы должны начинаться с буквы или цифры, могут содержать дефисы(-) и должны содержать не более 35 символов.

188 lines
7.3KB

  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()