pytorch支持自定义卷积核进行卷积操作,使用
torch.nn.functional.conv2d
下面是我用到的自定义高斯卷积核的代码:
class SA_net(nn.Module):
def __init__(self):
super(SA_net, self).__init__()
kernel =get_kernel(kernlen=5,nsig=3) #获得高斯卷积核
kernel = torch.FloatTensor(kernel).unsqueeze(0).unsqueeze(0) #扩展两个维度
self.weight = nn.Parameter(data=kernel, requires_grad=False)
self.BN=nn.BatchNorm2d(num_features=1)
def forward(self, x1,x2): #x1是用来计算attention的,x2是用来计算的Cs
x1_attention = F.conv2d(x1, self.weight, padding=2) #bs,i_c,H1,W1---->bs,1,H1,W1
x1_attention=self.BN(x1_attention) #bs,1,H1,W1
x_max=torch.max(x1_attention,x1) #bs,1,H1,W1
x_out=x_max*x2 #bs,1,H,W *bs,i_c,H1,W1 =bs,i_c,H_max,W_max (H1和H2取较大的那个)
return x_out
def get_kernel(kernlen=16, nsig=3): # nsig 标准差 ,kernlen=16核尺寸
interval = (2*nsig+1.)/kernlen #计算间隔
x = np.linspace(-nsig-interval/2., nsig+interval/2., kernlen+1) #在前两者之间均匀产生数据
#高斯函数其实就是正态分布的密度函数
kern1d = np.diff(st.norm.cdf(x)) #先积分在求导是为啥?得到一个维度上的高斯函数值
'''st.norm.cdf(x):计算正态分布累计分布函数指定点的函数值
累计分布函数:概率分布函数的积分'''
kernel_raw = np.sqrt(np.outer(kern1d, kern1d)) #np.outer计算外积,再开平方,从1维高斯参数到2维高斯参数
kernel = kernel_raw/kernel_raw.sum() #确保均值为1
return kernel