Add functional convolutions in paddle.nn.functional (#23408)

* add functional conv

* add test and doc for function convs, test=develop

* update ConvTransposeOp's InferShape and error message, test=develop
revert-23830-2.0-beta
Feiyu Chan 5 years ago committed by GitHub
parent 70782e6379
commit 81f1402f6c
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

@ -109,14 +109,30 @@ void ConvTransposeOp::InferShape(framework::InferShapeContext* ctx) const {
const int offset = (data_layout != DataLayout::kNHWC ? 2 : 1); const int offset = (data_layout != DataLayout::kNHWC ? 2 : 1);
for (size_t i = 0; i < strides.size(); ++i) { for (size_t i = 0; i < strides.size(); ++i) {
auto filter_extent = dilations[i] * (filter_dims[i + 2] - 1) + 1; auto filter_extent = dilations[i] * (filter_dims[i + 2] - 1) + 1;
auto infer_shape = (in_dims[i + offset] - 1) * strides[i] - auto infer_shape = (ctx->IsRuntime() || in_dims[i + offset] > 0)
paddings[2 * i] - paddings[2 * i + 1] + filter_extent; ? (in_dims[i + offset] - 1) * strides[i] -
paddings[2 * i] - paddings[2 * i + 1] +
filter_extent
: -1;
if (output_size.size()) { if (output_size.size()) {
PADDLE_ENFORCE_EQ((output_size[i] >= infer_shape && if (ctx->IsRuntime()) {
output_size[i] < infer_shape + strides[i]), PADDLE_ENFORCE_GE(
true, output_size[i], infer_shape,
"output_size of Op(ConvTransposeOp) should be " platform::errors::InvalidArgument(
"in appropriate range."); "output_size of Op(ConvTransposeOp) should not be "
"less than the infered output size. But received output_size = "
"[%s], whose dim %d is less than the infered output size [%s]",
framework::make_ddim(output_size), i, infer_shape));
PADDLE_ENFORCE_LT(
output_size[i], infer_shape + strides[i],
platform::errors::InvalidArgument(
"output_size of Op(ConvTransposeOp) should be less "
"than infered size + stride. But received output_size = [%s], "
"whose dim %d is not less than the infered output size (%d) + "
"stride (%d) = %d",
framework::make_ddim(output_size), i, infer_shape, strides[i],
infer_shape + strides[i]));
}
output_shape.push_back(output_size[i]); output_shape.push_back(output_size[i]);
} else { } else {
output_shape.push_back(infer_shape); output_shape.push_back(infer_shape);

@ -3857,10 +3857,10 @@ def conv2d_transpose(input,
if output_size is None: if output_size is None:
output_size = [] output_size = []
elif isinstance(output_size, list) or isinstance(output_size, int): elif isinstance(output_size, (list, tuple, int)):
output_size = utils.convert_to_list(output_size, 2, 'output_size') output_size = utils.convert_to_list(output_size, 2, 'output_size')
else: else:
raise ValueError("output_size should be list or int") raise ValueError("output_size should be int, list[int] or tuple[int]")
groups = 1 if groups is None else groups groups = 1 if groups is None else groups
filter_shape = [input_channel, num_filters // groups] + filter_size filter_shape = [input_channel, num_filters // groups] + filter_size
@ -4129,7 +4129,7 @@ def conv3d_transpose(input,
if output_size is None: if output_size is None:
raise ValueError("output_size must be set when filter_size is None") raise ValueError("output_size must be set when filter_size is None")
if isinstance(output_size, int): if isinstance(output_size, int):
output_size = [output_size, output_size] output_size = [output_size, output_size, output_size]
d_in = input.shape[2] if data_format == 'NCDHW' else input.shape[1] d_in = input.shape[2] if data_format == 'NCDHW' else input.shape[1]
h_in = input.shape[3] if data_format == 'NCDHW' else input.shape[2] h_in = input.shape[3] if data_format == 'NCDHW' else input.shape[2]
@ -4149,6 +4149,13 @@ def conv3d_transpose(input,
if len(padding) == 6 and utils._is_symmetric_padding(padding, 3): if len(padding) == 6 and utils._is_symmetric_padding(padding, 3):
padding = [padding[0], padding[2], padding[4]] padding = [padding[0], padding[2], padding[4]]
if output_size is None:
output_size = []
elif isinstance(output_size, (list, tuple, int)):
output_size = utils.convert_to_list(output_size, 3, 'output_size')
else:
raise ValueError("output_size should be int, list[int] or tuple[int]")
groups = 1 if groups is None else groups groups = 1 if groups is None else groups
filter_shape = [input_channel, num_filters // groups] + filter_size filter_shape = [input_channel, num_filters // groups] + filter_size
img_filter = helper.create_parameter( img_filter = helper.create_parameter(
@ -4166,6 +4173,7 @@ def conv3d_transpose(input,
'Filter': [img_filter]}, 'Filter': [img_filter]},
outputs={'Output': pre_bias}, outputs={'Output': pre_bias},
attrs={ attrs={
'output_size': output_size,
'strides': stride, 'strides': stride,
'paddings': padding, 'paddings': padding,
'padding_algorithm': padding_algorithm, 'padding_algorithm': padding_algorithm,

@ -12,7 +12,7 @@
# See the License for the specific language governing permissions and # See the License for the specific language governing permissions and
# limitations under the License. # limitations under the License.
# TODO: import all neural network related api under this directory, # TODO: import all neural network related api under this directory,
# including layers, linear, conv, rnn etc. # including layers, linear, conv, rnn etc.
__all__ = [] __all__ = []
@ -85,10 +85,10 @@ from .layer import loss #DEFINE_ALIAS
# from .layer.common import Embedding #DEFINE_ALIAS # from .layer.common import Embedding #DEFINE_ALIAS
# from .layer.common import Linear #DEFINE_ALIAS # from .layer.common import Linear #DEFINE_ALIAS
# from .layer.common import UpSample #DEFINE_ALIAS # from .layer.common import UpSample #DEFINE_ALIAS
# from .functional.conv import conv2d #DEFINE_ALIAS from .functional.conv import conv2d #DEFINE_ALIAS
# from .functional.conv import conv2d_transpose #DEFINE_ALIAS from .functional.conv import conv2d_transpose #DEFINE_ALIAS
# from .functional.conv import conv3d #DEFINE_ALIAS from .functional.conv import conv3d #DEFINE_ALIAS
# from .functional.conv import conv3d_transpose #DEFINE_ALIAS from .functional.conv import conv3d_transpose #DEFINE_ALIAS
# from .functional.loss import bpr_loss #DEFINE_ALIAS # from .functional.loss import bpr_loss #DEFINE_ALIAS
# from .functional.loss import center_loss #DEFINE_ALIAS # from .functional.loss import center_loss #DEFINE_ALIAS
# from .functional.loss import cross_entropy #DEFINE_ALIAS # from .functional.loss import cross_entropy #DEFINE_ALIAS

@ -12,15 +12,15 @@
# See the License for the specific language governing permissions and # See the License for the specific language governing permissions and
# limitations under the License. # limitations under the License.
# TODO: import all neural network related api under this directory, # TODO: import all neural network related api under this directory,
# including layers, linear, conv, rnn etc. # including layers, linear, conv, rnn etc.
# __all__ = [ ] # __all__ = [ ]
# TODO: define alias in functional directory # TODO: define alias in functional directory
# from .conv import conv2d #DEFINE_ALIAS from .conv import conv2d #DEFINE_ALIAS
# from .conv import conv2d_transpose #DEFINE_ALIAS from .conv import conv2d_transpose #DEFINE_ALIAS
# from .conv import conv3d #DEFINE_ALIAS from .conv import conv3d #DEFINE_ALIAS
# from .conv import conv3d_transpose #DEFINE_ALIAS from .conv import conv3d_transpose #DEFINE_ALIAS
# from .loss import bpr_loss #DEFINE_ALIAS # from .loss import bpr_loss #DEFINE_ALIAS
# from .loss import center_loss #DEFINE_ALIAS # from .loss import center_loss #DEFINE_ALIAS
# from .loss import cross_entropy #DEFINE_ALIAS # from .loss import cross_entropy #DEFINE_ALIAS

File diff suppressed because it is too large Load Diff

@ -146,7 +146,10 @@ packages=['paddle',
'paddle.fluid.incubate.fleet.parameter_server.distribute_transpiler', 'paddle.fluid.incubate.fleet.parameter_server.distribute_transpiler',
'paddle.fluid.incubate.fleet.parameter_server.pslib', 'paddle.fluid.incubate.fleet.parameter_server.pslib',
'paddle.fluid.incubate.fleet.collective', 'paddle.fluid.incubate.fleet.collective',
'paddle.fluid.incubate.fleet.utils'] 'paddle.fluid.incubate.fleet.utils',
'paddle.nn',
'paddle.nn.functional',
'paddle.nn.layer']
with open('@PADDLE_SOURCE_DIR@/python/requirements.txt') as f: with open('@PADDLE_SOURCE_DIR@/python/requirements.txt') as f:
setup_requires = f.read().splitlines() setup_requires = f.read().splitlines()

Loading…
Cancel
Save