self_attention机制作用于图像处理

244 阅读2分钟

2022 年什么会火?什么该学?本文正在参与“聊聊 2022 技术趋势”征文活动

在深度学习领域,自从注意力机制出现之后,各分支领域都积极加入并取得了对于对应技术的较好的表现,所以我相信在2022年对这个模块的使用同样也会很火热,所以看了一些论文。然后其中的部分重点我便记录在这篇文章中,希望大家能喜欢。

论文中的自注意力机制(VPR2021)

import torch,math
max_len = 2116
d_model = 128
mx = torch.zeros([max_len,d_model]).float()
a = torch.arange(0, d_model, 2).float()
b = -(math.log(10000.0) / d_model)
c = (a * b)
div_term = c.exp()
position = torch.arange(0, max_len).float().unsqueeze(1)
mx[:,0::2] = torch.sin(position * div_term)
mx[:,1::2] = torch.cos(position * div_term)
x = torch.sin(position * div_term)
print(mx.size())
print(mx)
print(x.size())
print(x)
  • 理解:对于这部分代码的理解来说其实并不难,我也是参考输出结果之后才勉强懂了其中的作用原理的。简单来说就是通过以上代码实现某个特征点与其他特征点的距离关系,通过这个关系来达到全局注意的目的。
  • 运行结果:
torch.Size([2116, 128])
tensor([[ 0.0000e+00,  1.0000e+00,  0.0000e+00,  ...,  1.0000e+00,          0.0000e+00,  1.0000e+00],
        [ 8.4147e-01,  5.4030e-01,  7.6172e-01,  ...,  1.0000e+00,          1.1548e-04,  1.0000e+00],
        [ 9.0930e-01, -4.1615e-01,  9.8705e-01,  ...,  1.0000e+00,          2.3096e-04,  1.0000e+00],
        ...,
        [ 9.6135e-01, -2.7534e-01,  9.8102e-01,  ...,  9.6056e-01,          2.4159e-01,  9.7038e-01],
        [ 2.8773e-01, -9.5771e-01,  7.8330e-01,  ...,  9.6053e-01,          2.4170e-01,  9.7035e-01],
        [-6.5043e-01, -7.5957e-01,  3.3984e-02,  ...,  9.6049e-01,          2.4182e-01,  9.7032e-01]])
torch.Size([2116, 64])
tensor([[ 0.0000e+00,  0.0000e+00,  0.0000e+00,  ...,  0.0000e+00,          0.0000e+00,  0.0000e+00],
        [ 8.4147e-01,  7.6172e-01,  6.8156e-01,  ...,  1.5399e-04,          1.3335e-04,  1.1548e-04],
        [ 9.0930e-01,  9.8705e-01,  9.9748e-01,  ...,  3.0799e-04,          2.6670e-04,  2.3096e-04],
        ...,
        [ 9.6135e-01,  9.8102e-01,  9.1831e-01,  ...,  3.1968e-01,          2.7806e-01,  2.4159e-01],
        [ 2.8773e-01,  7.8330e-01,  9.4179e-01,  ...,  3.1982e-01,          2.7819e-01,  2.4170e-01],
        [-6.5043e-01,  3.3984e-02,  4.6004e-01,  ...,  3.1997e-01,          2.7832e-01,  2.4182e-01]])

自注意力机制(了解)

  • 对比理解: 自注意力机制和注意力机制还是存在一定的差别的。(之前的文章《Attention作用于图像》有详细介绍,这里只介绍自注意机制的应用)

  • 具体理解: 自注意力机制主要是最后生成的注意力矩阵张量和输入的feature_map的shape除了channels层其他是一样的,经过自注意模块输出的结果是两个张量的乘积。具体代码思路如下所示,主要理清一下shape的思路就好了:

import tensorflow as tf

def hw_flatten(x) :
    return tf.reshape(x, shape=[x.shape[0], -1, x.shape[-1]])

def self_attention(x, channels, sn=False, scope='self_attention'):
    with tf.variable_scope(scope):
        f = conv(x, channels // 8, kernel=1, stride=1, scope='f_conv')  # [bs, h, w, c']
        g = conv(x, channels // 8, kernel=1, stride=1, scope='g_conv')  # [bs, h, w, c']
        h = conv(x, channels, kernel=1, stride=1, sn=sn, scope='h_conv')  # [bs, h, w, c]

        # N = h * w
        s = tf.matmul(hw_flatten(g), hw_flatten(f), transpose_b=True)  # # [bs, N, N]

        beta = tf.nn.softmax(s)  # attention map

        o = tf.matmul(beta, hw_flatten(h))  # [bs, N, C]
        gamma = tf.get_variable("gamma", [1], initializer=tf.constant_initializer(0.0))

        o = tf.reshape(o, shape=x.shape)  # [bs, h, w, C]
        x = gamma * o + x

    return x
  • 注意: 如果你想直接拷贝代码是运行不了的,这里只是提供一个思路,具体的能运行版本之后我会通过pytorch进行改写一下。softmax的参数张量不能是int型,需要是float型,不然会报错。

  • 上文是我的自己理解,代码是参考的。有了代码才能更好地理解自注意机制的意思:参考文章