Caffe2 - Python API
A deep learning, cross platform ML framework
conv.py
1 
3 from __future__ import absolute_import
4 from __future__ import division
5 from __future__ import print_function
6 from __future__ import unicode_literals
7 
8 from caffe2.python import core
9 
10 
11 def _ConvBase(model, is_nd, blob_in, blob_out, dim_in, dim_out, kernel,
12  weight_init=None, bias_init=None, group=1, transform_inputs=None,
13  use_cudnn=False, order="NCHW", cudnn_exhaustive_search=False,
14  ws_nbytes_limit=None, **kwargs):
15  kernels = []
16  if is_nd:
17  if not isinstance(kernel, list):
18  kernels = [kernel]
19  else:
20  kernels = kernel
21  else:
22  kernels = [kernel] * 2
23 
24  if use_cudnn:
25  kwargs['engine'] = 'CUDNN'
26  kwargs['exhaustive_search'] = cudnn_exhaustive_search
27  if ws_nbytes_limit:
28  kwargs['ws_nbytes_limit'] = ws_nbytes_limit
29 
30  use_bias =\
31  False if ("no_bias" in kwargs and kwargs["no_bias"]) else True
32  weight_init = weight_init if weight_init else ('XavierFill', {})
33  bias_init = bias_init if bias_init else ('ConstantFill', {})
34  blob_out = blob_out or model.net.NextName()
35  weight_shape = [dim_out]
36  if order == "NCHW":
37  weight_shape.append(int(dim_in / group))
38  weight_shape.extend(kernels)
39  else:
40  weight_shape.extend(kernels)
41  weight_shape.append(int(dim_in / group))
42 
43  if model.init_params:
44  weight = model.param_init_net.__getattr__(weight_init[0])(
45  [],
46  blob_out + '_w',
47  shape=weight_shape,
48  **weight_init[1]
49  )
50  if use_bias:
51  bias = model.param_init_net.__getattr__(bias_init[0])(
52  [],
53  blob_out + '_b',
54  shape=[dim_out, ],
55  **bias_init[1]
56  )
57  else:
58  weight = core.ScopedBlobReference(
59  blob_out + '_w', model.param_init_net)
60  if use_bias:
62  blob_out + '_b', model.param_init_net)
63  if use_bias:
64  model.params.extend([weight, bias])
65  else:
66  model.params.extend([weight])
67 
68  model.weights.append(weight)
69 
70  if use_bias:
71  model.biases.append(bias)
72 
73  if use_bias:
74  inputs = [blob_in, weight, bias]
75  else:
76  inputs = [blob_in, weight]
77 
78  if transform_inputs is not None:
79  transform_inputs(model, blob_out, inputs)
80 
81  # For the operator, we no longer need to provide the no_bias field
82  # because it can automatically figure this out from the number of
83  # inputs.
84  if 'no_bias' in kwargs:
85  del kwargs['no_bias']
86  if group != 1:
87  kwargs['group'] = group
88  if is_nd:
89  return model.net.Conv(
90  inputs,
91  blob_out,
92  kernels=kernels,
93  order=order,
94  **kwargs)
95  else:
96  return model.net.Conv(
97  inputs,
98  blob_out,
99  kernel=kernel,
100  order=order,
101  **kwargs)
102 
103 
104 def ConvNd(model, blob_in, blob_out, dim_in, dim_out, kernel,
105  weight_init=None, bias_init=None, group=1, transform_inputs=None,
106  order="NCHW", **kwargs):
107  """N-dimensional convolution for inputs with NCHW storage order.
108  """
109  assert order == "NCHW", "ConvNd only supported for NCHW storage."
110  return _ConvBase(model, True, blob_in, blob_out, dim_in, dim_out, kernel,
111  weight_init, bias_init, group, transform_inputs,
112  order=order, **kwargs)
113 
114 
115 def Conv(model, blob_in, blob_out, dim_in, dim_out, kernel, weight_init=None,
116  bias_init=None, group=1, transform_inputs=None, **kwargs):
117  """2-dimensional convolution.
118  """
119  return _ConvBase(model, False, blob_in, blob_out, dim_in, dim_out, kernel,
120  weight_init, bias_init, group, transform_inputs, **kwargs)
121 
122 
123 def ConvTranspose(
124  model, blob_in, blob_out, dim_in, dim_out, kernel, weight_init=None,
125  bias_init=None, use_cudnn=False, order="NCHW",
126  cudnn_exhaustive_search=False, ws_nbytes_limit=None, **kwargs
127 ):
128  """ConvTranspose.
129  """
130  weight_init = weight_init if weight_init else ('XavierFill', {})
131  bias_init = bias_init if bias_init else ('ConstantFill', {})
132  blob_out = blob_out or model.net.NextName()
133  weight_shape = (
134  [dim_in, dim_out, kernel, kernel]
135  if order == "NCHW" else [dim_in, kernel, kernel, dim_out]
136  )
137  if model.init_params:
138  weight = model.param_init_net.__getattr__(weight_init[0])(
139  [],
140  blob_out + '_w',
141  shape=weight_shape,
142  **weight_init[1]
143  )
144  bias = model.param_init_net.__getattr__(bias_init[0])(
145  [],
146  blob_out + '_b',
147  shape=[dim_out, ],
148  **bias_init[1]
149  )
150  else:
151  weight = core.ScopedBlobReference(
152  blob_out + '_w', model.param_init_net)
154  blob_out + '_b', model.param_init_net)
155  model.params.extend([weight, bias])
156  model.weights.append(weight)
157  model.biases.append(bias)
158  if use_cudnn:
159  kwargs['engine'] = 'CUDNN'
160  kwargs['exhaustive_search'] = cudnn_exhaustive_search
161  if ws_nbytes_limit:
162  kwargs['ws_nbytes_limit'] = ws_nbytes_limit
163  return model.net.ConvTranspose(
164  [blob_in, weight, bias],
165  blob_out,
166  kernel=kernel,
167  order=order,
168  **kwargs
169  )
170 
171 
172 def GroupConv(
173  model,
174  blob_in,
175  blob_out,
176  dim_in,
177  dim_out,
178  kernel,
179  weight_init=None,
180  bias_init=None,
181  group=1,
182  **kwargs
183 ):
184  """Group Convolution.
185 
186  This is essentially the same as Conv with a group argument passed in.
187  We specialize this for backward interface compatibility.
188  """
189  return Conv(blob_in, blob_out, dim_in, dim_out, kernel,
190  weight_init=weight_init, bias_init=bias_init,
191  group=group, **kwargs)
192 
193 
194 def GroupConv_Deprecated(model,
195  blob_in,
196  blob_out,
197  dim_in,
198  dim_out,
199  kernel,
200  weight_init=None,
201  bias_init=None,
202  group=1,
203  use_cudnn=False,
204  order="NCHW",
205  cudnn_exhaustive_search=False,
206  ws_nbytes_limit=None,
207  **kwargs):
208  """GroupConvolution's deprecated interface.
209 
210  This is used to simulate a group convolution via split and concat. You
211  should always use the new group convolution in your new code.
212  """
213  weight_init = weight_init if weight_init else ('XavierFill', {})
214  bias_init = bias_init if bias_init else ('ConstantFill', {})
215  use_bias = False if ("no_bias" in kwargs and kwargs["no_bias"]) else True
216  if use_cudnn:
217  kwargs['engine'] = 'CUDNN'
218  kwargs['exhaustive_search'] = cudnn_exhaustive_search
219  if ws_nbytes_limit:
220  kwargs['ws_nbytes_limit'] = ws_nbytes_limit
221  if dim_in % group:
222  raise ValueError("dim_in should be divisible by group.")
223  if dim_out % group:
224  raise ValueError("dim_out should be divisible by group.")
225  splitted_blobs = model.net.DepthSplit(
226  blob_in,
227  ['_' + blob_out + '_gconv_split_' + str(i) for i in range(group)],
228  dimensions=[int(dim_in / group) for i in range(group)],
229  order=order
230  )
231  weight_shape = (
232  [dim_out / group, dim_in / group, kernel, kernel]
233  if order == "NCHW" else
234  [dim_out / group, kernel, kernel, dim_in / group]
235  )
236  # Make sure that the shapes are of int format. Especially for py3 where
237  # int division gives float output.
238  weight_shape = [int(v) for v in weight_shape]
239  conv_blobs = []
240  for i in range(group):
241  if model.init_params:
242  weight = model.param_init_net.__getattr__(weight_init[0])(
243  [],
244  blob_out + '_gconv_%d_w' % i,
245  shape=weight_shape,
246  **weight_init[1]
247  )
248  if use_bias:
249  bias = model.param_init_net.__getattr__(bias_init[0])(
250  [],
251  blob_out + '_gconv_%d_b' % i,
252  shape=[int(dim_out / group)],
253  **bias_init[1]
254  )
255  else:
256  weight = core.ScopedBlobReference(
257  blob_out + '_gconv_%d_w' % i, model.param_init_net)
258  if use_bias:
260  blob_out + '_gconv_%d_b' % i, model.param_init_net)
261  if use_bias:
262  model.params.extend([weight, bias])
263  else:
264  model.params.extend([weight])
265  model.weights.append(weight)
266  if use_bias:
267  model.biases.append(bias)
268  if use_bias:
269  inputs = [weight, bias]
270  else:
271  inputs = [weight]
272  if 'no_bias' in kwargs:
273  del kwargs['no_bias']
274  conv_blobs.append(
275  splitted_blobs[i].Conv(
276  inputs,
277  blob_out + '_gconv_%d' % i,
278  kernel=kernel,
279  order=order,
280  **kwargs
281  )
282  )
283  concat, concat_dims = model.net.Concat(
284  conv_blobs,
285  [blob_out,
286  "_" + blob_out + "_concat_dims"],
287  order=order
288  )
289  return concat
def ConvTranspose(model, blob_in, blob_out, dim_in, dim_out, kernel, weight_init=None, bias_init=None, use_cudnn=False, order="NCHW", cudnn_exhaustive_search=False, ws_nbytes_limit=None, kwargs)
Definition: conv.py:127
def ConvNd(model, blob_in, blob_out, dim_in, dim_out, kernel, weight_init=None, bias_init=None, group=1, transform_inputs=None, order="NCHW", kwargs)
Definition: conv.py:106
def ScopedBlobReference(name, args, kwargs)
Definition: core.py:212
def GroupConv_Deprecated(model, blob_in, blob_out, dim_in, dim_out, kernel, weight_init=None, bias_init=None, group=1, use_cudnn=False, order="NCHW", cudnn_exhaustive_search=False, ws_nbytes_limit=None, kwargs)
Definition: conv.py:207
def Conv(model, blob_in, blob_out, dim_in, dim_out, kernel, weight_init=None, bias_init=None, group=1, transform_inputs=None, kwargs)
Definition: conv.py:116
def GroupConv(model, blob_in, blob_out, dim_in, dim_out, kernel, weight_init=None, bias_init=None, group=1, kwargs)
Definition: conv.py:183