学习笔记32-pytorch代码实现全局协方差池化GCP

实现torch协方差矩阵可参考博客

GCP概念
协方差矩阵描述的是一组随机变量两两之间的相关性大小。全局协方差池化的做法,就是通过计算特征图的协方差矩阵(二阶信息)来选出这个能代表特征图数据分布情况的值。
torch.cov()函数可以自行实现协方差矩阵的计算,具体计算过程由下图官方解释。
学习笔记32-pytorch代码实现全局协方差池化GCP_第1张图片
根据协方差的计算公式,简单写代码实现GCP,并应用于CNN网络的分类层中。

class CovariancePooling(nn.Module):
    def __init__(self, input_c: int, squeeze_factor: int = 4):  # 输入通道数,超参压缩因子(默认为4)
        super(CovariancePooling, self).__init__()
    def forward(self, x):
        scale = torch.zeros(x.shape[0],x.shape[1],1,1)
        x=x.cpu()
        for i, batch in enumerate(x):     #用于将一个可遍历的数据对象 (如列表、元组或字符串)组合为一个索引序列
            for j, ch in enumerate(batch):
                ch = ch.view(-1)#重新定义矩阵的形状,自动调整这个维度上的元素个数,以保证元素的总数不变。
                vecs_np = ch.detach().numpy()
                cov = np.cov(vecs_np.T)
                cov = torch.tensor(cov)
                scale[i, j] = cov
        return scale.cuda()

解决方法
值得注意的是,vecs_np = ch.detach().numpy()
由于待转换类型的PyTorch Tensor变量带有梯度,如果不加.detach()直接将其转换为numpy数据会破坏计算图,因此numpy拒绝进行数据转换。这实际上这是对开发者的一种提醒。如果自己在转换数据时不需要保留梯度信息,可以在变量转换之前添加.detach()调用。

你可能感兴趣的:(学习笔记,pytorch,深度学习,python)