当前位置:网站首页>[Thesis code] SML part code reading
[Thesis code] SML part code reading
2022-07-06 05:55:00 【starbuling~】
SML Boundary suppression and Gaussian smoothing in
Boundary smoothing suppression class
class BoundarySuppressionWithSmoothing(nn.Module):
""" Apply boundary suppression and dilated smoothing Boundary suppression , Expand and smooth """
initialization
def __init__(self, boundary_suppression=True, boundary_width=4, boundary_iteration=4,
dilated_smoothing=True, kernel_size=7, dilation=6):
Define some parameters
super(BoundarySuppressionWithSmoothing, self).__init__()
self.kernel_size = kernel_size # Convolution kernel size
self.dilation = dilation # expansion
self.boundary_suppression = boundary_suppression # Boundary suppression
self.boundary_width = boundary_width # Boundary width
self.boundary_iteration = boundary_iteration # Boundary iteration
Create Gaussian kernel
sigma = 1.0
size = 7
# function Is the probability density function of two-dimensional Gaussian distribution
gaussian_kernel = np.fromfunction(lambda x, y:
(1/(2*math.pi*sigma**2)) * math.e ** ((-1*((x-(size-1)/2)**2+(y-(size-1)/2)**2))/(2*sigma**2)),
(size, size)) # Construct Gaussian kernel (7,7) 3 * sigma + 1
gaussian_kernel /= np.sum(gaussian_kernel) # Divide by the sum of all elements in the Gaussian kernel ( weighted mean , Avoid image pixel overflow )
gaussian_kernel = torch.Tensor(gaussian_kernel).unsqueeze(0).unsqueeze(0)
self.dilated_smoothing = dilated_smoothing # Expand and smooth
l a m b d a ( x , y ) = 1 2 ∗ π ∗ σ 2 e x p ( − ( x − s i z e − 1 2 ) 2 + ( y − s i z e − 1 2 ) 2 2 ∗ σ 2 ) lambda(x,y) = \frac{1}{2 * \pi * \sigma^2} exp(-\frac{(x - \frac{size-1}{2})^2 + (y - \frac{size-1}{2})^2}{2 * \sigma^2}) lambda(x,y)=2∗π∗σ21exp(−2∗σ2(x−2size−1)2+(y−2size−1)2)
numpy In the library
fromfunction
: Through custom functions fun, shape shape, data format dtype -> According to the array subscript (x,y) Generate values for each location , Make an array
Function parameter
np.fromfunction(function, shape, dtype)
function: A function transformed into a specific value according to coordinates
def function(x,y): Internal function (x,y) Are the coordinates with the upper left corner as the origin ,x For row coordinates ,y Column coordinates , It means the first one x That's ok y Column .
shape(a,b): Represents an array array Size ,a That's ok b Column .
dtype: Represents the number type of the array
Define two-layer convolution (in_channel, out_channel, k, s)
- (1, 1, 3, 1) The weight matrix is full 1 matrix
- (1, 1, 7, 1) The weight matrix is Gaussian kernel
self.first_conv = nn.Conv2d(1, 1, kernel_size=3, stride=1, bias=False)
self.first_conv.weight = torch.nn.Parameter(torch.ones_like((self.first_conv.weight)))
self.second_conv = nn.Conv2d(
1, 1, kernel_size=self.kernel_size, stride=1, dilation=self.dilation, bias=False)
self.second_conv.weight = torch.nn.Parameter(gaussian_kernel)
Forward propagation
def forward(self, x, prediction=None):
if len(x.shape) == 3:
x = x.unsqueeze(1) # If it is 3 dimension , expand 1 dimension
x_size = x.size()
# B x 1 x H x W
assert len(x.shape) == 4
out = x
Branch 1: Need boundary suppression
if self.boundary_suppression:
# obtain the boundary map of width 2 by default The default acquisition width is 2 Boundary graph of
# this can be calculated by the difference of dilation and erosion This can be calculated by the difference between expansion and corrosion
boundaries = find_boundaries(prediction.unsqueeze(1)) # Look for boundaries
expanded_boundaries = None
if self.boundary_iteration != 0:
assert self.boundary_width % self.boundary_iteration == 0 # The boundary width is divided by the number of iterations
diff = self.boundary_width // self.boundary_iteration # Width increased each time
The main process of boundary suppression
for iteration in range(self.boundary_iteration):
if len(out.shape) != 4:
out = out.unsqueeze(1)
prev_out = out
Get the boundary
# if it is the last iteration or boundary width is zero The last iteration or boundary width is 0 after , Stop expanding width if self.boundary_width == 0 or iteration == self.boundary_iteration - 1: expansion_width = 0 # reduce the expansion width for each iteration Otherwise, the width of the freight station will be continuously increased in each iteration else: expansion_width = self.boundary_width - diff * iteration - 1 # expand the boundary obtained from the prediction (width of 2) by expansion rate expanded_boundaries = expand_boundaries(boundaries, r=expansion_width) # Expand the boundary according to the expansion width , The specific method is explained in detail in the function later
Reverse the boundary -> Get a non boundary mask
# invert it so that we can obtain non-boundary mask non_boundary_mask = 1. * (expanded_boundaries == 0) # Reverse the boundary , Get the non boundary mask . The non boundary is 1, The boundary is 0
Make the boundary area to 0
f_size = 1 num_pad = f_size # making boundary regions to 0 x_masked = out * non_boundary_mask # The input image * Non boundary mask -> Get the non boundary region (1) x_padded = nn.ReplicationPad2d(num_pad)(x_masked) non_boundary_mask_padded = nn.ReplicationPad2d(num_pad)(non_boundary_mask)
class torch.nn.ReplicationPad2d(padding)
padding(int ,tuple) The size of the fill . If int , Then use the same fill in all boundaries .
If it is 4 tuple , Then use (padding_left, padding_right, padding_top, padding_bottom)Sum the values in the receptive field
# sum up the values in the receptive field y = self.first_conv(x_padded) # count non-boundary elements in the receptive field num_calced_elements = self.first_conv(non_boundary_mask_padded) num_calced_elements = num_calced_elements.long()
Averaging
# take an average by dividing y by count # if there is no non-boundary element in the receptive field, # keep the original value avg_y = torch.where((num_calced_elements == 0), prev_out, y / num_calced_elements) out = avg_y
Update boundaries
# update boundaries only out = torch.where((non_boundary_mask == 0), out, prev_out) del expanded_boundaries, non_boundary_mask
The second step : Expand and smooth
# second stage; apply dilated smoothing
if self.dilated_smoothing == True:
out = nn.ReplicationPad2d(self.dilation * 3)(out)
out = self.second_conv(out)
return out.squeeze(1)
Branch 1: No boundary suppression is required
else:
if self.dilated_smoothing == True: # Expand and smooth
out = nn.ReplicationPad2d(self.dilation * 3)(out)
out = self.second_conv(out)
else:
out = x
return out.squeeze(1)
find_boundaries
def find_boundaries(label):
""" Calculate boundary mask by getting diff of dilated and eroded prediction maps """
assert len(label.shape) == 4
boundaries = (dilation(label.float(), selem_dilation) != erosion(label.float(), selem)).float()
### save_image(boundaries, f'boundaries_{boundaries.float().mean():.2f}.png', normalize=True)
return boundaries
selem = torch.ones((3, 3)).cuda() # It's a (3,3) Full size 1 Tensor , Corrosion coil nucleation
selem_dilation = torch.FloatTensor(ndi.generate_binary_structure(2, 1)).cuda() # Expanded convolution kernel
corrosion :
inflation :
inflation (dilation) & corrosion (erosion)
These are two basic morphological operations , It is mainly used to find the maximum and minimum regions in the image .
- Expansion is similar to ‘ Domain expansion ’ , Expand the highlighted area or white part of the image , The operation result graph is larger than the highlighted area of the original graph .
- Corrosion similar ‘ The field is being eroded ’ , Reduce and refine the highlighted area or white part of the image , The operation result is smaller than the highlighted area of the original image .
The specific process : Define a convolution kernel , Convolute the picture . Expansion do “ or ” operation , expand 1 The scope of the ; Corrosion makes “ And ” operation , Reduce 1 The number of
dilation(image, kernel) # Images , Convolution kernel
erosion(image, kernel)
After expansion and corrosion of the label drawings , Different positions , It's the boundary . use 1 Express
expand_boundaries
def expand_boundaries(boundaries, r=0):
""" Expand boundary maps with the rate of r """
if r == 0:
return boundaries
expanded_boundaries = dilation(boundaries, d_ks[r]) # Do the expansion operation
### save_image(expanded_boundaries, f'expanded_boundaries_{r}_{boundaries.float().mean():.2f}.png', normalize=True)
return expanded_boundaries
About d_ks[]
:
d_k1 = torch.zeros((1, 1, 2 * 1 + 1, 2 * 1 + 1)).cuda()
d_k2 = torch.zeros((1, 1, 2 * 2 + 1, 2 * 2 + 1)).cuda()
d_k3 = torch.zeros((1, 1, 2 * 3 + 1, 2 * 3 + 1)).cuda()
d_k4 = torch.zeros((1, 1, 2 * 4 + 1, 2 * 4 + 1)).cuda()
d_k5 = torch.zeros((1, 1, 2 * 5 + 1, 2 * 5 + 1)).cuda()
d_k6 = torch.zeros((1, 1, 2 * 6 + 1, 2 * 6 + 1)).cuda()
d_k7 = torch.zeros((1, 1, 2 * 7 + 1, 2 * 7 + 1)).cuda()
d_k8 = torch.zeros((1, 1, 2 * 8 + 1, 2 * 8 + 1)).cuda()
d_k9 = torch.zeros((1, 1, 2 * 9 + 1, 2 * 9 + 1)).cuda()
d_ks = {
1: d_k1, 2: d_k2, 3: d_k3, 4: d_k4,
5: d_k5, 6: d_k6, 7: d_k7, 8: d_k8, 9: d_k9}
for k, v in d_ks.items():
v[:, :, k, k] = 1
for i in range(k):
v = dilation(v, selem_dilation)
d_ks[k] = v.squeeze(0).squeeze(0)
print(f'dilation kernel at {
k}:\n\n{
d_ks[k]}')
The appearance of these convolution kernels is roughly as follows , And so on
边栏推荐
- 实践分享:如何安全快速地从 Centos迁移到openEuler
- [C language syntax] the difference between typedef struct and struct
- Report on the competition status and investment decision recommendations of Guangxi hospital industry in China from 2022 to 2028
- Anti shake and throttling are easy to understand
- 【SQL server速成之路】——身份验证及建立和管理用户账户
- 应用安全系列之三十七:日志注入
- Quantitative description of ANC noise reduction
- MIT6.s081-2020 Lab2 System Calls
- B站刘二大人-反向传播
- CoDeSys note 2: set coil and reset coil
猜你喜欢
P2802 回家
First knowledge database
CoDeSys note 2: set coil and reset coil
数字经济破浪而来 ,LTD是权益独立的Web3.0网站?
Network protocol model
Leetcode 701 insertion operation in binary search tree -- recursive method and iterative method
B站刘二大人-Softmx分类器及MNIST实现-Lecture 9
C language bubble sort
The digital economy has broken through the waves. Is Ltd a Web3.0 website with independent rights and interests?
Is it difficult for an information system project manager?
随机推荐
移植InfoNES到STM32
Winter 2021 pat class B problem solution (C language)
What is independent IP and how about independent IP host?
Market development prospect and investment risk assessment report of China's humidity sensor industry from 2022 to 2028
59. Spiral matrix
Analysis report on development trends and investment planning of China's methanol industry from 2022 to 2028
如何在业务代码中使用 ThinkPHP5.1 封装的容器内反射方法
Station B, Master Liu Er - back propagation
Web服务连接器:Servlet
[JVM] [Chapter 17] [garbage collector]
[Baiwen smart home] first day of the course_ Learn Embedded and understand the development mode of bare metal and RTOS
The usage and difference between strlen and sizeof
P2802 go home
Memory and stack related concepts
The ECU of 21 Audi q5l 45tfsi brushes is upgraded to master special adjustment, and the horsepower is safely and stably increased to 305 horsepower
Text classification still stays at Bert? The dual contrast learning framework is too strong
查詢生產訂單中某個(些)工作中心對應的標准文本碼
YYGH-11-定时统计
C language learning notes (mind map)
进程和线程