Re3中搭建网络的细节——tensorflow_util

tensorflow_util目录下

构建网络的具体函数分析

0. 预处理

0.1 get_cropped_input( )

参数: get_cropped_input(inputImage, bbox, padScale, outputSize),根据论文CROP_PAD = 2,CROP_SIZE = 227.

这个函数将box放大两倍形成ROI区域送入卷积网络。

注意边界判断(boxOn是放大两倍后的box坐标,放大两倍之后不能超过原图边界):

1
2
imagePatch = inputImage[max(boxOn[1], 0):min(boxOn[3], imShape[0]),
max(boxOn[0], 0):min(boxOn[2], imShape[1]), :]
1
boundedBox = np.clip(boxOn, 0, imShape[[1,0,1,0]])

设原图片imShape:[352, 624, 3]。则imShape[[1, 0, 1, 0]]就是[624, 352, 624, 352]

np.clip( )保证数值在一定的范围,这里的min就是0,max就是boxOn[624, 352, 624, 352]对应位置的元素。

写成下面也行:

1
doundedBox = [max(boxOn[0], 0), max(boxOn[1], 0), min(boxOn[2], imShape[1]), min(boxOn[3], imShape[0])]

上面的代码其实有点重复了,完全可以用boundedBox来计算imagePatch.

如果计算得到的ROI区域是一条线,那么默认用全0的227×227×3区域作为crop:

1
patch = np.zeros((int(outputSize), int(outputSize), 3))

将ROI区域进行resize(目的是resize到227×227×3),第一步:

1
2
3
patch = cv2.resize(imagePatch, (
max(1, int(np.round(outputSize * boundedBoxWH[0] / boxOnWH[0]))),
max(1, int(np.round(outputSize * boundedBoxWH[1] / boxOnWH[1])))))

因为存在扩大两倍后的ROI区域超出原图边界的情况,所以,这里计算的时候用outputSize × boundedBoxWH / boxOnWHboundedBoxWH、boxOnWH分别表示ROI box的有效边长和理论边长(扩大两倍的边长)。

通过这种方式计算,理论边长超出原图的话,会产生无法补满227的情况(patch大小可能是143×227×3),需要进行填充:

1
2
3
4
5
patchShape = np.array(patch.shape)

pad = np.zeros(4, dtype=int)
pad[:2] = np.maximum(0, -boxOn[:2] * outputSize / boxOnWH)
pad[2:] = outputSize - (pad[:2] + patchShape[[1,0]])

pad表示需要填充的大小,里面四个元素分别表示box两个点的x、y方向,pad全为0表示不需要填充。

用0填充:

1
2
3
4
patch = np.lib.pad(
patch,
((pad[1], pad[3]), (pad[0], pad[2]), (0, 0)),
'constant', constant_values=0)

参考:numpy.pad( ).

例:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
>>> a = [1, 2, 3, 4, 5]
>>> np.lib.pad(a, (2,3), 'constant', constant_values=(4, 6))
array([4, 4, 1, 2, 3, 4, 5, 6, 6, 6])

>>> a = [[1, 2], [3, 4]]
>>> np.lib.pad(a, ((3, 2), (2, 3)), 'minimum')
#先对第一维度进行(3,2)pad,再对第二维进行(2,3)pad
array([[1, 1, 1, 2, 1, 1, 1],
[1, 1, 1, 2, 1, 1, 1],
[1, 1, 1, 2, 1, 1, 1],
[1, 1, 1, 2, 1, 1, 1],
[3, 3, 3, 4, 3, 3, 3],
[1, 1, 1, 2, 1, 1, 1],
[1, 1, 1, 2, 1, 1, 1]])

最后返回的是填充到(227×227×3)的patch和扩大两倍后的理论坐标表示的box–outputBox(坐标中有负值):

1
return patch, outputBox

resize到227的几个例子(黑边是放大两倍超出边界后填充的):

#1. 卷积层

1.1 conv_layer( )

2. LSTM层

tf.nn.dynamic_rnn,有点奇怪,代码里不像官方教程里那样用了tf.nn.rnn_cell.MultiRNNCell(rnn_layers)来进行一次流通,而是用了两次tf.nn.dynamic_rnn( ),是为了更方便的取每一层的输出结果和中间状态?

TODO

  1. 是不是在预处理过程中把crop的提取方式改变一下(直接把有效区域resize到227×227)会更好?

对比:https://github.com/qimingyudaowenti/Image_classficatioin/blob/master/dlnd_image_classification.ipynb


----------over----------


文章标题:Re3中搭建网络的细节——tensorflow_util

文章作者:Ge垚

发布时间:2018年07月17日 - 17:07

最后更新:2018年11月07日 - 23:11

原始链接:http://geyao1995.com/Re3_tf_util_py/

许可协议: 署名-非商业性使用-禁止演绎 4.0 国际 转载请保留原文链接及作者。