Skip to content

Commit 7f1acd4

Browse files
authored
update documents and offset initialisation for the deformable CNN
1 parent 9d3c9a5 commit 7f1acd4

File tree

1 file changed

+33
-15
lines changed

1 file changed

+33
-15
lines changed

tensorlayer/layers.py

Lines changed: 33 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -1852,7 +1852,7 @@ class DeformableConv2dLayer(Layer):
18521852
e.g. if apply a 3*3 kernel, the number of the last dimension should be 18 (2*3*3)
18531853
channel_multiplier : int, The number of channels to expand to.
18541854
filter_size : tuple (height, width) for filter size.
1855-
strides : tuple (height, width) for strides.
1855+
strides : tuple (height, width) for strides. Current implementation fix to (1, 1, 1, 1)
18561856
act : None or activation function.
18571857
shape : list of shape
18581858
shape of the filters, [filter_height, filter_width, in_channels, out_channels].
@@ -1867,35 +1867,49 @@ class DeformableConv2dLayer(Layer):
18671867
name : a string or None
18681868
An optional name to attach to this layer.
18691869
1870+
Examples
1871+
--------
1872+
>>> network = tl.layers.InputLayer(x, name='input_layer')
1873+
>>> offset_1 = tl.layers.Conv2dLayer(layer=network, act =act, shape=[3, 3, 3, 18], strides=[1, 1, 1, 1],padding='SAME', name='offset_layer1')
1874+
>>> network = tl.layers.DeformableConv2dLayer(layer=network, act=act, offset_layer=offset_1, shape=[3, 3, 3, 32], name='deformable_conv_2d_layer1')
1875+
>>> offset_2 = tl.layers.Conv2dLayer(layer=network, act = act, shape=[3, 3, 32, 18], strides=[1, 1, 1, 1], padding='SAME', name='offset_layer2')
1876+
>>> network = tl.layers.DeformableConv2dLayer(layer=network, act = act, offset_layer=offset_2, shape=[3, 3, 32, 64], name='deformable_conv_2d_layer2')
1877+
1878+
References
1879+
-----------
1880+
- The deformation operation was adapted from the implementation in `<https://github.com/felixlaumon/deform-conv>`_
1881+
18701882
Notes
18711883
-----------
18721884
- The stride is fixed as (1, 1, 1, 1)
1873-
- `The padding is fixed as 'same'
1885+
- `The padding is fixed as 'SAME'
18741886
- The current implementation is memory-inefficient, please use carefully
18751887
"""
1888+
18761889
def __init__(
18771890
self,
18781891
layer=None,
1879-
offset_layer=None,
18801892
act=tf.identity,
1881-
shape=[3, 3, 10, 10],
1893+
offset_layer=None,
1894+
shape=[3, 3, 1, 100],
1895+
name='deformable_conv_2d_layer',
18821896
W_init=tf.truncated_normal_initializer(stddev=0.02),
18831897
b_init=tf.constant_initializer(value=0.0),
18841898
W_init_args={},
1885-
b_init_args={},
1886-
name='deformable_conv_2d_layer',
1899+
b_init_args={}
18871900
):
1901+
if tf.__version__ < "1.4":
1902+
raise Exception("Deformable CNN layer requires tensrflow 1.4 or higher version")
1903+
18881904
Layer.__init__(self, name=name)
18891905
self.inputs = layer.outputs
18901906
self.offset_layer = offset_layer
18911907

1892-
if tf.__version__ < "1.4":
1893-
raise Exception("Deformable CNN layer requires tensrflow 1.4 or higher version")
1894-
18951908
print(" [TL] DeformableConv2dLayer %s: shape:%s, act:%s" %
18961909
(self.name, str(shape), act.__name__))
18971910

18981911
with tf.variable_scope(name) as vs:
1912+
18991913
offset = self.offset_layer.outputs
19001914
assert offset.get_shape()[-1] == 2 * shape[0] * shape[1]
19011915

@@ -1912,18 +1926,19 @@ def __init__(
19121926
initial_offsets = tf.tile(initial_offsets, [input_h, input_w, 1, 1]) # initial_offsets --> (h, w, n, 2)
19131927
initial_offsets = tf.cast(initial_offsets, 'float32')
19141928
grid = tf.meshgrid(
1915-
tf.range(input_h), tf.range(input_w), indexing='ij'
1916-
)
1929+
tf.range(- int((shape[0] - 1)/2.0), int(input_h - int((shape[0] - 1)/2.0)), 1),
1930+
tf.range(- int((shape[1] - 1)/2.0), int(input_w - int((shape[1] - 1)/2.0)), 1), indexing='ij')
1931+
19171932
grid = tf.stack(grid, axis=-1)
19181933
grid = tf.cast(grid, 'float32') # grid --> (h, w, 2)
19191934
grid = tf.expand_dims(grid, 2) # grid --> (h, w, 1, 2)
19201935
grid = tf.tile(grid, [1, 1, kernel_n, 1]) # grid --> (h, w, n, 2)
19211936
grid_offset = grid + initial_offsets # grid_offset --> (h, w, n, 2)
19221937

1923-
input_deform = tf_batch_map_offsets(self.inputs, offset, grid_offset)
1938+
input_deform = efficient_tf_batch_map_offsets(self.inputs, offset, grid_offset)
19241939

19251940
W = tf.get_variable(name='W_conv2d', shape=[1, 1, shape[0] * shape[1], shape[-2], shape[-1]],
1926-
initializer=W_init, **W_init_args)
1941+
initializer=W_init, **W_init_args)
19271942
b = tf.get_variable(name='b_conv2d', shape=(shape[-1]), initializer=b_init, **b_init_args)
19281943

19291944
self.outputs = tf.reshape(act(
@@ -1936,8 +1951,11 @@ def __init__(
19361951
self.all_drop = dict(layer.all_drop)
19371952

19381953
## offset_layer
1939-
self.all_layers.extend(offset_layer.all_layers)
1940-
self.all_params.extend(offset_layer.all_params)
1954+
offset_params = [osparam for osparam in offset_layer.all_params if osparam not in layer.all_params]
1955+
offset_layers = [oslayer for oslayer in offset_layer.all_layers if oslayer not in layer.all_layers]
1956+
1957+
self.all_params.extend(offset_params)
1958+
self.all_layers.extend(offset_layers)
19411959
self.all_drop.update(offset_layer.all_drop)
19421960

19431961
## this layer

0 commit comments

Comments
 (0)