Skip to content

Commit 07c1ea2

Browse files
author
wangyang59
committed
python interface for convTransProjection and convTransOperator
1 parent 6b7f647 commit 07c1ea2

File tree

7 files changed

+145
-32
lines changed

7 files changed

+145
-32
lines changed

paddle/gserver/layers/ConvBaseOperator.h

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ distributed under the License is distributed on an "AS IS" BASIS,
1111
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
1212
See the License for the specific language governing permissions and
1313
limitations under the License. */
14+
#pragma once
1415

1516
#include "Operator.h"
1617
#include "paddle/math/MathUtils.h"
@@ -44,10 +45,8 @@ class ConvBaseOperator : public Operator {
4445
hl_destroy_filter_descriptor(filterDesc_);
4546
hl_destroy_convolution_descriptor(convDesc_);
4647
}
47-
virtual void forward();
48-
virtual void backward();
4948

50-
private:
49+
protected:
5150
/**
5251
* Get convolution parameters from layer config and
5352
* initialize member variables.

paddle/gserver/layers/ConvOperator.h

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ distributed under the License is distributed on an "AS IS" BASIS,
1111
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
1212
See the License for the specific language governing permissions and
1313
limitations under the License. */
14+
#pragma once
1415

1516
#include "ConvBaseOperator.h"
1617
#include "paddle/math/MathUtils.h"
@@ -35,8 +36,8 @@ class ConvOperator : public ConvBaseOperator {
3536
* Free workspace in device and destroy cudnn tensor descriptor.
3637
*/
3738
virtual ~ConvOperator() {}
38-
virtual void forward();
39-
virtual void backward();
39+
void forward() override;
40+
void backward() override;
4041
};
4142

4243
} // namespace paddle

paddle/gserver/layers/ConvTransOperator.h

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ distributed under the License is distributed on an "AS IS" BASIS,
1111
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
1212
See the License for the specific language governing permissions and
1313
limitations under the License. */
14+
#pragma once
1415

1516
#include "ConvBaseOperator.h"
1617
#include "paddle/math/MathUtils.h"
@@ -35,8 +36,8 @@ class ConvTransOperator : public ConvBaseOperator {
3536
* Free workspace in device and destroy cudnn tensor descriptor.
3637
*/
3738
virtual ~ConvTransOperator() {}
38-
virtual void forward();
39-
virtual void backward();
39+
void forward() override;
40+
void backward() override;
4041
};
4142

4243
} // namespace paddle

paddle/gserver/tests/test_LayerGrad.cpp

Lines changed: 27 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1503,16 +1503,20 @@ TEST(Layer, BatchNormalizationLayer) {
15031503
#endif
15041504
}
15051505

1506-
TEST(Operator, conv) {
1506+
void testConvOperator(bool isDeconv) {
15071507
TestConfig config;
15081508
const int NUM_FILTERS = 16;
15091509
const int FILTER_SIZE = 2;
15101510
const int FILTER_SIZE_Y = 3;
15111511
const int CHANNELS = 3;
15121512
const int IMAGE_SIZE = 16;
1513-
const int IMAGE_SIZE_Y = 8;
1513+
const int IMAGE_SIZE_Y = 9;
15141514
OperatorConfig& operatorConf = *config.layerConfig.add_operator_confs();
1515-
operatorConf.set_type("conv");
1515+
if (isDeconv) {
1516+
operatorConf.set_type("convt");
1517+
} else {
1518+
operatorConf.set_type("conv");
1519+
}
15161520
ConvConfig* conv = operatorConf.mutable_conv_conf();
15171521
operatorConf.set_num_filters(NUM_FILTERS);
15181522
conv->set_filter_size(FILTER_SIZE);
@@ -1523,7 +1527,6 @@ TEST(Operator, conv) {
15231527
conv->set_stride(2);
15241528
conv->set_stride_y(2);
15251529
conv->set_groups(1);
1526-
conv->set_filter_channels(conv->channels() / conv->groups());
15271530
conv->set_img_size(IMAGE_SIZE);
15281531
conv->set_img_size_y(IMAGE_SIZE_Y);
15291532
conv->set_output_x(outputSize(conv->img_size(),
@@ -1536,11 +1539,22 @@ TEST(Operator, conv) {
15361539
conv->padding_y(),
15371540
conv->stride_y(),
15381541
/* caffeMode */ true));
1539-
config.layerConfig.set_size(conv->output_x() * conv->output_y() *
1540-
NUM_FILTERS);
15411542

1542-
config.inputDefs.push_back(
1543-
{INPUT_DATA, "layer_0", IMAGE_SIZE * IMAGE_SIZE_Y * CHANNELS, 0});
1543+
if (isDeconv) {
1544+
conv->set_filter_channels(NUM_FILTERS / conv->groups());
1545+
config.inputDefs.push_back({INPUT_DATA,
1546+
"layer_0",
1547+
conv->output_x() * conv->output_y() * CHANNELS,
1548+
0});
1549+
config.layerConfig.set_size(IMAGE_SIZE * IMAGE_SIZE_Y * NUM_FILTERS);
1550+
} else {
1551+
conv->set_filter_channels(conv->channels() / conv->groups());
1552+
config.inputDefs.push_back(
1553+
{INPUT_DATA, "layer_0", IMAGE_SIZE * IMAGE_SIZE_Y * CHANNELS, 0});
1554+
config.layerConfig.set_size(conv->output_x() * conv->output_y() *
1555+
NUM_FILTERS);
1556+
}
1557+
15441558
config.inputDefs.push_back(
15451559
{INPUT_DATA,
15461560
"layer_1",
@@ -1552,6 +1566,11 @@ TEST(Operator, conv) {
15521566
testOperatorGrad(config, operatorConf, 100, /*useGpu*/ true, false);
15531567
}
15541568

1569+
TEST(Operator, conv) {
1570+
testConvOperator(/*isDeconv*/ true);
1571+
testConvOperator(/*isDeconv*/ false);
1572+
}
1573+
15551574
TEST(Layer, FeatureMapExpandLayer) {
15561575
TestConfig config;
15571576
config.layerConfig.set_type("featmap_expand");

python/paddle/trainer/config_parser.py

Lines changed: 72 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -686,25 +686,17 @@ def calc_parameter_dims(self, input_size, output_size):
686686

687687

688688
@config_class
689-
class ConvProjection(Projection):
690-
type = 'conv'
691-
689+
class ConvBaseProjection(Projection):
692690
def __init__(self,
693691
input_layer_name,
694692
num_filters=None,
695693
conv_conf=None,
696694
**xargs):
697-
super(ConvProjection, self).__init__(input_layer_name, **xargs)
695+
super(ConvBaseProjection, self).__init__(input_layer_name, **xargs)
698696

699697
if num_filters is not None:
700698
self.proj_conf.num_filters = num_filters
701699

702-
parse_conv(conv_conf, input_layer_name, self.proj_conf.conv_conf,
703-
num_filters)
704-
self.proj_conf.output_size = self.proj_conf.conv_conf.output_x * \
705-
self.proj_conf.conv_conf.output_y * \
706-
num_filters
707-
708700
def calc_output_size(self, input_layer_config):
709701
return self.proj_conf.output_size
710702

@@ -723,6 +715,46 @@ def calc_parameter_dims(self, input_size, output_size):
723715
return None
724716

725717

718+
@config_class
719+
class ConvProjection(ConvBaseProjection):
720+
type = 'conv'
721+
722+
def __init__(self,
723+
input_layer_name,
724+
num_filters=None,
725+
conv_conf=None,
726+
**xargs):
727+
super(ConvProjection, self).__init__(input_layer_name, **xargs)
728+
729+
parse_conv(conv_conf, input_layer_name, self.proj_conf.conv_conf,
730+
num_filters)
731+
self.proj_conf.output_size = self.proj_conf.conv_conf.output_x * \
732+
self.proj_conf.conv_conf.output_y * \
733+
num_filters
734+
735+
736+
@config_class
737+
class ConvTransProjection(ConvBaseProjection):
738+
type = 'convt'
739+
740+
def __init__(self,
741+
input_layer_name,
742+
num_filters=None,
743+
conv_conf=None,
744+
**xargs):
745+
super(ConvTransProjection, self).__init__(input_layer_name, **xargs)
746+
747+
parse_conv(
748+
conv_conf,
749+
input_layer_name,
750+
self.proj_conf.conv_conf,
751+
num_filters,
752+
trans=True)
753+
self.proj_conf.output_size = self.proj_conf.conv_conf.img_size_y * \
754+
self.proj_conf.conv_conf.img_size * \
755+
num_filters
756+
757+
726758
# Define a operator for mixed layer
727759
@config_class
728760
class Operator(Cfg):
@@ -789,6 +821,36 @@ def calc_output_size(self, input_sizes):
789821
return self.operator_conf.output_size
790822

791823

824+
@config_class
825+
class ConvTransOperator(Operator):
826+
type = 'convt'
827+
828+
def __init__(self,
829+
input_layer_names,
830+
num_filters=None,
831+
conv_conf=None,
832+
**xargs):
833+
super(ConvTransOperator, self).__init__(input_layer_names, **xargs)
834+
if num_filters is not None:
835+
self.operator_conf.num_filters = num_filters
836+
837+
parse_conv(
838+
conv_conf,
839+
MakeLayerNameInSubmodel(input_layer_names[0]),
840+
self.operator_conf.conv_conf,
841+
num_filters,
842+
trans=True)
843+
self.operator_conf.output_size = \
844+
self.operator_conf.conv_conf.img_size * \
845+
self.operator_conf.conv_conf.img_size_y * \
846+
num_filters
847+
848+
config_assert(len(input_layer_names) == 2, "Conv is binary operator")
849+
850+
def calc_output_size(self, input_sizes):
851+
return self.operator_conf.output_size
852+
853+
792854
# please refer to the comments in proto/ModelConfig.proto
793855
@config_class
794856
class Conv(Cfg):

python/paddle/trainer_config_helpers/layers.py

Lines changed: 17 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -712,8 +712,10 @@ def __enter__(self):
712712
assert len(self.inputs) == 0
713713
return self
714714

715-
def __exit__(self, *args, **kwargs):
716-
del args, kwargs # unused parameter to suppress warning
715+
def __exit__(self, exc_type, exc_value, tb):
716+
if exc_type != None:
717+
traceback.print_exception(exc_type, exc_value, tb)
718+
sys.exit(1)
717719
assert len(self.inputs) != 0
718720
ml = MixedLayer(
719721
name=self.name,
@@ -3715,7 +3717,8 @@ def conv_operator(img,
37153717
padding=0,
37163718
filter_size_y=None,
37173719
stride_y=None,
3718-
padding_y=None):
3720+
padding_y=None,
3721+
trans=False):
37193722
"""
37203723
Different from img_conv_layer, conv_op is an Operator, which can be used
37213724
in mixed_layer. And conv_op takes two inputs to perform convolution.
@@ -3771,7 +3774,9 @@ def conv_operator(img,
37713774
if filter.size is not None:
37723775
filter.size = filter_size * filter_size_y * num_filters * num_channels
37733776

3774-
op = ConvOperator(
3777+
opCls = ConvTransOperator if trans else ConvOperator
3778+
3779+
op = opCls(
37753780
input_layer_names=[img.name, filter.name],
37763781
num_filters=num_filters,
37773782
conv_conf=Conv(
@@ -3783,6 +3788,7 @@ def conv_operator(img,
37833788
padding_y=padding_y,
37843789
stride_y=stride_y,
37853790
groups=1))
3791+
37863792
op.origin = [img, filter]
37873793
return op
37883794

@@ -3798,7 +3804,8 @@ def conv_projection(input,
37983804
stride_y=None,
37993805
padding_y=None,
38003806
groups=1,
3801-
param_attr=None):
3807+
param_attr=None,
3808+
trans=False):
38023809
"""
38033810
Different from img_conv_layer and conv_op, conv_projection is an Projection,
38043811
which can be used in mixed_layer and conat_layer. It use cudnn to implement
@@ -3837,6 +3844,8 @@ def conv_projection(input,
38373844
:type groups: int
38383845
:param param_attr: Convolution param attribute. None means default attribute
38393846
:type param_attr: ParameterAttribute
3847+
:param trans: whether it is convTrans or conv
3848+
:type trans: boolean
38403849
:return: A DotMulProjection Object.
38413850
:rtype: DotMulProjection
38423851
"""
@@ -3873,7 +3882,9 @@ def conv_projection(input,
38733882
param_attr.attr["initial_strategy"] = 0
38743883
param_attr.attr["initial_smart"] = False
38753884

3876-
proj = ConvProjection(
3885+
projCls = ConvTransProjection if trans else ConvProjection
3886+
3887+
proj = projCls(
38773888
input_layer_name=input.name,
38783889
num_filters=num_filters,
38793890
conv_conf=Conv(

python/paddle/trainer_config_helpers/tests/configs/projections.py

Lines changed: 21 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -34,11 +34,31 @@
3434
with mixed_layer() as m7:
3535
m7 += conv_operator(
3636
img=img, filter=flt, num_filters=64, num_channels=1, filter_size=3)
37+
m7 += conv_projection(img, filter_size=3, num_filters=64, num_channels=1)
3738

39+
with mixed_layer() as m8:
40+
m8 += conv_operator(
41+
img=img,
42+
filter=flt,
43+
num_filters=64,
44+
num_channels=1,
45+
filter_size=3,
46+
stride=2,
47+
padding=1,
48+
trans=True)
49+
m8 += conv_projection(
50+
img,
51+
filter_size=3,
52+
num_filters=64,
53+
num_channels=1,
54+
stride=2,
55+
padding=1,
56+
trans=True)
3857
end = mixed_layer(
3958
input=[
4059
full_matrix_projection(input=m5),
41-
trans_full_matrix_projection(input=m6), full_matrix_projection(input=m7)
60+
trans_full_matrix_projection(input=m6),
61+
full_matrix_projection(input=m7), full_matrix_projection(input=m8)
4262
],
4363
size=100,
4464
layer_attr=ExtraAttr(

0 commit comments

Comments
 (0)