@@ -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