转送门:https://www.jianshu.com/p/e0845ecaf7f7.
博主已经写的是非常明白了但是有一点需要重点的标注
vgg16:13个卷积层加上3个全链接层
vgg19:16个卷积层加上3个全链接层
Attention模型的基本表述可以这样理解成:
当我们人在看一样东西的时候,我们当前时刻关注的一定是我们当前正在看的这样东西的某一地方,换句话说,当我们目光移到别处时,注意力随着目光的移动也在转移。
这意味着,当人们注意到某个目标或某个场景时,该目标内部以及该场景内每一处空间位置上的注意力分布是不一样的。
这一点在如下情形下同样成立:当我们试图描述一件事情,我们当前时刻说到的单词和句子和正在描述的该事情的对应某个片段最先关,而其他部分随着描述的进行,相关性也在不断地改变。
从上面两种情形来看,对于 Attention的作用角度出发,我们就可以从两个角度来分类 Attention种类:
空间注意力 Spatial Attention
时间注意力 Temporal Attention
这样的分类更多的是从应用层面上,而从 Attention的作用方法上,可以将其分为 Soft Attention 和 Hard Attention,这既我们所说的, Attention输出的向量分布是一种one-hot的独热分布还是soft的软分布,这直接影响对于上下文信息的选择作用。其实这里可以发现整个注意力机制是模仿人类的注意力来进行工作的。由于我研究的是图像处理方面的所以在这里我不去介绍attention 机制在自然语句方法的应用了。毕竟这是最主要的应用。在图像处理上的attention 机制是 在特征图上生成空间分布的权重,然后再对特征图加权求和,试图让网络学出来对不同物体区域加以不同关注度。之后的在CV领域中应用attention绝大多数都是这么干的。例如,spatial transformer networks(STN)是之后将attention用于物体识别比较有名的一篇文章,在一些现实应用中仍被使用。再如residual attention network.
attention机制听起来高达上,其实就是学出一个权重分布,再拿这个权重分布施加在原来的特征之上,就可以叫做attention。简单来说:(1)这个加权可以是保留所有分量均做加权(即soft attention);也可以是在分布中以某种采样策略选取部分分量(即hard attention)。(2)这个加权可以作用在原图上,也就是RAM和DRAM;也可以作用在特征图上,如后续的好多文章(例如image caption)。(3)这个加权可以作用在空间尺度上,给不同空间区域加权;也可以作用在channel尺度上,给不同通道特征加权;甚至特征图上每个元素加权。
引用其他博主经典语录,写的比较简便也没有夹杂一些比较难理解的公式。
链接: https://blog.csdn.net/nijiayan123/article/details/84984820.
但是为什么要加入attention呢,因为有一句废话我也不得不说,在加入之后图像分类,或者语义分割等场景下我们的模型精度大概能提高1~2个百分点何乐而不为呢?
1. vgg GIT链接地址
2. attention tensorflow版代码,但是这边我要特此声明这个代码也不是我写的!这个是之前找到的找不到作者地址,就这样吧 -.-!!
import tensorflow as tf
import numpy as np
slim = tf.contrib.slim
'''
建议将文件名称命名为 attention
'''
def combined_static_and_dynamic_shape(tensor):
"""Returns a list containing static and dynamic values for the dimensions.
Returns a list of static and dynamic values for shape dimensions. This is
useful to preserve static shapes when available in reshape operation.
Args:
tensor: A tensor of any type.
Returns:
A list of size tensor.shape.ndims containing integers or a scalar tensor.
"""
static_tensor_shape = tensor.shape.as_list()
dynamic_tensor_shape = tf.shape(tensor)
combined_shape = []
for index, dim in enumerate(static_tensor_shape):
if dim is not None:
combined_shape.append(dim)
else:
combined_shape.append(dynamic_tensor_shape[index])
return combined_shape
def convolutional_block_attention_module(feature_map, index, inner_units_ratio=0.5):
"""
CBAM: convolution block attention_a module, which is described in "CBAM: Convolutional Block Attention Module"
If you want to use this module, just plug this module into your network
:param feature_map : input feature map
:param index : the index of convolution block attention_a module
:param inner_units_ratio: output units number of fully connected layer: inner_units_ratio*feature_map_channel
:return:feature map with channel and spatial attention_a
"""
with tf.variable_scope("cbam"):
feature_map_shape = combined_static_and_dynamic_shape(feature_map)
# channel attention_a
# print(feature_map_shape)
channel_avg_weights = tf.nn.avg_pool(
value=feature_map,
ksize=[1, feature_map_shape[1], feature_map_shape[2], 1],
strides=[1, 1, 1, 1],
padding='VALID'
)
channel_max_weights = tf.nn.max_pool(
value=feature_map,
ksize=[1, feature_map_shape[1], feature_map_shape[2], 1],
strides=[1, 1, 1, 1],
padding='VALID'
)
channel_avg_reshape = tf.reshape(channel_avg_weights,
[feature_map_shape[0], 1, feature_map_shape[3]])
channel_max_reshape = tf.reshape(channel_max_weights,
[feature_map_shape[0], 1, feature_map_shape[3]])
channel_w_reshape = tf.concat([channel_avg_reshape, channel_max_reshape], axis=1)
fc_1 = tf.layers.dense(
inputs=channel_w_reshape,
units=feature_map_shape[3] * inner_units_ratio,
name="fc_1",
activation=tf.nn.relu
)
fc_2 = tf.layers.dense(
inputs=fc_1,
units=feature_map_shape[3],
name="fc_2",
activation=tf.nn.sigmoid
)
channel_attention = tf.reduce_sum(fc_2, axis=1, name="channel_attention_sum")
channel_attention = tf.reshape(channel_attention, shape=[feature_map_shape[0], 1, 1, feature_map_shape[3]])
feature_map_with_channel_attention = tf.multiply(feature_map, channel_attention)
# spatial attention_a
channel_wise_avg_pooling = tf.reduce_mean(feature_map_with_channel_attention, axis=3)
channel_wise_max_pooling = tf.reduce_max(feature_map_with_channel_attention, axis=3)
channel_wise_avg_pooling = tf.reshape(channel_wise_avg_pooling,
shape=[feature_map_shape[0], feature_map_shape[1], feature_map_shape[2],
1])
channel_wise_max_pooling = tf.reshape(channel_wise_max_pooling,
shape=[feature_map_shape[0], feature_map_shape[1], feature_map_shape[2],
1])
channel_wise_pooling = tf.concat([channel_wise_avg_pooling, channel_wise_max_pooling], axis=3)
spatial_attention = slim.conv2d(
channel_wise_pooling,
1,
[3, 3],
padding='SAME',
activation_fn=tf.nn.sigmoid,
scope="spatial_attention_conv"
)
feature_map_with_attention = tf.multiply(feature_map_with_channel_attention, spatial_attention)
#print(feature_map_with_attention)
#with tf.Session() as sess:
# init = tf.global_variables_initializer()
# sess.run(init)
# result = sess.run(feature_map_with_attention)
return feature_map_with_attention
3. 部署attention-vgg-master虚拟环境环境
这个我就不用多说了吧,相对来说这个是比较基础的,如若小白的话我建议在本机上安装一个conda的python包管理器,即方便也快捷。小编在部署环境的过程遇到过很多意外的错误,请使用的时候一个个在网上搜索对应的错误即可,都有解决方案。
4.attention加入vgg19
也终于到了怎么今天最关键的时刻,
#1.进入项目
cd tensorflow-vgg-master
#2. 编辑vgg19.py
vi vgg19.py
#3.ctrl+f找到self.pool5 = self.max_pool(self.conv5_4, 'pool5')
#4.将你的attention文件引入
#5.attention_feature = convolutional_block_attention_module(self.pool5,index=0)
#6.将self.fc6 = self.fc_layer(attention_feature, "fc6") 替代 self.fc6 = self.fc_layer(self.pool5, "fc6")
#7.保存并关闭文件即可
'''
解释:我们找到第五次最大池化层 尾部进行加入attention机制
建议:如若加入atttention等于网络文件已修改,必须模型重新训练
'''
该技术总结了目前比较流行的深度学习方法,可用的技术方向:
1.图像分类
2.以图收图
3.相似图像检索
再次感谢各位大佬的指点。