Skip to content

Commit b7ee6fb

Browse files
zotanikaIvy
authored andcommitted
[Caffe Frontend] supporting group > 1 cases for Deconv op (apache#8260)
* [Caffe Frontend] supporting group > 1 cases for Deconv op - Handling group > 1 cases, assuming group == output channels - Simply decomposed into Relay split, conv2d_transposed, and multi-leveled concatenate ops - Added some test cases Signed-off-by: zotanika <[email protected]> * [Caffe Frontend] amending a test case for Deconv op Signed-off-by: zotanika <[email protected]> * explicit importing tvm.testing * changing split axis to 0, according to PR apache#9336
1 parent 4748276 commit b7ee6fb

File tree

2 files changed

+89
-4
lines changed

2 files changed

+89
-4
lines changed

python/tvm/relay/frontend/caffe.py

Lines changed: 59 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -515,21 +515,76 @@ def convert_deconv(self, op):
515515
if weight:
516516
kh, kw = params["kernel_size"]
517517
weight_shape = [-1, conv_params.num_output, kh, kw]
518-
weight_value = np.asarray(weight.data, np.float32)
518+
if not weight.data:
519+
if conv_params.weight_filler:
520+
_filler = conv_params.weight_filler.value
521+
weight_value = np.full(weight.shape.dim, _filler, np.float32)
522+
else:
523+
raise tvm.error.OpAttributeInvalid("At least weight_filler must be given")
524+
else:
525+
weight_value = np.asarray(weight.data, np.float32)
519526
weight_value = np.reshape(weight_value, weight_shape)
520527

521528
# weight shape is in relay's IOHW format rn, we need it to be OIHW
522529
weight_value = np.transpose(weight_value, [1, 0, 2, 3])
523530
else:
524-
raise Exception("No weight value of layer {} in caffemodel".format(op.name))
531+
raise tvm.error.OpAttributeRequired(
532+
"No weight value of layer {} in caffemodel".format(op.name)
533+
)
525534

526535
weight_expr = self.exp_tab.new_const(weight_value, dtype="float32")
527536
in_expr = self.exp_tab.get_expr(inputs[0])
528-
out = _op.nn.conv2d_transpose(data=in_expr, weight=weight_expr, **params)
537+
538+
groups = params["groups"]
539+
channels = params["channels"]
540+
529541
if bias:
530542
bias_value = np.asarray(bias.data, np.float32)
531543
bias_expr = self.exp_tab.new_const(bias_value, dtype="float32")
532-
out = _op.nn.bias_add(out, bias_expr)
544+
545+
if groups > channels:
546+
raise tvm.error.OpAttributeInvalid(
547+
"Groups cannot be larger than the number of input channels"
548+
)
549+
550+
if groups == channels:
551+
inputs_expr = _op.split(in_expr, groups, axis=1)
552+
# changing split axis to 0, according to PR #9336
553+
weights_expr = _op.split(weight_expr, groups, axis=0)
554+
# Preventing to create Concat layer with too many tensors(> 16)
555+
q = groups >> 4
556+
r = groups % 16
557+
558+
params["groups"] = 1
559+
params["channels"] = 1
560+
out = []
561+
for lc in range(q):
562+
_outputs = []
563+
_inputs = [inputs_expr[i] for i in range(lc << 4, (lc << 4) + 16)]
564+
_weights = [weights_expr[i] for i in range(lc << 4, (lc << 4) + 16)]
565+
for (i, w) in zip(_inputs, _weights):
566+
_out = _op.nn.conv2d_transpose(data=i, weight=w, **params)
567+
if bias:
568+
_out = _op.nn.bias_add(_out, bias_expr)
569+
_outputs.append(_out)
570+
out.append(_op.concatenate(_outputs, axis=1))
571+
if r != 0:
572+
_outputs = []
573+
_inputs = [inputs_expr[i] for i in range(groups - r, groups)]
574+
_weights = [weights_expr[i] for i in range(groups - r, groups)]
575+
for (i, w) in zip(_inputs, _weights):
576+
_out = _op.nn.conv2d_transpose(data=i, weight=w, **params)
577+
if bias:
578+
_out = _op.nn.bias_add(_out, bias_expr)
579+
_outputs.append(_out)
580+
out.append(_op.concatenate(_outputs, axis=1))
581+
out = _op.concatenate(out, axis=1)
582+
elif groups == 1:
583+
out = _op.nn.conv2d_transpose(data=in_expr, weight=weight_expr, **params)
584+
if bias:
585+
out = _op.nn.bias_add(out, bias_expr)
586+
else:
587+
raise tvm.error.OpAttributeInvalid("Unable to handle.")
533588
return out
534589

535590
def convert_slice(self, op):

tests/python/frontend/caffe/test_forward.py

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,7 @@
3535
from caffe.proto import caffe_pb2 as pb
3636

3737
import tvm
38+
import tvm.testing
3839
from tvm import relay
3940
from tvm.contrib import utils, graph_executor
4041
from tvm.contrib.download import download_testdata
@@ -451,6 +452,35 @@ def test_forward_Deconvolution():
451452
bias_filler=dict(type="xavier"),
452453
),
453454
)
455+
_test_deconvolution(
456+
data,
457+
convolution_param=dict(
458+
num_output=16,
459+
bias_term=False,
460+
pad=0,
461+
kernel_size=2,
462+
stride=2,
463+
dilation=1,
464+
group=16,
465+
weight_filler=dict(type="xavier"),
466+
bias_filler=dict(type="xavier"),
467+
),
468+
)
469+
data = np.random.rand(1, 100, 32, 32).astype(np.float32)
470+
_test_deconvolution(
471+
data,
472+
convolution_param=dict(
473+
num_output=100,
474+
bias_term=False,
475+
pad=0,
476+
kernel_size=2,
477+
stride=2,
478+
dilation=1,
479+
group=100,
480+
weight_filler=dict(type="xavier"),
481+
bias_filler=dict(type="xavier"),
482+
),
483+
)
454484

455485

456486
#######################################################################

0 commit comments

Comments
 (0)