self attention机制

作者: 菜田的守望者w | 来源:发表于2019-07-25 15:54 被阅读12次

    主要思想:CNN中的 convolution单元每次只关注邻域 kernel size 的区域,就算后期感受野越来越大,终究还是局部区域的运算,这样就忽略了全局其他片区(比如很远的像素)对当前区域的贡献。图示如下:

    download.jpg
    • 首先对输入的 feature map (inputs) 进行三个卷积操作(都是 1X1 卷积,因为要保证图片的weight和height在整个过程中保持不变,然后得到图中的f(x),g(x),h(x),然后将f(x),g(x),分别reshape再将f(x)转置形状变成(batch_size,HW,C)和(batch_size,C,WH)后经过matmul和softmax激活成为(1,HW,HW)即得到所说的attenton了。最后将h(x)经过reshape变成(batch_size,HW,C)相乘后就变成(batch_size,HW,C),经过reshape就可以得到原来形状的图。

    主要代码:inputs就是上面处理后得到的四维tensor。

        inputs_shape = inputs.get_shape().as_list()
        batchsize, height, width, C = inputs_shape[0], inputs_shape[1], inputs_shape[2], inputs_shape[3]
        filter = tf.Variable(tf.truncated_normal([1, 1, C, 1], dtype=tf.float32, stddev=0.1), name='weights')
        filter1 = tf.Variable(tf.truncated_normal([1, 1, C, C], dtype=tf.float32, stddev=0.1), name='weights1')
        query_conv = tf.nn.conv2d(inputs, filter, strides=[1, 1, 1, 1], padding='VALID')
        print(query_conv)
        key_conv = tf.nn.conv2d(inputs, filter, strides=[1, 1, 1, 1], padding='VALID')
        value_conv = tf.nn.conv2d(inputs, filter1, strides=[1, 1, 1, 1], padding='VALID')
        proj_query = tf.reshape(query_conv, [batchsize, width * height, -1])
        proj_key = tf.transpose((tf.reshape(key_conv, [batchsize, width * height, -1])), perm=[0, 2, 1])
        energy = tf.matmul(proj_query, proj_key)
        attention = tf.nn.softmax(energy)
        proj_value = tf.reshape(value_conv, [batchsize, width * height, -1])
        out = tf.matmul(attention, proj_value)
        out = tf.reshape(out, [batchsize, height, width, C])
    

    实现过程中在out输出中加入batch_normalization效果会更好一点.


    20190725144520.png
    20190725144046.png

    原图是:


    3A3F27E1355AB34B24BA84F7A01C5684.jpg
    44BEFB4E4D02FAE2A7E38F99EE991D62.jpg

    相关文章

      网友评论

        本文标题:self attention机制

        本文链接:https://www.haomeiwen.com/subject/zyxalctx.html