end_points用来记录每一层的特征图,各层的特征图大小是不一样的
end_points[end_point] = net
特征层数记录
for i, layer in enumerate(feat_layers):
i表示第几个特征层,layer表示特征层的名字
把各层的特征图数据取出来end_points[layer]
把所有目标类别取出来num_classes
anchor的尺寸列表,有6个尺寸(莫非一个特征图上只用一个尺寸的anchor?)
anchor_sizes=[(21.,45.),(45., 99.), (99., 153.), (153., 207.), (207., 261.), (261., 315.)],
一个anchor尺寸上的不同比例列表anchor_ratios,不同层的比例个数不一样。
anchor_ratios=[[2,.5], [2, .5, 3, 1./3], [2, .5, 3, 1./3], [2, .5, 3, 1./3], [2, .5], [2, .5]],
各层上像素的放缩到的值,总共6层,
anchor_steps=[8,16, 32, 64, 100, 300]
取anchor 回归时需要用的调整数anchor_offset
normalizations是什么鬼还不清楚
normalizations=[20, -1, -1, -1, -1, -1],
一层特征图上的多框预测:(也就是在一层图上想要返回一个预测结果和位置的时候需要准备什么,准备好怎么处理)
需要准备的东西:这一层的特征图,这层图上框的尺寸,这个尺寸对应的几个比例,和一个不知道是什么鬼的normalization.
p, l = ssd_multibox_layer(end_points[layer],
num_classes,
anchor_sizes[i],
anchor_ratios[i],
normalizations[i])
准备好后怎么处理:
第一步:先看normalization是不是大于0,大于0的就把这一层的特征数据给正则化一下,不大于0的就不正则化了。(看normalizations的所有值,发现应该是只有在第一个特征图的那一层做了正则化,后面几个都没有做。)
if normalization > 0:
net =custom_layers.l2_normalization(net, scaling=True)
第二步:算一下这一特征图上的anchor个数,因为在传的时候anchor_size只传进来一个尺寸,所以这里的len(sizes)应该等于1,而传进来的anchor对应的不同比例len(rations)就是自定义的其他的几个比例个数,所以anchor个数就是等于1+其他定义好的比例个数。代码里这样写的:
num_anchors= len(sizes) + len(ratios)
第三步:框有了后进行确定框所在的位置,如何确定呢?利用和真实标记的anchor做回归来确定。
因为有多个anchor,而每个anchor要回归出4个值来确定位置。所以总共需要回归出值的个数有num_anchors*4个。
回归的过程:需要准备的东西有,这层特征图的值,要回归出的值的个数,再来一个3*3的卷积核,准备完回归用的东西后,通过卷积操作来完成回归。卷积操作后输入出的东西应该是一个通道个数为回归值个数的特征图。代码如下:
loc_pred= slim.conv2d(net, num_loc_pred, [3, 3], activation_fn=None,
scope='conv_loc')
(代码中还给了一个这样的操作,把通道数放到最后,但由于tensorflow默认的就是通道数在最后放的,所以这个代码感觉有点多余loc_pred = custom_layers.channel_to_last(loc_pred))
回归结束后,把得到的特征图进行了重新塑形reshape,(塑形后的数据是一个列表,列表的长度为anchor的个数,列表里的具体每一项又是一个列表,这个列表是一个4个长度的list,即这4个值是一个anchor的四个位置信息)
、、、-------------------------------------------------精华代码啊-------------------------------
deftensor_shape(x, rank=3):
"""Returns the dimensions ofa tensor.
Args:
image: A N-D Tensor of shape.
Returns:
A list of dimensions. Dimensions that arestatically known are python
integers,otherwise they are integerscalar tensors.
"""
if x.get_shape().is_fully_defined():
return x.get_shape().as_list()
else:
static_shape =x.get_shape().with_rank(rank).as_list()
dynamic_shape = tf.unstack(tf.shape(x),rank)
return [s if s is not None else d
for s, d in zip(static_shape,dynamic_shape)]
‘’‘’‘’---------------------------------------------------------------------------------